Skip to content
6 changes: 6 additions & 0 deletions redisinsight/ui/src/pages/slow-log/SlowLogPage.styles.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import styled from 'styled-components'
import { RiSelect } from 'uiSrc/components/base/forms/select/RiSelect'

export const StyledSelect = styled(RiSelect)`
border: none;
`
96 changes: 51 additions & 45 deletions redisinsight/ui/src/pages/slow-log/SlowLogPage.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -32,17 +32,15 @@
import { AnalyticsViewTab } from 'uiSrc/slices/interfaces/analytics'

import { FormatedDate } from 'uiSrc/components'
import { FlexItem, Row } from 'uiSrc/components/base/layout/flex'
import { Text } from 'uiSrc/components/base/text'
import {
defaultValueRender,
RiSelect,
} from 'uiSrc/components/base/forms/select/RiSelect'
import { Col, FlexItem, Row } from 'uiSrc/components/base/layout/flex'
import { Text, Title } from 'uiSrc/components/base/text'
import { defaultValueRender } from 'uiSrc/components/base/forms/select/RiSelect'
import { SlowLog } from 'apiSrc/modules/slow-log/models'

import { Actions, EmptySlowLog, SlowLogTable } from './components'

import styles from './styles.module.scss'
import { StyledSelect } from './SlowLogPage.styles'

const HIDE_TIMESTAMP_FROM_WIDTH = 850
const DEFAULT_COUNT_VALUE = '50'
Expand Down Expand Up @@ -144,85 +142,93 @@
const isEmptySlowLog = !data.length

return (
<div className={styles.main} data-testid="slow-log-page">
<Row className={styles.header} align="center" justify="between">
<FlexItem>
<AnalyticsTabs />
</FlexItem>

<FlexItem>
{connectionType !== ConnectionType.Cluster && config && (
<Text size="xs" color="subdued" data-testid="config-info">
Execution time:{' '}
{numberWithSpaces(
convertNumberByUnits(slowlogLogSlowerThan, durationUnit),
)}
&nbsp;
{durationUnit === DurationUnits.milliSeconds
? DurationUnits.mSeconds
: DurationUnits.microSeconds}
, Max length: {numberWithSpaces(slowlogMaxLen)}
</Text>
)}
</FlexItem>
</Row>

<Col className={styles.main} data-testid="slow-log-page">
<AutoSizer disableHeight>
{({ width }) => (
<div style={{ width }}>
<Row className={styles.header} align="center" justify="between">
<FlexItem>
<AnalyticsTabs />
</FlexItem>

<FlexItem>
<Row align="center" gap="xl">
{connectionType !== ConnectionType.Cluster && config && (
<Text size="s" color="secondary" data-testid="config-info">
Execution time:{' '}
{numberWithSpaces(
convertNumberByUnits(
slowlogLogSlowerThan,
durationUnit,
),
)}
&nbsp;
{durationUnit === DurationUnits.milliSeconds
? DurationUnits.mSeconds

Check warning on line 167 in redisinsight/ui/src/pages/slow-log/SlowLogPage.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
Comment on lines +158 to +167
Copy link
Collaborator

Choose a reason for hiding this comment

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

I know you've copied this over but this is a weird way to represent a single string value

Copy link
Member Author

Choose a reason for hiding this comment

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

Yes, it's the same code that we had so far. I've worked only on the visual representation of the surrounding elements.

: DurationUnits.microSeconds}

Check warning on line 168 in redisinsight/ui/src/pages/slow-log/SlowLogPage.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
, Max length: {numberWithSpaces(slowlogMaxLen)}
</Text>

Check warning on line 170 in redisinsight/ui/src/pages/slow-log/SlowLogPage.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
)}

<Actions
width={width}
isEmptySlowLog={isEmptySlowLog}
durationUnit={durationUnit}
onClear={onClearSlowLogs}
onRefresh={getSlowLogs}
/>
</Row>
</FlexItem>
</Row>

<Row
className={styles.actionsLine}
align="center"
justify="between"
>
<FlexItem>
<Row align="center" gap="s">
<Title size="L" color="primary">
Slow Log
Copy link
Collaborator

Choose a reason for hiding this comment

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

This looks weird. You have the title in the tab, and right below it, you have it again

Copy link
Member Author

Choose a reason for hiding this comment

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

It's what we have in Figma, I didn't make it up myself 🤷‍♂️

</Title>
</FlexItem>
<FlexItem>
<Row align="center" gap="xs">
<FlexItem>
<Text color="subdued">
<Text size="s" color="primary">
{connectionType === ConnectionType.Cluster
? 'Display per node:'
: 'Display up to:'}
</Text>
</FlexItem>
<FlexItem>
<RiSelect
<StyledSelect
options={countOptions}
valueRender={defaultValueRender}
value={count}
onChange={(value) => setCount(value)}
className={styles.countSelect}
data-testid="count-select"
/>
</FlexItem>
{width > HIDE_TIMESTAMP_FROM_WIDTH && (
<FlexItem style={{ marginLeft: 12 }}>
<Text
size="xs"
color="subdued"
size="s"
color="secondary"
data-testid="entries-from-timestamp"
>
({data.length} entries
{lastTimestamp && (
<>
<span>&nbsp;from &nbsp;</span>
<FormatedDate date={lastTimestamp * 1000} />
</>
)}
)
</Text>
</FlexItem>

Check warning on line 228 in redisinsight/ui/src/pages/slow-log/SlowLogPage.tsx

View workflow job for this annotation

GitHub Actions / Coverage annotations (🧪 jest-coverage-report-action)

🌿 Branch is not covered

Warning! Not covered branch
)}
</Row>
</FlexItem>
<FlexItem>
<Actions
width={width}
isEmptySlowLog={isEmptySlowLog}
durationUnit={durationUnit}
onClear={onClearSlowLogs}
onRefresh={getSlowLogs}
/>
</FlexItem>
</Row>
</div>
)}
Expand All @@ -239,7 +245,7 @@
durationUnit={durationUnit}
/>
)}
</div>
</Col>
)
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
import styled from 'styled-components'

export const StyledInfoIconWrapper = styled.span`
display: flex;
align-self: center;
cursor: pointer;
`
119 changes: 33 additions & 86 deletions redisinsight/ui/src/pages/slow-log/components/Actions/Actions.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
import React, { useState } from 'react'
import { useSelector } from 'react-redux'
import cx from 'classnames'
import { useParams } from 'react-router-dom'
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
import { DurationUnits } from 'uiSrc/constants'
Expand All @@ -13,15 +12,14 @@ import { FlexItem, Row } from 'uiSrc/components/base/layout/flex'
import { Spacer } from 'uiSrc/components/base/layout/spacer'
import { EraserIcon, SettingsIcon } from 'uiSrc/components/base/icons'
import {
DestructiveButton,
IconButton,
SecondaryButton,
} from 'uiSrc/components/base/forms/buttons'
import { Text } from 'uiSrc/components/base/text'
import { RiIcon } from 'uiSrc/components/base/icons/RiIcon'

import SlowLogConfig from '../SlowLogConfig'
import styles from './styles.module.scss'
import { StyledInfoIconWrapper } from './Actions.styles'
import { ClearSlowLogModal } from '../ClearSlowLogModal/ClearSlowLogModal'

export interface Props {
width: number
Expand All @@ -45,15 +43,15 @@ const Actions = (props: Props) => {
const { name = '' } = useSelector(connectedInstanceSelector)
const { loading, lastRefreshTime } = useSelector(slowLogSelector)

const [isPopoverClearOpen, setIsPopoverClearOpen] = useState(false)
const [isClearModalOpen, setIsClearModalOpen] = useState(false)
const [isPopoverConfigOpen, setIsPopoverConfigOpen] = useState(false)

const showClearPopover = () => {
setIsPopoverClearOpen((isPopoverClearOpen) => !isPopoverClearOpen)
const showClearModal = () => {
setIsClearModalOpen((isClearModalOpen) => !isClearModalOpen)
}

const closePopoverClear = () => {
setIsPopoverClearOpen(false)
const closeClearModal = () => {
setIsClearModalOpen(false)
}
const showConfigPopover = () => {
setIsPopoverConfigOpen((isPopoverConfigOpen) => !isPopoverConfigOpen)
Expand All @@ -63,11 +61,6 @@ const Actions = (props: Props) => {
setIsPopoverConfigOpen(false)
}

const handleClearClick = () => {
onClear()
closePopoverClear()
}

const handleEnableAutoRefresh = (
enableAutoRefresh: boolean,
refreshRate: string,
Expand Down Expand Up @@ -98,66 +91,32 @@ const Actions = (props: Props) => {
}
}

const ToolTipContent = (
<div className={styles.popoverContainer}>
<RiIcon
type="ToastDangerIcon"
color="attention600"
className={styles.warningIcon}
/>
<div>
<Text size="m" component="div">
<h4 className={styles.popoverTitle}>
<b>Clear Slow Log?</b>
</h4>
<Text size="xs" color="subdued">
Slow Log will be cleared for&nbsp;
<span className={styles.popoverDBName}>{name}</span>
<br />
NOTE: This is server configuration
</Text>
</Text>
<div className={styles.popoverFooter}>
<DestructiveButton
size="small"
icon={EraserIcon}
onClick={() => handleClearClick()}
className={styles.popoverDeleteBtn}
data-testid="reset-confirm-btn"
>
Clear
</DestructiveButton>
</div>
</div>
</div>
)

return (
<Row className={styles.actions} gap="s" align="center">
<FlexItem grow={5} style={{ alignItems: 'flex-end' }}>
<Row gap="s" align="center">
<FlexItem>
<AutoRefresh
postfix="slowlog"
loading={loading}
displayText={width > HIDE_REFRESH_LABEL_WIDTH}
lastRefreshTime={lastRefreshTime}
containerClassName={styles.refreshContainer}
onRefresh={() => onRefresh()}
onEnableAutoRefresh={handleEnableAutoRefresh}
onChangeAutoRefreshRate={handleChangeAutoRefreshRate}
testid="slowlog"
/>
</FlexItem>
<FlexItem grow>

<FlexItem>
<RiPopover
ownFocus
anchorPosition="downRight"
isOpen={isPopoverConfigOpen}
panelPaddingSize="m"
closePopover={() => {}}
panelClassName={cx('popover-without-top-tail', styles.configWrapper)}
button={
<SecondaryButton
size="small"
inverted
icon={SettingsIcon}
aria-label="Configure"
onClick={() => showConfigPopover()}
Expand All @@ -173,38 +132,29 @@ const Actions = (props: Props) => {
/>
</RiPopover>
</FlexItem>

{!isEmptySlowLog && (
<FlexItem grow>
<RiPopover
anchorPosition="leftCenter"
ownFocus
isOpen={isPopoverClearOpen}
closePopover={closePopoverClear}
panelPaddingSize="m"
button={
<RiTooltip
position="left"
content="Clear Slow Log"
anchorClassName={styles.icon}
>
<IconButton
icon={EraserIcon}
aria-label="Clear Slow Log"
onClick={() => showClearPopover()}
data-testid="clear-btn"
/>
</RiTooltip>
}
>
{ToolTipContent}
</RiPopover>
</FlexItem>
<>
<IconButton
icon={EraserIcon}
aria-label="Clear Slow Log"
onClick={() => showClearModal()}
data-testid="clear-btn"
/>

<ClearSlowLogModal
name={name}
isOpen={isClearModalOpen}
onClose={closeClearModal}
onClear={onClear}
/>
</>
)}
<FlexItem grow>

<FlexItem>
<RiTooltip
title="Slow Log"
position="bottom"
anchorClassName={styles.icon}
content={
<span data-testid="slowlog-tooltip-text">
Slow Log is a list of slow operations for your Redis instance.
Expand All @@ -218,12 +168,9 @@ const Actions = (props: Props) => {
</span>
}
>
<RiIcon
className={styles.infoIcon}
type="InfoIcon"
style={{ cursor: 'pointer' }}
data-testid="slow-log-tooltip-icon"
/>
<StyledInfoIconWrapper>
<RiIcon type="InfoIcon" data-testid="slow-log-tooltip-icon" />
</StyledInfoIconWrapper>
</RiTooltip>
</FlexItem>
</Row>
Expand Down
Loading
Loading