Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
e891e6d
RI-5917-ShowTTL-checkbox-for-hash-fields
kchepikava Jul 18, 2024
24ab8a4
5917 comments resolve, show TTl checkbox only when necessary
kchepikava Jul 22, 2024
383e17a
5917 fix tests
kchepikava Jul 22, 2024
a178747
Merge branch 'main' into fe/feature/RI-5917-hide-ttl-for-individual-h…
mariasergeenko Jul 26, 2024
7e81886
Merge remote-tracking branch 'origin/release/2.54.0' into fe/feature/…
mariasergeenko Jul 26, 2024
c9d4023
RI-5959 fixed showttl not working
kchepikava Jul 26, 2024
ee2e973
RI-5960 fixed borders are not aligned
kchepikava Jul 26, 2024
9332b5d
RI-5960-fix-style
kchepikava Jul 26, 2024
c7fc9a8
Merge pull request #3650 from RedisInsight/fe/bugfix/RI-5960-borders-…
mariasergeenko Jul 29, 2024
7b302b7
Merge pull request #3649 from RedisInsight/fe/bugfix/RI-5959-show-ttl…
mariasergeenko Jul 29, 2024
934e6d7
Merge remote-tracking branch 'origin/fe/feature/RI-5917-hide-ttl-for-…
mariasergeenko Jul 29, 2024
2426d8d
Verify add show ttl
mariasergeenko Jul 29, 2024
02be7e3
Merge remote-tracking branch 'origin' into fe/feature/RI-5917-hide-tt…
kchepikava Jul 29, 2024
bb5121d
Merge branch 'main' into fe/feature/RI-5917-hide-ttl-for-individual-h…
kchepikava Jul 29, 2024
5252acf
Merge branch 'release/2.54.0' into fe/feature/RI-5917-hide-ttl-for-in…
kchepikava Jul 29, 2024
9a9ea6b
Merge branch 'fe/feature/RI-5917-hide-ttl-for-individual-hash-fields'…
mariasergeenko Jul 29, 2024
1a94b1c
remove only
mariasergeenko Jul 29, 2024
667590a
remove config
mariasergeenko Jul 29, 2024
1dad4ba
Merge pull request #3655 from RedisInsight/e2e/feature/RI-5917-hide-t…
mariasergeenko Jul 29, 2024
c1132af
RI-5917 add subheader for all fields
kchepikava Jul 29, 2024
3c2a64c
RI-5917 move show ttl checkbox in hash actions
kchepikava Jul 30, 2024
822eac7
RI 5917 returned margin to key-details-header-formatter
kchepikava Jul 30, 2024
4a69cc2
Merge branch 'main' into fe/feature/RI-5917-hide-ttl-for-individual-h…
kchepikava Aug 6, 2024
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
4 changes: 3 additions & 1 deletion redisinsight/ui/src/components/divider/Divider.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,16 +9,18 @@ export interface Props {
orientation?: 'horizontal' | 'vertical',
variant? : 'fullWidth' | 'middle' | 'half';
className?: string;
style?: any
}

const Divider = ({ orientation, variant, className, color, colorVariable }: Props) => (
const Divider = ({ orientation, variant, className, color, colorVariable, ...props }: Props) => (
<div
className={cx(
styles.divider,
styles[`divider-${variant || 'fullWidth'}`],
styles[`divider-${orientation || 'horizontal'}`],
className,
)}
{...props}
>
<hr style={(color || colorVariable) ? { backgroundColor: color ?? `var(--${colorVariable})` } : {}} />
</div>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,6 +47,7 @@ export interface KeyDetailsHeaderProps {
arePanelsCollapsed: boolean
onToggleFullScreen: () => void
Actions?: (props: { width: number }) => ReactElement
displayKeyFormatter?: boolean
}

const KeyDetailsHeader = ({
Expand All @@ -58,6 +59,7 @@ const KeyDetailsHeader = ({
onEditKey,
keyType,
Actions,
displayKeyFormatter = true
}: KeyDetailsHeaderProps) => {
const { refreshing, loading, lastRefreshTime, isRefreshDisabled } = useSelector(selectedKeySelector)
const {
Expand Down Expand Up @@ -110,6 +112,8 @@ const KeyDetailsHeader = ({
}
}

const formatter = displayKeyFormatter && Object.values(KeyTypes).includes(keyType as KeyTypes)

return (
<div className={`key-details-header ${styles.container}`} data-testid="key-details-header">
{loading ? (
Expand Down Expand Up @@ -177,7 +181,7 @@ const KeyDetailsHeader = ({
onChangeAutoRefreshRate={handleChangeAutoRefreshRate}
testid="key"
/>
{Object.values(KeyTypes).includes(keyType as KeyTypes) && (
{formatter && (
<KeyDetailsHeaderFormatter width={width} />
)}
{!isUndefined(Actions) && <Actions width={width} />}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,76 @@
import React from 'react'
import { instance, mock } from 'ts-mockito'
import { render } from 'uiSrc/utils/test-utils'
import { render, screen, fireEvent } from 'uiSrc/utils/test-utils'
import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry'
import { INSTANCE_ID_MOCK } from 'uiSrc/mocks/handlers/instances/instancesHandlers'
import { Props, HashDetails } from './HashDetails'

const mockedProps = mock<Props>()

jest.mock('uiSrc/telemetry', () => ({
...jest.requireActual('uiSrc/telemetry'),
sendEventTelemetry: jest.fn(),
}))

describe('HashDetails', () => {
beforeEach(() => {
jest.clearAllMocks()
})
it('should render', () => {
expect(render(<HashDetails {...instance(mockedProps)} />)).toBeTruthy()
})

it('should render subheader', () => {
render(<HashDetails {...instance(mockedProps)} />)
expect(screen.getByText('Show TTL')).toBeInTheDocument()
})

it('opens and closes the add item panel', () => {
render(
<HashDetails
{...instance(mockedProps)}
onOpenAddItemPanel={() => {}}
onCloseAddItemPanel={() => {}}
/>
)
fireEvent.click(screen.getByText('+'))
expect(screen.getByText('Save')).toBeInTheDocument()
fireEvent.click(screen.getByText('Cancel'))
expect(screen.queryByText('Save')).not.toBeInTheDocument()
})

it('toggles the show TTL button', () => {
render(<HashDetails {...instance(mockedProps)} />)
const el = screen.getByTestId('test-check-ttl') as HTMLInputElement
expect(el.checked).toBe(true)
fireEvent.click(el)
expect(el.checked).toBe(false)
})

it('should call proper telemetry event after click on showTtl', () => {
const sendEventTelemetryMock = jest.fn();
(sendEventTelemetry as jest.Mock).mockImplementation(() => sendEventTelemetryMock)

render(<HashDetails {...instance(mockedProps)} />)

fireEvent.click(screen.getByTestId('test-check-ttl'))

expect(sendEventTelemetry).toBeCalledWith({
event: TelemetryEvent.SHOW_HASH_TTL_CLICKED,
eventData: {
databaseId: INSTANCE_ID_MOCK,
action: 'hide'
}
})

fireEvent.click(screen.getByTestId('test-check-ttl'))

expect(sendEventTelemetry).toBeCalledWith({
event: TelemetryEvent.SHOW_HASH_TTL_CLICKED,
eventData: {
databaseId: INSTANCE_ID_MOCK,
action: 'show'
}
})
})
})
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import cx from 'classnames'

import { useParams } from 'react-router-dom'
import {
selectedKeySelector,
} from 'uiSrc/slices/browser/keys'
Expand All @@ -12,9 +13,10 @@ import { isVersionHigherOrEquals } from 'uiSrc/utils'
import { CommandsVersions } from 'uiSrc/constants/commandsVersions'
import { connectedInstanceOverviewSelector } from 'uiSrc/slices/instances/instances'
import { appFeatureFlagsFeaturesSelector } from 'uiSrc/slices/app/features'
import { TelemetryEvent, sendEventTelemetry } from 'uiSrc/telemetry'
import AddHashFields from './add-hash-fields/AddHashFields'
import { HashDetailsTable } from './hash-details-table'
import { AddItemsAction } from '../key-details-actions'
import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader'

export interface Props extends KeyDetailsHeaderProps {
onRemoveKey: () => void
Expand All @@ -28,14 +30,17 @@ const HashDetails = (props: Props) => {

const { loading } = useSelector(selectedKeySelector)
const { version } = useSelector(connectedInstanceOverviewSelector)
const { instanceId } = useParams<{ instanceId: string }>()
const {
[FeatureFlags.hashFieldExpiration]: hashFieldExpirationFeature
} = useSelector(appFeatureFlagsFeaturesSelector)

const [isAddItemPanelOpen, setIsAddItemPanelOpen] = useState<boolean>(false)
const [showTtl, setShowTtl] = useState<boolean>(true)

const isExpireFieldsAvailable = hashFieldExpirationFeature?.flag
&& isVersionHigherOrEquals(version, CommandsVersions.HASH_TTL.since)
&& showTtl

const openAddItemPanel = () => {
setIsAddItemPanelOpen(true)
Expand All @@ -49,17 +54,30 @@ const HashDetails = (props: Props) => {
}
}

const Actions = ({ width }: { width: number }) => (
<AddItemsAction title="Add Fields" width={width} openAddItemPanel={openAddItemPanel} />
)
const handleSelectShow = (show: boolean) => {
setShowTtl(show)

sendEventTelemetry({
event: TelemetryEvent.SHOW_HASH_TTL_CLICKED,
eventData: {
databaseId: instanceId,
action: show ? 'show' : 'hide'
}
})
}

return (
<div className="fluid flex-column relative">
<KeyDetailsHeader
{...props}
key="key-details-header"
keyType={keyType}
Actions={Actions}
displayKeyFormatter={false}
/>
<KeyDetailsSubheader
showTtl={showTtl}
onShowTtl={handleSelectShow}
onAddKey={openAddItemPanel}
/>
<div className="key-details-body" key="key-details-body">
{!loading && (
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import React from 'react'
import { render, fireEvent } from 'uiSrc/utils/test-utils'
import { KeyDetailsSubheader } from './KeyDetailsSubheader'

describe('KeyDetailsSubheader', () => {
const props = {
showTtl: false,
onShowTtl: jest.fn(),
onAddKey: jest.fn(),
}

it('should render', () => {
const { getByText, getByTestId } = render(<KeyDetailsSubheader {...props} />)
expect(getByText('Show TTL')).toBeInTheDocument()
expect(getByTestId('btn-add-key')).toBeInTheDocument()
})

it('calls onShowTtl when checkbox is clicked', () => {
const { getByLabelText } = render(<KeyDetailsSubheader {...props} />)
fireEvent.click(getByLabelText('Show TTL'))
expect(props.onShowTtl).toHaveBeenCalledWith(true)
})

it('calls onAddKey when add key button is clicked', () => {
const { getByTestId } = render(<KeyDetailsSubheader {...props} />)
fireEvent.click(getByTestId('btn-add-key'))
expect(props.onAddKey).toHaveBeenCalled()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
import React from 'react'

import { EuiButton, EuiCheckbox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui'
import AutoSizer from 'react-virtualized-auto-sizer'

import VerticalDivider from 'uiSrc/pages/rdi/statistics/components/vertical-divider'
Copy link
Contributor

Choose a reason for hiding this comment

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

I do not recommend using here VerticalDivider from rdi statistics components, could you please change it to Divider from common components? Maybe add property to have an ability use vertical

import { KeyDetailsHeaderFormatter } from '../../../key-details-header/components/key-details-header-formatter'
import styles from './styles.module.scss'

interface Props {
showTtl: boolean
onShowTtl: (checked: boolean) => void
onAddKey: () => void
}

export const KeyDetailsSubheader = ({
showTtl,
onShowTtl,
onAddKey
}: Props) => (
<div className={styles.subheaderContainer}>
<AutoSizer disableHeight>
{({ width = 0 }) => (
<div style={{ width }}>
<EuiFlexGroup justifyContent="flexEnd">
<EuiFlexItem className={styles.keyFormatter__item}>
Copy link
Contributor

Choose a reason for hiding this comment

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

no reason use BEM since we use scoped styles,
it is better to name keyFormatterItem

<KeyDetailsHeaderFormatter width={width} />
</EuiFlexItem>
<VerticalDivider variant="half" />
<EuiFlexItem className={styles.showTtl__item}>
<EuiCheckbox
id="showField"
name="showTtl"
label="Show TTL"
className={styles.showTtl__checkbox}
checked={showTtl}
onChange={(e) => onShowTtl(e.target.checked)}
data-testId="test-check-ttl"
/>
</EuiFlexItem>
<VerticalDivider variant="half" />
<EuiFlexItem className={styles.addBtn__container}>
<EuiButton
fill
color="secondary"
onClick={onAddKey}
data-testid="btn-add-key"
>
+
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</div>
)}
</AutoSizer>
</div>
)

export default KeyDetailsSubheader
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
.subheaderContainer {
padding: 12px 18px 0px 18px;

.keyFormatter__item {
max-width: 100px;
margin-right: 0;
}

.showTtl__item {
max-width: 110px;
display: 'flex';
margin-left: 0;
.showTtl__checkbox {
font-weight: 400;
font-size: 14px;
margin: auto;

:global(.euiCheckbox__input) {
color: var(--controlsBorderColor) !important;
}

:global(.euiCheckbox__square) {
width: 18px !important;
height: 18px !important;
border: 1px solid var(--controlsBorderColor) !important;
border-radius: 4px !important;
box-shadow: none !important;
}

:global(.euiCheckbox__label) {
color: var(--controlsLabelColor) !important;
}
}
}

.addBtn__container {
max-width: 40px;
align-self: center;
margin-right: 0 !important;
:global(.euiButton) {
height: 24px !important;
width: 27px !important;
min-width: 27px !important;

:global(.euiButton__content) {
padding: 0 !important;
:global(.euiButton__text) {
font-size: 12px !important;
font-weight: 400 !important;
}
}
}
}
}

Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ import Divider from 'uiSrc/components/divider/Divider'

import styles from './styles.module.scss'

const VerticalDivider = () => (
<Divider className={styles.divider} colorVariable="separatorColor" orientation="vertical" />
const VerticalDivider = (props: any) => (
<Divider className={styles.divider} colorVariable="separatorColor" orientation="vertical" {...props} />
)

export default VerticalDivider
1 change: 1 addition & 0 deletions redisinsight/ui/src/telemetry/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,7 @@ export enum TelemetryEvent {
TREE_VIEW_KEY_FIELD_VALUE_COLLAPSED = 'TREE_VIEW_KEY_FIELD_VALUE_COLLAPSED',
TREE_VIEW_KEY_DETAILS_FORMATTER_CHANGED = 'TREE_VIEW_KEY_DETAILS_FORMATTER_CHANGED',
TREE_VIEW_WORKBENCH_LINK_CLICKED = 'TREE_VIEW_WORKBENCH_LINK_CLICKED',
SHOW_HASH_TTL_CLICKED = 'SHOW_HASH_TTL_CLICKED',

SLOWLOG_LOADED = 'SLOWLOG_LOADED',
SLOWLOG_CLEARED = 'SLOWLOG_CLEARED',
Expand Down