@@ -2,36 +2,26 @@ import React from 'react';
2
2
import { useEffect } from 'react' ;
3
3
import { useSelector } from 'react-redux' ;
4
4
import {
5
- addFirstLevelTab ,
6
5
getSensorFolderTree ,
7
- toggleSensorFolderTree ,
8
- openRuleFolderTree ,
9
6
getRuleFolderTree ,
10
- toggleRuleFolderTree ,
11
7
toggleFirstLevelFolder ,
12
- openSensorFolderTree ,
13
- getdataQualityChecksFolderTree ,
14
- toggledataQualityChecksFolderTree ,
15
- opendataQualityChecksFolderTree
8
+ getdataQualityChecksFolderTree
16
9
} from '../../redux/actions/definition.actions' ;
17
10
import { useActionDispatch } from '../../hooks/useActionDispatch' ;
18
11
import { IRootState } from '../../redux/reducers' ;
19
12
import {
20
13
CheckDefinitionFolderModel ,
21
14
RuleFolderModel ,
22
- RuleListModel ,
23
- SensorFolderModel ,
24
- SensorListModel ,
25
- CheckDefinitionListModel
15
+ SensorFolderModel
26
16
} from '../../api' ;
27
17
import SvgIcon from '../SvgIcon' ;
28
18
import clsx from 'clsx' ;
29
- import { ROUTES } from '../../shared/routes' ;
30
19
import SensorContextMenu from './SensorContextMenu' ;
31
20
import RuleContextMenu from './RuleContextMenu' ;
32
21
import DataQualityContextMenu from './DataQualityContextMenu' ;
33
22
import { urlencodeEncoder } from '../../utils' ;
34
23
import { Tooltip } from '@material-tailwind/react' ;
24
+ import { useDefinition } from '../../contexts/definitionContext' ;
35
25
36
26
const defaultChecks = [
37
27
'Profiling checks' ,
@@ -56,6 +46,18 @@ export const DefinitionTree = () => {
56
46
refreshSensorsTreeIndicator
57
47
} = useSelector ( ( state : IRootState ) => state . definition ) ;
58
48
49
+ const {
50
+ openCheckDefaultFirstLevelTab,
51
+ openCheckFirstLevelTab,
52
+ openRuleFirstLevelTab,
53
+ openSensorFirstLevelTab,
54
+ toggleTree,
55
+ nodes,
56
+ toggleSensorFolder,
57
+ toggleRuleFolder,
58
+ toggleDataQualityChecksFolder
59
+ } = useDefinition ( ) ;
60
+
59
61
useEffect ( ( ) => {
60
62
dispatch ( getSensorFolderTree ( ) ) ;
61
63
} , [ refreshSensorsTreeIndicator ] ) ;
@@ -68,209 +70,13 @@ export const DefinitionTree = () => {
68
70
dispatch ( getdataQualityChecksFolderTree ( ) ) ;
69
71
} , [ refreshChecksTreeIndicator ] ) ;
70
72
71
- const toggleSensorFolder = ( key : string ) => {
72
- dispatch ( toggleSensorFolderTree ( key ) ) ;
73
- } ;
74
-
75
- const openSensorFolder = ( key : string ) => {
76
- dispatch ( openSensorFolderTree ( key ) ) ;
77
- } ;
78
-
79
- const toggleRuleFolder = ( key : string ) => {
80
- dispatch ( toggleRuleFolderTree ( key ) ) ;
81
- } ;
82
-
83
- const openRuleFolder = ( key : string ) => {
84
- dispatch ( openRuleFolderTree ( key ) ) ;
85
- } ;
86
-
87
- const toggleDataQualityChecksFolder = ( fullPath : string ) => {
88
- dispatch ( toggledataQualityChecksFolderTree ( fullPath ) ) ;
89
- } ;
90
- const openDataQualityChecksFolder = ( fullPath : string ) => {
91
- dispatch ( opendataQualityChecksFolderTree ( fullPath ) ) ;
92
- } ;
93
-
94
- const openSensorFirstLevelTab = ( sensor : SensorListModel ) => {
95
- dispatch (
96
- addFirstLevelTab ( {
97
- url : ROUTES . SENSOR_DETAIL ( urlencodeEncoder ( sensor . sensor_name ) ?? '' ) ,
98
- value : ROUTES . SENSOR_DETAIL_VALUE (
99
- urlencodeEncoder ( sensor . sensor_name ) ?? ''
100
- ) ,
101
- state : {
102
- full_sensor_name : urlencodeEncoder ( sensor . full_sensor_name )
103
- } ,
104
- label : urlencodeEncoder ( sensor . sensor_name )
105
- } )
106
- ) ;
107
- } ;
108
-
109
- const openRuleFirstLevelTab = ( rule : RuleListModel ) => {
110
- dispatch (
111
- addFirstLevelTab ( {
112
- url : ROUTES . RULE_DETAIL ( urlencodeEncoder ( rule . rule_name ) ?? '' ) ,
113
- value : ROUTES . RULE_DETAIL_VALUE ( urlencodeEncoder ( rule . rule_name ) ?? '' ) ,
114
- state : {
115
- full_rule_name : urlencodeEncoder ( rule . full_rule_name )
116
- } ,
117
- label : urlencodeEncoder ( rule . rule_name )
118
- } )
119
- ) ;
120
- } ;
121
-
122
- const openCheckFirstLevelTab = ( check : CheckDefinitionListModel ) => {
123
- dispatch (
124
- addFirstLevelTab ( {
125
- url : ROUTES . CHECK_DETAIL ( urlencodeEncoder ( check . check_name ) ?? '' ) ,
126
- value : ROUTES . CHECK_DETAIL_VALUE (
127
- urlencodeEncoder ( check . check_name ) ?? ''
128
- ) ,
129
- state : {
130
- full_check_name : urlencodeEncoder ( check . full_check_name ) ,
131
- custom : check . custom
132
- } ,
133
- label : urlencodeEncoder ( check . check_name )
134
- } )
135
- ) ;
136
- } ;
137
-
138
- const openCheckDefaultFirstLevelTab = ( defaultCheck : string ) => {
139
- dispatch (
140
- addFirstLevelTab ( {
141
- url : ROUTES . CHECK_DEFAULT_DETAIL ( defaultCheck . replace ( / \s / g, '_' ) ) ,
142
- value : ROUTES . CHECK_DEFAULT_DETAIL_VALUE (
143
- defaultCheck . replace ( / \s / g, '_' )
144
- ) ,
145
- state : {
146
- type : defaultCheck
147
- } ,
148
- label : defaultCheck
149
- } )
150
- ) ;
151
- } ;
152
-
153
- const openAllUsersFirstLevelTab = ( ) => {
154
- dispatch (
155
- addFirstLevelTab ( {
156
- url : ROUTES . USERS_LIST_DETAIL ( ) ,
157
- value : ROUTES . USERS_LIST_DETAIL_VALUE ( ) ,
158
- label : 'All users'
159
- } )
160
- ) ;
161
- } ;
162
-
163
- const openDefaultSchedulesFirstLevelTab = ( ) => {
164
- dispatch (
165
- addFirstLevelTab ( {
166
- url : ROUTES . SCHEDULES_DEFAULT_DETAIL ( ) ,
167
- value : ROUTES . SCHEDULES_DEFAULT_DETAIL_VALUE ( ) ,
168
- label : 'Default schedules'
169
- } )
170
- ) ;
171
- } ;
172
-
173
- const openDefaultWebhooksFirstLevelTab = ( ) => {
174
- dispatch (
175
- addFirstLevelTab ( {
176
- url : ROUTES . WEBHOOKS_DEFAULT_DETAIL ( ) ,
177
- value : ROUTES . WEBHOOKS_DEFAULT_DETAIL_VALUE ( ) ,
178
- label : 'Default webhooks'
179
- } )
180
- ) ;
181
- } ;
182
-
183
- const openSharedCredentialsFirstLevelTab = ( ) => {
184
- dispatch (
185
- addFirstLevelTab ( {
186
- url : ROUTES . SHARED_CREDENTIALS_LIST_DETAIL ( ) ,
187
- value : ROUTES . SHARED_CREDENTIALS_LIST_DETAIL_VALUE ( ) ,
188
- label : 'Shared credentials'
189
- } )
190
- ) ;
191
- } ;
192
-
193
- const openDataDictionaryFirstLevelTab = ( ) => {
194
- dispatch (
195
- addFirstLevelTab ( {
196
- url : ROUTES . DATA_DICTIONARY_LIST_DETAIL ( ) ,
197
- value : ROUTES . DATA_DICTIONARY_LIST_VALUE ( ) ,
198
- label : 'Data dictionaries'
199
- } )
200
- ) ;
201
- } ;
202
-
203
- const toggleFolderRecursively = (
204
- elements : string [ ] ,
205
- index = 0 ,
206
- type : string
207
- ) => {
208
- if ( index >= elements . length - 1 ) {
209
- return ;
210
- }
211
- const path = elements . slice ( 0 , index + 1 ) . join ( '/' ) ;
212
- if ( index === 0 ) {
213
- if ( type === 'checks' ) {
214
- openDataQualityChecksFolder ( 'undefined/' + path ) ;
215
- } else if ( type === 'rules' ) {
216
- openRuleFolder ( 'undefined/' + path ) ;
217
- } else {
218
- openSensorFolder ( 'undefined/' + path ) ;
219
- }
220
- } else {
221
- if ( type === 'checks' ) {
222
- openDataQualityChecksFolder ( path ) ;
223
- } else if ( type === 'rules' ) {
224
- openRuleFolder ( path ) ;
225
- } else {
226
- openSensorFolder ( path ) ;
227
- }
228
- }
229
- toggleFolderRecursively ( elements , index + 1 , type ) ;
230
- } ;
231
-
232
73
useEffect ( ( ) => {
233
- const configuration = [
234
- { category : 'Sensors' , isOpen : false } ,
235
- { category : 'Rules' , isOpen : false } ,
236
- { category : 'Data quality checks' , isOpen : false } ,
237
- { category : 'Default checks configuration' , isOpen : false }
238
- ] ;
239
- if ( tabs && tabs . length !== 0 ) {
240
- for ( let i = 0 ; i < tabs . length ; i ++ ) {
241
- if ( tabs [ i ] . url ?. includes ( 'default_checks' ) ) {
242
- configuration [ 3 ] . isOpen = true ;
243
- } else if ( tabs [ i ] ?. url ?. includes ( 'sensors' ) ) {
244
- configuration [ 0 ] . isOpen = true ;
245
- const arrayOfElemsToToggle = (
246
- tabs [ i ] . state . full_sensor_name as string
247
- ) ?. split ( '/' ) ;
248
- if ( arrayOfElemsToToggle ) {
249
- toggleFolderRecursively ( arrayOfElemsToToggle , 0 , 'sensors' ) ;
250
- }
251
- } else if ( tabs [ i ] ?. url ?. includes ( 'checks' ) ) {
252
- configuration [ 2 ] . isOpen = true ;
253
- const arrayOfElemsToToggle = (
254
- tabs [ i ] . state . fullCheckName as string
255
- ) ?. split ( '/' ) ;
256
- if ( arrayOfElemsToToggle ) {
257
- toggleFolderRecursively ( arrayOfElemsToToggle , 0 , 'checks' ) ;
258
- }
259
- } else if ( tabs [ i ] ?. url ?. includes ( 'rules' ) ) {
260
- configuration [ 1 ] . isOpen = true ;
261
- const arrayOfElemsToToggle = (
262
- tabs [ i ] . state . full_rule_name as string
263
- ) ?. split ( '/' ) ;
264
- if ( arrayOfElemsToToggle ) {
265
- toggleFolderRecursively ( arrayOfElemsToToggle , 0 , 'rules' ) ;
266
- }
267
- }
268
- dispatch ( toggleFirstLevelFolder ( configuration ) ) ;
269
- }
270
- } else {
271
- dispatch ( toggleFirstLevelFolder ( configuration ) ) ;
272
- }
273
- } , [ ] ) ;
74
+ toggleTree ( tabs ) ;
75
+ } , [ activeTab ] ) ;
76
+
77
+ const highlightedNode = activeTab
78
+ ?. split ( '/' )
79
+ . at ( activeTab ?. split ( '/' ) . length - 1 ) ;
274
80
275
81
const renderSensorFolderTree = (
276
82
folder ?: SensorFolderModel ,
@@ -599,15 +405,36 @@ export const DefinitionTree = () => {
599
405
) ;
600
406
} ;
601
407
408
+ const NodeComponent = ( {
409
+ onClick,
410
+ icon,
411
+ text
412
+ } : {
413
+ onClick : ( ) => void ;
414
+ icon : string ;
415
+ text : string ;
416
+ } ) => (
417
+ < div
418
+ onClick = { onClick }
419
+ className = { clsx (
420
+ 'cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300' ,
421
+ highlightedNode === text . toLowerCase ( ) . replace ( ' ' , '-' ) &&
422
+ 'bg-gray-300'
423
+ ) }
424
+ >
425
+ < SvgIcon name = { icon } className = "w-4 h-4 min-w-4 " />
426
+ < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
427
+ { text }
428
+ </ div >
429
+ </ div >
430
+ ) ;
431
+
602
432
return (
603
- < div className = "fixed left-0 top-16 bottom-0 overflow-y-auto w-80 shadow border-r border-gray-300 p-4 pt-4 bg-white" >
433
+ < div className = "overflow-hidden w-80 p-4 pt-4 bg-white" >
604
434
{ definitionFirstLevelFolder ?. map ( ( x , index ) => (
605
- < div
606
- key = { index }
607
- className = "mt-2 mb-2 text-sm font-regular cursor-pointer"
608
- >
435
+ < div key = { index } className = "text-[13px] cursor-pointer" >
609
436
< div
610
- className = "flex items-center mb-2 "
437
+ className = "flex items-center mb-1 gap-x-1 "
611
438
onClick = { ( ) => {
612
439
const updatedRootTree = [ ...definitionFirstLevelFolder ] ;
613
440
updatedRootTree [ index ] . isOpen = ! updatedRootTree [ index ] . isOpen ;
@@ -670,51 +497,9 @@ export const DefinitionTree = () => {
670
497
) }
671
498
</ div >
672
499
) ) }
673
- < div
674
- onClick = { openAllUsersFirstLevelTab }
675
- className = "cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300"
676
- >
677
- < SvgIcon name = "userprofile" className = "w-4 h-4 min-w-4 " />
678
- < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
679
- Manage users
680
- </ div >
681
- </ div >
682
- < div
683
- onClick = { openDefaultSchedulesFirstLevelTab }
684
- className = "cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300"
685
- >
686
- < SvgIcon name = "clock" className = "w-4 h-4 min-w-4 " />
687
- < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
688
- Default schedules
689
- </ div >
690
- </ div >
691
- < div
692
- onClick = { openDefaultWebhooksFirstLevelTab }
693
- className = "cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300"
694
- >
695
- < SvgIcon name = "webhooks" className = "w-4 h-4 min-w-4 " />
696
- < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
697
- Default webhooks
698
- </ div >
699
- </ div >
700
- < div
701
- onClick = { openSharedCredentialsFirstLevelTab }
702
- className = "cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300"
703
- >
704
- < SvgIcon name = "definitionsrules" className = "w-4 h-4 min-w-4 " />
705
- < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
706
- Shared credentials
707
- </ div >
708
- </ div >
709
- < div
710
- onClick = { openDataDictionaryFirstLevelTab }
711
- className = "cursor-pointer flex space-x-1 items-center mb-1 h-5 hover:bg-gray-300"
712
- >
713
- < SvgIcon name = "datadictionary" className = "w-4 h-4 min-w-4 " />
714
- < div className = "text-[14.5px] leading-1.5 whitespace-nowrap flex items-center justify-between" >
715
- Data dictionaries
716
- </ div >
717
- </ div >
500
+ { ( nodes as any [ ] ) . map ( ( tab , index ) => (
501
+ < NodeComponent key = { index } { ...tab } />
502
+ ) ) }
718
503
</ div >
719
504
) ;
720
505
} ;
0 commit comments