Skip to content

Commit cbc5242

Browse files
authored
RI-7399: Add "Create Free Cloud DB" button to db list (#5160)
1 parent 3095574 commit cbc5242

File tree

5 files changed

+118
-54
lines changed

5 files changed

+118
-54
lines changed

redisinsight/ui/src/pages/home/components/database-list-component/DatabasesListWrapper.tsx

Lines changed: 4 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -55,8 +55,6 @@ import {
5555
CONNECTION_TYPE_DISPLAY,
5656
ConnectionType,
5757
Instance,
58-
OAuthSocialAction,
59-
OAuthSocialSource,
6058
} from 'uiSrc/slices/interfaces'
6159
import {
6260
getRedisInfoSummary,
@@ -72,11 +70,8 @@ import {
7270
replaceSpaces,
7371
} from 'uiSrc/utils'
7472

75-
import { setSSOFlow } from 'uiSrc/slices/instances/cloud'
76-
import { setSocialDialogState } from 'uiSrc/slices/oauth/cloud'
7773
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
78-
import { getUtmExternalLink } from 'uiSrc/utils/links'
79-
import { CREATE_CLOUD_DB_ID, HELP_LINKS } from 'uiSrc/pages/home/constants'
74+
import { CREATE_CLOUD_DB_ID } from 'uiSrc/pages/home/constants'
8075

8176
import { Tag } from 'uiSrc/slices/interfaces/tag'
8277
import { FeatureFlagComponent } from 'uiSrc/components'
@@ -86,6 +81,7 @@ import { Link } from 'uiSrc/components/base/link/Link'
8681
import { RIResizeObserver } from 'uiSrc/components/base/utils'
8782
import { Row } from 'uiSrc/components/base/layout/flex'
8883

84+
import handleClickFreeDb from './methods/handleClickFreeCloudDb'
8985
import DbStatus from '../db-status'
9086
import { TagsCell } from '../tags-cell/TagsCell'
9187
import { TagsCellHeader } from '../tags-cell/TagsCellHeader'
@@ -122,10 +118,8 @@ const DatabasesListWrapper = (props: Props) => {
122118
const { theme } = useContext(ThemeContext)
123119

124120
const { contextInstanceId } = useSelector(appContextSelector)
125-
const {
126-
[FeatureFlags.cloudSso]: cloudSsoFeature,
127-
[FeatureFlags.databaseManagement]: databaseManagementFeature,
128-
} = useSelector(appFeatureFlagsFeaturesSelector)
121+
const { [FeatureFlags.databaseManagement]: databaseManagementFeature } =
122+
useSelector(appFeatureFlagsFeaturesSelector)
129123
const { shownColumns } = useSelector(instancesSelector)
130124

131125
const [width, setWidth] = useState(0)
@@ -312,35 +306,6 @@ const DatabasesListWrapper = (props: Props) => {
312306
})
313307
}
314308

315-
const handleClickFreeDb = () => {
316-
if (cloudSsoFeature?.flag) {
317-
dispatch(setSSOFlow(OAuthSocialAction.Create))
318-
dispatch(setSocialDialogState(OAuthSocialSource.DatabaseConnectionList))
319-
sendEventTelemetry({
320-
event: TelemetryEvent.CLOUD_FREE_DATABASE_CLICKED,
321-
eventData: { source: OAuthSocialSource.DatabaseConnectionList },
322-
})
323-
return
324-
}
325-
326-
sendEventTelemetry({
327-
event: HELP_LINKS.cloud.event,
328-
eventData: { source: HELP_LINKS.cloud.sources.databaseConnectionList },
329-
})
330-
331-
const link = document.createElement('a')
332-
link.setAttribute(
333-
'href',
334-
getUtmExternalLink(EXTERNAL_LINKS.tryFree, {
335-
campaign: 'list_of_databases',
336-
}),
337-
)
338-
link.setAttribute('target', '_blank')
339-
340-
link.click()
341-
link.remove()
342-
}
343-
344309
const getRowProps = (instance: Instance) => ({
345310
className: cx({
346311
'euiTableRow-isSelected': instance?.id === editedInstance?.id,
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
import { FeatureFlags } from 'uiSrc/constants'
2+
import { EXTERNAL_LINKS } from 'uiSrc/constants/links'
3+
4+
import { OAuthSocialAction, OAuthSocialSource } from 'uiSrc/slices/interfaces'
5+
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
6+
7+
import { setSSOFlow } from 'uiSrc/slices/instances/cloud'
8+
import { setSocialDialogState } from 'uiSrc/slices/oauth/cloud'
9+
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
10+
import { getUtmExternalLink } from 'uiSrc/utils/links'
11+
import { HELP_LINKS } from 'uiSrc/pages/home/constants'
12+
13+
import { dispatch, store } from 'uiSrc/slices/store'
14+
15+
// Note: Extracted from DatabasesListWrapper.tsx
16+
const handleClickFreeCloudDb = () => {
17+
const { [FeatureFlags.cloudSso]: cloudSsoFeature } =
18+
appFeatureFlagsFeaturesSelector(store.getState())
19+
20+
if (cloudSsoFeature?.flag) {
21+
dispatch(setSSOFlow(OAuthSocialAction.Create))
22+
dispatch(setSocialDialogState(OAuthSocialSource.DatabaseConnectionList))
23+
sendEventTelemetry({
24+
event: TelemetryEvent.CLOUD_FREE_DATABASE_CLICKED,
25+
eventData: { source: OAuthSocialSource.DatabaseConnectionList },
26+
})
27+
return
28+
}
29+
30+
sendEventTelemetry({
31+
event: HELP_LINKS.cloud.event,
32+
eventData: { source: HELP_LINKS.cloud.sources.databaseConnectionList },
33+
})
34+
35+
const link = document.createElement('a')
36+
link.setAttribute(
37+
'href',
38+
getUtmExternalLink(EXTERNAL_LINKS.tryFree, {
39+
campaign: 'list_of_databases',
40+
}),
41+
)
42+
link.setAttribute('target', '_blank')
43+
44+
link.click()
45+
link.remove()
46+
}
47+
48+
export default handleClickFreeCloudDb

redisinsight/ui/src/pages/home/components/database-list-header/DatabaseListHeader.spec.tsx

Lines changed: 38 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,10 +4,13 @@ import { cloneDeep } from 'lodash'
44

55
import { cleanup, fireEvent, mockedStore, render, screen } from 'uiSrc/utils/test-utils'
66
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
7-
import { ConnectionType, Instance } from 'uiSrc/slices/interfaces'
7+
import { ConnectionType, Instance, OAuthSocialAction, OAuthSocialSource } from 'uiSrc/slices/interfaces'
88
import { DatabaseListColumn } from 'uiSrc/constants'
99
import { instancesSelector, setShownColumns } from 'uiSrc/slices/instances/instances'
10+
import { setSSOFlow } from 'uiSrc/slices/instances/cloud'
11+
import { setSocialDialogState } from 'uiSrc/slices/oauth/cloud'
1012
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
13+
import { CREATE_CLOUD_DB_ID } from 'uiSrc/pages/home/constants'
1114

1215
import DatabaseListHeader, { Props } from './DatabaseListHeader'
1316

@@ -216,4 +219,38 @@ describe('DatabaseListHeader', () => {
216219
},
217220
})
218221
})
222+
223+
it('should dispatch SSO actions when clicking Create Free Cloud DB header button', () => {
224+
const featureMock = appFeatureFlagsFeaturesSelector as jest.Mock
225+
226+
// Ensure the header button is visible and SSO path is taken
227+
featureMock.mockReturnValue({
228+
enhancedCloudUI: { flag: true },
229+
cloudAds: { flag: true },
230+
cloudSso: { flag: true },
231+
databaseManagement: { flag: true },
232+
})
233+
234+
render(<DatabaseListHeader {...instance(mockedProps)} />)
235+
236+
const btn = screen.getByTestId(`${CREATE_CLOUD_DB_ID}-button`)
237+
expect(btn).toBeInTheDocument()
238+
239+
fireEvent.click(btn)
240+
241+
expect(store.getActions()).toEqual(
242+
expect.arrayContaining([
243+
setSSOFlow(OAuthSocialAction.Create),
244+
setSocialDialogState(OAuthSocialSource.DatabaseConnectionList),
245+
]),
246+
)
247+
248+
// Restore default flags for other tests
249+
featureMock.mockReturnValue({
250+
enhancedCloudUI: { flag: false },
251+
databaseManagement: { flag: true },
252+
cloudAds: { flag: true },
253+
})
254+
})
255+
219256
})

redisinsight/ui/src/pages/home/components/database-list-header/DatabaseListHeader.tsx

Lines changed: 27 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import { FeatureFlagComponent, OAuthSsoHandlerDialog } from 'uiSrc/components'
1515
import { RiPopover } from 'uiSrc/components/base'
1616
import { getPathToResource } from 'uiSrc/services/resourcesService'
1717
import { ContentCreateRedis } from 'uiSrc/slices/interfaces/content'
18-
import { HELP_LINKS } from 'uiSrc/pages/home/constants'
18+
import { CREATE_CLOUD_DB_ID, HELP_LINKS } from 'uiSrc/pages/home/constants'
1919
import { contentSelector } from 'uiSrc/slices/content/create-redis-buttons'
2020
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
2121
import { getContentByFeature } from 'uiSrc/utils/content'
@@ -33,6 +33,7 @@ import {
3333
} from 'uiSrc/components/base/forms/buttons'
3434
import { ColumnsIcon } from 'uiSrc/components/base/icons'
3535
import { Checkbox } from 'uiSrc/components/base/forms/checkbox/Checkbox'
36+
import handleClickFreeCloudDb from '../database-list-component/methods/handleClickFreeCloudDb'
3637
import SearchDatabasesList from '../search-databases-list'
3738

3839
import styles from './styles.module.scss'
@@ -62,7 +63,7 @@ const DatabaseListHeader = ({ onAddInstance }: Props) => {
6263
}
6364

6465
if (data?.cloud && !isEmpty(data.cloud)) {
65-
setPromoData(getContentByFeature(data.cloud, featureFlags))
66+
setPromoData(getContentByFeature(data.cloud as any, featureFlags))
6667
}
6768
}, [loading, data, featureFlags])
6869

@@ -122,14 +123,28 @@ const DatabaseListHeader = ({ onAddInstance }: Props) => {
122123
})
123124
}
124125

125-
const AddInstanceBtn = () => (
126-
<PrimaryButton
127-
onClick={handleOnAddDatabase}
128-
className={styles.addInstanceBtn}
129-
data-testid="add-redis-database-short"
126+
const AddCloudInstanceButton = () => (
127+
<FeatureFlagComponent
128+
name={[FeatureFlags.enhancedCloudUI, FeatureFlags.cloudAds]}
130129
>
131-
<span>+ Add Redis database</span>
132-
</PrimaryButton>
130+
<PrimaryButton
131+
onClick={handleClickFreeCloudDb}
132+
data-testid={`${CREATE_CLOUD_DB_ID}-button`}
133+
>
134+
+ Create Free Cloud DB
135+
</PrimaryButton>
136+
</FeatureFlagComponent>
137+
)
138+
139+
const AddLocalInstanceButton = () => (
140+
<FeatureFlagComponent name={FeatureFlags.databaseManagement}>
141+
<SecondaryButton
142+
onClick={handleOnAddDatabase}
143+
data-testid="add-redis-database-short"
144+
>
145+
+ Connect Existing DB
146+
</SecondaryButton>
147+
</FeatureFlagComponent>
133148
)
134149

135150
const CreateBtn = ({ content }: { content: ContentCreateRedis }) => {
@@ -191,10 +206,9 @@ const DatabaseListHeader = ({ onAddInstance }: Props) => {
191206
responsive={false}
192207
gap="s"
193208
>
194-
<FlexItem>
195-
<FeatureFlagComponent name={FeatureFlags.databaseManagement}>
196-
<AddInstanceBtn />
197-
</FeatureFlagComponent>
209+
<FlexItem direction="row" $gap="m">
210+
<AddCloudInstanceButton />
211+
<AddLocalInstanceButton />
198212
</FlexItem>
199213
{!loading && !isEmpty(data) && (
200214
<FlexItem className={cx(styles.promo)}>

redisinsight/ui/src/utils/test-store.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ const getState: ReduxStore['getState'] = () => {
2222
return storeRef.getState()
2323
}
2424

25-
const dispatch: ReduxStore['dispatch'] = (action: any) => {
25+
export const dispatch: ReduxStore['dispatch'] = (action: any) => {
2626
if (!storeRef) {
2727
throw new Error(
2828
'Store not initialized. Make sure store-dynamic is imported after store creation.',

0 commit comments

Comments
 (0)