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) + }) +})