Skip to content

Commit 55023a5

Browse files
authored
RI-7705: refactor RdiInstancesList (#5188)
1 parent ff5f269 commit 55023a5

File tree

5 files changed

+67
-70
lines changed

5 files changed

+67
-70
lines changed
Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,8 @@
1-
import React from 'react'
2-
31
import { ColumnDef, Table } from 'uiSrc/components/base/layout/table'
42
import { RDI_COLUMN_FIELD_NAME_MAP, RdiListColumn } from 'uiSrc/constants'
53
import { RdiInstance } from 'uiSrc/slices/interfaces'
64

5+
import RdiInstancesListCellSelect from './components/RdiInstancesListCellSelect/RdiInstancesListCellSelect'
76
import RdiInstancesListCellControls from './components/RdiInstancesListCellControls/RdiInstancesListCellControls'
87
import RdiInstancesListCell from './components/RdiInstancesListCell/RdiInstancesListCell'
98

@@ -17,21 +16,14 @@ export const BASE_COLUMNS: ColumnDef<RdiInstance>[] = [
1716
isHeaderCustom: true,
1817
enableSorting: false,
1918
header: Table.HeaderMultiRowSelectionButton,
20-
cell: (props) => (
21-
<Table.RowSelectionButton
22-
{...props}
23-
onClick={(e: any) => e.stopPropagation()}
24-
/>
25-
),
19+
cell: RdiInstancesListCellSelect,
2620
},
2721
{
2822
id: RdiListColumn.Name,
2923
accessorKey: RdiListColumn.Name,
3024
header: RDI_COLUMN_FIELD_NAME_MAP.get(RdiListColumn.Name),
3125
enableSorting: true,
32-
cell: (props) => (
33-
<RdiInstancesListCell {...props} field={RdiListColumn.Name} />
34-
),
26+
cell: RdiInstancesListCell,
3527
sortingFn: (rowA, rowB) =>
3628
`${rowA.original.name?.toLowerCase()}`.localeCompare(
3729
`${rowB.original.name?.toLowerCase()}`,
@@ -42,9 +34,7 @@ export const BASE_COLUMNS: ColumnDef<RdiInstance>[] = [
4234
accessorKey: RdiListColumn.Url,
4335
header: RDI_COLUMN_FIELD_NAME_MAP.get(RdiListColumn.Url),
4436
enableSorting: true,
45-
cell: (props) => (
46-
<RdiInstancesListCell {...props} field={RdiListColumn.Url} withCopyIcon />
47-
),
37+
cell: RdiInstancesListCell,
4838
sortingFn: (rowA, rowB) =>
4939
`${rowA.original.url?.toLowerCase()}`.localeCompare(
5040
`${rowB.original.url?.toLowerCase()}`,
@@ -55,18 +45,14 @@ export const BASE_COLUMNS: ColumnDef<RdiInstance>[] = [
5545
accessorKey: RdiListColumn.Version,
5646
header: RDI_COLUMN_FIELD_NAME_MAP.get(RdiListColumn.Version),
5747
enableSorting: true,
58-
cell: (props) => (
59-
<RdiInstancesListCell {...props} field={RdiListColumn.Version} />
60-
),
48+
cell: RdiInstancesListCell,
6149
},
6250
{
6351
id: RdiListColumn.LastConnection,
6452
accessorKey: RdiListColumn.LastConnection,
6553
header: RDI_COLUMN_FIELD_NAME_MAP.get(RdiListColumn.LastConnection),
6654
enableSorting: true,
67-
cell: (props) => (
68-
<RdiInstancesListCell {...props} field={RdiListColumn.LastConnection} />
69-
),
55+
cell: RdiInstancesListCell,
7056
sortingFn: (rowA, rowB) => {
7157
const a = rowA.original.lastConnection
7258
const b = rowB.original.lastConnection

redisinsight/ui/src/pages/rdi/home/components/rdi-instances-list/RdiInstancesList.types.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,5 @@ import type { CellContext } from 'uiSrc/components/base/layout/table'
44
import type { RdiInstance } from 'uiSrc/slices/interfaces'
55

66
export type IRdiListCell = (
7-
props: CellContext<RdiInstance, unknown> & {
8-
field?: keyof RdiInstance
9-
withCopyIcon?: boolean
10-
},
7+
props: CellContext<RdiInstance, unknown>,
118
) => ReactElement<any, any> | null
Lines changed: 30 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1,8 +1,6 @@
11
import React from 'react'
22
import { render, screen, userEvent } from 'uiSrc/utils/test-utils'
3-
43
import { rdiInstanceFactory } from 'uiSrc/mocks/rdi/RdiInstance.factory'
5-
64
import RdiInstancesListCell from './RdiInstancesListCell'
75
import { lastConnectionFormat } from 'uiSrc/utils'
86

@@ -19,7 +17,8 @@ jest.mock('uiSrc/utils', () => ({
1917
lastConnectionFormat: jest.fn(() => '3 min ago'),
2018
}))
2119

22-
const buildRow = (
20+
const makeProps = (
21+
columnId: string,
2322
overrides: Partial<ReturnType<typeof rdiInstanceFactory.build>> = {},
2423
) => {
2524
const instance = rdiInstanceFactory.build({
@@ -28,49 +27,55 @@ const buildRow = (
2827
url: 'https://example',
2928
...overrides,
3029
})
31-
return { row: { original: instance } as any, instance }
30+
return {
31+
row: { original: instance } as any,
32+
column: { id: columnId } as any,
33+
instance,
34+
}
3235
}
3336

3437
describe('RdiInstancesListCell', () => {
3538
beforeEach(() => {
3639
jest.clearAllMocks()
3740
})
3841

39-
it('should render null when field is not provided', () => {
40-
const { row } = buildRow()
41-
const { container } = render(<RdiInstancesListCell {...({ row } as any)} />)
42+
it('should render null when value is missing for the column', () => {
43+
const { row, column } = makeProps('version', { version: undefined as any })
44+
const { container } = render(
45+
<RdiInstancesListCell {...({ row, column } as any)} />,
46+
)
4247
expect(container.firstChild).toBeNull()
4348
})
4449

4550
it('should render text value and data-testid for a string field (name)', () => {
46-
const { row, instance } = buildRow({ id: 'cell-1', name: 'My Endpoint' })
51+
const { row, column, instance } = makeProps('name', {
52+
id: 'cell-1',
53+
name: 'My Endpoint',
54+
})
4755

48-
render(<RdiInstancesListCell {...({ row } as any)} field="name" />)
56+
render(<RdiInstancesListCell {...({ row, column } as any)} />)
4957

5058
expect(screen.getByText('My Endpoint')).toBeInTheDocument()
51-
// data-testid includes id and text
5259
expect(
5360
screen.getByTestId(`rdi-list-cell-${instance.id}-${instance.name}`),
5461
).toBeInTheDocument()
5562
})
5663

57-
it('should not show copy icon by default', () => {
58-
const { row } = buildRow()
64+
it('should not show copy icon for non-url field', () => {
65+
const { row, column } = makeProps('name')
5966

60-
render(<RdiInstancesListCell {...({ row } as any)} field="url" />)
67+
render(<RdiInstancesListCell {...({ row, column } as any)} />)
6168

6269
expect(screen.queryByRole('button')).not.toBeInTheDocument()
6370
})
6471

6572
it('should show copy icon and call handleCopyUrl with url text and id', async () => {
66-
const { row, instance } = buildRow({
73+
const { row, column, instance } = makeProps('url', {
6774
id: 'cpy-1',
6875
url: 'https://ri.example',
6976
})
7077

71-
render(
72-
<RdiInstancesListCell {...({ row } as any)} field="url" withCopyIcon />,
73-
)
78+
render(<RdiInstancesListCell {...({ row, column } as any)} />)
7479

7580
const btn = screen.getByRole('button')
7681
await userEvent.click(btn, { pointerEventsCheck: 0 })
@@ -82,27 +87,17 @@ describe('RdiInstancesListCell', () => {
8287
expect(id).toBe(instance.id)
8388
})
8489

85-
it('should format lastConnection via lastConnectionFormat and pass formatted text to handler', async () => {
90+
it('should format lastConnection via lastConnectionFormat and render formatted text (no copy icon)', async () => {
8691
const date = new Date('2023-01-01T00:00:00.000Z')
87-
const { row, instance } = buildRow({ id: 'last-1', lastConnection: date })
88-
89-
render(
90-
<RdiInstancesListCell
91-
{...({ row } as any)}
92-
field="lastConnection"
93-
withCopyIcon
94-
/>,
95-
)
92+
const { row, column } = makeProps('lastConnection', {
93+
id: 'last-1',
94+
lastConnection: date,
95+
})
96+
97+
render(<RdiInstancesListCell {...({ row, column } as any)} />)
9698

97-
// Uses mocked formatter
9899
expect(lastConnectionFormat).toHaveBeenCalledWith(date as any)
99100
expect(screen.getByText('3 min ago')).toBeInTheDocument()
100-
101-
const btn = screen.getByRole('button')
102-
await userEvent.click(btn, { pointerEventsCheck: 0 })
103-
104-
const [, text, id] = mockHandleCopyUrl.mock.calls[0]
105-
expect(text).toBe('3 min ago')
106-
expect(id).toBe(instance.id)
101+
expect(screen.queryByRole('button')).not.toBeInTheDocument()
107102
})
108103
})

redisinsight/ui/src/pages/rdi/home/components/rdi-instances-list/components/RdiInstancesListCell/RdiInstancesListCell.tsx

Lines changed: 17 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,26 +5,32 @@ import { IconButton } from 'uiSrc/components/base/forms/buttons'
55
import { CopyIcon } from 'uiSrc/components/base/icons'
66
import { Text } from 'uiSrc/components/base/text'
77
import { lastConnectionFormat } from 'uiSrc/utils'
8-
import { RdiInstance } from 'uiSrc/slices/interfaces'
8+
import { RdiListColumn } from 'uiSrc/constants'
99

1010
import { handleCopyUrl } from '../../methods/handlers'
1111
import { IRdiListCell } from '../../RdiInstancesList.types'
1212
import { CellContainer } from './RdiInstancesListCell.styles'
1313

14-
const RdiInstancesListCell: IRdiListCell = ({ row, field, withCopyIcon }) => {
15-
const instance = row.original as RdiInstance
14+
const fieldCopyIcon: Record<string, boolean> = {
15+
[RdiListColumn.Url]: true,
16+
}
17+
18+
const fieldFormatters: Record<string, (v: any) => string> = {
19+
[RdiListColumn.LastConnection]: lastConnectionFormat,
20+
}
21+
22+
const RdiInstancesListCell: IRdiListCell = ({ row, column }) => {
23+
const item = row.original
24+
const id = item.id
25+
const field = column.id as keyof typeof item
26+
const value = item[field]
1627

17-
if (!field) {
28+
if (!field || !value) {
1829
return null
1930
}
2031

21-
const id = instance.id
22-
const value = instance[field]
23-
const text =
24-
// lastConnection is returned as a string
25-
field === 'lastConnection'
26-
? lastConnectionFormat(value as any)
27-
: value?.toString()
32+
const text = fieldFormatters[field]?.(value) ?? value?.toString()
33+
const withCopyIcon = fieldCopyIcon[field]
2834

2935
return (
3036
<CellContainer
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import React from 'react'
2+
3+
import { Table } from 'uiSrc/components/base/layout/table'
4+
import { IRdiListCell } from '../../RdiInstancesList.types'
5+
6+
const RdiInstancesListCellSelect: IRdiListCell = (props) => (
7+
<Table.RowSelectionButton
8+
{...props}
9+
onClick={(e: any) => e.stopPropagation()}
10+
/>
11+
)
12+
13+
export default RdiInstancesListCellSelect

0 commit comments

Comments
 (0)