Skip to content

Commit 549a042

Browse files
committed
#RI-985 - Display the list of modules per database
#RI-2460 - Highlight Redis Stack databases in the list of databases
1 parent c9c3f63 commit 549a042

File tree

8 files changed

+192
-147
lines changed

8 files changed

+192
-147
lines changed

redisinsight/ui/src/components/database-list-modules/DatabaseListModules.tsx

Lines changed: 86 additions & 51 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
1+
/* eslint-disable sonarjs/no-nested-template-literals */
12
import React, { useContext } from 'react'
2-
import { EuiButton, EuiButtonIcon, EuiToolTip } from '@elastic/eui'
3+
import { EuiButtonIcon, EuiIcon, EuiTextColor, EuiToolTip } from '@elastic/eui'
34
import cx from 'classnames'
45

56
import {
@@ -31,16 +32,14 @@ import { RedisModuleDto } from 'apiSrc/modules/instances/dto/database-instance.d
3132
import styles from './styles.module.scss'
3233

3334
export interface Props {
34-
modules: RedisModuleDto[];
35-
inCircle?: boolean;
36-
dark?: boolean;
35+
modules: RedisModuleDto[]
36+
inCircle?: boolean
37+
dark?: boolean
38+
highlight?: boolean
39+
maxViewModules?: number
40+
tooltipTitle?: React.ReactNode
3741
}
3842

39-
interface ITooltipProps {
40-
icon: any;
41-
content: any;
42-
abbreviation?: string;
43-
}
4443
export const modulesDefaultInit = {
4544
[RedisDefaultModules.AI]: {
4645
iconDark: RedisAIDark,
@@ -79,68 +78,104 @@ export const modulesDefaultInit = {
7978
},
8079
}
8180

82-
const DatabaseListModules = React.memo(({ modules, inCircle }: Props) => {
81+
const DatabaseListModules = React.memo(({ modules, inCircle, highlight, tooltipTitle, maxViewModules }: Props) => {
8382
const { theme } = useContext(ThemeContext)
8483

84+
const mainContent = []
85+
8586
const handleCopy = (text = '') => {
8687
navigator?.clipboard?.writeText(text)
8788
}
8889

89-
const Tooltip = ({ icon, content, abbreviation }: ITooltipProps) => (
90-
<>
91-
<EuiToolTip
92-
content={content}
93-
position="top"
94-
display="inlineBlock"
95-
anchorClassName={cx({ [styles.anchorCircleIcon]: inCircle })}
96-
>
97-
{icon ? (
98-
<EuiButtonIcon
99-
iconType={icon}
100-
className={cx(styles.icon, { [styles.circle]: inCircle })}
101-
onClick={() => handleCopy(content)}
102-
data-testid={`${content}_module`}
103-
aria-labelledby={`${content}_module`}
104-
/>
105-
) : (
106-
<EuiButton
107-
className={cx(styles.icon, { [styles.circle]: inCircle })}
108-
onClick={() => handleCopy(content)}
109-
data-testid={`${content}_module`}
110-
aria-labelledby={`${content}_module`}
111-
>
112-
{abbreviation}
113-
</EuiButton>
114-
)}
115-
</EuiToolTip>
116-
</>
117-
)
118-
119-
const modulesRender = modules?.map(({ name: propName, semanticVersion = '', version = '' }) => {
90+
const newModules = modules?.map(({ name: propName, semanticVersion = '', version = '' }) => {
12091
const moduleName = modulesDefaultInit[propName]?.text || propName
12192

12293
const { abbreviation = '', name = moduleName } = getModule(moduleName)
12394

12495
const moduleAlias = truncateText(name, 50)
12596
// eslint-disable-next-line sonarjs/no-nested-template-literals
126-
const content = `${moduleAlias}${semanticVersion || version ? ` v. ${semanticVersion || version}` : ''}`
12797
let icon = modulesDefaultInit[propName]?.[theme === Theme.Dark ? 'iconDark' : 'iconLight']
98+
const content = `${moduleAlias}${semanticVersion || version ? ` v. ${semanticVersion || version}` : ''}`
12899

129100
if (!icon && !abbreviation) {
130101
icon = theme === Theme.Dark ? UnknownDark : UnknownLight
131102
}
132103

133-
return (
134-
<Tooltip
135-
key={moduleName}
136-
icon={icon}
137-
abbreviation={abbreviation}
138-
content={content}
139-
/>
140-
)
104+
mainContent.push({ icon, content, abbreviation })
105+
106+
return {
107+
moduleName,
108+
icon,
109+
abbreviation,
110+
content
111+
}
141112
})
142113

143-
return <>{modulesRender}</>
114+
// set count of hidden modules
115+
if (maxViewModules && newModules.length > maxViewModules) {
116+
newModules.length = maxViewModules
117+
newModules.push({
118+
icon: null,
119+
content: '',
120+
moduleName: '',
121+
abbreviation: `+${modules.length - maxViewModules}`
122+
})
123+
}
124+
125+
const Content = mainContent.map(({ icon, content, abbreviation = '' }) => (
126+
<div className={styles.tooltipItem}>
127+
{!!icon && (<EuiIcon type={icon} style={{ marginRight: 10 }} />)}
128+
{!icon && (
129+
<EuiTextColor
130+
className={cx(styles.icon, styles.abbr)}
131+
style={{ marginRight: 10 }}
132+
>
133+
{abbreviation}
134+
</EuiTextColor>
135+
)}
136+
{!!content && (<EuiTextColor className={cx(styles.tooltipItemText)}>{content}</EuiTextColor>)}
137+
<br />
138+
</div>
139+
))
140+
141+
return (
142+
<div className={cx(styles.container, {
143+
[styles.highlight]: highlight,
144+
[styles.containerCircle]: inCircle,
145+
})}
146+
>
147+
<EuiToolTip
148+
position="bottom"
149+
title={tooltipTitle ?? undefined}
150+
display="inlineBlock"
151+
content={Content}
152+
>
153+
<>
154+
{newModules.map(({ icon, content, abbreviation, moduleName }) => (
155+
icon ? (
156+
<EuiButtonIcon
157+
iconType={icon}
158+
className={cx(styles.icon, { [styles.circle]: inCircle })}
159+
onClick={() => handleCopy(content)}
160+
data-testid={`${content}_module`}
161+
aria-labelledby={`${content}_module`}
162+
key={moduleName}
163+
/>
164+
) : (
165+
<EuiTextColor
166+
className={cx(styles.icon, styles.abbr, { [styles.circle]: inCircle })}
167+
onClick={() => handleCopy(content)}
168+
data-testid={`${content}_module`}
169+
aria-labelledby={`${content}_module`}
170+
key={moduleName}
171+
>
172+
{abbreviation}
173+
</EuiTextColor>
174+
)))}
175+
</>
176+
</EuiToolTip>
177+
</div>
178+
)
144179
})
145180

146181
export default DatabaseListModules
Lines changed: 47 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,30 +1,54 @@
1-
.circle {
2-
background-color: var(--moduleBackgroundColor);
3-
border: none !important;
4-
width: 28px !important;
5-
height: 28px !important;
6-
border-radius: 14px !important;
7-
8-
&:hover,
9-
&:focus,
10-
&:focus-within {
11-
background-color: var(--moduleBackgroundColor) !important;
1+
.container {
2+
height: 24px;
3+
line-height: 20px;
4+
5+
&.highlight {
6+
background-color: var(--hoverInListColorLight);
7+
border-radius: 12px;
8+
padding-left: 6px;
9+
padding-right: 6px;
1210
}
13-
}
1411

15-
button.icon {
16-
width: 28px !important;
17-
min-width: 28px !important;
18-
max-width: 28px !important;
19-
height: 28px !important;
20-
* {
21-
padding: 0 !important;
12+
&.containerCircle {
13+
height: 28px;
2214
}
23-
:global(.euiButton__text) {
24-
font-size: 13px !important;
15+
16+
.circle {
17+
background-color: var(--moduleBackgroundColor);
18+
border: none !important;
19+
width: 28px !important;
20+
max-width: 28px !important;
21+
height: 27px !important;
22+
border-radius: 50% !important;
23+
margin-right: 14px;
24+
padding: 4px;
25+
26+
&:hover,
27+
&:focus,
28+
&:focus-within {
29+
background-color: var(--moduleBackgroundColor) !important;
30+
}
2531
}
2632
}
2733

28-
.anchorCircleIcon {
29-
margin-right: 14px;
34+
.icon {
35+
margin-right: 4px;
36+
}
37+
38+
.icon img {
39+
width: 18px !important;
40+
max-width: 18px !important;
41+
height: 16px !important;
42+
}
43+
44+
.tooltipItem:not(:last-of-type) {
45+
padding-bottom: 6px;
46+
}
47+
48+
.tooltipItemText {
49+
vertical-align: text-top;
50+
}
51+
52+
.abbr {
53+
vertical-align: text-top;
3054
}

0 commit comments

Comments
 (0)