diff --git a/redisinsight/ui/src/components/database-list-modules/DatabaseListModules.tsx b/redisinsight/ui/src/components/database-list-modules/DatabaseListModules.tsx
index 6c88b81242..1c67b549ba 100644
--- a/redisinsight/ui/src/components/database-list-modules/DatabaseListModules.tsx
+++ b/redisinsight/ui/src/components/database-list-modules/DatabaseListModules.tsx
@@ -9,6 +9,7 @@ import {
} from 'uiSrc/slices/interfaces'
import { Theme } from 'uiSrc/constants'
import { getModule, truncateText } from 'uiSrc/utils'
+import { IDatabaseModule, sortModules } from 'uiSrc/utils/modules'
import { ThemeContext } from 'uiSrc/contexts/themeContext'
import RedisAILight from 'uiSrc/assets/img/modules/RedisAILight.svg'
@@ -84,13 +85,13 @@ const DatabaseListModules = React.memo((props: Props) => {
const { content, modules, inCircle, highlight, tooltipTitle, maxViewModules, withoutStyles } = props
const { theme } = useContext(ThemeContext)
- const mainContent = []
+ const mainContent: IDatabaseModule[] = []
const handleCopy = (text = '') => {
navigator?.clipboard?.writeText(text)
}
- const newModules = modules?.map(({ name: propName, semanticVersion = '', version = '' }) => {
+ const newModules: IDatabaseModule[] = sortModules(modules?.map(({ name: propName, semanticVersion = '', version = '' }) => {
const moduleName = modulesDefaultInit[propName]?.text || propName
const { abbreviation = '', name = moduleName } = getModule(moduleName)
@@ -104,7 +105,7 @@ const DatabaseListModules = React.memo((props: Props) => {
icon = theme === Theme.Dark ? UnknownDark : UnknownLight
}
- mainContent.push({ icon, content, abbreviation })
+ mainContent.push({ icon, content, abbreviation, moduleName })
return {
moduleName,
@@ -112,7 +113,7 @@ const DatabaseListModules = React.memo((props: Props) => {
abbreviation,
content
}
- })
+ }))
// set count of hidden modules
if (maxViewModules && newModules.length > maxViewModules + 1) {
@@ -125,7 +126,7 @@ const DatabaseListModules = React.memo((props: Props) => {
})
}
- const Content = mainContent.map(({ icon, content, abbreviation = '' }) => (
+ const Content = sortModules(mainContent).map(({ icon, content, abbreviation = '' }) => (
{!!icon && ()}
{!icon && (
@@ -141,8 +142,9 @@ const DatabaseListModules = React.memo((props: Props) => {
))
- const Module = (moduleName: string = '', abbreviation: string = '', icon: string, content: string = '') => (
-
+ const Module = (moduleName: string = '', abbreviation: string = '', icon: string, content: string = '') => {
+ return (
+
{icon ? (
{
)}
- )
+ )
+ }
const Modules = () => (
newModules.map(({ icon, content, abbreviation, moduleName }, i) => (
@@ -197,6 +200,7 @@ const DatabaseListModules = React.memo((props: Props) => {
title={tooltipTitle ?? undefined}
display="inlineBlock"
content={Content}
+ data-testid="modules-tooltip"
>
<>
{content ?? Modules()}
diff --git a/redisinsight/ui/src/components/database-overview/DatabaseOverview.tsx b/redisinsight/ui/src/components/database-overview/DatabaseOverview.tsx
index 36da15b2fe..c620219f6c 100644
--- a/redisinsight/ui/src/components/database-overview/DatabaseOverview.tsx
+++ b/redisinsight/ui/src/components/database-overview/DatabaseOverview.tsx
@@ -63,7 +63,7 @@ const DatabaseOverview = (props: Props) => {
}, [windowDimensions, metricsProps, modulesProps])
const RediStackLogo = (
-
+
diff --git a/redisinsight/ui/src/pages/home/components/DatabaseAlias/DatabaseAlias.tsx b/redisinsight/ui/src/pages/home/components/DatabaseAlias/DatabaseAlias.tsx
index db1ff12b14..558c0c54fe 100644
--- a/redisinsight/ui/src/pages/home/components/DatabaseAlias/DatabaseAlias.tsx
+++ b/redisinsight/ui/src/pages/home/components/DatabaseAlias/DatabaseAlias.tsx
@@ -79,7 +79,11 @@ const DatabaseAlias = (props: Props) => {
{isRediStack && (
-
+
)}
) : undefined}
modules={modules}
diff --git a/redisinsight/ui/src/utils/modules.ts b/redisinsight/ui/src/utils/modules.ts
new file mode 100644
index 0000000000..74b87a6b44
--- /dev/null
+++ b/redisinsight/ui/src/utils/modules.ts
@@ -0,0 +1,28 @@
+import { DATABASE_LIST_MODULES_TEXT, RedisDefaultModules } from 'uiSrc/slices/interfaces'
+
+export interface IDatabaseModule {
+ abbreviation: string
+ moduleName: string
+ icon?: any
+ content?: any,
+ [key: string]: any
+}
+
+const PREDEFINED_MODULES_ORDER = [
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.Search],
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.ReJSON],
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.TimeSeries],
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.Bloom],
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.Gears],
+ DATABASE_LIST_MODULES_TEXT[RedisDefaultModules.AI]
+]
+
+export const sortModules = (modules: IDatabaseModule[]) => {
+ return modules.sort((a, b) => {
+ if (!a.moduleName && !a.abbreviation) return 1
+ if (!b.moduleName && !b.abbreviation) return -1
+ if (PREDEFINED_MODULES_ORDER.indexOf(a.moduleName) === -1) return 1
+ if (PREDEFINED_MODULES_ORDER.indexOf(b.moduleName) === -1) return -1
+ return PREDEFINED_MODULES_ORDER.indexOf(a.moduleName) - PREDEFINED_MODULES_ORDER.indexOf(b.moduleName)
+ })
+}
diff --git a/redisinsight/ui/src/utils/redistack.ts b/redisinsight/ui/src/utils/redistack.ts
index 3a323744a1..3e16444cb2 100644
--- a/redisinsight/ui/src/utils/redistack.ts
+++ b/redisinsight/ui/src/utils/redistack.ts
@@ -1,8 +1,14 @@
import { map, isEqual } from 'lodash'
-import { Instance } from 'uiSrc/slices/interfaces'
+import { Instance, RedisDefaultModules } from 'uiSrc/slices/interfaces'
export const REDISTACK_PORT = 6379
-export const REDISTACK_MODULES = ['ReJSON', 'graph', 'timeseries', 'search', 'bf'].sort()
+export const REDISTACK_MODULES = [
+ RedisDefaultModules.ReJSON,
+ RedisDefaultModules.Graph,
+ RedisDefaultModules.TimeSeries,
+ RedisDefaultModules.Search,
+ RedisDefaultModules.Bloom,
+].sort()
const checkRediStackModules = (modules: any[]) => isEqual(map(modules, 'name').sort(), REDISTACK_MODULES)
diff --git a/redisinsight/ui/src/utils/tests/modules.spec.ts b/redisinsight/ui/src/utils/tests/modules.spec.ts
new file mode 100644
index 0000000000..ffea5d1319
--- /dev/null
+++ b/redisinsight/ui/src/utils/tests/modules.spec.ts
@@ -0,0 +1,45 @@
+import { IDatabaseModule, sortModules } from 'uiSrc/utils/modules'
+
+const modules1: IDatabaseModule[] = [
+ { moduleName: 'RedisJSON', abbreviation: 'RS' },
+ { moduleName: 'My1Module', abbreviation: 'MD' },
+ { moduleName: 'RediSearch', abbreviation: 'RS' },
+]
+const modules2: IDatabaseModule[] = [
+ { moduleName: '', abbreviation: '' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: 'RedisBloom', abbreviation: 'RS' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: 'MycvModule', abbreviation: 'MC' },
+ { moduleName: 'My1Module', abbreviation: 'MD' },
+ { moduleName: 'RedisJSON', abbreviation: 'RS' },
+ { moduleName: 'My2Modul2e', abbreviation: 'MX' },
+ { moduleName: 'RediSearch', abbreviation: 'RS' },
+]
+
+const result1: IDatabaseModule[] = [
+ { moduleName: 'RediSearch', abbreviation: 'RS' },
+ { moduleName: 'RedisJSON', abbreviation: 'RS' },
+ { moduleName: 'My1Module', abbreviation: 'MD' }
+]
+
+const result2: IDatabaseModule[] = [
+ { moduleName: 'RediSearch', abbreviation: 'RS' },
+ { moduleName: 'RedisJSON', abbreviation: 'RS' },
+ { moduleName: 'RedisBloom', abbreviation: 'RS' },
+ { moduleName: 'MycvModule', abbreviation: 'MC' },
+ { moduleName: 'My1Module', abbreviation: 'MD' },
+ { moduleName: 'My2Modul2e', abbreviation: 'MX' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: '', abbreviation: '' },
+ { moduleName: '', abbreviation: '' },
+]
+
+describe('sortModules', () => {
+ it('should proper sort modules list', () => {
+ expect(sortModules(modules1)).toEqual(result1)
+ expect(sortModules(modules2)).toEqual(result2)
+ })
+})