@@ -24,15 +24,6 @@ import { ArrowCounterclockwise } from "react-bootstrap-icons";
24
24
import { Button , Modal , ModalBody , ModalFooter , ModalHeader } from "reactstrap" ;
25
25
26
26
import { RtkOrNotebooksError } from "../../../components/errors/RtkErrorAlert" ;
27
- import { usePostStoragesV2ByStorageIdSecretsMutation } from "../../projectsV2/api/projectV2.enhanced-api" ;
28
- import {
29
- CloudStorageGetV2Read ,
30
- CloudStoragePatch ,
31
- PostStoragesV2ApiArg ,
32
- RCloneConfig ,
33
- usePatchStoragesV2ByStorageIdMutation ,
34
- usePostStoragesV2Mutation ,
35
- } from "../../projectsV2/api/storagesV2.api" ;
36
27
37
28
import AddStorageBreadcrumbNavbar from "../../project/components/cloudStorage/AddStorageBreadcrumbNavbar" ;
38
29
import {
@@ -62,28 +53,63 @@ import {
62
53
} from "../../project/components/cloudStorage/cloudStorageModalComponents" ;
63
54
import {
64
55
findSensitive ,
65
- getCurrentStorageDetails ,
66
56
getSchemaProviders ,
67
57
hasProviderShortlist ,
68
58
} from "../../project/utils/projectCloudStorage.utils" ;
69
59
60
+ import {
61
+ usePatchDataConnectorsByDataConnectorIdMutation ,
62
+ usePostDataConnectorsMutation ,
63
+ usePostStoragesV2ByStorageIdSecretsMutation ,
64
+ } from "../../projectsV2/api/projectV2.enhanced-api" ;
65
+ import { CloudStoragePatch } from "../../projectsV2/api/storagesV2.api" ;
66
+ import type {
67
+ DataConnectorPatch ,
68
+ DataConnectorPost ,
69
+ DataConnectorRead ,
70
+ } from "../../projectsV2/api/data-connectors.api" ;
71
+
70
72
import styles from "../../project/components/cloudStorage/CloudStorage.module.scss" ;
71
73
72
74
import DataConnectorModalBody from "./DataConnectorModalBody" ;
73
75
76
+ function dataConnectorStorageDetails (
77
+ dataConnector : DataConnectorRead | null
78
+ ) : CloudStorageDetails {
79
+ if ( ! dataConnector ) {
80
+ return EMPTY_CLOUD_STORAGE_DETAILS ;
81
+ }
82
+ const configurationOptions = dataConnector . storage . configuration
83
+ ? dataConnector . storage . configuration
84
+ : { } ;
85
+ const { type, provider, ...options } = configurationOptions ; // eslint-disable-line @typescript-eslint/no-unused-vars
86
+ const storageDetails : CloudStorageDetails = {
87
+ storageId : dataConnector . id ,
88
+ schema : dataConnector . storage . configuration . type as string ,
89
+ name : dataConnector . name ,
90
+ mountPoint : dataConnector . storage . target_path ,
91
+ sourcePath : dataConnector . storage . source_path ,
92
+ readOnly : dataConnector . storage . readonly ,
93
+ provider : dataConnector . storage . configuration . provider
94
+ ? ( dataConnector . storage . configuration . provider as string )
95
+ : undefined ,
96
+ options,
97
+ } ;
98
+
99
+ return storageDetails ;
100
+ }
101
+
74
102
interface DataConnectorModalProps {
75
- currentStorage ?: CloudStorageGetV2Read | null ;
103
+ dataConnector ?: DataConnectorRead | null ;
76
104
isOpen : boolean ;
77
105
toggle : ( ) => void ;
78
- projectId : string ;
79
106
}
80
107
export default function DataConnectorModal ( {
81
- currentStorage = null ,
108
+ dataConnector = null ,
82
109
isOpen,
83
110
toggle : originalToggle ,
84
- projectId,
85
111
} : DataConnectorModalProps ) {
86
- const storageId = currentStorage ?. storage . storage_id ?? null ;
112
+ const dataConnectorId = dataConnector ?. id ?? null ;
87
113
// Fetch available schema when users open the modal
88
114
const {
89
115
data : schema ,
@@ -94,11 +120,9 @@ export default function DataConnectorModal({
94
120
// Reset state on props change
95
121
useEffect ( ( ) => {
96
122
const cloudStorageDetails : CloudStorageDetails =
97
- currentStorage != null
98
- ? getCurrentStorageDetails ( currentStorage )
99
- : EMPTY_CLOUD_STORAGE_DETAILS ;
123
+ dataConnectorStorageDetails ( dataConnector ) ;
100
124
const cloudStorageState : AddCloudStorageState =
101
- currentStorage != null
125
+ dataConnector != null
102
126
? {
103
127
...EMPTY_CLOUD_STORAGE_STATE ,
104
128
step : 2 ,
@@ -107,7 +131,7 @@ export default function DataConnectorModal({
107
131
: EMPTY_CLOUD_STORAGE_STATE ;
108
132
setStorageDetails ( cloudStorageDetails ) ;
109
133
setState ( cloudStorageState ) ;
110
- } , [ currentStorage ] ) ;
134
+ } , [ dataConnector ] ) ;
111
135
112
136
const [ success , setSuccess ] = useState ( false ) ;
113
137
const [ credentialSaveStatus , setCredentialSaveStatus ] =
@@ -167,19 +191,18 @@ export default function DataConnectorModal({
167
191
} , [ redraw ] ) ;
168
192
169
193
// Mutations
170
- const [ addCloudStorageForProjectV2 , addResultV2 ] =
171
- usePostStoragesV2Mutation ( ) ;
172
- const [ modifyCloudStorageV2ForProject , modifyResultV2 ] =
173
- usePatchStoragesV2ByStorageIdMutation ( ) ;
194
+ const [ createDataConnector , createResult ] = usePostDataConnectorsMutation ( ) ;
195
+ const [ updateDataConnector , updateResult ] =
196
+ usePatchDataConnectorsByDataConnectorIdMutation ( ) ;
174
197
const [ saveCredentials , saveCredentialsResult ] =
175
198
usePostStoragesV2ByStorageIdSecretsMutation ( ) ;
176
199
const [ validateCloudStorageConnection , validationResult ] =
177
200
useTestCloudStorageConnectionMutation ( ) ;
178
201
179
202
const reset = useCallback ( ( ) => {
180
- const resetStatus = getCurrentStorageDetails ( currentStorage ) ;
203
+ const resetStatus = dataConnectorStorageDetails ( dataConnector ) ;
181
204
setState ( ( prevState ) =>
182
- currentStorage != null
205
+ dataConnector != null
183
206
? {
184
207
...EMPTY_CLOUD_STORAGE_STATE ,
185
208
step : prevState . step ,
@@ -189,14 +212,14 @@ export default function DataConnectorModal({
189
212
...EMPTY_CLOUD_STORAGE_STATE ,
190
213
}
191
214
) ;
192
- addResultV2 . reset ( ) ;
215
+ createResult . reset ( ) ;
193
216
validationResult . reset ( ) ;
194
217
setStorageDetails ( resetStatus ) ;
195
218
setSuccess ( false ) ;
196
219
setCredentialSaveStatus ( "none" ) ;
197
220
setValidationSucceeded ( false ) ;
198
221
setRedraw ( true ) ; // This forces re-loading the useForm fields
199
- } , [ addResultV2 , currentStorage , validationResult ] ) ;
222
+ } , [ createResult , dataConnector , validationResult ] ) ;
200
223
201
224
const setStorageDetailsSafe = useCallback (
202
225
( newStorageDetails : Partial < CloudStorageDetails > ) => {
@@ -248,12 +271,13 @@ export default function DataConnectorModal({
248
271
} , [ storageDetails , validateCloudStorageConnection ] ) ;
249
272
250
273
const addOrEditStorage = useCallback ( ( ) => {
274
+ // TODO Convert this to a data-connector-native structure
251
275
const storageParameters :
252
276
| AddCloudStorageForProjectParams
253
277
| CloudStoragePatch = {
254
278
name : storageDetails . name as string ,
279
+ project_id : "" ,
255
280
readonly : storageDetails . readOnly ?? true ,
256
- project_id : `${ projectId } ` ,
257
281
source_path : storageDetails . sourcePath ?? "/" ,
258
282
target_path : storageDetails . mountPoint as string ,
259
283
configuration : { type : storageDetails . schema } ,
@@ -274,8 +298,8 @@ export default function DataConnectorModal({
274
298
const allOptions = storageDetails . options as CloudStorageDetailsOptions ;
275
299
const sensitiveFields = schema
276
300
? findSensitive ( schema . find ( ( s ) => s . prefix === storageDetails . schema ) )
277
- : currentStorage ?. sensitive_fields
278
- ? currentStorage . sensitive_fields . map ( ( field ) => field . name )
301
+ : dataConnector ?. storage ?. sensitive_fields
302
+ ? dataConnector . storage . sensitive_fields . map ( ( field ) => field . name )
279
303
: [ ] ;
280
304
const validOptions = Object . keys (
281
305
storageDetails . options
@@ -296,41 +320,52 @@ export default function DataConnectorModal({
296
320
}
297
321
298
322
// We manually set success only when we get an ID back. That's just to show a success message
299
- if ( storageId ) {
300
- const cloudStoragePatch : CloudStoragePatch = {
301
- project_id : projectId ,
323
+ if ( dataConnector && dataConnectorId ) {
324
+ const dataConnectorPatch : DataConnectorPatch = {
302
325
name : storageParameters . name ,
303
- configuration : storageParameters . configuration as RCloneConfig ,
304
- source_path : storageParameters . source_path ,
305
- target_path : storageParameters . target_path ,
306
- readonly : storageParameters . readonly ,
326
+ // TODO ad namespace, slug, visibility, description, keywords
327
+ storage : {
328
+ ...storageParameters . configuration ,
329
+ source_path : storageParameters . source_path ,
330
+ target_path : storageParameters . target_path ,
331
+ readonly : storageParameters . readonly ,
332
+ } ,
307
333
} ;
308
- modifyCloudStorageV2ForProject ( {
309
- storageId : storageId ,
310
- cloudStoragePatch,
334
+ updateDataConnector ( {
335
+ dataConnectorId,
336
+ dataConnectorPatch,
337
+ "If-Match" : dataConnector . etag ,
311
338
} ) . then ( ( result ) => {
312
- if ( "data" in result && result . data . storage . storage_id ) {
339
+ if ( "data" in result && result . data . id ) {
313
340
setSuccess ( true ) ;
314
341
}
315
342
} ) ;
316
343
} else {
317
- const parameterV2 = {
318
- body : storageParameters ,
319
- } as PostStoragesV2ApiArg ;
320
- addCloudStorageForProjectV2 ( parameterV2 ) . then ( ( result ) => {
321
- if ( "data" in result && result . data . storage . storage_id ) {
344
+ const dataConnectorPost = {
345
+ name : storageParameters . name ,
346
+ // TODO ad namespace, slug, visibility, description, keywords
347
+ storage : {
348
+ ...storageParameters . configuration ,
349
+ source_path : storageParameters . source_path ,
350
+ target_path : storageParameters . target_path ,
351
+ readonly : storageParameters . readonly ,
352
+ } ,
353
+ } as DataConnectorPost ;
354
+ createDataConnector ( {
355
+ dataConnectorPost,
356
+ } ) . then ( ( result ) => {
357
+ if ( "data" in result && result . data . id ) {
322
358
setSuccess ( true ) ;
323
359
}
324
360
} ) ;
325
361
}
326
362
} , [
327
- addCloudStorageForProjectV2 ,
328
- currentStorage ,
329
- modifyCloudStorageV2ForProject ,
330
- projectId ,
363
+ createDataConnector ,
364
+ dataConnector ,
365
+ dataConnectorId ,
366
+ updateDataConnector ,
331
367
schema ,
332
368
storageDetails ,
333
- storageId ,
334
369
] ) ;
335
370
336
371
const toggle = useCallback ( ( ) => {
@@ -341,10 +376,10 @@ export default function DataConnectorModal({
341
376
setSuccess ( false ) ;
342
377
reset ( ) ;
343
378
} else {
344
- addResultV2 . reset ( ) ;
379
+ createResult . reset ( ) ;
345
380
validationResult . reset ( ) ;
346
381
}
347
- } , [ addResultV2 , originalToggle , reset , success , validationResult ] ) ;
382
+ } , [ createResult , originalToggle , reset , success , validationResult ] ) ;
348
383
349
384
// Handle unmount
350
385
useEffect ( ( ) => {
@@ -361,8 +396,8 @@ export default function DataConnectorModal({
361
396
) ;
362
397
363
398
useEffect ( ( ) => {
364
- const storageId = addResultV2 . data ?. storage ?. storage_id ;
365
- if ( storageId == null ) return ;
399
+ const dataConnectorId = createResult . data ?. id ;
400
+ if ( dataConnectorId == null ) return ;
366
401
const shouldSaveCredentials = shouldSaveDataConnectorCredentials (
367
402
storageDetails . options ,
368
403
state . saveCredentials ,
@@ -387,11 +422,11 @@ export default function DataConnectorModal({
387
422
value : "" + secret . value ,
388
423
} ) ) ;
389
424
saveCredentials ( {
390
- storageId,
425
+ storageId : dataConnectorId ,
391
426
cloudStorageSecretPostList,
392
427
} ) ;
393
428
} , [
394
- addResultV2 . data ?. storage ?. storage_id ,
429
+ createResult . data ?. id ,
395
430
saveCredentials ,
396
431
state . saveCredentials ,
397
432
schema ,
@@ -406,7 +441,7 @@ export default function DataConnectorModal({
406
441
return ;
407
442
}
408
443
if (
409
- addResultV2 . data ?. storage ?. storage_id == null ||
444
+ createResult . data ?. id == null ||
410
445
saveCredentialsResult . isUninitialized
411
446
) {
412
447
setCredentialSaveStatus ( "none" ) ;
@@ -425,19 +460,19 @@ export default function DataConnectorModal({
425
460
return ;
426
461
}
427
462
setCredentialSaveStatus ( "none" ) ;
428
- } , [ addResultV2 , saveCredentialsResult , validationSucceeded ] ) ;
463
+ } , [ createResult , saveCredentialsResult , validationSucceeded ] ) ;
429
464
430
465
// Visual elements
431
466
const disableContinueButton =
432
467
state . step === 1 &&
433
468
( ! storageDetails . schema ||
434
469
( schemaRequiresProvider && ! storageDetails . provider ) ) ;
435
470
436
- const isAddResultLoading = addResultV2 . isLoading ;
437
- const isModifyResultLoading = modifyResultV2 . isLoading ;
438
- const addResultError = addResultV2 . error ;
439
- const modifyResultError = modifyResultV2 . error ;
440
- const addResultStorageName = addResultV2 ?. data ?. storage ?. name ;
471
+ const isAddResultLoading = createResult . isLoading ;
472
+ const isModifyResultLoading = updateResult . isLoading ;
473
+ const addResultError = createResult . error ;
474
+ const modifyResultError = updateResult . error ;
475
+ const addResultStorageName = createResult ?. data ?. name ;
441
476
442
477
const disableAddButton =
443
478
isAddResultLoading ||
@@ -448,7 +483,7 @@ export default function DataConnectorModal({
448
483
( hasProviderShortlist ( storageDetails . schema ) && ! storageDetails . provider ) ;
449
484
const addButtonDisableReason = isAddResultLoading
450
485
? "Please wait, the storage is being added"
451
- : modifyResultV2 . isLoading
486
+ : updateResult . isLoading
452
487
? "Please wait, the storage is being modified"
453
488
: ! storageDetails . name
454
489
? "Please provide a name"
@@ -460,8 +495,8 @@ export default function DataConnectorModal({
460
495
const isResultLoading = isAddResultLoading || isModifyResultLoading ;
461
496
462
497
const storageSecrets =
463
- currentStorage != null && "secrets" in currentStorage
464
- ? currentStorage . secrets ?? [ ]
498
+ dataConnector != null && "secrets" in dataConnector
499
+ ? dataConnector . secrets ?? [ ]
465
500
: [ ] ;
466
501
const hasStoredCredentialsInConfig = storageSecrets . length > 0 ;
467
502
@@ -472,15 +507,15 @@ export default function DataConnectorModal({
472
507
className = { styles . modal }
473
508
data-cy = "cloud-storage-edit-modal"
474
509
fullscreen = "lg"
475
- id = { currentStorage ?. storage . storage_id ?? "new-cloud-storage" }
510
+ id = { dataConnector ?. id ?? "new-cloud-storage" }
476
511
isOpen = { isOpen }
477
512
scrollable
478
513
size = "lg"
479
514
unmountOnClose = { false }
480
515
toggle = { toggle }
481
516
>
482
517
< ModalHeader toggle = { toggle } data-cy = "cloud-storage-edit-header" >
483
- < AddCloudStorageHeaderContent isV2 = { true } storageId = { storageId } />
518
+ < AddCloudStorageHeaderContent isV2 = { true } storageId = { dataConnectorId } />
484
519
</ ModalHeader >
485
520
486
521
< ModalBody data-cy = "cloud-storage-edit-body" >
@@ -497,7 +532,7 @@ export default function DataConnectorModal({
497
532
state = { state }
498
533
storageDetails = { storageDetails }
499
534
storageSecrets = { storageSecrets }
500
- storageId = { storageId }
535
+ storageId = { dataConnectorId }
501
536
success = { success }
502
537
validationSucceeded = { validationSucceeded }
503
538
/>
@@ -549,7 +584,7 @@ export default function DataConnectorModal({
549
584
setValidationSucceeded = { setValidationSucceeded }
550
585
state = { state }
551
586
storageDetails = { storageDetails }
552
- storageId = { storageId }
587
+ storageId = { dataConnectorId }
553
588
validateConnection = { validateConnection }
554
589
validationResult = { validationResult }
555
590
/>
0 commit comments