1
- import { EuiFieldText , EuiIcon , EuiSpacer , EuiText , EuiToolTip } from '@elastic/eui'
1
+ import { EuiFieldText , EuiIcon , EuiText , EuiToolTip } from '@elastic/eui'
2
2
import React , { useCallback , useEffect , useState } from 'react'
3
3
import { useDispatch , useSelector } from 'react-redux'
4
4
import PopoverItemEditor from 'uiSrc/components/popover-item-editor'
5
- import { selectedKeyDataSelector } from 'uiSrc/slices/browser/keys'
5
+ import { lastDeliveredIDTooltipText } from 'uiSrc/constants/texts'
6
+ import { selectedKeyDataSelector , updateSelectedKeyRefreshTime } from 'uiSrc/slices/browser/keys'
6
7
7
8
import {
8
9
streamGroupsSelector ,
@@ -13,12 +14,13 @@ import {
13
14
} from 'uiSrc/slices/browser/stream'
14
15
import { ITableColumn } from 'uiSrc/components/virtual-table/interfaces'
15
16
import PopoverDelete from 'uiSrc/pages/browser/components/popover-delete/PopoverDelete'
17
+ import { consumerGroupIdRegex } from 'uiSrc/utils'
16
18
import { getFormatTime } from 'uiSrc/utils/streamUtils'
17
19
import { KeyTypes , TableCellTextAlignment } from 'uiSrc/constants'
18
20
import { connectedInstanceSelector } from 'uiSrc/slices/instances/instances'
19
21
import { StreamViewType } from 'uiSrc/slices/interfaces/stream'
20
- import { updateSelectedKeyRefreshTime } from 'uiSrc/slices/browser/keys'
21
- import { ConsumerGroupDto } from 'apiSrc/modules/browser/dto/stream.dto'
22
+
23
+ import { ConsumerGroupDto , UpdateConsumerGroupDto } from 'apiSrc/modules/browser/dto/stream.dto'
22
24
23
25
import GroupsView from './GroupsView'
24
26
@@ -39,15 +41,18 @@ const GroupsViewWrapper = (props: Props) => {
39
41
const {
40
42
lastRefreshTime,
41
43
data : loadedGroups = [ ] ,
44
+ loading
42
45
} = useSelector ( streamGroupsSelector )
43
46
const { name : key = '' } = useSelector ( connectedInstanceSelector )
44
- const { name : selectedKey } = useSelector ( selectedKeyDataSelector )
47
+ const { name : selectedKey } = useSelector ( selectedKeyDataSelector ) ?? { }
45
48
46
49
const dispatch = useDispatch ( )
47
50
48
51
const [ groups , setGroups ] = useState < IConsumerGroup [ ] > ( [ ] )
49
52
const [ deleting , setDeleting ] = useState < string > ( '' )
50
53
const [ editValue , setEditValue ] = useState < string > ( '' )
54
+ const [ idError , setIdError ] = useState < string > ( '' )
55
+ const [ isIdFocused , setIsIdFocused ] = useState < boolean > ( false )
51
56
52
57
useEffect ( ( ) => {
53
58
dispatch ( updateSelectedKeyRefreshTime ( lastRefreshTime ) )
@@ -62,6 +67,14 @@ const GroupsViewWrapper = (props: Props) => {
62
67
setGroups ( streamItem )
63
68
} , [ loadedGroups , deleting ] )
64
69
70
+ useEffect ( ( ) => {
71
+ if ( ! consumerGroupIdRegex . test ( editValue ) ) {
72
+ setIdError ( 'ID format is not correct' )
73
+ return
74
+ }
75
+ setIdError ( '' )
76
+ } , [ editValue ] )
77
+
65
78
const closePopover = useCallback ( ( ) => {
66
79
setDeleting ( '' )
67
80
} , [ ] )
@@ -98,12 +111,14 @@ const GroupsViewWrapper = (props: Props) => {
98
111
}
99
112
100
113
const handleApplyEditId = ( groupName : string ) => {
101
- const data = {
102
- keyName : selectedKey ,
103
- name : groupName ,
104
- lastDeliveredId : editValue
114
+ if ( ! ! groupName . length && ! idError && selectedKey ) {
115
+ const data : UpdateConsumerGroupDto = {
116
+ keyName : selectedKey ,
117
+ name : groupName ,
118
+ lastDeliveredId : editValue
119
+ }
120
+ dispatch ( modifyLastDeliveredIdAction ( data ) )
105
121
}
106
- dispatch ( modifyLastDeliveredIdAction ( data ) )
107
122
}
108
123
109
124
const columns : ITableColumn [ ] = [
@@ -193,43 +208,44 @@ const GroupsViewWrapper = (props: Props) => {
193
208
maxWidth : actionsWidth ,
194
209
minWidth : actionsWidth ,
195
210
render : function Actions ( _act : any , { lastDeliveredId, name } : ConsumerGroupDto ) {
211
+ const showIdError = ! isIdFocused && idError
196
212
return (
197
213
< div >
198
214
< PopoverItemEditor
199
215
btnTestId = { `edit-stream-last-id-${ lastDeliveredId } ` }
200
216
onOpen = { ( ) => setEditValue ( lastDeliveredId ) }
201
217
onApply = { ( ) => handleApplyEditId ( name ) }
202
218
className = { styles . editLastId }
219
+ isDisabled = { ! editValue . length || ! ! idError }
220
+ isLoading = { loading }
203
221
>
204
- < EuiFieldText
205
- fullWidth
206
- name = "id"
207
- id = "id"
208
- placeholder = "ID*"
209
- value = { editValue }
210
- onChange = { ( e : any ) => setEditValue ( e . target . value ) }
211
- append = { (
212
- < EuiToolTip
213
- anchorClassName = "inputAppendIcon"
214
- className = { styles . entryIdTooltip }
215
- position = "left"
216
- title = "Enter Valid ID, 0 or $"
217
- content = { (
218
- < >
219
- Specify the ID of the last delivered entry in the stream from the new group's perspective.
220
- < EuiSpacer size = "xs" />
221
- Otherwise, < b > $</ b > represents the ID of the last entry in the stream,
222
- < b > 0</ b > fetches the entire stream from the beginning.
223
- </ >
224
- ) }
225
- >
226
- < EuiIcon type = "iInCircle" style = { { cursor : 'pointer' } } />
227
- </ EuiToolTip >
228
- ) }
229
- style = { { width : 240 } }
230
- autoComplete = "off"
231
- data-testid = "id-field"
232
- />
222
+ < >
223
+ < EuiFieldText
224
+ fullWidth
225
+ name = "id"
226
+ id = "id"
227
+ placeholder = "ID*"
228
+ value = { editValue }
229
+ onChange = { ( e : any ) => setEditValue ( e . target . value ) }
230
+ onBlur = { ( ) => setIsIdFocused ( false ) }
231
+ onFocus = { ( ) => setIsIdFocused ( true ) }
232
+ append = { (
233
+ < EuiToolTip
234
+ anchorClassName = "inputAppendIcon"
235
+ position = "left"
236
+ title = "Enter Valid ID, 0 or $"
237
+ content = { lastDeliveredIDTooltipText }
238
+ >
239
+ < EuiIcon type = "iInCircle" style = { { cursor : 'pointer' } } />
240
+ </ EuiToolTip >
241
+ ) }
242
+ style = { { width : 240 } }
243
+ autoComplete = "off"
244
+ data-testid = "last-id-field"
245
+ />
246
+ { ! showIdError && < span className = { styles . idText } data-testid = "id-help-text" > Timestamp - Sequence Number or $</ span > }
247
+ { showIdError && < span className = { styles . error } data-testid = "id-error" > { idError } </ span > }
248
+ </ >
233
249
</ PopoverItemEditor >
234
250
< PopoverDelete
235
251
text = { (
0 commit comments