From e891e6de40777ac0117ae8d6d92006d84489b223 Mon Sep 17 00:00:00 2001 From: kchepikava Date: Thu, 18 Jul 2024 18:13:44 +0200 Subject: [PATCH 01/12] RI-5917-ShowTTL-checkbox-for-hash-fields --- .../ui/src/components/divider/Divider.tsx | 4 +- .../key-details-header/KeyDetailsHeader.tsx | 6 +- .../hash-details/HashDetails.spec.tsx | 66 ++++++++++++++++++- .../components/hash-details/HashDetails.tsx | 28 ++++++-- .../KeyDetailsSubheader.spec.tsx | 29 ++++++++ .../KeyDetailsSubheader.tsx | 59 +++++++++++++++++ .../key-details-subheader/styles.module.scss | 55 ++++++++++++++++ .../vertical-divider/VerticalDivider.tsx | 4 +- redisinsight/ui/src/telemetry/events.ts | 1 + 9 files changed, 242 insertions(+), 10 deletions(-) create mode 100644 redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx create mode 100644 redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx create mode 100644 redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss diff --git a/redisinsight/ui/src/components/divider/Divider.tsx b/redisinsight/ui/src/components/divider/Divider.tsx index 5aa438605c..2f04d2acfe 100644 --- a/redisinsight/ui/src/components/divider/Divider.tsx +++ b/redisinsight/ui/src/components/divider/Divider.tsx @@ -9,9 +9,10 @@ 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) => (

diff --git a/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx index 0eab86ff0c..05b8dcf186 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx @@ -47,6 +47,7 @@ export interface KeyDetailsHeaderProps { arePanelsCollapsed: boolean onToggleFullScreen: () => void Actions?: (props: { width: number }) => ReactElement + displayKeyFormatter?: boolean } const KeyDetailsHeader = ({ @@ -58,6 +59,7 @@ const KeyDetailsHeader = ({ onEditKey, keyType, Actions, + displayKeyFormatter = true }: KeyDetailsHeaderProps) => { const { refreshing, loading, lastRefreshTime, isRefreshDisabled } = useSelector(selectedKeySelector) const { @@ -110,6 +112,8 @@ const KeyDetailsHeader = ({ } } + const formatter = displayKeyFormatter && Object.values(KeyTypes).includes(keyType as KeyTypes) + return (
{loading ? ( @@ -177,7 +181,7 @@ const KeyDetailsHeader = ({ onChangeAutoRefreshRate={handleChangeAutoRefreshRate} testid="key" /> - {Object.values(KeyTypes).includes(keyType as KeyTypes) && ( + {formatter && ( )} {!isUndefined(Actions) && } diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx index da72dfa82c..316e3abf31 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx @@ -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() +jest.mock('uiSrc/telemetry', () => ({ + ...jest.requireActual('uiSrc/telemetry'), + sendEventTelemetry: jest.fn(), +})) + describe('HashDetails', () => { + beforeEach(() => { + jest.clearAllMocks() + }) it('should render', () => { expect(render()).toBeTruthy() }) + + it('should render subheader', () => { + render() + expect(screen.getByText('Show TTL')).toBeInTheDocument() + }) + + it('opens and closes the add item panel', () => { + render( + {}} + 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() + 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() + + 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' + } + }) + }) }) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx index cc83fd8137..232aa2e77b 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx @@ -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' @@ -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 @@ -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(false) + const [showTtl, setShowTtl] = useState(true) const isExpireFieldsAvailable = hashFieldExpirationFeature?.flag && isVersionHigherOrEquals(version, CommandsVersions.HASH_TTL.since) + && showTtl const openAddItemPanel = () => { setIsAddItemPanelOpen(true) @@ -49,9 +54,17 @@ const HashDetails = (props: Props) => { } } - const Actions = ({ width }: { width: number }) => ( - - ) + const handleSelectShow = (show: boolean) => { + setShowTtl(show) + + sendEventTelemetry({ + event: TelemetryEvent.SHOW_HASH_TTL_CLICKED, + eventData: { + databaseId: instanceId, + action: show ? 'show' : 'hide' + } + }) + } return (
@@ -59,7 +72,12 @@ const HashDetails = (props: Props) => { {...props} key="key-details-header" keyType={keyType} - Actions={Actions} + displayKeyFormatter={false} + /> +
{!loading && ( diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx new file mode 100644 index 0000000000..254d546f2c --- /dev/null +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx @@ -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() + expect(getByText('Show TTL')).toBeInTheDocument() + expect(getByTestId('btn-add-key')).toBeInTheDocument() + }) + + it('calls onShowTtl when checkbox is clicked', () => { + const { getByLabelText } = render() + fireEvent.click(getByLabelText('Show TTL')) + expect(props.onShowTtl).toHaveBeenCalledWith(true) + }) + + it('calls onAddKey when add key button is clicked', () => { + const { getByTestId } = render() + fireEvent.click(getByTestId('btn-add-key')) + expect(props.onAddKey).toHaveBeenCalled() + }) +}) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx new file mode 100644 index 0000000000..8d4bb30ea8 --- /dev/null +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -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' +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) => ( +
+ + {({ width = 0 }) => ( +
+ + + + + + + onShowTtl(e.target.checked)} + data-testId="test-check-ttl" + /> + + + + + + + + + +
+ )} +
+
+) + +export default KeyDetailsSubheader diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss new file mode 100644 index 0000000000..f37b63d8b1 --- /dev/null +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss @@ -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; + } + } + } + } +} + diff --git a/redisinsight/ui/src/pages/rdi/statistics/components/vertical-divider/VerticalDivider.tsx b/redisinsight/ui/src/pages/rdi/statistics/components/vertical-divider/VerticalDivider.tsx index 2dcc296be8..2c630fcd86 100644 --- a/redisinsight/ui/src/pages/rdi/statistics/components/vertical-divider/VerticalDivider.tsx +++ b/redisinsight/ui/src/pages/rdi/statistics/components/vertical-divider/VerticalDivider.tsx @@ -4,8 +4,8 @@ import Divider from 'uiSrc/components/divider/Divider' import styles from './styles.module.scss' -const VerticalDivider = () => ( - +const VerticalDivider = (props: any) => ( + ) export default VerticalDivider diff --git a/redisinsight/ui/src/telemetry/events.ts b/redisinsight/ui/src/telemetry/events.ts index 31a3c90858..b28760033c 100644 --- a/redisinsight/ui/src/telemetry/events.ts +++ b/redisinsight/ui/src/telemetry/events.ts @@ -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', From 24ab8a49d14f0d8e4d83aab486072721074908df Mon Sep 17 00:00:00 2001 From: kchepikava Date: Mon, 22 Jul 2024 11:32:30 +0200 Subject: [PATCH 02/12] 5917 comments resolve, show TTl checkbox only when necessary --- .../components/hash-details/HashDetails.tsx | 4 +- .../KeyDetailsSubheader.tsx | 50 ++++++++++++------- .../key-details-subheader/styles.module.scss | 12 +++-- 3 files changed, 43 insertions(+), 23 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx index 232aa2e77b..e2fb5fd6f7 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx @@ -40,7 +40,6 @@ const HashDetails = (props: Props) => { const isExpireFieldsAvailable = hashFieldExpirationFeature?.flag && isVersionHigherOrEquals(version, CommandsVersions.HASH_TTL.since) - && showTtl const openAddItemPanel = () => { setIsAddItemPanelOpen(true) @@ -78,6 +77,7 @@ const HashDetails = (props: Props) => { showTtl={showTtl} onShowTtl={handleSelectShow} onAddKey={openAddItemPanel} + isExpireFieldsAvailable={isExpireFieldsAvailable} />
{!loading && ( @@ -87,7 +87,7 @@ const HashDetails = (props: Props) => { )} {isAddItemPanelOpen && (
- +
)}
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index 8d4bb30ea8..3af65e1af7 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -3,7 +3,7 @@ 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' +import Divider from 'uiSrc/components/divider/Divider' import { KeyDetailsHeaderFormatter } from '../../../key-details-header/components/key-details-header-formatter' import styles from './styles.module.scss' @@ -11,35 +11,51 @@ interface Props { showTtl: boolean onShowTtl: (checked: boolean) => void onAddKey: () => void + isExpireFieldsAvailable: boolean } export const KeyDetailsSubheader = ({ showTtl, onShowTtl, - onAddKey + onAddKey, + isExpireFieldsAvailable }: Props) => (
{({ width = 0 }) => (
- + - - - onShowTtl(e.target.checked)} - data-testId="test-check-ttl" - /> - - - + + {isExpireFieldsAvailable && ( + <> + + onShowTtl(e.target.checked)} + data-testId="test-check-ttl" + /> + + + + )} + Date: Mon, 22 Jul 2024 13:54:21 +0200 Subject: [PATCH 03/12] 5917 fix tests --- .../hash-details/HashDetails.spec.tsx | 75 ++++++++++++------- .../KeyDetailsSubheader.spec.tsx | 1 + 2 files changed, 49 insertions(+), 27 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx index 316e3abf31..14e174ce69 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx @@ -12,6 +12,20 @@ jest.mock('uiSrc/telemetry', () => ({ sendEventTelemetry: jest.fn(), })) +jest.mock('uiSrc/slices/instances/instances', () => ({ + ...jest.requireActual('uiSrc/slices/instances/instances'), + connectedInstanceOverviewSelector: jest.fn().mockReturnValue({ + version: '7.4.2', + }), +})) + +jest.mock('uiSrc/slices/app/features', () => ({ + ...jest.requireActual('uiSrc/slices/app/features'), + appFeatureFlagsFeaturesSelector: jest.fn().mockReturnValue({ + hashFieldExpiration: { flag: true }, + }), +})) + describe('HashDetails', () => { beforeEach(() => { jest.clearAllMocks() @@ -22,7 +36,7 @@ describe('HashDetails', () => { it('should render subheader', () => { render() - expect(screen.getByText('Show TTL')).toBeInTheDocument() + expect(screen.getByText('+')).toBeInTheDocument() }) it('opens and closes the add item panel', () => { @@ -39,38 +53,45 @@ describe('HashDetails', () => { expect(screen.queryByText('Save')).not.toBeInTheDocument() }) - it('toggles the show TTL button', () => { - render() - const el = screen.getByTestId('test-check-ttl') as HTMLInputElement - expect(el.checked).toBe(true) - fireEvent.click(el) - expect(el.checked).toBe(false) - }) + describe('when hashFieldFeatureFlag and version higher 7.3', () => { + it('renders subheader with checkbox', () => { + render() + expect(screen.getByText('Show TTL')).toBeInTheDocument() + }) - it('should call proper telemetry event after click on showTtl', () => { - const sendEventTelemetryMock = jest.fn(); - (sendEventTelemetry as jest.Mock).mockImplementation(() => sendEventTelemetryMock) + it('toggles the show TTL button', () => { + render() + const el = screen.getByTestId('test-check-ttl') as HTMLInputElement + expect(el.checked).toBe(true) + fireEvent.click(el) + expect(el.checked).toBe(false) + }) - render() + it('should call proper telemetry event after click on showTtl', () => { + const sendEventTelemetryMock = jest.fn(); + (sendEventTelemetry as jest.Mock).mockImplementation(() => sendEventTelemetryMock) - fireEvent.click(screen.getByTestId('test-check-ttl')) + render() - 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: 'hide' + } + }) - fireEvent.click(screen.getByTestId('test-check-ttl')) + fireEvent.click(screen.getByTestId('test-check-ttl')) - expect(sendEventTelemetry).toBeCalledWith({ - event: TelemetryEvent.SHOW_HASH_TTL_CLICKED, - eventData: { - databaseId: INSTANCE_ID_MOCK, - action: 'show' - } + expect(sendEventTelemetry).toBeCalledWith({ + event: TelemetryEvent.SHOW_HASH_TTL_CLICKED, + eventData: { + databaseId: INSTANCE_ID_MOCK, + action: 'show' + } + }) }) }) }) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx index 254d546f2c..9193e1f92f 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx @@ -7,6 +7,7 @@ describe('KeyDetailsSubheader', () => { showTtl: false, onShowTtl: jest.fn(), onAddKey: jest.fn(), + isExpireFieldsAvailable: true, } it('should render', () => { From c9d40236e3e06991bb538d4b17f372d9f3139f7f Mon Sep 17 00:00:00 2001 From: kchepikava Date: Fri, 26 Jul 2024 13:42:52 +0200 Subject: [PATCH 04/12] RI-5959 fixed showttl not working --- .../key-details/components/hash-details/HashDetails.tsx | 4 ++-- .../components/key-details-subheader/KeyDetailsSubheader.tsx | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx index e2fb5fd6f7..fd6ce4be2c 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx @@ -82,12 +82,12 @@ const HashDetails = (props: Props) => {
{!loading && (
- +
)} {isAddItemPanelOpen && (
- +
)}
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index 3af65e1af7..0473afb403 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -11,7 +11,7 @@ interface Props { showTtl: boolean onShowTtl: (checked: boolean) => void onAddKey: () => void - isExpireFieldsAvailable: boolean + isExpireFieldsAvailable?: boolean } export const KeyDetailsSubheader = ({ From ee2e973258245bf2e7686daeee6cf5c117a7ca9a Mon Sep 17 00:00:00 2001 From: kchepikava Date: Fri, 26 Jul 2024 13:48:16 +0200 Subject: [PATCH 05/12] RI-5960 fixed borders are not aligned --- .../components/key-details-subheader/styles.module.scss | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss index 51800f38b2..37507a5835 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss @@ -7,13 +7,15 @@ .keyFormatterItem { max-width: 100px; - margin-right: 0; + } + + :global(.euiFlexGroup--gutterLarge>.euiFlexItem) { + margin: 12px 0 !important; } .showTtlItem { max-width: 110px; display: 'flex'; - margin-left: 0; .showTtlCheckbox { font-weight: 400; font-size: 14px; @@ -40,7 +42,6 @@ .addBtnContainer { max-width: 40px; align-self: center; - margin-right: 0 !important; :global(.euiButton) { height: 24px !important; width: 27px !important; From 9332b5d4b1cdf73c4dc4981dfce4600726152b51 Mon Sep 17 00:00:00 2001 From: kchepikava Date: Fri, 26 Jul 2024 15:41:32 +0200 Subject: [PATCH 06/12] RI-5960-fix-style --- .../key-details-subheader/KeyDetailsSubheader.tsx | 6 +++--- .../components/key-details-subheader/styles.module.scss | 6 +----- 2 files changed, 4 insertions(+), 8 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index 3af65e1af7..7091ab9d20 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -24,7 +24,7 @@ export const KeyDetailsSubheader = ({ {({ width = 0 }) => (
- + @@ -36,7 +36,7 @@ export const KeyDetailsSubheader = ({ /> {isExpireFieldsAvailable && ( <> - + )} - + .euiFlexItem) { - margin: 12px 0 !important; - } - .showTtlItem { - max-width: 110px; + width: 114px; display: 'flex'; .showTtlCheckbox { font-weight: 400; From 2426d8dd216cb6407fb29b4fa932472792e61336 Mon Sep 17 00:00:00 2001 From: mariasergeenko Date: Mon, 29 Jul 2024 10:43:20 +0200 Subject: [PATCH 07/12] Verify add show ttl --- .../KeyDetailsSubheader.tsx | 2 +- tests/e2e/pageObjects/browser-page.ts | 2 ++ .../smoke/browser/verify-key-details.e2e.ts | 21 ++++++++++++------- 3 files changed, 16 insertions(+), 9 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index 46abfff49e..f1cf2b8566 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -60,7 +60,7 @@ export const KeyDetailsSubheader = ({ fill color="secondary" onClick={onAddKey} - data-testid="btn-add-key" + data-testid="add-key-value-items-btn" > + diff --git a/tests/e2e/pageObjects/browser-page.ts b/tests/e2e/pageObjects/browser-page.ts index 2dab013eb3..3b9d061cca 100644 --- a/tests/e2e/pageObjects/browser-page.ts +++ b/tests/e2e/pageObjects/browser-page.ts @@ -271,6 +271,8 @@ export class BrowserPage extends InstancePage { //Get Hash key field ttl value //for Redis databases 7.4 and higher getHashTtlFieldInput = (fieldName: string): Selector => (Selector(`[data-testid=hash-ttl_content-value-${fieldName}]`)); + //checkbox + showTtlCheckbox = Selector('[data-testid=test-check-ttl]~label'); /** * Common part for Add any new key diff --git a/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts b/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts index d1fde3dceb..3a880a408f 100644 --- a/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts +++ b/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts @@ -1,7 +1,7 @@ import { rte } from '../../../../helpers/constants'; import { DatabaseHelper } from '../../../../helpers/database'; import { BrowserPage } from '../../../../pageObjects'; -import { commonUrl, ossStandaloneConfig } from '../../../../helpers/conf'; +import { commonUrl, ossStandaloneConfig, ossStandaloneV7Config } from '../../../../helpers/conf'; import { Common } from '../../../../helpers/common'; import { DatabaseAPIRequests } from '../../../../helpers/api/api-database'; import { APIKeyRequests } from '../../../../helpers/api/api-keys'; @@ -119,17 +119,16 @@ test('Verify that user can see JSON Key details', async t => { await t.expect(keyTTLValue).match(expectedTTL, 'The JSON Key TTL is incorrect'); await t.expect(keyBadge).contains('JSON', 'The JSON Key Badge is incorrect'); }); -//the test is skipped until redis databases 7.4 is not added to docker -test + +test.only .before(async() => { - // await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(); + await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneV7Config); }) .after(async() => { // Clear and delete database - // await apiKeyRequests.deleteKeyByNameApi(keyName, ); - // await databaseAPIRequests.deleteStandaloneDatabaseApi(); - }) - .skip('Verify that user can set ttl for Hash fields', async t => { + await apiKeyRequests.deleteKeyByNameApi(keyName, ossStandaloneV7Config.databaseName); + await databaseAPIRequests.deleteStandaloneDatabaseApi(ossStandaloneV7Config); + })('Verify that user can set ttl for Hash fields', async t => { keyName = Common.generateWord(10); const keyName2 = Common.generateWord(10); const field1 = 'Field1WithTtl'; @@ -150,6 +149,11 @@ test ttlFieldValue = await browserPage.getHashTtlFieldInput(field2).textContent; await t.expect(ttlFieldValue).match(expectedTTL, 'the field ttl is not set'); + //verify that ttl column can be hidden + await t.click(browserPage.showTtlCheckbox); + await t.expect(await browserPage.getHashTtlFieldInput(field2).exists).notOk('the ttl column is not hidden'); + await t.click(browserPage.showTtlCheckbox); + //verify that field is removed after ttl field is expired await browserPage.editHashFieldTtlValue(field1, '1'); await t.wait(1000); @@ -160,6 +164,7 @@ test //verify that the key is removed if key has 1 field and ttl field is expired await browserPage.addHashKey(keyName2, ' ', field1); await browserPage.editHashFieldTtlValue(field1, '1'); + await t.wait(1000); await t.click(browserPage.refreshKeysButton); await t.expect(browserPage.getKeySelectorByName(keyName2).exists).notOk('key is not removed when the field ttl is expired'); From 1a94b1c51472c5685fb43c96e0dbe604c652c817 Mon Sep 17 00:00:00 2001 From: mariasergeenko Date: Mon, 29 Jul 2024 11:58:37 +0200 Subject: [PATCH 08/12] remove only --- tests/e2e/helpers/conf.ts | 8 ++++---- .../e2e/tests/web/smoke/browser/verify-key-details.e2e.ts | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/e2e/helpers/conf.ts b/tests/e2e/helpers/conf.ts index 3a3e813a9f..1d6bcd56bc 100644 --- a/tests/e2e/helpers/conf.ts +++ b/tests/e2e/helpers/conf.ts @@ -40,8 +40,8 @@ export const ossStandaloneV5Config = { }; export const ossStandaloneV7Config = { - host: process.env.OSS_STANDALONE_V7_HOST || 'oss-standalone-v7', - port: process.env.OSS_STANDALONE_V7_PORT || '6379', + host: process.env.OSS_STANDALONE_V7_HOST || 'localhost', + port: process.env.OSS_STANDALONE_V7_PORT || '6378', databaseName: `${process.env.OSS_STANDALONE_V7_DATABASE_NAME || 'test_standalone-v7'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_V7_USERNAME, databasePassword: process.env.OSS_STANDALONE_V7_PASSWORD @@ -115,7 +115,7 @@ export const cloudDatabaseConfig = { }; export const ossStandaloneNoPermissionsConfig = { - host: process.env.OSS_STANDALONE_NOPERM_HOST || 'oss-standalone', + host: process.env.OSS_STANDALONE_NOPERM_HOST || 'localhost', port: process.env.OSS_STANDALONE_NOPERM_PORT || '6379', databaseName: `${process.env.OSS_STANDALONE_NOPERM_DATABASE_NAME || 'oss-standalone-no-permissions'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_NOPERM_USERNAME || 'noperm', @@ -140,7 +140,7 @@ export const ossClusterForSSHConfig = { export const ossStandaloneTlsConfig = { host: process.env.OSS_STANDALONE_TLS_HOST || 'oss-standalone-tls', - port: process.env.OSS_STANDALONE_TLS_PORT || '6379', + port: process.env.OSS_STANDALONE_TLS_PORT || '6301', databaseName: `${process.env.OSS_STANDALONE_TLS_DATABASE_NAME || 'test_standalone_tls'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_TLS_USERNAME, databasePassword: process.env.OSS_STANDALONE_TLS_PASSWORD, diff --git a/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts b/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts index 3a880a408f..ee75bb969b 100644 --- a/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts +++ b/tests/e2e/tests/web/smoke/browser/verify-key-details.e2e.ts @@ -120,7 +120,7 @@ test('Verify that user can see JSON Key details', async t => { await t.expect(keyBadge).contains('JSON', 'The JSON Key Badge is incorrect'); }); -test.only +test .before(async() => { await databaseHelper.acceptLicenseTermsAndAddDatabaseApi(ossStandaloneV7Config); }) From 667590af84bb3437af20fea066d6659a89493e94 Mon Sep 17 00:00:00 2001 From: mariasergeenko Date: Mon, 29 Jul 2024 12:00:17 +0200 Subject: [PATCH 09/12] remove config --- tests/e2e/helpers/conf.ts | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/tests/e2e/helpers/conf.ts b/tests/e2e/helpers/conf.ts index 1d6bcd56bc..3a3e813a9f 100644 --- a/tests/e2e/helpers/conf.ts +++ b/tests/e2e/helpers/conf.ts @@ -40,8 +40,8 @@ export const ossStandaloneV5Config = { }; export const ossStandaloneV7Config = { - host: process.env.OSS_STANDALONE_V7_HOST || 'localhost', - port: process.env.OSS_STANDALONE_V7_PORT || '6378', + host: process.env.OSS_STANDALONE_V7_HOST || 'oss-standalone-v7', + port: process.env.OSS_STANDALONE_V7_PORT || '6379', databaseName: `${process.env.OSS_STANDALONE_V7_DATABASE_NAME || 'test_standalone-v7'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_V7_USERNAME, databasePassword: process.env.OSS_STANDALONE_V7_PASSWORD @@ -115,7 +115,7 @@ export const cloudDatabaseConfig = { }; export const ossStandaloneNoPermissionsConfig = { - host: process.env.OSS_STANDALONE_NOPERM_HOST || 'localhost', + host: process.env.OSS_STANDALONE_NOPERM_HOST || 'oss-standalone', port: process.env.OSS_STANDALONE_NOPERM_PORT || '6379', databaseName: `${process.env.OSS_STANDALONE_NOPERM_DATABASE_NAME || 'oss-standalone-no-permissions'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_NOPERM_USERNAME || 'noperm', @@ -140,7 +140,7 @@ export const ossClusterForSSHConfig = { export const ossStandaloneTlsConfig = { host: process.env.OSS_STANDALONE_TLS_HOST || 'oss-standalone-tls', - port: process.env.OSS_STANDALONE_TLS_PORT || '6301', + port: process.env.OSS_STANDALONE_TLS_PORT || '6379', databaseName: `${process.env.OSS_STANDALONE_TLS_DATABASE_NAME || 'test_standalone_tls'}-${uniqueId}`, databaseUsername: process.env.OSS_STANDALONE_TLS_USERNAME, databasePassword: process.env.OSS_STANDALONE_TLS_PASSWORD, From c1132af543ac98a9a6339fd76945882c56aa0191 Mon Sep 17 00:00:00 2001 From: kchepikava Date: Mon, 29 Jul 2024 16:48:14 +0200 Subject: [PATCH 10/12] RI-5917 add subheader for all fields --- .../key-details-header/KeyDetailsHeader.tsx | 12 --- .../styles.module.scss | 1 - .../DynamicTypeDetails.tsx | 1 + .../hash-details/HashDetails.spec.tsx | 4 +- .../components/hash-details/HashDetails.tsx | 10 ++- .../key-details-actions/styles.module.scss | 1 - .../KeyDetailsSubheader.spec.tsx | 35 ++++----- .../KeyDetailsSubheader.tsx | 76 +++++++++---------- .../key-details-subheader/styles.module.scss | 29 ++----- .../components/list-details/ListDetails.tsx | 7 +- .../list-details/styles.module.scss | 6 +- .../rejson-details/RejsonDetailsWrapper.tsx | 3 - .../components/set-details/SetDetails.tsx | 3 + .../stream-details/StreamDetails.tsx | 3 + .../string-details/StringDetails.tsx | 5 +- .../components/zset-details/ZSetDetails.tsx | 3 + 16 files changed, 90 insertions(+), 109 deletions(-) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx index 05b8dcf186..9db1f9a16b 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details-header/KeyDetailsHeader.tsx @@ -13,8 +13,6 @@ import AutoSizer from 'react-virtualized-auto-sizer' import { GroupBadge, AutoRefresh, FullScreen } from 'uiSrc/components' import { HIDE_LAST_REFRESH, - KeyTypes, - ModulesKeyTypes, } from 'uiSrc/constants' import { deleteSelectedKeyAction, @@ -30,7 +28,6 @@ import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances' import { RedisResponseBuffer } from 'uiSrc/slices/interfaces' import { getBasedOnViewTypeEvent, sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' -import { KeyDetailsHeaderFormatter } from './components/key-details-header-formatter' import { KeyDetailsHeaderName } from './components/key-details-header-name' import { KeyDetailsHeaderTTL } from './components/key-details-header-ttl' import { KeyDetailsHeaderDelete } from './components/key-details-header-delete' @@ -39,7 +36,6 @@ import { KeyDetailsHeaderSizeLength } from './components/key-details-header-size import styles from './styles.module.scss' export interface KeyDetailsHeaderProps { - keyType: KeyTypes | ModulesKeyTypes onCloseKey: (key: RedisResponseBuffer) => void onRemoveKey: () => void onEditKey: (key: RedisResponseBuffer, newKey: RedisResponseBuffer, onFailure?: () => void) => void @@ -47,7 +43,6 @@ export interface KeyDetailsHeaderProps { arePanelsCollapsed: boolean onToggleFullScreen: () => void Actions?: (props: { width: number }) => ReactElement - displayKeyFormatter?: boolean } const KeyDetailsHeader = ({ @@ -57,9 +52,7 @@ const KeyDetailsHeader = ({ onCloseKey, onRemoveKey, onEditKey, - keyType, Actions, - displayKeyFormatter = true }: KeyDetailsHeaderProps) => { const { refreshing, loading, lastRefreshTime, isRefreshDisabled } = useSelector(selectedKeySelector) const { @@ -112,8 +105,6 @@ const KeyDetailsHeader = ({ } } - const formatter = displayKeyFormatter && Object.values(KeyTypes).includes(keyType as KeyTypes) - return (
{loading ? ( @@ -181,9 +172,6 @@ const KeyDetailsHeader = ({ onChangeAutoRefreshRate={handleChangeAutoRefreshRate} testid="key" /> - {formatter && ( - - )} {!isUndefined(Actions) && }
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss index 91d3dcbba1..49b006c521 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss @@ -1,5 +1,4 @@ .container { - margin-right: 12px; height: 30px; border-radius: 4px; transition: transform 0.3s ease; diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/dynamic-type-details/DynamicTypeDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/dynamic-type-details/DynamicTypeDetails.tsx index e801038b8f..2deec0191e 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/dynamic-type-details/DynamicTypeDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/dynamic-type-details/DynamicTypeDetails.tsx @@ -14,6 +14,7 @@ import { StreamDetails } from '../stream-details' export interface Props extends KeyDetailsHeaderProps { onOpenAddItemPanel: () => void onCloseAddItemPanel: () => void + keyType: KeyTypes | ModulesKeyTypes } const DynamicTypeDetails = (props: Props) => { diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx index 14e174ce69..14c3cce7a8 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.spec.tsx @@ -36,7 +36,7 @@ describe('HashDetails', () => { it('should render subheader', () => { render() - expect(screen.getByText('+')).toBeInTheDocument() + expect(screen.getByTestId('select-format-key-value')).toBeInTheDocument() }) it('opens and closes the add item panel', () => { @@ -47,7 +47,7 @@ describe('HashDetails', () => { onCloseAddItemPanel={() => {}} /> ) - fireEvent.click(screen.getByText('+')) + fireEvent.click(screen.getByTestId('add-key-value-items-btn')) expect(screen.getByText('Save')).toBeInTheDocument() fireEvent.click(screen.getByText('Cancel')) expect(screen.queryByText('Save')).not.toBeInTheDocument() diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx index fd6ce4be2c..989488b80f 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx @@ -17,6 +17,7 @@ import { TelemetryEvent, sendEventTelemetry } from 'uiSrc/telemetry' import AddHashFields from './add-hash-fields/AddHashFields' import { HashDetailsTable } from './hash-details-table' import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' +import { AddItemsAction } from '../key-details-actions' export interface Props extends KeyDetailsHeaderProps { onRemoveKey: () => void @@ -53,6 +54,10 @@ const HashDetails = (props: Props) => { } } + const Actions = ({ width }: { width: number }) => ( + + ) + const handleSelectShow = (show: boolean) => { setShowTtl(show) @@ -70,13 +75,12 @@ const HashDetails = (props: Props) => {
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-actions/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-actions/styles.module.scss index 52eb240997..7702301a82 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-actions/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-actions/styles.module.scss @@ -1,5 +1,4 @@ .actionBtn { - margin-right: 12px; position: relative; z-index: 2; diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx index 9193e1f92f..7c2acf46e6 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx @@ -1,30 +1,23 @@ import React from 'react' -import { render, fireEvent } from 'uiSrc/utils/test-utils' -import { KeyDetailsSubheader } from './KeyDetailsSubheader' +import { instance, mock } from 'ts-mockito' +import { render, screen } from 'uiSrc/utils/test-utils' +import { KeyDetailsSubheader, Props } from './KeyDetailsSubheader' -describe('KeyDetailsSubheader', () => { - const props = { - showTtl: false, - onShowTtl: jest.fn(), - onAddKey: jest.fn(), - isExpireFieldsAvailable: true, - } +const mockedProps = mock() +describe('KeyDetailsSubheader', () => { it('should render', () => { - const { getByText, getByTestId } = render() - expect(getByText('Show TTL')).toBeInTheDocument() - expect(getByTestId('btn-add-key')).toBeInTheDocument() + expect(render()).toBeTruthy() }) it('calls onShowTtl when checkbox is clicked', () => { - const { getByLabelText } = render() - fireEvent.click(getByLabelText('Show TTL')) - expect(props.onShowTtl).toHaveBeenCalledWith(true) - }) - - it('calls onAddKey when add key button is clicked', () => { - const { getByTestId } = render() - fireEvent.click(getByTestId('btn-add-key')) - expect(props.onAddKey).toHaveBeenCalled() + const { getByLabelText } = render() + const el = screen.getByTestId('test-check-ttl') as HTMLInputElement + expect(el.checked).toBe(true) + expect(getByLabelText('Show TTL')).toBeInTheDocument() }) }) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index f1cf2b8566..2d07ccf6f5 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -1,70 +1,68 @@ -import React from 'react' +import React, { ReactElement } from 'react' -import { EuiButton, EuiCheckbox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui' +import { EuiCheckbox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui' import AutoSizer from 'react-virtualized-auto-sizer' +import { isUndefined } from 'lodash' import Divider from 'uiSrc/components/divider/Divider' +import { KeyTypes, ModulesKeyTypes } from 'uiSrc/constants' 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 interface Props { + keyType: KeyTypes | ModulesKeyTypes + showTtl?: boolean + onShowTtl?: (checked: boolean) => void + Actions?: (props: { width: number }) => ReactElement isExpireFieldsAvailable?: boolean } export const KeyDetailsSubheader = ({ showTtl, onShowTtl, - onAddKey, + keyType, + Actions, isExpireFieldsAvailable }: Props) => (
{({ width = 0 }) => (
- - - - - - {isExpireFieldsAvailable && ( + + {Object.values(KeyTypes).includes(keyType as KeyTypes) && ( <> - - onShowTtl(e.target.checked)} - data-testId="test-check-ttl" - /> + + )} - - - + - - + {isExpireFieldsAvailable && ( + <> + + onShowTtl && onShowTtl(e.target.checked)} + data-testId="test-check-ttl" + /> + + + + )} + + {!isUndefined(Actions) && }
)} diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss index 64643fe42d..043f0de247 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss @@ -2,20 +2,15 @@ padding: 12px 18px 0px 18px; .divider { - margin: 0 12px; - } - - .keyFormatterItem { - max-width: 100px; + margin: 0 14px; + height: 20px; + width: 1px; } .showTtlItem { - width: 114px; - display: 'flex'; .showTtlCheckbox { font-weight: 400; font-size: 14px; - margin: auto; :global(.euiCheckbox__input) { color: var(--controlsBorderColor) !important; @@ -35,22 +30,8 @@ } } - .addBtnContainer { - max-width: 40px; - align-self: center; - :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; - } - } - } + .actionItem { + margin-left: 12px; } } diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/ListDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/ListDetails.tsx index 5959f8cfcf..a1b1645f00 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/ListDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/ListDetails.tsx @@ -14,6 +14,7 @@ import { RemoveListElements } from './remove-list-elements' import AddListElements from './add-list-elements/AddListElements' import { AddItemsAction, RemoveItemsAction } from '../key-details-actions' +import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' import styles from './styles.module.scss' export interface Props extends KeyDetailsHeaderProps { @@ -55,7 +56,9 @@ const ListDetails = (props: Props) => { const Actions = ({ width }: { width: number }) => ( <> - +
+ +
) @@ -64,6 +67,8 @@ const ListDetails = (props: Props) => { + diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/styles.module.scss index 0838dd17dc..2b7fb38e92 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/list-details/styles.module.scss @@ -1,4 +1,8 @@ .contentActive { border-color: var(--euiColorPrimary) !important; border-bottom-width: 1px !important; -} \ No newline at end of file +} + +.removeBtnContainer { + margin-left: 12px; +} diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/RejsonDetailsWrapper.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/RejsonDetailsWrapper.tsx index 69e5c88c81..23f44cbadb 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/RejsonDetailsWrapper.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/rejson-details/RejsonDetailsWrapper.tsx @@ -9,7 +9,6 @@ import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances' import { sendEventTelemetry, TelemetryEvent, getBasedOnViewTypeEvent } from 'uiSrc/telemetry' import { KeyDetailsHeader, KeyDetailsHeaderProps } from 'uiSrc/pages/browser/modules' -import { KeyTypes } from 'uiSrc/constants' import { stringToBuffer } from 'uiSrc/utils' import { IJSONData } from 'uiSrc/pages/browser/modules/key-details/components/rejson-details/interfaces' import RejsonDetails from './rejson-details' @@ -19,7 +18,6 @@ import styles from './styles.module.scss' export interface Props extends KeyDetailsHeaderProps {} const RejsonDetailsWrapper = (props: Props) => { - const keyType = KeyTypes.ReJSON const { loading } = useSelector(rejsonSelector) const { data, downloaded, type, path } = useSelector(rejsonDataSelector) const { name: selectedKey, nameString, length } = useSelector(selectedKeyDataSelector) || {} @@ -83,7 +81,6 @@ const RejsonDetailsWrapper = (props: Props) => {
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/set-details/SetDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/set-details/SetDetails.tsx index 69c5ffda38..0c240e09de 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/set-details/SetDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/set-details/SetDetails.tsx @@ -11,6 +11,7 @@ import { KeyDetailsHeader, KeyDetailsHeaderProps } from 'uiSrc/pages/browser/mod import { SetDetailsTable } from './set-details-table' import { AddSetMembers } from './add-set-members' import { AddItemsAction } from '../key-details-actions' +import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' export interface Props extends KeyDetailsHeaderProps { onRemoveKey: () => void @@ -47,6 +48,8 @@ const SetDetails = (props: Props) => { + diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/stream-details/StreamDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/stream-details/StreamDetails.tsx index f92ce58f95..b6207e1af3 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/stream-details/StreamDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/stream-details/StreamDetails.tsx @@ -14,6 +14,7 @@ import { StreamDetailsBody } from './stream-details-body' import AddStreamEntries from './add-stream-entity' import AddStreamGroup from './add-stream-group' import { StreamItemsAction } from '../key-details-actions' +import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' export interface Props extends KeyDetailsHeaderProps { onRemoveKey: () => void @@ -58,6 +59,8 @@ const StreamDetails = (props: Props) => { + diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx index 1832e7ca59..2e6c4d18b8 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/string-details/StringDetails.tsx @@ -23,6 +23,7 @@ import { resetStringValue, stringDataSelector, stringSelector } from 'uiSrc/slic import { isFormatEditable, isFullStringLoaded } from 'uiSrc/utils' import { StringDetailsValue } from './string-details-value' import { EditItemAction } from '../key-details-actions' +import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' export interface Props extends KeyDetailsHeaderProps {} @@ -70,8 +71,10 @@ const StringDetails = (props: Props) => { +
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/zset-details/ZSetDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/zset-details/ZSetDetails.tsx index cc70ef990d..f31ae79257 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/zset-details/ZSetDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/zset-details/ZSetDetails.tsx @@ -11,6 +11,7 @@ import { KeyDetailsHeader, KeyDetailsHeaderProps } from 'uiSrc/pages/browser/mod import { ZSetDetailsTable } from './zset-details-table' import AddZsetMembers from './add-zset-members/AddZsetMembers' import { AddItemsAction } from '../key-details-actions' +import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' export interface Props extends KeyDetailsHeaderProps { onRemoveKey: () => void @@ -48,6 +49,8 @@ const ZSetDetails = (props: Props) => { + From 3c2a64c8c7baa8b78979cc2ec9ac8533c85a806e Mon Sep 17 00:00:00 2001 From: kchepikava Date: Tue, 30 Jul 2024 11:32:20 +0200 Subject: [PATCH 11/12] RI-5917 move show ttl checkbox in hash actions --- .../components/hash-details/HashDetails.tsx | 28 +++++++++++++++--- .../hash-details/styles.module.scss | 28 ++++++++++++++++++ .../KeyDetailsSubheader.spec.tsx | 13 +-------- .../KeyDetailsSubheader.tsx | 29 +------------------ .../key-details-subheader/styles.module.scss | 23 --------------- 5 files changed, 54 insertions(+), 67 deletions(-) create mode 100644 redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/styles.module.scss diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx index 989488b80f..465d624028 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/HashDetails.tsx @@ -3,6 +3,7 @@ import { useSelector } from 'react-redux' import cx from 'classnames' import { useParams } from 'react-router-dom' +import { EuiCheckbox, EuiFlexItem } from '@elastic/eui' import { selectedKeySelector, } from 'uiSrc/slices/browser/keys' @@ -14,10 +15,12 @@ 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 Divider from 'uiSrc/components/divider/Divider' import AddHashFields from './add-hash-fields/AddHashFields' import { HashDetailsTable } from './hash-details-table' import { KeyDetailsSubheader } from '../key-details-subheader/KeyDetailsSubheader' import { AddItemsAction } from '../key-details-actions' +import styles from './styles.module.scss' export interface Props extends KeyDetailsHeaderProps { onRemoveKey: () => void @@ -55,7 +58,27 @@ const HashDetails = (props: Props) => { } const Actions = ({ width }: { width: number }) => ( - + <> + {isExpireFieldsAvailable && ( + <> + handleSelectShow(e.target.checked)} + data-testId="test-check-ttl" + /> + + + )} + + ) const handleSelectShow = (show: boolean) => { @@ -78,10 +101,7 @@ const HashDetails = (props: Props) => { />
{!loading && ( diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/styles.module.scss new file mode 100644 index 0000000000..cece59b663 --- /dev/null +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/hash-details/styles.module.scss @@ -0,0 +1,28 @@ +.divider { + margin: 0 14px; + height: 20px; + width: 1px; +} + + +.showTtlCheckbox { + font-weight: 400; + font-size: 14px; + + :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; + } +} + diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx index 7c2acf46e6..e4c60ca288 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.spec.tsx @@ -1,6 +1,6 @@ import React from 'react' import { instance, mock } from 'ts-mockito' -import { render, screen } from 'uiSrc/utils/test-utils' +import { render } from 'uiSrc/utils/test-utils' import { KeyDetailsSubheader, Props } from './KeyDetailsSubheader' const mockedProps = mock() @@ -9,15 +9,4 @@ describe('KeyDetailsSubheader', () => { it('should render', () => { expect(render()).toBeTruthy() }) - - it('calls onShowTtl when checkbox is clicked', () => { - const { getByLabelText } = render() - const el = screen.getByTestId('test-check-ttl') as HTMLInputElement - expect(el.checked).toBe(true) - expect(getByLabelText('Show TTL')).toBeInTheDocument() - }) }) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx index 2d07ccf6f5..7bd30a79d8 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/KeyDetailsSubheader.tsx @@ -1,6 +1,6 @@ import React, { ReactElement } from 'react' -import { EuiCheckbox, EuiFlexGroup, EuiFlexItem } from '@elastic/eui' +import { EuiFlexGroup, EuiFlexItem } from '@elastic/eui' import AutoSizer from 'react-virtualized-auto-sizer' import { isUndefined } from 'lodash' @@ -11,18 +11,12 @@ import styles from './styles.module.scss' export interface Props { keyType: KeyTypes | ModulesKeyTypes - showTtl?: boolean - onShowTtl?: (checked: boolean) => void Actions?: (props: { width: number }) => ReactElement - isExpireFieldsAvailable?: boolean } export const KeyDetailsSubheader = ({ - showTtl, - onShowTtl, keyType, Actions, - isExpireFieldsAvailable }: Props) => (
@@ -41,27 +35,6 @@ export const KeyDetailsSubheader = ({ /> )} - {isExpireFieldsAvailable && ( - <> - - onShowTtl && onShowTtl(e.target.checked)} - data-testId="test-check-ttl" - /> - - - - )} - {!isUndefined(Actions) && }
diff --git a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss index 043f0de247..7f61d48e37 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details/components/key-details-subheader/styles.module.scss @@ -7,29 +7,6 @@ width: 1px; } - .showTtlItem { - .showTtlCheckbox { - font-weight: 400; - font-size: 14px; - - :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; - } - } - } - .actionItem { margin-left: 12px; } From 822eac7dec8240ab6213bca95c0be45e8e00e433 Mon Sep 17 00:00:00 2001 From: kchepikava Date: Tue, 30 Jul 2024 14:07:46 +0200 Subject: [PATCH 12/12] RI 5917 returned margin to key-details-header-formatter --- .../components/key-details-header-formatter/styles.module.scss | 1 + 1 file changed, 1 insertion(+) diff --git a/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss b/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss index 49b006c521..91d3dcbba1 100644 --- a/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss +++ b/redisinsight/ui/src/pages/browser/modules/key-details-header/components/key-details-header-formatter/styles.module.scss @@ -1,4 +1,5 @@ .container { + margin-right: 12px; height: 30px; border-radius: 4px; transition: transform 0.3s ease;