Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
9809b19
#RI-810 - initial implementation of add consumer groups
rsergeenko May 23, 2022
3ed7c48
#RI-2932 - Show Consumer groups
egor-zalenski May 23, 2022
6df7166
Merge branch 'feature/RI-2932_Consumer_Groups' into feature/RI-810_cr…
rsergeenko May 23, 2022
1d18c3b
#RI-810 - integration with consumer groups list
rsergeenko May 23, 2022
fd7468a
Merge remote-tracking branch 'origin/feature/RI-2834-streams_consumer…
egor-zalenski May 23, 2022
f65173f
Merge remote-tracking branch 'origin/feature/RI-2834-streams_consumer…
egor-zalenski May 25, 2022
a37501b
added fetched consumer groups list and consumers per group
egor-zalenski May 25, 2022
8c605c3
removed context
egor-zalenski May 25, 2022
fdfef1c
Added pending messages
egor-zalenski May 26, 2022
2c56f9f
rename folder
egor-zalenski May 26, 2022
a4f40c4
rename folder
egor-zalenski May 26, 2022
bab51ac
fix folder name
egor-zalenski May 26, 2022
94e012b
delete wrong folder
egor-zalenski May 26, 2022
d4d7bd3
fix errors
egor-zalenski May 26, 2022
eb85d65
Merge remote-tracking branch 'origin/feature/RI-2932_Consumer_Groups'…
egor-zalenski May 26, 2022
f990fac
#RI-2935 - base implementation of modify last entry id
rsergeenko May 27, 2022
e9f81c9
#RI-2932 - Show Consumer Groups
egor-zalenski May 27, 2022
b90941f
Merge branch 'feature/RI-2932_Consumer_Groups' into feature/RI-2936_m…
rsergeenko May 27, 2022
54893ed
Merge branch 'feature/RI-2932_Consumer_Groups' into feature/RI-2936_m…
rsergeenko May 27, 2022
d433022
Merge branch 'feature/RI-2932_Consumer_Groups' into feature/RI-810_cr…
rsergeenko May 27, 2022
5eeb382
#RI-2930 - add interfaces, fix loading state
rsergeenko May 27, 2022
8b542bc
#RI-2930 - add unit tests
rsergeenko May 27, 2022
ffe5194
Merge pull request #683 from RedisInsight/feature/RI-810_create_consu…
rsergeenko May 27, 2022
bcb2308
Merge branch 'feature/RI-2932_Consumer_Groups' into feature/RI-2936_m…
rsergeenko May 27, 2022
eafe31b
#RI-2932 - removed useless interfaces and mocked Data.now
egor-zalenski May 27, 2022
b6ff7db
Merge remote-tracking branch 'origin/feature/RI-2932_Consumer_Groups'…
egor-zalenski May 27, 2022
0960e72
#RI-2936 - integrations with list
rsergeenko May 27, 2022
aa08a73
Merge pull request #714 from RedisInsight/feature/RI-2936_modify_last-id
rsergeenko May 27, 2022
32071c0
#RI-2932 - fix pr comments
egor-zalenski May 27, 2022
90c5e92
Merge remote-tracking branch 'origin/feature/RI-2932_Consumer_Groups'…
egor-zalenski May 27, 2022
9b9c6ce
Merge branch 'main' into feature/RI-2932_Consumer_Groups
egor-zalenski May 27, 2022
37fcc1c
fix text remove entry
egor-zalenski May 27, 2022
b9fbd14
fix text remove entry
egor-zalenski May 27, 2022
83fe389
Merge remote-tracking branch 'origin/feature/RI-2932_Consumer_Groups'…
egor-zalenski May 27, 2022
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
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,6 @@
"opencollective-postinstall": "^2.0.3",
"react-hot-loader": "^4.13.0",
"react-refresh": "^0.9.0",
"react-test-renderer": "^17.0.1",
"redux-mock-store": "^1.5.4",
"regenerator-runtime": "^0.13.5",
"rimraf": "^3.0.2",
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,15 @@ import { ReactComponent as LogoIcon } from 'uiSrc/assets/img/logo.svg'
import { EuiLoadingLogo, EuiEmptyPrompt } from '@elastic/eui'

const PagePlaceholder = () => (
<EuiEmptyPrompt
icon={<EuiLoadingLogo logo={LogoIcon} size="xl" style={{ fontSize: '40px' }} />}
titleSize="s"
/>
<>
{ process.env.NODE_ENV !== 'development' && (
<EuiEmptyPrompt
icon={<EuiLoadingLogo logo={LogoIcon} size="xl" style={{ fontSize: '40px' }} />}
titleSize="s"
/>
)}
</>

)

export default PagePlaceholder
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
import React from 'react'
import { instance, mock } from 'ts-mockito'
import { render, screen, fireEvent } from 'uiSrc/utils/test-utils'
import PopoverItemEditor, { Props } from './PopoverItemEditor'

const mockedProps = mock<Props>()

describe('PopoverItemEditor', () => {
it('should render', () => {
expect(
render(
<PopoverItemEditor
{...instance(mockedProps)}
onDecline={jest.fn()}
>
<></>
</PopoverItemEditor>
)
).toBeTruthy()
})
})
Original file line number Diff line number Diff line change
@@ -0,0 +1,123 @@
import React, {
FormEvent,
useEffect,
useState,
} from 'react'

import {
EuiButton,
EuiButtonIcon, EuiFlexGroup, EuiFlexItem, EuiForm,
EuiPopover,
} from '@elastic/eui'
import styles from './styles.module.scss'

export interface Props {
children: React.ReactElement
className?: string
onOpen: () => void
onApply: () => void
onDecline?: () => void
isLoading?: boolean
isDisabled?: boolean
declineOnUnmount?: boolean
btnTestId?: string
btnIconType?: string
}

const PopoverItemEditor = (props: Props) => {
const {
onOpen,
onDecline,
onApply,
children,
isLoading,
declineOnUnmount = true,
isDisabled,
btnTestId,
btnIconType,
className
} = props
const [isPopoverOpen, setIsPopoverOpen] = useState<boolean>(false)

useEffect(() =>
// componentWillUnmount
() => {
declineOnUnmount && onDecline?.()
},
[])

const onFormSubmit = (e: FormEvent<HTMLFormElement>) => {
e.preventDefault()
handleApply()
}

const handleApply = (): void => {
setIsPopoverOpen(false)
onApply()
}

const handleDecline = () => {
setIsPopoverOpen(false)
onDecline?.()
}

const handleButtonClick = (e: React.MouseEvent<HTMLButtonElement, MouseEvent>) => {
e.stopPropagation()
onOpen?.()
setIsPopoverOpen(true)
}

const isDisabledApply = (): boolean => !!(isLoading || isDisabled)

const button = (
<EuiButtonIcon
iconType={btnIconType || 'pencil'}
aria-label="Edit field"
color="primary"
disabled={isLoading}
onClick={handleButtonClick}
data-testid={btnTestId || 'popover-edit-bnt'}
/>
)

return (
<EuiPopover
ownFocus
anchorPosition="downLeft"
isOpen={isPopoverOpen}
anchorClassName={className}
panelClassName={styles.popoverWrapper}
closePopover={handleDecline}
button={button}
data-testid="popover-item-editor"
onClick={(e) => e.stopPropagation()}
>
<EuiForm component="form" onSubmit={onFormSubmit}>
<div className={styles.content}>
{children}
</div>
<EuiFlexGroup className={styles.footer} responsive={false} justifyContent="flexEnd">
<EuiFlexItem grow={false}>
<EuiButton color="secondary" onClick={() => handleDecline()} data-testid="cancel-btn">
Cancel
</EuiButton>
</EuiFlexItem>

<EuiFlexItem grow={false}>
<EuiButton
fill
type="submit"
color="secondary"
isDisabled={isDisabledApply()}
data-testid="save-btn"
>
Save
</EuiButton>
</EuiFlexItem>
</EuiFlexGroup>
</EuiForm>
</EuiPopover>
)
}

export default PopoverItemEditor
3 changes: 3 additions & 0 deletions redisinsight/ui/src/components/popover-item-editor/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import PopoverItemEditor from './PopoverItemEditor'

export default PopoverItemEditor
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
.content {

}

.footer {
margin-top: 6px !important;
}
4 changes: 4 additions & 0 deletions redisinsight/ui/src/components/range-filter/RangeFilter.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ export interface Props {
min: number
start: number
end: number
disabled?: boolean
handleChangeStart: (value: number, shouldSentEventTelemetry: boolean) => void
handleChangeEnd: (value: number, shouldSentEventTelemetry: boolean) => void
handleUpdateRangeMax: (value: number) => void
Expand All @@ -33,6 +34,7 @@ const RangeFilter = (props: Props) => {
min,
start,
end,
disabled = false,
handleChangeStart,
handleChangeEnd,
handleUpdateRangeMax,
Expand Down Expand Up @@ -152,6 +154,7 @@ const RangeFilter = (props: Props) => {
max={max}
value={startVal}
ref={minValRef}
disabled={disabled}
onChange={onChangeStart}
onMouseUp={onMouseUpStart}
className={cx(styles.thumb, styles.thumbZindex3)}
Expand All @@ -163,6 +166,7 @@ const RangeFilter = (props: Props) => {
max={max}
value={endVal}
ref={maxValRef}
disabled={disabled}
onChange={onChangeEnd}
onMouseUp={onMouseUpEnd}
className={cx(styles.thumb, styles.thumbZindex4)}
Expand Down
3 changes: 3 additions & 0 deletions redisinsight/ui/src/components/range-filter/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
import RangeFilter from './RangeFilter'

export default RangeFilter
Original file line number Diff line number Diff line change
Expand Up @@ -151,12 +151,6 @@ $footerHeight: 38px;
white-space: pre-wrap;
}

:global(.key-details-table) {
:global(.ReactVirtualized__Table__row) {
font-size: 13px;
}
}

:global(.key-list-table) {
height: calc(100% - 58px);
}
Expand All @@ -176,6 +170,9 @@ $footerHeight: 38px;
}
}
}
:global(.ReactVirtualized__Table__row) {
font-size: 13px;
}
:global(.ReactVirtualized__Table__headerRow) {
border: 1px solid var(--tableLightestBorderColor) !important;
}
Expand Down
4 changes: 4 additions & 0 deletions redisinsight/ui/src/constants/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,10 @@ enum ApiEndpoints {
REJSON_ARRAPPEND = 'rejson-rl/arrappend',
STREAMS_ENTRIES = 'streams/entries',
STREAMS_ENTRIES_GET = 'streams/entries/get',
STREAMS_CONSUMER_GROUPS = 'streams/consumer-groups',
STREAMS_CONSUMER_GROUPS_GET = 'streams/consumer-groups/get',
STREAMS_CONSUMERS_GET = 'streams/consumer-groups/consumers/get',
STREAMS_CONSUMERS_MESSAGES_GET = 'streams/consumer-groups/consumers/pending-messages/get',
STREAMS = 'streams',
CLI = 'cli',
CLI_BLOCKING_COMMANDS = 'info/cli-blocking-commands',
Expand Down
27 changes: 22 additions & 5 deletions redisinsight/ui/src/constants/keys.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import { StreamViewType } from 'uiSrc/slices/interfaces/stream'
import { CommandGroup } from './commands'

export enum KeyTypes {
Expand Down Expand Up @@ -114,11 +115,27 @@ export const KEY_TYPES_ACTIONS: KeyTypesActions = Object.freeze({
name: 'Edit Value',
},
},
[KeyTypes.ReJSON]: {},
[KeyTypes.Stream]: {
addItems: {
name: 'New Entry',
},
[KeyTypes.ReJSON]: {}
})

export const STREAM_ADD_GROUP_VIEW_TYPES = [
StreamViewType.Groups,
StreamViewType.Consumers,
StreamViewType.Messages
]

export const STREAM_ADD_ACTION = Object.freeze({
[StreamViewType.Data]: {
name: 'New Entry'
},
[StreamViewType.Groups]: {
name: 'New Group'
},
[StreamViewType.Consumers]: {
name: 'New Group'
},
[StreamViewType.Messages]: {
name: 'New Group'
}
})

Expand Down
9 changes: 9 additions & 0 deletions redisinsight/ui/src/constants/texts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -25,3 +25,12 @@ export const ScanNoResultsFoundText = (
</EuiText>
</>
)

export const lastDeliveredIDTooltipText = (
<>
Specify the ID of the last delivered entry in the stream from the new group's perspective.
<EuiSpacer size="xs" />
Otherwise, <b>$</b> represents the ID of the last entry in the stream,&nbsp;
<b>0</b> fetches the entire stream from the beginning.
</>
)
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ export interface Props {
testid?: string
containerClassName?: string
turnOffAutoRefresh?: boolean
onRefresh: (enableAutoRefresh?: boolean) => void
onRefresh: (enableAutoRefresh: boolean) => void
onEnableAutoRefresh?: (enableAutoRefresh: boolean, refreshRate: string) => void
onChangeAutoRefreshRate?: (enableAutoRefresh: boolean, refreshRate: string) => void
}
Expand All @@ -49,7 +49,7 @@ const AutoRefresh = ({
onChangeAutoRefreshRate,
}: Props) => {
let intervalText: NodeJS.Timeout
let timeoutRefresh: NodeJS.Timeout
let intervalRefresh: NodeJS.Timeout

const [refreshMessage, setRefreshMessage] = useState(NOW)
const [isPopoverOpen, setIsPopoverOpen] = useState(false)
Expand All @@ -74,7 +74,7 @@ const AutoRefresh = ({
useEffect(() => {
if (turnOffAutoRefresh && enableAutoRefresh) {
setEnableAutoRefresh(false)
clearInterval(timeoutRefresh)
clearInterval(intervalRefresh)
}
}, [turnOffAutoRefresh])

Expand All @@ -96,20 +96,20 @@ const AutoRefresh = ({
updateLastRefresh()

if (enableAutoRefresh && !loading) {
timeoutRefresh = setInterval(() => {
intervalRefresh = setInterval(() => {
if (document.hidden) return

handleRefresh()
}, +refreshRate * 1_000)
} else {
clearInterval(timeoutRefresh)
clearInterval(intervalRefresh)
}

if (enableAutoRefresh) {
updateAutoRefreshText(refreshRate)
}

return () => clearInterval(timeoutRefresh)
return () => clearInterval(intervalRefresh)
}, [enableAutoRefresh, refreshRate, loading, lastRefreshTime])

const getLastRefreshDelta = (time:Nullable<number>) => (Date.now() - (time || 0)) / 1_000
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -159,7 +159,7 @@ const HashDetails = (props: Props) => {
})
}
setMatch(match)
dispatch(fetchHashFields(key, 0, SCAN_COUNT_DEFAULT, match || matchAllValue, onSuccess))
dispatch(fetchHashFields(key, 0, SCAN_COUNT_DEFAULT, match || matchAllValue, true, onSuccess))
}
}

Expand Down
Loading