@@ -17,29 +17,32 @@ import {
17
17
SvgIcon ,
18
18
Tooltip ,
19
19
Typography ,
20
+ MenuItem ,
21
+ Select ,
22
+ Alert ,
20
23
} from "@mui/material" ;
21
24
import { MagnifyingGlassIcon , PencilIcon , TrashIcon } from "@heroicons/react/24/outline" ;
22
25
import { Add , AddCircle , RemoveCircle , Sync , WarningAmber } from "@mui/icons-material" ;
23
26
import CippFormComponent from "../../../components/CippComponents/CippFormComponent" ;
24
27
import { useForm , useWatch } from "react-hook-form" ;
25
28
import { CippApiDialog } from "../../../components/CippComponents/CippApiDialog" ;
26
29
import { Grid } from "@mui/system" ;
30
+ import CippButtonCard from "../../../components/CippCards/CippButtonCard" ;
27
31
28
32
const CustomAddEditRowDialog = ( { formControl, open, onClose, onSubmit, defaultValues } ) => {
29
33
const fields = useWatch ( { control : formControl . control , name : "fields" } ) ;
30
34
31
35
useEffect ( ( ) => {
32
36
if ( open ) {
33
- console . log ( defaultValues ) ;
34
37
formControl . reset ( {
35
38
fields : defaultValues . fields || [ ] ,
36
39
} ) ;
37
40
}
38
- } , [ open , defaultValues ] ) ;
41
+ } , [ open , defaultValues , formControl ] ) ;
39
42
40
43
const addField = ( ) => {
41
44
formControl . reset ( {
42
- fields : [ ...fields , { name : "" , value : "" } ] ,
45
+ fields : [ ...fields , { name : "" , value : "" , type : "textField" } ] ,
43
46
} ) ;
44
47
} ;
45
48
@@ -48,6 +51,11 @@ const CustomAddEditRowDialog = ({ formControl, open, onClose, onSubmit, defaultV
48
51
formControl . reset ( { fields : newFields } ) ;
49
52
} ;
50
53
54
+ const handleTypeChange = ( index , newType ) => {
55
+ const newFields = fields . map ( ( field , i ) => ( i === index ? { ...field , type : newType } : field ) ) ;
56
+ formControl . reset ( { fields : newFields } ) ;
57
+ } ;
58
+
51
59
return (
52
60
< Dialog fullWidth maxWidth = "lg" open = { open } onClose = { onClose } width = "xl" >
53
61
< DialogTitle > Add/Edit Row</ DialogTitle >
@@ -65,14 +73,36 @@ const CustomAddEditRowDialog = ({ formControl, open, onClose, onSubmit, defaultV
65
73
label = "Name"
66
74
/>
67
75
</ Box >
68
- < Box width = "80%" >
76
+ < Box width = "10%" >
77
+ < Select
78
+ value = { field . type }
79
+ onChange = { ( e ) => handleTypeChange ( index , e . target . value ) }
80
+ fullWidth
81
+ sx = { { py : 1 } }
82
+ >
83
+ < MenuItem value = "textField" > Text</ MenuItem >
84
+ < MenuItem value = "number" > Number</ MenuItem >
85
+ < MenuItem value = "switch" > Boolean</ MenuItem >
86
+ </ Select >
87
+ </ Box >
88
+ < Box width = "50%" >
69
89
< CippFormComponent
70
- type = "textField"
90
+ type = { field . type }
71
91
name = { `fields[${ index } ].value` }
72
92
formControl = { formControl }
73
93
label = "Value"
94
+ sx = { ( ) => {
95
+ if ( field . type === "switch" ) {
96
+ return { ml : 2 } ;
97
+ } else if ( field . type === "number" ) {
98
+ return { width : "100%" } ;
99
+ } else {
100
+ return { } ;
101
+ }
102
+ } }
74
103
/>
75
104
</ Box >
105
+
76
106
< IconButton onClick = { ( ) => removeField ( index ) } >
77
107
< RemoveCircle />
78
108
</ IconButton >
@@ -86,8 +116,12 @@ const CustomAddEditRowDialog = ({ formControl, open, onClose, onSubmit, defaultV
86
116
</ Stack >
87
117
</ DialogContent >
88
118
< DialogActions >
89
- < Button onClick = { onClose } > Cancel</ Button >
90
- < Button onClick = { formControl . handleSubmit ( onSubmit ) } > Save</ Button >
119
+ < Button variant = "outlined" onClick = { onClose } >
120
+ Cancel
121
+ </ Button >
122
+ < Button variant = "contained" onClick = { formControl . handleSubmit ( onSubmit ) } >
123
+ Save
124
+ </ Button >
91
125
</ DialogActions >
92
126
</ Dialog >
93
127
) ;
@@ -103,14 +137,23 @@ const Page = () => {
103
137
const deleteTableDialog = useDialog ( ) ; // Add dialog for deleting table
104
138
const addEditRowDialog = useDialog ( ) ; // Add dialog for adding/editing row
105
139
const [ defaultAddEditValues , setDefaultAddEditValues ] = useState ( { } ) ;
140
+ const [ tableFilterParams , setTableFilterParams ] = useState ( { First : 1000 } ) ;
106
141
const formControl = useForm ( {
107
142
mode : "onChange" ,
108
143
} ) ;
144
+ const [ accordionExpanded , setAccordionExpanded ] = useState ( false ) ;
109
145
110
146
const addEditFormControl = useForm ( {
111
147
mode : "onChange" ,
112
148
} ) ;
113
149
150
+ const filterFormControl = useForm ( {
151
+ mode : "onChange" ,
152
+ defaultValues : {
153
+ First : 1000 ,
154
+ } ,
155
+ } ) ;
156
+
114
157
const tableFilter = useWatch ( { control : formControl . control , name : "tableFilter" } ) ;
115
158
116
159
const fetchTables = ApiPostCall ( {
@@ -132,7 +175,7 @@ const Page = () => {
132
175
data : {
133
176
FunctionName : "Get-AzDataTableEntity" ,
134
177
TableName : tableName ,
135
- Parameters : { First : 1000 } ,
178
+ Parameters : filterFormControl . getValues ( ) ,
136
179
} ,
137
180
} ) ;
138
181
} ;
@@ -144,7 +187,7 @@ const Page = () => {
144
187
data : {
145
188
FunctionName : "Get-AzDataTableEntity" ,
146
189
TableName : selectedTable ,
147
- Parameters : { First : 1000 } ,
190
+ Parameters : tableFilterParams ,
148
191
} ,
149
192
} ) ;
150
193
}
@@ -159,6 +202,20 @@ const Page = () => {
159
202
fetchTables . mutate ( { url : apiUrl , data : { FunctionName : "Get-AzDataTable" , Parameters : { } } } ) ;
160
203
} ;
161
204
205
+ const getSelectedProps = ( data ) => {
206
+ if ( data ?. Property && data ?. Property . length > 0 ) {
207
+ var selectedProps = [ "ETag" , "PartitionKey" , "RowKey" ] ;
208
+ data ?. Property . map ( ( prop ) => {
209
+ if ( selectedProps . indexOf ( prop . value ) === - 1 ) {
210
+ selectedProps . push ( prop . value ) ;
211
+ }
212
+ } ) ;
213
+ return selectedProps ;
214
+ } else {
215
+ return [ ] ;
216
+ }
217
+ } ;
218
+
162
219
useEffect ( ( ) => {
163
220
handleTableRefresh ( ) ;
164
221
} , [ ] ) ;
@@ -183,16 +240,11 @@ const Page = () => {
183
240
{
184
241
label : "" ,
185
242
value : (
186
- < Stack direction = "row" spacing = { 1 } alignItems = "center" >
243
+ < Stack direction = "row" spacing = { 1 } alignItems = "center" sx = { { my : 1 } } >
187
244
< SvgIcon fontSize = "small" >
188
245
< MagnifyingGlassIcon />
189
246
</ SvgIcon >
190
- < CippFormComponent
191
- type = "textField"
192
- name = "tableFilter"
193
- formControl = { formControl }
194
- label = "Filter"
195
- />
247
+ < CippFormComponent type = "textField" name = "tableFilter" formControl = { formControl } />
196
248
</ Stack >
197
249
) ,
198
250
} ,
@@ -203,19 +255,32 @@ const Page = () => {
203
255
const sampleRow = tableData [ 0 ] ;
204
256
return Object . keys ( sampleRow )
205
257
. filter ( ( key ) => key !== "ETag" && key !== "Timestamp" )
206
- . map ( ( key ) => ( {
207
- name : key ,
208
- label : key ,
209
- type : "textField" ,
210
- required : false ,
211
- } ) ) ;
258
+ . map ( ( key ) => {
259
+ const value = sampleRow [ key ] ;
260
+ let type = "textField" ;
261
+ if ( typeof value === "number" ) {
262
+ type = "number" ;
263
+ } else if ( typeof value === "boolean" ) {
264
+ type = "switch" ;
265
+ }
266
+ return {
267
+ name : key ,
268
+ label : key ,
269
+ type : type ,
270
+ required : false ,
271
+ } ;
272
+ } ) ;
212
273
} ;
213
274
214
275
return (
215
276
< Container maxWidth = "xl" sx = { { mt : 4 } } >
216
277
< Typography variant = "h4" gutterBottom >
217
278
{ pageTitle }
218
279
</ Typography >
280
+ < Alert severity = "warning" sx = { { mb : 2 } } >
281
+ This page allows you to view and manage data in Azure Tables. This is advanced functionality
282
+ that should only be used when directed by CyberDrain support.
283
+ </ Alert >
219
284
< Grid container spacing = { 2 } >
220
285
< Grid item size = { 3 } >
221
286
< CippPropertyListCard
@@ -257,6 +322,60 @@ const Page = () => {
257
322
< Grid item size = { 9 } >
258
323
{ selectedTable && (
259
324
< Box sx = { { width : "100%" } } >
325
+ < CippButtonCard
326
+ title = "Table Filters"
327
+ cardSx = { { mb : 2 } }
328
+ accordionExpanded = { accordionExpanded }
329
+ component = "accordion"
330
+ CardButton = {
331
+ < Button
332
+ variant = "contained"
333
+ color = "primary"
334
+ size = "small"
335
+ onClick = { filterFormControl . handleSubmit ( ( data ) => {
336
+ var properties = getSelectedProps ( data ) ;
337
+ setTableFilterParams ( { ...data , Property : properties } ) ;
338
+ handleRefresh ( ) ;
339
+ setAccordionExpanded ( false ) ;
340
+ } ) }
341
+ >
342
+ Apply Filters
343
+ </ Button >
344
+ }
345
+ >
346
+ < Stack spacing = { 1 } >
347
+ < CippFormComponent
348
+ type = "textField"
349
+ name = "Filter"
350
+ formControl = { filterFormControl }
351
+ label = "OData Filter"
352
+ />
353
+ < CippFormComponent
354
+ type = "autoComplete"
355
+ name = "Property"
356
+ formControl = { filterFormControl }
357
+ label = "Property"
358
+ options = { getTableFields ( ) . map ( ( field ) => ( {
359
+ label : field ?. label ,
360
+ value : field ?. name ,
361
+ } ) ) }
362
+ />
363
+ < Stack direction = "row" spacing = { 1 } >
364
+ < CippFormComponent
365
+ type = "number"
366
+ name = "First"
367
+ formControl = { filterFormControl }
368
+ label = "First"
369
+ />
370
+ < CippFormComponent
371
+ type = "number"
372
+ name = "Skip"
373
+ formControl = { filterFormControl }
374
+ label = "Skip"
375
+ />
376
+ </ Stack >
377
+ </ Stack >
378
+ </ CippButtonCard >
260
379
< CippDataTable
261
380
title = { `${ selectedTable } ` }
262
381
data = { tableData }
@@ -273,6 +392,7 @@ const Page = () => {
273
392
fields : getTableFields ( ) . map ( ( field ) => ( {
274
393
name : field ?. name ,
275
394
value : "" ,
395
+ type : field ?. type ,
276
396
} ) ) ,
277
397
} ) ;
278
398
addEditRowDialog . handleOpen ( ) ;
@@ -313,7 +433,16 @@ const Page = () => {
313
433
setDefaultAddEditValues ( {
314
434
fields : Object . keys ( row )
315
435
. filter ( ( key ) => key !== "ETag" && key !== "Timestamp" )
316
- . map ( ( key ) => ( { name : key , value : row [ key ] } ) ) ,
436
+ . map ( ( key ) => {
437
+ const value = row [ key ] ;
438
+ let type = "textField" ;
439
+ if ( typeof value === "number" ) {
440
+ type = "number" ;
441
+ } else if ( typeof value === "boolean" ) {
442
+ type = "switch" ;
443
+ }
444
+ return { name : key , value : value , type : type } ;
445
+ } ) ,
317
446
} ) ;
318
447
addEditRowDialog . handleOpen ( ) ;
319
448
} ,
0 commit comments