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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
13 changes: 13 additions & 0 deletions redisinsight/ui/src/assets/img/multi_play_icon_dark.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
13 changes: 13 additions & 0 deletions redisinsight/ui/src/assets/img/multi_play_icon_light.svg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Original file line number Diff line number Diff line change
@@ -1,21 +1,17 @@
import { cloneDeep } from 'lodash'
import React from 'react'
import { instance, mock } from 'ts-mockito'
import { WORKBENCH_HISTORY_WRAPPER_NAME } from 'uiSrc/pages/workbench/constants'
import { WBHistoryObject } from 'uiSrc/pages/workbench/interfaces'
import HistoryContainer from 'uiSrc/services/queryHistory'
import { cleanup, mockedStore, render } from 'uiSrc/utils/test-utils'
import WBResults, { Props } from './WBResults'

const mockedProps = mock<Props>()

let store: typeof mockedStore
let history: HistoryContainer<WBHistoryObject>
beforeEach(() => {
cleanup()
store = cloneDeep(mockedStore)
store.clearActions()
history = new HistoryContainer<WBHistoryObject>(WORKBENCH_HISTORY_WRAPPER_NAME)
})

jest.mock('uiSrc/services', () => ({
Expand All @@ -37,11 +33,11 @@ describe('WBResults', () => {

// sendCliClusterCommandAction.mockImplementation(() => sendCliClusterActionMock);

expect(render(<WBResults {...instance(mockedProps)} history={history} />)).toBeTruthy()
expect(render(<WBResults {...instance(mockedProps)} />)).toBeTruthy()
})

it('should render with custom props', () => {
const historyObjectsMock: WBHistoryObject[] = [
const historyItemsMock: WBHistoryObject[] = [
{
query: 'query1',
data: 'data1',
Expand All @@ -56,10 +52,27 @@ describe('WBResults', () => {
},
]

const historyProp = {
getData: () => historyObjectsMock,
}
expect(render(<WBResults {...instance(mockedProps)} historyItems={historyItemsMock} />)).toBeTruthy()
})

it('should not render NoResults component with empty history', () => {
const { getByTestId } = render(<WBResults {...instance(mockedProps)} historyItems={[]} />)

expect(getByTestId('wb_no-results')).toBeInTheDocument()
})

it('should render NoResults component with history', () => {
const historyItemsMock: WBHistoryObject[] = [{
query: 'query1',
data: 'data1',
id: 1,
fromPersistentStore: true,
}]

const { queryByTestId } = render(<WBResults {...instance(mockedProps)} historyItems={historyItemsMock} />)

const noResultsEl = queryByTestId('wb_no-results')

expect(render(<WBResults {...instance(mockedProps)} history={historyProp} />)).toBeTruthy()
expect(noResultsEl).not.toBeInTheDocument()
})
})
Original file line number Diff line number Diff line change
@@ -1,9 +1,14 @@
import React from 'react'
import React, { useContext } from 'react'
import cx from 'classnames'
import { EuiIcon, EuiText } from '@elastic/eui'

import { Theme } from 'uiSrc/constants'
import QueryCard from 'uiSrc/components/query-card'
import { WBHistoryObject } from 'uiSrc/pages/workbench/interfaces'
import { WBQueryType } from 'uiSrc/pages/workbench/constants'
import { ThemeContext } from 'uiSrc/contexts/themeContext'
import MultiPlayIconDark from 'uiSrc/assets/img/multi_play_icon_dark.svg'
import MultiPlayIconLight from 'uiSrc/assets/img/multi_play_icon_light.svg'
import styles from './styles.module.scss'

export interface Props {
Expand All @@ -12,26 +17,44 @@ export interface Props {
onQueryRun: (query: string, historyId?: number, type?: WBQueryType) => void;
onQueryDelete: (historyId: number) => void
}
const WBResults = ({ historyItems = [], onQueryRun, onQueryDelete, scrollDivRef }: Props) => (
<div className={cx(styles.container)}>
<div ref={scrollDivRef} />
{historyItems.map(({ query, data, id, time, fromPersistentStore, matched, loading, status }) => (
<QueryCard
id={id}
key={id}
data={data}
status={status}
loading={loading}
query={query}
matched={matched}
time={time}
fromStore={!!fromPersistentStore}
onQueryRun={(queryType: WBQueryType) => onQueryRun(query, id, queryType)}
onQueryReRun={() => onQueryRun(query)}
onQueryDelete={() => onQueryDelete(id)}
const WBResults = ({ historyItems = [], onQueryRun, onQueryDelete, scrollDivRef }: Props) => {
const { theme } = useContext(ThemeContext)

const NoResults = (
<div className={styles.noResults} data-testid="wb_no-results">
<EuiIcon
type={theme === Theme.Dark ? MultiPlayIconDark : MultiPlayIconLight}
className={styles.playIcon}
/>
))}
</div>
)
<EuiText className={styles.noResultsTitle} color="subdued">No results to display.</EuiText>
<EuiText className={styles.noResultsText} color="subdued">
Run Redis commands to get results or see the left menu to learn more.
</EuiText>
</div>
)

return (
<div className={cx(styles.container)}>
<div ref={scrollDivRef} />
{historyItems.map(({ query, data, id, time, fromPersistentStore, matched, loading, status }) => (
<QueryCard
id={id}
key={id}
data={data}
status={status}
loading={loading}
query={query}
matched={matched}
time={time}
fromStore={!!fromPersistentStore}
onQueryRun={(queryType: WBQueryType) => onQueryRun(query, id, queryType)}
onQueryReRun={() => onQueryRun(query)}
onQueryDelete={() => onQueryDelete(id)}
/>
))}
{!historyItems.length && NoResults}
</div>
)
}

export default React.memo(WBResults)
Original file line number Diff line number Diff line change
Expand Up @@ -13,3 +13,32 @@
border: 1px solid var(--euiColorLightShade);
overflow: auto;
}

.noResults {
width: 326px;
height: 100%;
min-height: 140px;
display: flex;
margin: 0 auto;
flex-direction: column;
align-items: center;
justify-content: center;
text-align: center;
overflow: hidden;
}

.noResultsTitle {
padding-top: 18px;
font: normal normal 500 15px/24px 'Graphik', sans-serif !important;
}

.noResultsText {
font: normal normal normal 13px/18px 'Graphik', sans-serif !important;
letter-spacing: -0.13px;
padding-top: 12px;
}

.playIcon {
width: 42px !important;
height: 42px !important;
}