Skip to content

Commit cb07936

Browse files
committed
RI-6371 code refactor
1 parent bbeb2e4 commit cb07936

File tree

15 files changed

+310
-145
lines changed

15 files changed

+310
-145
lines changed

redisinsight/ui/src/components/instance-header/InstanceHeader.spec.tsx

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -101,8 +101,6 @@ describe('InstanceHeader', () => {
101101
fireEvent.click(screen.getByTestId('apply-btn'))
102102

103103
const expectedActions = [
104-
loadInstances(),
105-
loadRdiInstances(),
106104
checkDatabaseIndex()
107105
]
108106
expect(store.getActions()).toEqual([...expectedActions])

redisinsight/ui/src/components/instance-header/InstanceHeader.tsx

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,7 @@ import {
1414
connectedInstanceInfoSelector,
1515
connectedInstanceOverviewSelector,
1616
connectedInstanceSelector,
17-
fetchInstancesAction,
1817
} from 'uiSrc/slices/instances/instances'
19-
import { fetchInstancesAction as fetchRdiInstancesAction } from 'uiSrc/slices/rdi/instances'
2018
import { appInfoSelector } from 'uiSrc/slices/app/info'
2119
import { appContextDbIndex, clearBrowserKeyListData, setBrowserSelectedKey } from 'uiSrc/slices/app/context'
2220

@@ -73,11 +71,6 @@ const InstanceHeader = ({ onChangeDbIndex }: Props) => {
7371

7472
useEffect(() => { setDbIndex(String(db || 0)) }, [db])
7573

76-
useEffect(() => {
77-
dispatch(fetchInstancesAction())
78-
dispatch(fetchRdiInstancesAction())
79-
}, [])
80-
8174
const isRedisStack = server?.buildType === BuildType.RedisStack
8275

8376
const goHome = () => {

redisinsight/ui/src/components/instance-header/components/instances-navigation-popover/InstancesNavigationPopover.spec.tsx

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -109,13 +109,13 @@ describe('InstancesNavigationPopover', () => {
109109
act(() => {
110110
fireEvent.click(screen.getByTestId(`${InstancesTabs.RDI}-tab-id`))
111111
})
112-
expect(screen.getByText('All RDIs')).toBeInTheDocument()
112+
expect(screen.getByText('Redis Data Integration page')).toBeInTheDocument()
113113

114114
act(() => {
115115
fireEvent.click(screen.getByTestId(`${InstancesTabs.Databases}-tab-id`))
116116
})
117117

118-
expect(screen.getByText('All Databases')).toBeInTheDocument()
118+
expect(screen.getByText('Redis Databases page')).toBeInTheDocument()
119119
})
120120

121121
it('should send event telemetry', () => {

redisinsight/ui/src/components/instance-header/components/instances-navigation-popover/InstancesNavigationPopover.tsx

Lines changed: 13 additions & 110 deletions
Original file line numberDiff line numberDiff line change
@@ -1,21 +1,18 @@
11
import React, { ChangeEvent, useEffect, useState } from 'react'
2-
import { EuiDescriptionListDescription, EuiFieldText, EuiIcon, EuiListGroup, EuiListGroupItem, EuiLoadingSpinner, EuiPopover, EuiSpacer, EuiTab, EuiTabs, EuiText } from '@elastic/eui'
2+
import { EuiFieldText, EuiIcon, EuiPopover, EuiSpacer, EuiTab, EuiTabs, EuiText } from '@elastic/eui'
33
import cx from 'classnames'
4-
import { useDispatch, useSelector } from 'react-redux'
4+
import { useSelector } from 'react-redux'
55
import { useHistory, useParams } from 'react-router-dom'
6-
import { checkConnectToRdiInstanceAction, instancesSelector as rdiInstancesSelector } from 'uiSrc/slices/rdi/instances'
7-
import { checkConnectToInstanceAction, instancesSelector as dbInstancesSelector, setConnectedInstanceId } from 'uiSrc/slices/instances/instances'
6+
import { instancesSelector as rdiInstancesSelector } from 'uiSrc/slices/rdi/instances'
7+
import { instancesSelector as dbInstancesSelector } from 'uiSrc/slices/instances/instances'
88
import Divider from 'uiSrc/components/divider/Divider'
99
import { Pages } from 'uiSrc/constants'
10-
import { resetRdiContext, setAppContextInitialState, setAppContextConnectedRdiInstanceId } from 'uiSrc/slices/app/context'
11-
import { resetKeys } from 'uiSrc/slices/browser/keys'
12-
import { resetRedisearchKeysData } from 'uiSrc/slices/browser/redisearch'
13-
import { resetCliHelperSettings, resetCliSettingsAction } from 'uiSrc/slices/cli/cli-settings'
1410
import Down from 'uiSrc/assets/img/Down.svg?react'
1511
import Search from 'uiSrc/assets/img/Search.svg'
1612
import { Instance, RdiInstance } from 'uiSrc/slices/interfaces'
17-
import { TelemetryEvent, getRedisModulesSummary, sendEventTelemetry } from 'uiSrc/telemetry'
13+
import { TelemetryEvent, sendEventTelemetry } from 'uiSrc/telemetry'
1814
import { getDbIndex } from 'uiSrc/utils'
15+
import InstancesList from './components/instances-list'
1916
import styles from './styles.module.scss'
2017

2118
export interface Props {
@@ -32,16 +29,13 @@ const InstancesNavigationPopover = ({ name }: Props) => {
3229
const [searchFilter, setSearchFilter] = useState('')
3330
const [filteredDbInstances, setFilteredDbInstances] = useState<Instance[]>([])
3431
const [filteredRdiInstances, setFilteredRdiInstances] = useState<RdiInstance[]>([])
35-
const [loading, setLoading] = useState<boolean>(false)
36-
const [selected, setSelected] = useState<string>('')
3732

3833
const { instanceId, rdiInstanceId } = useParams<{ instanceId: string, rdiInstanceId: string }>()
3934
const [selectedTab, setSelectedTab] = useState(rdiInstanceId ? InstancesTabs.RDI : InstancesTabs.Databases)
4035

41-
const { data: rdiInstances, connectedInstance: connectedRdiInstance } = useSelector(rdiInstancesSelector)
42-
const { data: dbInstances, connectedInstance: connectedDbInstance } = useSelector(dbInstancesSelector)
36+
const { data: rdiInstances } = useSelector(rdiInstancesSelector)
37+
const { data: dbInstances } = useSelector(dbInstancesSelector)
4338
const history = useHistory()
44-
const dispatch = useDispatch()
4539

4640
useEffect(() => {
4741
const dbFiltered = dbInstances?.filter((db) => {
@@ -72,106 +66,11 @@ const InstancesNavigationPopover = ({ name }: Props) => {
7266
setIsPopoverOpen((isPopoverOpen) => !isPopoverOpen)
7367
}
7468

75-
const connectToInstance = (id = '') => {
76-
// reset rdi context
77-
dispatch(resetRdiContext())
78-
79-
dispatch(resetKeys())
80-
dispatch(resetRedisearchKeysData())
81-
dispatch(resetCliSettingsAction())
82-
dispatch(resetCliHelperSettings())
83-
dispatch(setAppContextInitialState())
84-
85-
dispatch(setConnectedInstanceId(id))
86-
setLoading(false)
87-
history.push(Pages.browser(id))
88-
}
89-
9069
const btnLabel = selectedTab === InstancesTabs.Databases ? 'Redis Databases page' : 'Redis Data Integration page'
9170

9271
const goHome = () => {
9372
history.push(selectedTab === InstancesTabs.Databases ? Pages.home : Pages.rdi)
9473
}
95-
const renderInstances = () => {
96-
const instances = selectedTab === InstancesTabs.Databases ? filteredDbInstances : filteredRdiInstances
97-
98-
const goToInstance = (instance: Instance) => {
99-
if (connectedDbInstance?.id === instance.id) {
100-
// already connected so do nothing
101-
return
102-
}
103-
setLoading(true)
104-
const modulesSummary = getRedisModulesSummary(instance.modules)
105-
sendEventTelemetry({
106-
event: TelemetryEvent.CONFIG_DATABASES_OPEN_DATABASE,
107-
eventData: {
108-
databaseId: instance.id,
109-
source: 'navigation_panel',
110-
provider: instance.provider,
111-
...modulesSummary,
112-
}
113-
})
114-
dispatch(checkConnectToInstanceAction(instance.id, connectToInstance, () => setLoading(false), false))
115-
}
116-
117-
const goToRdiInstance = (instance: RdiInstance) => {
118-
if (connectedRdiInstance?.id === instance.id) {
119-
// already connected so do nothing
120-
return
121-
}
122-
setLoading(true)
123-
dispatch(checkConnectToRdiInstanceAction(
124-
instance.id,
125-
(id: string) => {
126-
setLoading(false)
127-
history.push(Pages.rdiPipeline(id))
128-
},
129-
() => setLoading(false)
130-
))
131-
}
132-
133-
const goToPage = (instance: Instance | RdiInstance) => {
134-
if (selectedTab === InstancesTabs.Databases) {
135-
goToInstance(instance as Instance)
136-
} else {
137-
goToRdiInstance(instance as RdiInstance)
138-
}
139-
}
140-
141-
const isInstanceActive = (id: string) => {
142-
if (selectedTab === InstancesTabs.Databases) {
143-
return id === instanceId
144-
}
145-
return id === rdiInstanceId
146-
}
147-
148-
return (
149-
<div className={styles.listContainer}>
150-
<EuiListGroup flush maxWidth="none" gutterSize="none">
151-
{instances?.map((instance) => (
152-
<EuiListGroupItem
153-
className={styles.item}
154-
isActive={isInstanceActive(instance.id)}
155-
disabled={loading}
156-
key={instance.id}
157-
label={(
158-
<EuiText style={{ display: 'flex', alignItems: 'center' }}>
159-
{loading && instance?.id === selected && <EuiLoadingSpinner size="s" style={{ marginRight: '8px' }} />}
160-
{instance.name}
161-
{' '}
162-
{getDbIndex(instance.db)}
163-
</EuiText>
164-
)}
165-
onClick={() => {
166-
setSelected(instance.id)
167-
goToPage(instance)
168-
}}
169-
/>
170-
))}
171-
</EuiListGroup>
172-
</div>
173-
)
174-
}
17574

17675
return (
17776
<EuiPopover
@@ -231,7 +130,11 @@ const InstancesNavigationPopover = ({ name }: Props) => {
231130
</EuiTabs>
232131
</div>
233132
<EuiSpacer size="m" />
234-
{renderInstances()}
133+
<InstancesList
134+
selectedTab={selectedTab}
135+
filteredDbInstances={filteredDbInstances}
136+
filteredRdiInstances={filteredRdiInstances}
137+
/>
235138
<div>
236139
<EuiSpacer size="m" />
237140
<Divider />
Lines changed: 112 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,112 @@
1+
import { cloneDeep } from 'lodash'
2+
import React from 'react'
3+
import { instance, mock } from 'ts-mockito'
4+
import { act } from 'react-dom/test-utils'
5+
import { cleanup, fireEvent, mockedStore, render, screen } from 'uiSrc/utils/test-utils'
6+
import { TelemetryEvent, sendEventTelemetry } from 'uiSrc/telemetry'
7+
import InstancesList, { InstancesListProps } from './InstancesList'
8+
import { InstancesTabs } from '../../InstancesNavigationPopover'
9+
10+
const mockedProps = mock<InstancesListProps>()
11+
12+
let store: typeof mockedStore
13+
beforeEach(() => {
14+
cleanup()
15+
store = cloneDeep(mockedStore)
16+
store.clearActions()
17+
})
18+
19+
const mockRdis = [
20+
{
21+
id: 'rdiDB_1',
22+
name: 'RdiDB_1'
23+
},
24+
{
25+
id: 'rdiDB_2',
26+
name: 'RdiDB_2'
27+
}
28+
]
29+
30+
const mockDbs = [
31+
{
32+
id: 'db_1',
33+
name: 'DB_1'
34+
},
35+
{
36+
id: 'db_2',
37+
name: 'DB_2'
38+
}
39+
]
40+
41+
jest.mock('uiSrc/slices/rdi/instances', () => ({
42+
...jest.requireActual('uiSrc/slices/rdi/instances'),
43+
instancesSelector: jest.fn().mockReturnValue({
44+
data: mockRdis,
45+
connectedInstance: {
46+
id: 'rdiDB_1',
47+
name: 'RdiDB_1'
48+
},
49+
})
50+
}))
51+
52+
jest.mock('uiSrc/slices/instances/instances', () => ({
53+
...jest.requireActual('uiSrc/slices/instances/instances'),
54+
instancesSelector: jest.fn().mockReturnValue({
55+
data: mockDbs,
56+
connectedInstance: {
57+
id: 'db_1',
58+
name: 'DB_1'
59+
},
60+
})
61+
}))
62+
63+
jest.mock('uiSrc/telemetry', () => ({
64+
...jest.requireActual('uiSrc/telemetry'),
65+
sendEventTelemetry: jest.fn(),
66+
}))
67+
68+
describe('InstancesList', () => {
69+
it('should render', () => {
70+
expect(render(<InstancesList {...instance(mockedProps)} />)).toBeTruthy()
71+
})
72+
73+
it('should render database instances when selected tab is db', () => {
74+
render(<InstancesList
75+
{...instance(mockedProps)}
76+
selectedTab={InstancesTabs.Databases}
77+
filteredDbInstances={mockDbs}
78+
/>)
79+
80+
expect(screen.getByText(mockDbs[0].name)).toBeInTheDocument()
81+
})
82+
83+
it('should render rdi instances when selected tab is rdi', () => {
84+
render(<InstancesList
85+
{...instance(mockedProps)}
86+
selectedTab={InstancesTabs.RDI}
87+
filteredRdiInstances={mockRdis}
88+
/>)
89+
expect(screen.getByText(mockRdis[0].name)).toBeInTheDocument()
90+
})
91+
92+
it('should send event telemetry', () => {
93+
const sendEventTelemetryMock = jest.fn();
94+
(sendEventTelemetry as jest.Mock).mockImplementation(() => sendEventTelemetryMock)
95+
96+
render(<InstancesList
97+
{...instance(mockedProps)}
98+
selectedTab={InstancesTabs.Databases}
99+
filteredDbInstances={mockDbs}
100+
/>)
101+
102+
const listItem = screen.getByTestId(`instance-item-${mockDbs[1].id}`)
103+
act(() => {
104+
fireEvent.click(listItem)
105+
})
106+
107+
expect(sendEventTelemetry).toBeCalledWith({
108+
event: TelemetryEvent.CONFIG_DATABASES_OPEN_DATABASE,
109+
eventData: expect.any(Object)
110+
})
111+
})
112+
})

0 commit comments

Comments
 (0)