From 9c1203ac368f2c12a86595bda9a7506b32bf1a17 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 7 Nov 2025 12:58:09 +0200 Subject: [PATCH 01/21] fix the footer button location and sizes --- .../home/components/import-database/ImportDatabase.tsx | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index df24d0b484..1e59501f38 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -133,9 +133,8 @@ const ImportDatabase = (props: Props) => { } return ReactDOM.createPortal( -
+ { content={isSubmitDisabled ? 'Upload a file' : undefined} > { Submit -
, + , footerEl, ) } From 0f3b77234343256c1f21276ffe29b4aad76b497d Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 7 Nov 2025 14:34:16 +0200 Subject: [PATCH 02/21] fix import text and spacing between elements --- .../ui/src/components/import-file-modal/ImportFileModal.tsx | 6 +++--- .../home/components/import-database/ImportDatabase.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/redisinsight/ui/src/components/import-file-modal/ImportFileModal.tsx b/redisinsight/ui/src/components/import-file-modal/ImportFileModal.tsx index f9386ae39c..d3a655baeb 100644 --- a/redisinsight/ui/src/components/import-file-modal/ImportFileModal.tsx +++ b/redisinsight/ui/src/components/import-file-modal/ImportFileModal.tsx @@ -2,7 +2,7 @@ import React from 'react' import { Nullable } from 'uiSrc/utils' import { RiFilePicker, UploadWarning } from 'uiSrc/components' -import { Col, FlexItem } from 'uiSrc/components/base/layout/flex' +import { Col, FlexItem, Row } from 'uiSrc/components/base/layout/flex' import { ColorText, Text } from 'uiSrc/components/base/text' import { Loader, Modal } from 'uiSrc/components/base/display' import { RiIcon } from 'uiSrc/components/base/icons/RiIcon' @@ -137,7 +137,7 @@ const ImportFileModal = ({ {isShowForm && ( - <> + ({ > {submitBtnText || 'Import'} - + )} {data && OK} diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index 1e59501f38..467fdbdda4 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -167,11 +167,11 @@ const ImportDatabase = (props: Props) => { return ( <> - + {isShowForm && ( <> - + Use a JSON file to import your database connections. Ensure that you only use files from trusted sources to prevent the risk of automatically executing malicious code. From 8eb893a05a733f35830add490123d79a9b793199 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 7 Nov 2025 14:43:35 +0200 Subject: [PATCH 03/21] remove info icons next to submit buttons and remove unused import found --- .../cluster-connection-form/ClusterConnectionForm.tsx | 2 -- .../pages/home/components/import-database/ImportDatabase.tsx | 2 -- 2 files changed, 4 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/cluster-connection/cluster-connection-form/ClusterConnectionForm.tsx b/redisinsight/ui/src/pages/home/components/cluster-connection/cluster-connection-form/ClusterConnectionForm.tsx index f73a905815..f433678571 100644 --- a/redisinsight/ui/src/pages/home/components/cluster-connection/cluster-connection-form/ClusterConnectionForm.tsx +++ b/redisinsight/ui/src/pages/home/components/cluster-connection/cluster-connection-form/ClusterConnectionForm.tsx @@ -16,7 +16,6 @@ import { PrimaryButton, SecondaryButton, } from 'uiSrc/components/base/forms/buttons' -import { InfoIcon } from 'uiSrc/components/base/icons' import { FormField, RiInfoIconProps, @@ -163,7 +162,6 @@ const ClusterConnectionForm = (props: Props) => { onClick={onClick} disabled={submitIsDisabled} loading={loading} - icon={submitIsDisabled ? InfoIcon : undefined} data-testid="btn-submit" > Submit diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index 467fdbdda4..db63afa1e9 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -17,7 +17,6 @@ import { PrimaryButton, SecondaryButton, } from 'uiSrc/components/base/forms/buttons' -import { InfoIcon } from 'uiSrc/components/base/icons' import { Title } from 'uiSrc/components/base/text/Title' import { ColorText, Text } from 'uiSrc/components/base/text' import { Loader } from 'uiSrc/components/base/display' @@ -151,7 +150,6 @@ const ImportDatabase = (props: Props) => { onClick={onSubmit} loading={loading} disabled={isSubmitDisabled} - icon={isSubmitDisabled ? InfoIcon : undefined} data-testid="btn-submit" > Submit From 0f6b7a02e0c7fe84cf63bde21df75fa042384086 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 7 Nov 2025 14:52:50 +0200 Subject: [PATCH 04/21] Fix footer button sizes and alignment --- .../home/components/import-database/ImportDatabase.tsx | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index db63afa1e9..1a4e9750de 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -101,32 +101,30 @@ const ImportDatabase = (props: Props) => { if (error) { return ReactDOM.createPortal( -
+ Retry -
, + , footerEl, ) } if (data) { return ReactDOM.createPortal( -
+ Ok -
, + , footerEl, ) } From c0d37b26204ab08a6278c8cd10d5d3813871d4b6 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Mon, 10 Nov 2025 14:28:42 +0200 Subject: [PATCH 05/21] revert the submit button info icon --- .../pages/home/components/import-database/ImportDatabase.tsx | 2 ++ 1 file changed, 2 insertions(+) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index 1a4e9750de..265ed90e0f 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -17,6 +17,7 @@ import { PrimaryButton, SecondaryButton, } from 'uiSrc/components/base/forms/buttons' +import { InfoIcon } from 'uiSrc/components/base/icons' import { Title } from 'uiSrc/components/base/text/Title' import { ColorText, Text } from 'uiSrc/components/base/text' import { Loader } from 'uiSrc/components/base/display' @@ -148,6 +149,7 @@ const ImportDatabase = (props: Props) => { onClick={onSubmit} loading={loading} disabled={isSubmitDisabled} + icon={isSubmitDisabled ? InfoIcon : undefined} data-testid="btn-submit" > Submit From cfeffdca0aab8b31c8cf8d7d557653cd93f76cc4 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Wed, 12 Nov 2025 17:01:42 +0200 Subject: [PATCH 06/21] finalize styling for main import file db form and error form --- .../import-database/ImportDatabase.tsx | 67 +++++++++---------- .../import-database/styles.module.scss | 39 ----------- 2 files changed, 32 insertions(+), 74 deletions(-) delete mode 100644 redisinsight/ui/src/pages/home/components/import-database/styles.module.scss diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index 265ed90e0f..fa19a1a8ce 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react' import { useDispatch, useSelector } from 'react-redux' import ReactDOM from 'react-dom' + import { fetchInstancesAction, importInstancesSelector, @@ -9,22 +10,19 @@ import { } from 'uiSrc/slices/instances/instances' import { Nullable } from 'uiSrc/utils' import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' -import { RiTooltip, UploadWarning, RiFilePicker } from 'uiSrc/components' +import { RiFilePicker, RiTooltip, UploadWarning } from 'uiSrc/components' import { useModalHeader } from 'uiSrc/contexts/ModalTitleProvider' import { Col, FlexItem, Row } from 'uiSrc/components/base/layout/flex' -import { Spacer } from 'uiSrc/components/base/layout/spacer' import { PrimaryButton, SecondaryButton, } from 'uiSrc/components/base/forms/buttons' -import { InfoIcon } from 'uiSrc/components/base/icons' +import { InfoIcon, RiIcon } from 'uiSrc/components/base/icons' import { Title } from 'uiSrc/components/base/text/Title' import { ColorText, Text } from 'uiSrc/components/base/text' import { Loader } from 'uiSrc/components/base/display' -import { RiIcon } from 'uiSrc/components/base/icons/RiIcon' import ResultsLog from './components/ResultsLog' -import styles from './styles.module.scss' import { ScrollableWrapper } from '../styles.module' export interface Props { @@ -141,7 +139,6 @@ const ImportDatabase = (props: Props) => { { return ( <> - - + + {isShowForm && ( - <> + Use a JSON file to import your database connections. Ensure that you only use files from trusted sources to prevent the risk of automatically executing malicious code. - + {isInvalid && ( - + {`File should not exceed ${MAX_MB_FILE} MB`} )} - + )} {loading && ( -
- - Uploading... - -
+ Uploading... + )} {error && ( -
- - - Failed to add database connections - - {error} -
+ + + Failed to add database connections + {error} + )} -
+ {isShowForm && ( - + )} {data && ( - - - + )}
diff --git a/redisinsight/ui/src/pages/home/components/import-database/styles.module.scss b/redisinsight/ui/src/pages/home/components/import-database/styles.module.scss deleted file mode 100644 index 4e188a5139..0000000000 --- a/redisinsight/ui/src/pages/home/components/import-database/styles.module.scss +++ /dev/null @@ -1,39 +0,0 @@ -.formWrapper { - .loading { - margin-top: 40px; - text-align: center; - } -} - -.fileDrop { - width: 100%; - max-width: none !important; - - :global { - .RI-File-Picker__showDrop .RI-File-Picker__prompt, .RI-File-Picker__input:focus + .RI-File-Picker__prompt { - background-color: var(--browserTableRowEven); - } - - .RI-File-Picker__prompt { - background-color: var(--browserTableRowEven); - height: 140px; - border-radius: 4px; - box-shadow: none; - border: 1px dashed var(--controlsBorderColor); - color: var(--htmlColor); - } - - .RI-File-Picker { - width: 400px; - } - - .RI-File-Picker__clearButton { - margin-top: 4px; - } - } -} - -.result { - text-align: center; - margin-top: 32px; -} From 97f7cf4eb93577d76849dd9139b431e597e1af05 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Thu, 13 Nov 2025 12:52:04 +0200 Subject: [PATCH 07/21] extract import table result constants --- .../ui/src/constants/importDatabasesTableResult.ts | 14 ++++++++++++++ redisinsight/ui/src/constants/index.ts | 1 + 2 files changed, 15 insertions(+) create mode 100644 redisinsight/ui/src/constants/importDatabasesTableResult.ts diff --git a/redisinsight/ui/src/constants/importDatabasesTableResult.ts b/redisinsight/ui/src/constants/importDatabasesTableResult.ts new file mode 100644 index 0000000000..77a7119d6c --- /dev/null +++ b/redisinsight/ui/src/constants/importDatabasesTableResult.ts @@ -0,0 +1,14 @@ +export enum ImportTableResultColumn { + Index = 'index', + Host = 'host', + Errors = 'errors', +} + +export const TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP = new Map< + ImportTableResultColumn, + string +>([ + [ImportTableResultColumn.Index, '#'], + [ImportTableResultColumn.Host, 'Host:Port'], + [ImportTableResultColumn.Errors, 'Result'], +]) diff --git a/redisinsight/ui/src/constants/index.ts b/redisinsight/ui/src/constants/index.ts index 11e6cf97bf..bfee499623 100644 --- a/redisinsight/ui/src/constants/index.ts +++ b/redisinsight/ui/src/constants/index.ts @@ -36,4 +36,5 @@ export * from './datetime' export * from './sorting' export * from './databaseList' export * from './rdiList' +export * from './importDatabasesTableResult' export { ApiEndpoints, BrowserStorageItem, ApiStatusCode, apiErrors } From b53162bce421d8acae5a5d930cbb28f81c48f201 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Thu, 13 Nov 2025 12:59:38 +0200 Subject: [PATCH 08/21] replace hard coded values with defined constants; remove scss styles and files --- .../components/TableResult/TableResult.tsx | 38 ++++++++++--------- .../components/TableResult/styles.module.scss | 5 --- 2 files changed, 21 insertions(+), 22 deletions(-) delete mode 100644 redisinsight/ui/src/pages/home/components/import-database/components/TableResult/styles.module.scss diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx index 75cdb013d0..8b821d608f 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx @@ -1,10 +1,12 @@ import React from 'react' -import { Table, ColumnDefinition } from 'uiSrc/components/base/layout/table' +import { Table, ColumnDef } from 'uiSrc/components/base/layout/table' +import { + ImportTableResultColumn, + TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP, +} from 'uiSrc/constants' import { ErrorImportResult } from 'uiSrc/slices/interfaces' -import styles from './styles.module.scss' - export interface DataImportResult { index: number status: string @@ -27,11 +29,13 @@ const TableResult = (props: Props) => { ) - const columns: ColumnDefinition[] = [ + const columns: ColumnDef[] = [ { - header: '#', - id: 'index', - accessorKey: 'index', + header: TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP.get( + ImportTableResultColumn.Index, + ), + id: ImportTableResultColumn.Index, + accessorKey: ImportTableResultColumn.Index, cell: ({ row: { original: { index }, @@ -39,9 +43,11 @@ const TableResult = (props: Props) => { }) => ({index}), }, { - header: 'Host:Port', - id: 'host', - accessorKey: 'host', + header: TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP.get( + ImportTableResultColumn.Host, + ), + id: ImportTableResultColumn.Host, + accessorKey: ImportTableResultColumn.Host, cell: ({ row: { original: { host, port, index }, @@ -53,8 +59,10 @@ const TableResult = (props: Props) => { ), }, { - header: 'Result', - id: 'errors', + header: TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP.get( + ImportTableResultColumn.Errors, + ), + id: ImportTableResultColumn.Errors, accessorKey: 'errors', cell: ({ row: { @@ -74,11 +82,7 @@ const TableResult = (props: Props) => { if (data?.length === 0) return null - return ( -
- - - ) + return
} export default TableResult diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/styles.module.scss b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/styles.module.scss deleted file mode 100644 index cf242b91db..0000000000 --- a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/styles.module.scss +++ /dev/null @@ -1,5 +0,0 @@ -.tableWrapper { - max-height: 200px; - @include eui.scrollBar; - overflow: auto; -} From e7f6fa7cfc303caf30fe8b95226e69fc7043f257 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Thu, 13 Nov 2025 18:01:49 +0200 Subject: [PATCH 09/21] add sizing for table result index column; add some spacings in the component --- .../import-database/components/TableResult/TableResult.tsx | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx index 8b821d608f..c6e14b1868 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx @@ -1,10 +1,10 @@ import React from 'react' + import { Table, ColumnDef } from 'uiSrc/components/base/layout/table' import { ImportTableResultColumn, TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP, } from 'uiSrc/constants' - import { ErrorImportResult } from 'uiSrc/slices/interfaces' export interface DataImportResult { @@ -14,6 +14,7 @@ export interface DataImportResult { host?: string port?: number } + export interface Props { data: Array } @@ -41,6 +42,7 @@ const TableResult = (props: Props) => { original: { index }, }, }) => ({index}), + size: 50, }, { header: TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP.get( From 96c311b3ca45ec2f1a577afc6c49bf0fd6fa8e76 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Thu, 13 Nov 2025 18:05:18 +0200 Subject: [PATCH 10/21] add import db result type enum --- redisinsight/ui/src/constants/importDatabasesTableResult.ts | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/redisinsight/ui/src/constants/importDatabasesTableResult.ts b/redisinsight/ui/src/constants/importDatabasesTableResult.ts index 77a7119d6c..8b1138d52e 100644 --- a/redisinsight/ui/src/constants/importDatabasesTableResult.ts +++ b/redisinsight/ui/src/constants/importDatabasesTableResult.ts @@ -12,3 +12,9 @@ export const TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP = new Map< [ImportTableResultColumn.Host, 'Host:Port'], [ImportTableResultColumn.Errors, 'Result'], ]) + +export enum ImportDatabaseResultType { + Success = 'success', + Partial = 'partial', + Failed = 'failed', +} From a37a0f1caf0cc06a92bda3458bbad06738204395 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Thu, 13 Nov 2025 18:06:28 +0200 Subject: [PATCH 11/21] apply proper styling and refactor the results log component --- .../components/ResultsLog/ResultLog.styles.ts | 10 ++ .../components/ResultsLog/ResultsLog.tsx | 150 ++++++++---------- .../components/ResultsLog/styles.module.scss | 76 --------- 3 files changed, 72 insertions(+), 164 deletions(-) create mode 100644 redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts delete mode 100644 redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/styles.module.scss diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts new file mode 100644 index 0000000000..fd4c49c1b0 --- /dev/null +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts @@ -0,0 +1,10 @@ +import styled from 'styled-components' + +import { RICollapsibleNavGroup } from 'uiSrc/components/base/display' + +// Ideally this should be coming from the Section component +// replacing the box-shadow with the border so it is not cut by the parent container +export const StyledCollapsibleNavGroup = styled(RICollapsibleNavGroup)` + box-shadow: none; + border: 1px solid ${({ theme }) => theme.semantic.color.border.neutral600}; +` diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx index 68160f51ee..afa6b0b3ab 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx @@ -1,42 +1,61 @@ -import cx from 'classnames' -import React, { useState } from 'react' +import React, { useEffect, useState } from 'react' import { ImportDatabasesData } from 'uiSrc/slices/interfaces' import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' import { Nullable } from 'uiSrc/utils' -import { RICollapsibleNavGroup } from 'uiSrc/components/base/display' -import { Col } from 'uiSrc/components/base/layout/flex' +import { Col, Row } from 'uiSrc/components/base/layout/flex' +import { Text } from 'uiSrc/components/base/text' import TableResult from '../TableResult' -import styles from './styles.module.scss' +import { ImportDatabaseResultType } from 'uiSrc/constants' +import { DataImportResult } from '../TableResult/TableResult' +import { StyledCollapsibleNavGroup } from './ResultLog.styles' -enum ResultsStatus { - Success = 'success', - Partial = 'partial', - Failed = 'failed', +interface Props { + data: Nullable } -export interface Props { - data: Nullable +interface TableResultData { + type: ImportDatabaseResultType + title: string + data: DataImportResult[] } const ResultsLog = ({ data }: Props) => { - const [openedNav, setOpenedNav] = useState('') + const [openedNav, setOpenedNav] = + useState>(null) - const onToggle = (length: number = 0, isOpen: boolean, name: string) => { - if (length === 0) return - setOpenedNav(isOpen ? name : '') - - if (isOpen) { + useEffect(() => { + if (openedNav) { sendEventTelemetry({ event: TelemetryEvent.CONFIG_DATABASES_REDIS_IMPORT_LOG_VIEWED, eventData: { - length, - name, + length: + collapsibleNavData.find((item) => item.type === openedNav)?.data + .length ?? 0, + name: openedNav, }, }) } - } + }, [openedNav]) + + const collapsibleNavData: TableResultData[] = [ + { + type: ImportDatabaseResultType.Success, + title: 'Fully imported', + data: data?.success ?? [], + }, + { + type: ImportDatabaseResultType.Partial, + title: 'Partially imported', + data: data?.partial ?? [], + }, + { + type: ImportDatabaseResultType.Failed, + title: 'Failed to import', + data: data?.fail ?? [], + }, + ] const CollapsibleNavTitle = ({ title, @@ -45,78 +64,33 @@ const ResultsLog = ({ data }: Props) => { title: string length: number }) => ( -
- {title}: - {length} -
+ + {title}: + {length} + ) - const getNavGroupState = (name: ResultsStatus) => - openedNav === name ? 'open' : 'closed' + const getNavGroupState = (type: ImportDatabaseResultType) => + openedNav === type ? 'open' : 'closed' return ( -
- - } - className={cx(styles.collapsibleNav, ResultsStatus.Success, { - [styles.disabled]: !data?.success?.length, - })} - isCollapsible - initialIsOpen={false} - onToggle={(isOpen) => - onToggle(data?.success?.length, isOpen, ResultsStatus.Success) - } - forceState={getNavGroupState(ResultsStatus.Success)} - data-testid={`success-results-${getNavGroupState(ResultsStatus.Success)}`} - id={`success-results-${getNavGroupState(ResultsStatus.Success)}`} - > - - - - } - className={cx(styles.collapsibleNav, ResultsStatus.Partial, { - [styles.disabled]: !data?.partial?.length, - })} - isCollapsible - initialIsOpen={false} - onToggle={(isOpen) => - onToggle(data?.partial?.length, isOpen, ResultsStatus.Partial) - } - forceState={getNavGroupState(ResultsStatus.Partial)} - data-testid={`partial-results-${getNavGroupState(ResultsStatus.Partial)}`} - > - - - - } - className={cx(styles.collapsibleNav, ResultsStatus.Failed, { - [styles.disabled]: !data?.fail?.length, - })} - isCollapsible - initialIsOpen={false} - onToggle={(isOpen) => - onToggle(data?.fail?.length, isOpen, ResultsStatus.Failed) - } - forceState={getNavGroupState(ResultsStatus.Failed)} - data-testid={`failed-results-${getNavGroupState(ResultsStatus.Failed)}`} - > - - + + {collapsibleNavData.map((item) => ( + + } + data-testid={`${item.type}-results-${getNavGroupState(item.type)}`} + id={`${item.type}-results-${getNavGroupState(item.type)}`} + initialIsOpen={false} + onToggle={(isOpen) => setOpenedNav(isOpen ? item.type : null)} + forceState={getNavGroupState(item.type)} + open={openedNav === item.type} + > + + + ))} ) } diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/styles.module.scss b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/styles.module.scss deleted file mode 100644 index c3242fa4ae..0000000000 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/styles.module.scss +++ /dev/null @@ -1,76 +0,0 @@ -.collapsibleNav { - width: 100%; - margin-top: 5px !important; - position: relative; - - &.disabled { - :global { - .euiAccordion__button { - cursor: auto; - pointer-events: none; - } - .euiAccordion__iconWrapper { - display: none; - } - } - } - - &:global(.success) { - &:before { - background-color: var(--successBorderColor); - } - } - - &:global(.partial) { - &:before { - background-color: var(--warningBorderColor); - } - } - - &:global(.failed) { - &:before { - background-color: var(--errorBorderColor); - } - } - - &:before { - content: ''; - position: absolute; - left: 0; - top: 0; - bottom: 0; - width: 4px; - - border-radius: 4px 0 0 4px; - - z-index: 2; - } - - :global { - .euiCollapsibleNavGroup__title { - font-size: 12px !important; - font-weight: 400 !important; - color: var(--euiTextSubduedColor) !important; - } - .euiAccordion__triggerWrapper { - background-color: var(--euiColorEmptyShade); - padding: 12px 24px 12px 32px !important; - border-radius: 4px; - border: 1px solid var(--separatorColor); - } - .euiCollapsibleNavGroup__children { - padding: 0 !important; - } - - .euiIEFlexWrapFix { - flex-grow: 1; - padding-right: 4px; - } - } -} - -.collapsibleNavTitle { - display: flex; - justify-content: space-between; - align-items: center; -} From 3dcc0fa5954d2cdfebd17e68c6eb89399aeb96bf Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 13:29:38 +0200 Subject: [PATCH 12/21] Ok -> OK --- .../pages/home/components/import-database/ImportDatabase.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index fa19a1a8ce..1efd3ef59a 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -121,7 +121,7 @@ const ImportDatabase = (props: Props) => { onClick={handleOnClose} data-testid="btn-close" > - Ok + OK , footerEl, From 027fbc6ddf1b224bdbe4f0b93a550a5564b3e1d0 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 13:54:09 +0200 Subject: [PATCH 13/21] add padding to the container instead changing box-shadow -> border --- .../components/ResultsLog/ResultLog.styles.ts | 12 ++++++------ .../components/ResultsLog/ResultsLog.tsx | 17 +++++++++-------- 2 files changed, 15 insertions(+), 14 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts index fd4c49c1b0..4c258eea95 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultLog.styles.ts @@ -1,10 +1,10 @@ import styled from 'styled-components' -import { RICollapsibleNavGroup } from 'uiSrc/components/base/display' +import { Col } from 'uiSrc/components/base/layout/flex' -// Ideally this should be coming from the Section component -// replacing the box-shadow with the border so it is not cut by the parent container -export const StyledCollapsibleNavGroup = styled(RICollapsibleNavGroup)` - box-shadow: none; - border: 1px solid ${({ theme }) => theme.semantic.color.border.neutral600}; +// Ideally this should not be needed, but the section component +// will not let the parent cut the border, more precisely the box-shadow, +// so we need to add padding to the parent container +export const StyledColWrapper = styled(Col)` + padding: ${({ theme }) => theme.core.space.space025}; ` diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx index afa6b0b3ab..7ad431c2c0 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx @@ -3,13 +3,14 @@ import React, { useEffect, useState } from 'react' import { ImportDatabasesData } from 'uiSrc/slices/interfaces' import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' import { Nullable } from 'uiSrc/utils' -import { Col, Row } from 'uiSrc/components/base/layout/flex' +import { Row } from 'uiSrc/components/base/layout/flex' import { Text } from 'uiSrc/components/base/text' -import TableResult from '../TableResult' - +import { RICollapsibleNavGroup } from 'uiSrc/components/base/display' import { ImportDatabaseResultType } from 'uiSrc/constants' + +import TableResult from '../TableResult' import { DataImportResult } from '../TableResult/TableResult' -import { StyledCollapsibleNavGroup } from './ResultLog.styles' +import { StyledColWrapper } from './ResultLog.styles' interface Props { data: Nullable @@ -74,9 +75,9 @@ const ResultsLog = ({ data }: Props) => { openedNav === type ? 'open' : 'closed' return ( - + {collapsibleNavData.map((item) => ( - @@ -89,9 +90,9 @@ const ResultsLog = ({ data }: Props) => { open={openedNav === item.type} > - + ))} - + ) } From a045adc88d5a6dc0ffed2d1da57219f4329be951 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 13:54:33 +0200 Subject: [PATCH 14/21] add maxHeight to table result, beyond which a scroll will appear --- .../import-database/components/TableResult/TableResult.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx index c6e14b1868..6436c3f823 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx @@ -84,7 +84,7 @@ const TableResult = (props: Props) => { if (data?.length === 0) return null - return
+ return
} export default TableResult From 2056b69fb7cf7eda529ba1164269c70315087b2e Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 13:54:42 +0200 Subject: [PATCH 15/21] use rems instead of pixels --- .../pages/home/components/import-database/ImportDatabase.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index 1efd3ef59a..f02921fe95 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -210,7 +210,7 @@ const ImportDatabase = (props: Props) => { Failed to add database connections {error} From b114b2aa5316b779a6c4bbfe9e0eb1cb5a66e756 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 13:58:37 +0200 Subject: [PATCH 16/21] show only sections with items > 0 --- .../import-database/components/ResultsLog/ResultsLog.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx index 7ad431c2c0..9a1438cc15 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx @@ -76,7 +76,7 @@ const ResultsLog = ({ data }: Props) => { return ( - {collapsibleNavData.map((item) => ( + {collapsibleNavData.filter((item) => item.data.length > 0).map((item) => ( Date: Fri, 14 Nov 2025 14:28:43 +0200 Subject: [PATCH 17/21] decrease max table height --- .../import-database/components/TableResult/TableResult.tsx | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx index 6436c3f823..329329352c 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/TableResult/TableResult.tsx @@ -84,7 +84,7 @@ const TableResult = (props: Props) => { if (data?.length === 0) return null - return
+ return
} export default TableResult From 338411440ebd644d1fd2fb2a955e36d339f368f4 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 14:30:31 +0200 Subject: [PATCH 18/21] remove custom margin --- .../src/pages/home/components/import-database/ImportDatabase.tsx | 1 - 1 file changed, 1 deletion(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx index f02921fe95..c60a0d51e9 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/ImportDatabase.tsx @@ -133,7 +133,6 @@ const ImportDatabase = (props: Props) => { Cancel From 8afbd11048a9e70c971c761be1e310af8b241f9e Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 15:18:11 +0200 Subject: [PATCH 19/21] remove unneded collapsible nav title; calculate navState once per item, not three times --- .../components/ResultsLog/ResultsLog.tsx | 56 ++++++++----------- 1 file changed, 24 insertions(+), 32 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx index 9a1438cc15..8d8da137e9 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx @@ -58,40 +58,32 @@ const ResultsLog = ({ data }: Props) => { }, ] - const CollapsibleNavTitle = ({ - title, - length = 0, - }: { - title: string - length: number - }) => ( - - {title}: - {length} - - ) - - const getNavGroupState = (type: ImportDatabaseResultType) => - openedNav === type ? 'open' : 'closed' - return ( - {collapsibleNavData.filter((item) => item.data.length > 0).map((item) => ( - - } - data-testid={`${item.type}-results-${getNavGroupState(item.type)}`} - id={`${item.type}-results-${getNavGroupState(item.type)}`} - initialIsOpen={false} - onToggle={(isOpen) => setOpenedNav(isOpen ? item.type : null)} - forceState={getNavGroupState(item.type)} - open={openedNav === item.type} - > - - - ))} + {collapsibleNavData + .filter((item) => item.data.length > 0) + .map((item) => { + const navState = openedNav === item.type ? 'open' : 'closed' + return ( + + {item.title}: + {item.data.length} + + } + data-testid={`${item.type}-results-${navState}`} + id={`${item.type}-results-${navState}`} + initialIsOpen={false} + onToggle={(isOpen) => setOpenedNav(isOpen ? item.type : null)} + forceState={navState} + open={openedNav === item.type} + > + + + ) + })} ) } From 56c08d1607aae9a321d3e8a0a10993ed017e170f Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 16:15:52 +0200 Subject: [PATCH 20/21] extract the results data config in a separate file; use useMemo for the filtering --- .../constants/importDatabasesTableResult.ts | 2 +- .../ResultsLog/ResultsLog.config.tsx | 17 ++++ .../components/ResultsLog/ResultsLog.tsx | 83 ++++++++----------- 3 files changed, 52 insertions(+), 50 deletions(-) create mode 100644 redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.config.tsx diff --git a/redisinsight/ui/src/constants/importDatabasesTableResult.ts b/redisinsight/ui/src/constants/importDatabasesTableResult.ts index 8b1138d52e..57807285d2 100644 --- a/redisinsight/ui/src/constants/importDatabasesTableResult.ts +++ b/redisinsight/ui/src/constants/importDatabasesTableResult.ts @@ -16,5 +16,5 @@ export const TABLE_IMPORT_RESULT_COLUMN_ID_HEADER_MAP = new Map< export enum ImportDatabaseResultType { Success = 'success', Partial = 'partial', - Failed = 'failed', + Fail = 'fail', } diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.config.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.config.tsx new file mode 100644 index 0000000000..995ebab154 --- /dev/null +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.config.tsx @@ -0,0 +1,17 @@ +import { ImportDatabaseResultType } from 'uiSrc/constants' +import { TableResultData } from './ResultsLog' + +export const RESULTS_DATA_CONFIG: TableResultData[] = [ + { + type: ImportDatabaseResultType.Success, + title: 'Fully imported', + }, + { + type: ImportDatabaseResultType.Partial, + title: 'Partially imported', + }, + { + type: ImportDatabaseResultType.Fail, + title: 'Failed to import', + }, +] diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx index 8d8da137e9..d854b5b328 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.tsx @@ -1,4 +1,4 @@ -import React, { useEffect, useState } from 'react' +import React, { useEffect, useMemo, useState } from 'react' import { ImportDatabasesData } from 'uiSrc/slices/interfaces' import { sendEventTelemetry, TelemetryEvent } from 'uiSrc/telemetry' @@ -9,81 +9,66 @@ import { RICollapsibleNavGroup } from 'uiSrc/components/base/display' import { ImportDatabaseResultType } from 'uiSrc/constants' import TableResult from '../TableResult' -import { DataImportResult } from '../TableResult/TableResult' import { StyledColWrapper } from './ResultLog.styles' +import { RESULTS_DATA_CONFIG } from './ResultsLog.config' interface Props { data: Nullable } -interface TableResultData { +export interface TableResultData { type: ImportDatabaseResultType title: string - data: DataImportResult[] } const ResultsLog = ({ data }: Props) => { const [openedNav, setOpenedNav] = useState>(null) + const resultsData: TableResultData[] = useMemo(() => { + return RESULTS_DATA_CONFIG.filter( + (item) => data && data[item.type] && data[item.type].length > 0, + ) + }, [data]) + useEffect(() => { if (openedNav) { sendEventTelemetry({ event: TelemetryEvent.CONFIG_DATABASES_REDIS_IMPORT_LOG_VIEWED, eventData: { - length: - collapsibleNavData.find((item) => item.type === openedNav)?.data - .length ?? 0, + length: data?.[openedNav]?.length ?? 0, name: openedNav, }, }) } }, [openedNav]) - const collapsibleNavData: TableResultData[] = [ - { - type: ImportDatabaseResultType.Success, - title: 'Fully imported', - data: data?.success ?? [], - }, - { - type: ImportDatabaseResultType.Partial, - title: 'Partially imported', - data: data?.partial ?? [], - }, - { - type: ImportDatabaseResultType.Failed, - title: 'Failed to import', - data: data?.fail ?? [], - }, - ] - return ( - {collapsibleNavData - .filter((item) => item.data.length > 0) - .map((item) => { - const navState = openedNav === item.type ? 'open' : 'closed' - return ( - - {item.title}: - {item.data.length} - - } - data-testid={`${item.type}-results-${navState}`} - id={`${item.type}-results-${navState}`} - initialIsOpen={false} - onToggle={(isOpen) => setOpenedNav(isOpen ? item.type : null)} - forceState={navState} - open={openedNav === item.type} - > - - - ) - })} + {resultsData.map((item) => { + const navState = openedNav === item.type ? 'open' : 'closed' + return ( + + {item.title}: + + {data?.[item.type]?.length ?? 0} + + + } + data-testid={`${item.type}-results-${navState}`} + id={`${item.type}-results-${navState}`} + initialIsOpen={false} + onToggle={(isOpen) => setOpenedNav(isOpen ? item.type : null)} + forceState={navState} + open={openedNav === item.type} + > + + + ) + })} ) } From f1ce7d1794fd6da58902669310dbecb070fb38b0 Mon Sep 17 00:00:00 2001 From: Dijana Antovska Date: Fri, 14 Nov 2025 17:21:17 +0200 Subject: [PATCH 21/21] update tests since id is changed from failed-* to fail-* to match the type --- .../components/ResultsLog/ResultsLog.spec.tsx | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.spec.tsx b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.spec.tsx index 9cdb7daf26..e662be473f 100644 --- a/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.spec.tsx +++ b/redisinsight/ui/src/pages/home/components/import-database/components/ResultsLog/ResultsLog.spec.tsx @@ -27,7 +27,7 @@ describe('ResultsLog', () => { expect(screen.getByTestId('success-results-closed')).toBeInTheDocument() expect(screen.getByTestId('partial-results-closed')).toBeInTheDocument() - expect(screen.getByTestId('failed-results-closed')).toBeInTheDocument() + expect(screen.getByTestId('fail-results-closed')).toBeInTheDocument() }) it('should open and collapse other groups', () => { @@ -45,12 +45,12 @@ describe('ResultsLog', () => { expect(screen.getByTestId('success-results-open')).toBeInTheDocument() expect(screen.getByTestId('partial-results-closed')).toBeInTheDocument() - expect(screen.getByTestId('failed-results-closed')).toBeInTheDocument() + expect(screen.getByTestId('fail-results-closed')).toBeInTheDocument() fireEvent.click( - within(screen.getByTestId('failed-results-closed')).getByRole('button'), + within(screen.getByTestId('fail-results-closed')).getByRole('button'), ) - expect(screen.getByTestId('failed-results-open')).toBeInTheDocument() + expect(screen.getByTestId('fail-results-open')).toBeInTheDocument() expect(screen.getByTestId('partial-results-closed')).toBeInTheDocument() expect(screen.getByTestId('success-results-closed')).toBeInTheDocument() @@ -60,7 +60,7 @@ describe('ResultsLog', () => { ) expect(screen.getByTestId('partial-results-open')).toBeInTheDocument() - expect(screen.getByTestId('failed-results-closed')).toBeInTheDocument() + expect(screen.getByTestId('fail-results-closed')).toBeInTheDocument() expect(screen.getByTestId('success-results-closed')).toBeInTheDocument() }) @@ -87,7 +87,7 @@ describe('ResultsLog', () => { ), ).toHaveTextContent('1') expect( - within(screen.getByTestId('failed-results-closed')).getByTestId( + within(screen.getByTestId('fail-results-closed')).getByTestId( 'number-of-dbs', ), ).toHaveTextContent('1')