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
8 changes: 8 additions & 0 deletions redisinsight/ui/src/assets/img/oauth/cloud_color.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
Expand Up @@ -25,7 +25,7 @@ export interface Props {

const InsightsTrigger = (props: Props) => {
const { source = 'overview' } = props
const { isOpen: isInsigtsOpen, tabSelected } = useSelector(insightsPanelSelector)
const { isOpen: isInsightsOpen, tabSelected } = useSelector(insightsPanelSelector)
const { isHighlighted, } = useSelector(recommendationsSelector)
const { provider } = useSelector(connectedInstanceSelector)

Expand Down Expand Up @@ -58,7 +58,7 @@ const InsightsTrigger = (props: Props) => {
dispatch(toggleInsightsPanel())

sendEventTelemetry({
event: isInsigtsOpen ? TelemetryEvent.INSIGHTS_PANEL_CLOSED : TelemetryEvent.INSIGHTS_PANEL_OPENED,
event: isInsightsOpen ? TelemetryEvent.INSIGHTS_PANEL_CLOSED : TelemetryEvent.INSIGHTS_PANEL_OPENED,
eventData: {
provider,
page,
Expand All @@ -73,7 +73,7 @@ const InsightsTrigger = (props: Props) => {

return (
<div
className={cx(styles.container, { [styles.isOpen]: isInsigtsOpen })}
className={cx(styles.container, { [styles.isOpen]: isInsightsOpen })}
>
<HighlightedFeature
isHighlight={insightsHighlighting && !isHighlighted}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
.container {
display: flex;
flex: 1;
align-items: center;
justify-content: flex-end;
user-select: none;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,7 +96,7 @@ const InstanceHeader = ({ onChangeDbIndex }: Props) => {

return (
<div className={cx(styles.container)}>
<EuiFlexGroup gutterSize="none" responsive={false}>
<EuiFlexGroup gutterSize="none" responsive={false} alignItems="center">
<EuiFlexItem style={{ overflow: 'hidden' }}>
<div className={styles.breadcrumbsContainer} data-testid="breadcrumbs-container">
<div>
Expand Down
2 changes: 2 additions & 0 deletions redisinsight/ui/src/components/page-header/PageHeader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ import { resetDataRedisCloud } from 'uiSrc/slices/instances/cloud'
import { ThemeContext } from 'uiSrc/contexts/themeContext'
import { resetDataRedisCluster } from 'uiSrc/slices/instances/cluster'
import { resetDataSentinel } from 'uiSrc/slices/instances/sentinel'
import { CapabilityPromotion } from 'uiSrc/pages/home/components/capability-promotion'

import darkLogo from 'uiSrc/assets/img/dark_logo.svg'
import lightLogo from 'uiSrc/assets/img/light_logo.svg'
Expand Down Expand Up @@ -51,6 +52,7 @@ const PageHeader = (props: Props) => {
</EuiTitle>
{subtitle ? <span>{subtitle}</span> : ''}
</div>
<CapabilityPromotion wrapperClassName={cx(styles.section, styles.capabilityPromotion)} />
{logo || (
<div className={styles.pageHeaderLogo}>
<EuiButtonEmpty
Expand Down
2 changes: 1 addition & 1 deletion redisinsight/ui/src/components/promo-link/PromoLink.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React from 'react'
import { EuiIcon, EuiText } from '@elastic/eui'

import { Nullable } from 'uiSrc/utils'
import { ReactComponent as CloudIcon } from 'uiSrc/assets/img/oauth/cloud.svg'
import { ReactComponent as CloudIcon } from 'uiSrc/assets/img/oauth/cloud_color.svg'

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

Expand Down
12 changes: 3 additions & 9 deletions redisinsight/ui/src/components/promo-link/styles.module.scss
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
}

.link {
border: 1px solid var(--separatorColorLight);
border: 1px solid var(--euiColorSecondary);
padding: 6px 16px;
letter-spacing: normal;
border-radius: 4px;
Expand All @@ -19,7 +19,6 @@
height: 42px;
background-size: cover;
background-position: center;
background-color: var(--euiColorEmptyShade);

&::before {
content: "";
Expand Down Expand Up @@ -70,12 +69,7 @@
position: absolute;
width: 28px;
height: 20px;
top: 8px;
left: 10px;

path {
fill: var(--euiColorEmptyShade);
stroke: var(--euiTextSubduedColor);
}
top: 12px;
left: 16px;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ import { sendEventTelemetry, TELEMETRY_EMPTY_VALUE, TelemetryEvent } from 'uiSrc
import { MOCK_EXPLORE_GUIDES } from 'uiSrc/constants/mocks/mock-explore-guides'
import { findTutorialPath } from 'uiSrc/utils'

import CapabilityPromotion from './CapabilityPromotion'
import { CapabilityPromotion } from './CapabilityPromotion'

jest.mock('uiSrc/telemetry', () => ({
...jest.requireActual('uiSrc/telemetry'),
Expand Down Expand Up @@ -43,7 +43,7 @@ describe('CapabilityPromotion', () => {
it('should render capabilities', () => {
render(<CapabilityPromotion />)

MOCK_EXPLORE_GUIDES.forEach(({ tutorialId }) => {
MOCK_EXPLORE_GUIDES.slice(0, 2).forEach(({ tutorialId }) => {
expect(screen.getByTestId(`capability-promotion-${tutorialId}`)).toBeInTheDocument()
})
})
Expand Down Expand Up @@ -89,4 +89,28 @@ describe('CapabilityPromotion', () => {

(sendEventTelemetry as jest.Mock).mockRestore()
})

it('should call proper actions after click explore redis', () => {
render(<CapabilityPromotion />)

fireEvent.click(screen.getByTestId('explore-redis-btn'))

const expectedActions = [
changeSelectedTab(InsightsPanelTabs.Explore),
toggleInsightsPanel()
]

expect(store.getActions()).toEqual(expectedActions)

expect(sendEventTelemetry).toBeCalledWith({
event: TelemetryEvent.INSIGHTS_PANEL_OPENED,
eventData: {
databaseId: TELEMETRY_EMPTY_VALUE,
source: 'home page',
tab: InsightsPanelTabs.Explore,
}
});

(sendEventTelemetry as jest.Mock).mockRestore()
})
})
Original file line number Diff line number Diff line change
@@ -1,58 +1,78 @@
import React from 'react'

import { EuiIcon, EuiText, EuiTitle } from '@elastic/eui'
import { EuiIcon, EuiText } from '@elastic/eui'
import cx from 'classnames'
import { useDispatch, useSelector } from 'react-redux'
import { useHistory } from 'react-router-dom'
import ClickLearnRocketIcon from 'uiSrc/assets/img/click-learn-rocket.svg'
import { filter } from 'lodash'

import { openTutorialByPath } from 'uiSrc/slices/panels/insights'
import { changeSelectedTab, insightsPanelSelector, openTutorialByPath, toggleInsightsPanel } from 'uiSrc/slices/panels/insights'
import { sendEventTelemetry, TELEMETRY_EMPTY_VALUE, TelemetryEvent } from 'uiSrc/telemetry'
import { guideLinksSelector } from 'uiSrc/slices/content/guide-links'
import GUIDE_ICONS from 'uiSrc/components/explore-guides/icons'
import { findTutorialPath } from 'uiSrc/utils'
import { InsightsPanelTabs } from 'uiSrc/slices/interfaces/insights'
import styles from './styles.module.scss'

export interface Props {
mode?: 'reduced' | 'wide'
wrapperClassName?: string
capabilityIds?: string[]
}

const displayedCapabilityIds = ['sq-intro', 'ds-json-intro']

const CapabilityPromotion = (props: Props) => {
const { mode = 'wide', wrapperClassName } = props
const { data } = useSelector(guideLinksSelector)
const { mode = 'wide', wrapperClassName, capabilityIds = displayedCapabilityIds } = props
const { data: dataInit } = useSelector(guideLinksSelector)
const { isOpen: isInsightsOpen } = useSelector(insightsPanelSelector)

const dispatch = useDispatch()
const history = useHistory()

const onClickTutorial = (id: string) => {
const tutorialPath = findTutorialPath({ id: id ?? '' })
dispatch(openTutorialByPath(tutorialPath ?? '', history))
// display only RediSearch and JSON. In the future will be configured via github
const data = filter(dataInit, ({ tutorialId }) => capabilityIds.includes(tutorialId))

const sendTelemetry = (id?: string) => {
sendEventTelemetry({
event: TelemetryEvent.INSIGHTS_PANEL_OPENED,
event: isInsightsOpen ? TelemetryEvent.INSIGHTS_PANEL_CLOSED : TelemetryEvent.INSIGHTS_PANEL_OPENED,
eventData: {
databaseId: TELEMETRY_EMPTY_VALUE,
source: 'home page',
tutorialId: id
tutorialId: id || undefined,
tab: id ? undefined : InsightsPanelTabs.Explore,
},
})
}

const onClickTutorial = (id: string) => {
const tutorialPath = findTutorialPath({ id: id ?? '' })
dispatch(openTutorialByPath(tutorialPath ?? '', history))

sendTelemetry(id)
}

const onClickExplore = () => {
sendTelemetry()
dispatch(changeSelectedTab(InsightsPanelTabs.Explore))
dispatch(toggleInsightsPanel())
}

if (!data?.length) {
return null
}

return (
<div className={cx(styles.wrapper, mode, wrapperClassName)} data-testid="capability-promotion">
<img
className={styles.img}
src={ClickLearnRocketIcon}
alt="click and learn"
/>
<EuiTitle size="s" className={styles.title}>
<span>Click & Learn</span>
</EuiTitle>
<div
tabIndex={0}
role="button"
onKeyDown={() => {}}
onClick={onClickExplore}
className={styles.exploreItem}
data-testid="explore-redis-btn"
>
<EuiText>Explore Redis</EuiText>
</div>
<div className={styles.guides}>
{data.map(({ title, tutorialId, icon }) => (
// eslint-disable-next-line jsx-a11y/click-events-have-key-events
Expand All @@ -79,4 +99,4 @@ const CapabilityPromotion = (props: Props) => {
)
}

export default CapabilityPromotion
export { CapabilityPromotion }
Original file line number Diff line number Diff line change
@@ -1,3 +1 @@
import CapabilityPromotion from './CapabilityPromotion'

export default CapabilityPromotion
export { CapabilityPromotion } from './CapabilityPromotion'
Original file line number Diff line number Diff line change
Expand Up @@ -5,51 +5,55 @@
@import '@elastic/eui/src/global_styling/index';

.wrapper {
background-color: var(--browserTableRowEven);
border-radius: 8px;
height: 48px;
min-height: 48px;
flex-grow: 1;
overflow: hidden;

display: flex;
align-items: center;
justify-content: flex-end;

&:global(.reduced) {
.img, .title {
display: none;
}
}
.guides {
display: flex;
align-items: center;
justify-content: flex-end;

.img {
width: auto;
padding: 0 12px;
height: 100%;
}

.title {
font-size: 18px;
font-weight: 400;
}

.guides {
flex-grow: 1;
.exploreItem {
margin-right: 8px;
text-decoration: none;
display: flex;
align-items: center;
justify-content: space-around;
transition: transform 0.1s linear;

padding: 0 12px;
height: 100%;
&:hover {
transform: translateY(-1px) !important;
}

&:focus,
&:hover {
text-decoration: underline;
}
}

.guideItem {
display: flex;
align-items: center;
height: 100%;
padding: 6px 10px;
margin-right: 6px;
height: 32px;
border-radius: 20px;
border: 1px solid var(--euiColorSecondary);

cursor: pointer;
text-decoration: underline;
text-decoration: none;

&:focus, &:hover {
text-decoration: none;
text-decoration: underline;
}

&:nth-child(1) { .guideIcon { color: #FFAF2B; }}
Expand All @@ -64,24 +68,14 @@
}
}

@media screen and (max-width: 1024px) {
.img { display: none;}
.title { margin-left: 12px }
}

@include insights-open {
.img { display: none;}
.title { margin-left: 12px }
}

@include insights-open(1240px) {
.title { display: none;}
}

@include insights-open(1110px) {
.guideItem:nth-child(5) { display: none;}
@include welcome-page-header(650px) {
.guideItem:nth-child(3) {
display: none;
}
}

@include insights-open(1024px) {
.guideItem:nth-child(4) { display: none;}
@include welcome-page-header(850px) {
.guideItem:nth-child(4) {
display: none;
}
}
Loading