Skip to content

Commit 7b0be18

Browse files
dantovskaKrumTy
andauthored
RI-6841: Add close button for unsupported key types (#4401)
* add close button to module types details, unsuported type details and too long key name details * remove the key from onClose parameter as it is not used hence not needed * add the text details wrapper * side fix: make a property optional * wrap module type details with text details wrapper to reuse functionality * wrap too long key name details with text details wrapper to reuse functionality * wrap unsupported type details with text details wrapper to reuse functionality * remove unused property from key details header, as keyProp is no longer needed on key close. Co-authored-by: Krum Tyukenov <[email protected]> --------- Co-authored-by: Krum Tyukenov <[email protected]>
1 parent 8e19040 commit 7b0be18

File tree

14 files changed

+155
-105
lines changed

14 files changed

+155
-105
lines changed

redisinsight/ui/src/components/auto-refresh/AutoRefresh.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,7 @@ export interface Props {
3939
defaultRefreshRate?: string
4040
iconSize?: EuiButtonIconSizes
4141
disabled?: boolean
42-
disabledRefreshButtonMessage: string
42+
disabledRefreshButtonMessage?: string
4343
enableAutoRefreshDefault?: boolean
4444
}
4545

redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ import { KeyDetailsHeaderSizeLength } from './components/key-details-header-size
3636
import styles from './styles.module.scss'
3737

3838
export interface KeyDetailsHeaderProps {
39-
onCloseKey: (key: RedisResponseBuffer) => void
39+
onCloseKey: () => void
4040
onRemoveKey: () => void
4141
onEditKey: (key: RedisResponseBuffer, newKey: RedisResponseBuffer, onFailure?: () => void) => void
4242
isFullScreen: boolean
@@ -58,7 +58,6 @@ const KeyDetailsHeader = ({
5858
const {
5959
type,
6060
length,
61-
nameString: keyProp,
6261
name: keyBuffer,
6362
} = useSelector(selectedKeyDataSelector) ?? initialKeyInfo
6463
const { id: instanceId } = useSelector(connectedInstanceSelector)
@@ -142,7 +141,7 @@ const KeyDetailsHeader = ({
142141
color="primary"
143142
aria-label="Close key"
144143
className={styles.closeBtn}
145-
onClick={() => onCloseKey(keyProp)}
144+
onClick={() => onCloseKey()}
146145
data-testid="close-key-btn"
147146
/>
148147
</EuiToolTip>

redisinsight/ui/src/pages/browser/modules/key-details/components/dynamic-type-details/DynamicTypeDetails.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ const DynamicTypeDetails = (props: Props) => {
3636
}
3737

3838
if (isTruncatedString(keyProp)) {
39-
return <TooLongKeyNameDetails />
39+
return <TooLongKeyNameDetails onClose={ props.onCloseKey }/>
4040
}
4141

4242
// Supported key type
@@ -46,11 +46,11 @@ const DynamicTypeDetails = (props: Props) => {
4646

4747
// Unsupported redis modules key type
4848
if (Object.values(ModulesKeyTypes).includes(selectedKeyType as ModulesKeyTypes)) {
49-
return <ModulesTypeDetails moduleName={MODULES_KEY_TYPES_NAMES[selectedKeyType]} />
49+
return <ModulesTypeDetails moduleName={MODULES_KEY_TYPES_NAMES[selectedKeyType]} onClose={ props.onCloseKey }/>
5050
}
5151

5252
// Unsupported key type
53-
return <UnsupportedTypeDetails />
53+
return <UnsupportedTypeDetails onClose={ props.onCloseKey }/>
5454
}
5555

5656
export { DynamicTypeDetails }

redisinsight/ui/src/pages/browser/modules/key-details/components/modules-type-details/ModulesTypeDetails.spec.tsx

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,6 @@ import ModulesTypeDetails from './ModulesTypeDetails'
66

77
describe('ModulesTypeDetails', () => {
88
it('should render', () => {
9-
expect(render(<ModulesTypeDetails moduleName={MODULES_KEY_TYPES_NAMES[ModulesKeyTypes.Graph]} />)).toBeTruthy()
9+
expect(render(<ModulesTypeDetails moduleName={MODULES_KEY_TYPES_NAMES[ModulesKeyTypes.Graph]} onClose={jest.fn()} />)).toBeTruthy()
1010
})
1111
})

redisinsight/ui/src/pages/browser/modules/key-details/components/modules-type-details/ModulesTypeDetails.tsx

Lines changed: 28 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,19 @@
11
import React from 'react'
2-
import { EuiFlexGroup, EuiFlexItem, EuiText, EuiTitle } from '@elastic/eui'
2+
import { EuiText, EuiTitle } from '@elastic/eui'
33
import { useHistory } from 'react-router-dom'
44
import { useSelector } from 'react-redux'
55

66
import { Pages } from 'uiSrc/constants'
77
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
88

9-
import styles from '../unsupported-type-details/styles.module.scss'
9+
import styles from './styles.module.scss'
10+
import TextDetailsWrapper from '../text-details-wrapper/TextDetailsWrapper'
1011

11-
const ModulesTypeDetails = ({ moduleName = 'unsupported' }: { moduleName: string }) => {
12+
type ModulesTypeDetailsProps = {
13+
moduleName: string,
14+
onClose: () => void,
15+
}
16+
const ModulesTypeDetails = ({ moduleName = 'unsupported', onClose }: ModulesTypeDetailsProps) => {
1217
const history = useHistory()
1318
const { id: connectedInstanceId = '' } = useSelector(connectedInstanceSelector)
1419

@@ -18,30 +23,26 @@ const ModulesTypeDetails = ({ moduleName = 'unsupported' }: { moduleName: string
1823
}
1924

2025
return (
21-
<div className={styles.container} data-testid="modules-type-details">
22-
<EuiFlexGroup alignItems="center" justifyContent="center">
23-
<EuiFlexItem className={styles.textWrapper}>
24-
<EuiTitle>
25-
<h4>{`This is a ${moduleName} key.`}</h4>
26-
</EuiTitle>
27-
<EuiText size="s">
28-
{'Use Redis commands in the '}
29-
<a
30-
tabIndex={0}
31-
onClick={handleGoWorkbenchPage}
32-
className={styles.link}
33-
data-testid="internal-workbench-link"
34-
onKeyDown={() => ({})}
35-
role="link"
36-
rel="noreferrer"
37-
>
38-
Workbench
39-
</a>
40-
{' tool to view the value.'}
41-
</EuiText>
42-
</EuiFlexItem>
43-
</EuiFlexGroup>
44-
</div>
26+
<TextDetailsWrapper onClose={onClose} testid="modules-type">
27+
<EuiTitle>
28+
<h4>{`This is a ${moduleName} key.`}</h4>
29+
</EuiTitle>
30+
<EuiText size="s">
31+
{'Use Redis commands in the '}
32+
<a
33+
tabIndex={0}
34+
onClick={handleGoWorkbenchPage}
35+
className={styles.link}
36+
data-testid="internal-workbench-link"
37+
onKeyDown={() => ({})}
38+
role="link"
39+
rel="noreferrer"
40+
>
41+
Workbench
42+
</a>
43+
{' tool to view the value.'}
44+
</EuiText>
45+
</TextDetailsWrapper>
4546
)
4647
}
4748

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
.link {
2+
text-decoration: underline;
3+
color: var(--euiColorFullShade);
4+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import React from "react"
2+
import TextDetailsWrapper from "./TextDetailsWrapper"
3+
import { fireEvent, render, screen } from "uiSrc/utils/test-utils";
4+
5+
describe('TextDetailsWrapper', () => {
6+
it('should render children correctly', () => {
7+
const { queryByTestId } = render(
8+
<TextDetailsWrapper onClose={jest.fn()}>
9+
<div data-testid="children-wrapper">Children</div>
10+
</TextDetailsWrapper>
11+
);
12+
13+
expect(queryByTestId('children-wrapper')).toBeInTheDocument();
14+
});
15+
16+
it('should call onClose when close button is clicked', () => {
17+
const mockOnClose = jest.fn();
18+
19+
render(
20+
<TextDetailsWrapper onClose={mockOnClose}>
21+
<div data-testid="children-wrapper">Children</div>
22+
</TextDetailsWrapper>
23+
);
24+
25+
fireEvent.click(screen.getByTestId("close-key-btn"));
26+
27+
expect(mockOnClose).toBeCalledTimes(1);
28+
});
29+
})
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
import React, { ReactNode } from 'react';
2+
3+
import { EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiToolTip } from "@elastic/eui";
4+
5+
import styles from './styles.module.scss';
6+
7+
const TextDetailsWrapper = (
8+
{ onClose, children, testid }: { onClose: () => void, children: ReactNode, testid?: string }
9+
) => {
10+
const getDataTestid = (suffix: string) => (testid ? `${testid}-${suffix}` : suffix);
11+
12+
return (
13+
<div className={styles.container} data-testid={getDataTestid('details')}>
14+
<EuiToolTip
15+
content="Close"
16+
position="left"
17+
anchorClassName={styles.closeRightPanel}
18+
>
19+
<EuiButtonIcon
20+
iconType="cross"
21+
color="primary"
22+
aria-label="Close key"
23+
className={styles.closeBtn}
24+
onClick={() => onClose()}
25+
data-testid={getDataTestid('close-key-btn')}
26+
/>
27+
</EuiToolTip>
28+
<EuiFlexGroup alignItems="center" justifyContent="center">
29+
<EuiFlexItem className={styles.textWrapper}>
30+
<div>{children}</div>
31+
</EuiFlexItem>
32+
</EuiFlexGroup>
33+
</div>
34+
);
35+
}
36+
37+
38+
export default TextDetailsWrapper;
Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,15 @@
2020
top: -7%;
2121
}
2222

23-
.link {
24-
text-decoration: underline;
25-
color: var(--euiColorFullShade);
26-
}
23+
.closeRightPanel {
24+
position: absolute;
25+
top: 22px;
26+
right: 18px;
27+
28+
.closeBtn {
29+
:global(svg) {
30+
width: 20px;
31+
height: 20px;
32+
}
33+
}
34+
}
Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,9 @@
11
import React from 'react'
22
import { render } from 'uiSrc/utils/test-utils'
3-
import TooLongKeyNameDetails
4-
from 'uiSrc/pages/browser/modules/key-details/components/too-long-key-name-details/TooLongKeyNameDetails'
3+
import TooLongKeyNameDetails from './TooLongKeyNameDetails';
54

65
describe('TooLongKeyNameDetails', () => {
76
it('should render', () => {
8-
expect(render(<TooLongKeyNameDetails />)).toBeTruthy()
7+
expect(render(<TooLongKeyNameDetails onClose={jest.fn()}/>)).toBeTruthy()
98
})
109
})

0 commit comments

Comments
 (0)