Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 7 additions & 3 deletions redisinsight/ui/src/components/auto-refresh/AutoRefresh.spec.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import {
screen,
render,
act,
waitForRiPopoverVisible,
} from 'uiSrc/utils/test-utils'
import { localStorageService } from 'uiSrc/services'
import AutoRefresh, { Props } from './AutoRefresh'
Expand Down Expand Up @@ -77,7 +78,8 @@ describe('AutoRefresh', () => {
it('refresh text should contain "Auto-refresh" time with enabled auto-refresh', async () => {
render(<AutoRefresh {...instance(mockedProps)} displayText />)

fireEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await userEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await waitForRiPopoverVisible()
await userEvent.click(screen.getByTestId('auto-refresh-switch'))

expect(screen.getByTestId('refresh-message-label')).toHaveTextContent(
Expand Down Expand Up @@ -158,7 +160,8 @@ describe('AutoRefresh', () => {
const onRefresh = jest.fn()
render(<AutoRefresh {...instance(mockedProps)} onRefresh={onRefresh} />)

fireEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await userEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await waitForRiPopoverVisible()
await userEvent.click(screen.getByTestId('auto-refresh-switch'))
fireEvent.click(screen.getByTestId('refresh-rate'))

Expand Down Expand Up @@ -264,7 +267,8 @@ describe('AutoRefresh', () => {
<AutoRefresh {...instance(mockedProps)} onRefresh={onRefresh} />,
)

fireEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await userEvent.click(screen.getByTestId('auto-refresh-config-btn'))
await waitForRiPopoverVisible()
await userEvent.click(screen.getByTestId('auto-refresh-switch'))
fireEvent.click(screen.getByTestId('refresh-rate'))
fireEvent.change(screen.getByTestId(INLINE_ITEM_EDITOR), {
Expand Down
8 changes: 4 additions & 4 deletions redisinsight/ui/src/components/auto-refresh/AutoRefresh.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useEffect, useState } from 'react'
import { EuiIcon, EuiPopover } from '@elastic/eui'
import { EuiIcon } from '@elastic/eui'
import cx from 'classnames'
import { ChevronDownIcon, RefreshIcon } from 'uiSrc/components/base/icons'
import {
Expand All @@ -14,7 +14,7 @@ import { BrowserStorageItem } from 'uiSrc/constants'
import { IconButton } from 'uiSrc/components/base/forms/buttons'
import { ColorText } from 'uiSrc/components/base/text'
import { SwitchInput } from 'uiSrc/components/base/inputs'
import { RiTooltip } from 'uiSrc/components'
import { RiPopover, RiTooltip } from 'uiSrc/components/base'
import {
DEFAULT_REFRESH_RATE,
DURATION_FIRST_REFRESH_TIME,
Expand Down Expand Up @@ -245,7 +245,7 @@ const AutoRefresh = ({
/>
</RiTooltip>

<EuiPopover
<RiPopover
ownFocus={false}
anchorPosition="downRight"
isOpen={isPopoverOpen}
Expand Down Expand Up @@ -309,7 +309,7 @@ const AutoRefresh = ({
</>
)}
</div>
</EuiPopover>
</RiPopover>
</div>
)
}
Expand Down
1 change: 1 addition & 0 deletions redisinsight/ui/src/components/base/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ import { HorizontalRule, LoadingContent } from './layout'
export { ExternalLink, HorizontalRule, LoadingContent }

export * from './tooltip'
export * from './popover'
37 changes: 37 additions & 0 deletions redisinsight/ui/src/components/base/popover/RiPopover.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import React from 'react'
import { Popover } from '@redis-ui/components'

import { RiPopoverProps } from './types'
import { anchorPositionMap, panelPaddingSizeMap } from './config'

export const RiPopover = ({
isOpen,
closePopover,
children,
ownFocus,
button,
anchorPosition,
panelPaddingSize,
anchorClassName,
panelClassName,
maxWidth = '100%',
...props
}: RiPopoverProps) => (
<Popover
{...props}
open={isOpen}
onClickOutside={closePopover}
content={children}
// Props passed to the children wrapper:
className={panelClassName}
maxWidth={maxWidth}
style={{
padding: panelPaddingSize && panelPaddingSizeMap[panelPaddingSize],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Why inline style and not styled component?

Copy link
Collaborator Author

@KrumTy KrumTy Jul 10, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

it's a composed component and wrapping it in styled component yields a lot of ts issues
Moreover, these props under the comment, are passed to the wrapper of the content by the Popover internally (ref)

}}
autoFocus={ownFocus}
placement={anchorPosition && anchorPositionMap[anchorPosition]?.placement}
align={anchorPosition && anchorPositionMap[anchorPosition]?.align}
>
<span className={anchorClassName}>{button}</span>
</Popover>
)
57 changes: 57 additions & 0 deletions redisinsight/ui/src/components/base/popover/config.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
export const anchorPositionMap = {
upCenter: {
placement: 'top',
align: 'center',
},
upLeft: {
placement: 'top',
align: 'start',
},
upRight: {
placement: 'top',
align: 'end',
},
downCenter: {
placement: 'bottom',
align: 'center',
},
downLeft: {
placement: 'bottom',
align: 'start',
},
downRight: {
placement: 'bottom',
align: 'end',
},
leftCenter: {
placement: 'left',
align: 'center',
},
leftUp: {
placement: 'left',
align: 'start',
},
leftDown: {
placement: 'left',
align: 'end',
},
rightCenter: {
placement: 'right',
align: 'center',
},
rightUp: {
placement: 'right',
align: 'start',
},
rightDown: {
placement: 'right',
align: 'end',
},
} as const

export const panelPaddingSizeMap = {
l: 24,
m: 18,
s: 8,
none: 0,
} as const
2 changes: 2 additions & 0 deletions redisinsight/ui/src/components/base/popover/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
export * from './RiPopover'
export * from './types'
28 changes: 28 additions & 0 deletions redisinsight/ui/src/components/base/popover/types.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { type PopoverProps } from '@redis-ui/components'

import { anchorPositionMap, panelPaddingSizeMap } from './config'

type AnchorPosition = keyof typeof anchorPositionMap

type PanelPaddingSize = keyof typeof panelPaddingSizeMap

export type RiPopoverProps = Omit<
PopoverProps,
| 'open'
| 'onClickOutside'
| 'autoFocus'
| 'content'
| 'className'
| 'placement'
| 'align'
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I've changed the props a bit to preserve the previous structure and minimize the changes

> & {
isOpen?: PopoverProps['open']
closePopover?: PopoverProps['onClickOutside']
ownFocus?: PopoverProps['autoFocus']
button: PopoverProps['content']
anchorPosition?: AnchorPosition
panelPaddingSize?: PanelPaddingSize
anchorClassName?: string
panelClassName?: string
'data-testid'?: string
}
Original file line number Diff line number Diff line change
@@ -1,9 +1,9 @@
import React, { ChangeEvent, Ref, useEffect, useRef, useState } from 'react'
import { capitalize } from 'lodash'
import cx from 'classnames'
import { EuiFieldText, EuiForm, EuiPopover, keys } from '@elastic/eui'
import { EuiFieldText, EuiForm, keys } from '@elastic/eui'

import { RiTooltip } from 'uiSrc/components'
import { RiPopover, RiTooltip } from 'uiSrc/components/base'
import { FlexItem } from 'uiSrc/components/base/layout/flex'
import { WindowEvent } from 'uiSrc/components/base/utils/WindowEvent'
import { FocusTrap } from 'uiSrc/components/base/utils/FocusTrap'
Expand Down Expand Up @@ -250,13 +250,12 @@ const InlineItemEditor = (props: Props) => {
/>
{!approveByValidation && ApplyBtn}
{approveByValidation && (
<EuiPopover
<RiPopover
anchorPosition="leftCenter"
isOpen={isShowApprovePopover}
closePopover={() => setIsShowApprovePopover(false)}
anchorClassName={styles.popoverAnchor}
panelClassName={cx(styles.popoverPanel)}
className={styles.popoverWrapper}
button={ApplyBtn}
>
<div
Expand Down Expand Up @@ -289,7 +288,7 @@ const InlineItemEditor = (props: Props) => {
</DestructiveButton>
</div>
</div>
</EuiPopover>
</RiPopover>
)}
</div>
</EuiForm>
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { ChangeEvent, useEffect, useState, useMemo } from 'react'
import { EuiFieldText, EuiIcon, EuiPopover } from '@elastic/eui'
import { EuiFieldText, EuiIcon } from '@elastic/eui'
import { useSelector } from 'react-redux'
import { useHistory, useParams } from 'react-router-dom'
import { instancesSelector as rdiInstancesSelector } from 'uiSrc/slices/rdi/instances'
Expand All @@ -15,6 +15,7 @@ import { filterAndSort } from 'uiSrc/utils'
import { Spacer } from 'uiSrc/components/base/layout/spacer'
import { Text } from 'uiSrc/components/base/text'
import Tabs, { TabInfo } from 'uiSrc/components/base/layout/tabs'
import { RiPopover } from 'uiSrc/components/base'
import InstancesList from './components/instances-list'
import styles from './styles.module.scss'

Expand Down Expand Up @@ -110,7 +111,7 @@ const InstancesNavigationPopover = ({ name }: Props) => {
)

return (
<EuiPopover
<RiPopover
ownFocus
anchorPosition="downRight"
panelPaddingSize="none"
Expand Down Expand Up @@ -169,7 +170,7 @@ const InstancesNavigationPopover = ({ name }: Props) => {
</div>
</div>
</div>
</EuiPopover>
</RiPopover>
)
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import {
fireEvent,
render,
screen,
waitForEuiPopoverVisible,
waitForRiPopoverVisible,
within,
} from 'uiSrc/utils/test-utils'
import * as appFeaturesSlice from 'uiSrc/slices/app/features'
Expand Down Expand Up @@ -104,7 +104,7 @@ describe('UserProfileBadge', () => {
await act(async () => {
fireEvent.click(screen.getByTestId('user-profile-btn'))
})
await waitForEuiPopoverVisible()
await waitForRiPopoverVisible()

return resp
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react'
import { useDispatch, useSelector } from 'react-redux'
import { EuiIcon, EuiPopover } from '@elastic/eui'
import { EuiIcon } from '@elastic/eui'
import cx from 'classnames'
import { useHistory } from 'react-router-dom'
import { logoutUserAction } from 'uiSrc/slices/oauth/cloud'
Expand All @@ -19,6 +19,7 @@ import {
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
import { FeatureFlags, Pages } from 'uiSrc/constants'
import { FeatureFlagComponent } from 'uiSrc/components'
import { RiPopover } from 'uiSrc/components/base'
import { getConfig } from 'uiSrc/config'
import { Text } from 'uiSrc/components/base/text'
import { UserProfileLink } from 'uiSrc/components/base/link/UserProfileLink'
Expand Down Expand Up @@ -110,9 +111,8 @@ const UserProfileBadge = (props: UserProfileBadgeProps) => {

return (
<div className={styles.wrapper} data-testid={dataTestId}>
<EuiPopover
<RiPopover
ownFocus
initialFocus={false}
anchorPosition="upRight"
isOpen={isProfileOpen}
closePopover={() => setIsProfileOpen(false)}
Expand Down Expand Up @@ -261,7 +261,7 @@ const UserProfileBadge = (props: UserProfileBadgeProps) => {
</div>
</FeatureFlagComponent>
</div>
</EuiPopover>
</RiPopover>
</div>
)
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
import React, { useState } from 'react'
import { EuiIcon, EuiPopover } from '@elastic/eui'
import { EuiIcon } from '@elastic/eui'
import { formatLongName } from 'uiSrc/utils'

import {
Expand All @@ -9,6 +9,7 @@ import {
import { DeleteIcon } from 'uiSrc/components/base/icons'
import { FlexItem, Row } from 'uiSrc/components/base/layout/flex'
import { Text } from 'uiSrc/components/base/text'
import { RiPopover } from 'uiSrc/components'
import styles from '../styles.module.scss'

export interface Props<T> {
Expand Down Expand Up @@ -44,7 +45,7 @@ const DeleteAction = <T extends { id: string; name?: string }>(
)

return (
<EuiPopover
<RiPopover
id="deletePopover"
ownFocus
button={deleteBtn}
Expand Down Expand Up @@ -81,7 +82,7 @@ const DeleteAction = <T extends { id: string; name?: string }>(
Delete
</DestructiveButton>
</div>
</EuiPopover>
</RiPopover>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React, { useState } from 'react'

import { EuiIcon, EuiPopover } from '@elastic/eui'
import { EuiIcon } from '@elastic/eui'
import { formatLongName } from 'uiSrc/utils'

import { PrimaryButton } from 'uiSrc/components/base/forms/buttons'
Expand All @@ -10,6 +10,7 @@ import { FlexItem, Row } from 'uiSrc/components/base/layout/flex'
import { Text } from 'uiSrc/components/base/text'
import { Checkbox } from 'uiSrc/components/base/forms/checkbox/Checkbox'
import { FormField } from 'uiSrc/components/base/forms/FormField'
import { RiPopover } from 'uiSrc/components/base'
import styles from '../styles.module.scss'

export interface Props<T> {
Expand Down Expand Up @@ -38,7 +39,7 @@ const ExportAction = <T extends { id: string; name?: string }>(
)

return (
<EuiPopover
<RiPopover
id="exportPopover"
ownFocus
button={exportBtn}
Expand Down Expand Up @@ -85,7 +86,7 @@ const ExportAction = <T extends { id: string; name?: string }>(
Export
</PrimaryButton>
</div>
</EuiPopover>
</RiPopover>
)
}

Expand Down
Loading
Loading