1
1
// SPDX-License-Identifier: MIT
2
2
// Copyright contributors to the kepler.gl project
3
3
4
- import { withTask } from 'react-palm/tasks' ;
4
+ import Task , { withTask } from 'react-palm/tasks' ;
5
5
import Console from 'global/console' ;
6
- import { getError , isPlainObject } from '@kepler.gl/utils' ;
6
+ import { getApplicationConfig , getError , isPlainObject } from '@kepler.gl/utils' ;
7
7
import { generateHashId , toArray } from '@kepler.gl/common-utils' ;
8
8
import {
9
9
EXPORT_FILE_TO_CLOUD_TASK ,
@@ -16,6 +16,7 @@ import {
16
16
exportFileError ,
17
17
postSaveLoadSuccess ,
18
18
loadCloudMapSuccess ,
19
+ loadCloudMapSuccess2 ,
19
20
loadCloudMapError ,
20
21
resetProviderStatus ,
21
22
removeNotification ,
@@ -30,10 +31,11 @@ import {
30
31
DATASET_FORMATS ,
31
32
OVERWRITE_MAP_ID
32
33
} from '@kepler.gl/constants' ;
33
- import { ExportFileToCloudPayload } from '@kepler.gl/types' ;
34
+ import { AddDataToMapPayload , ExportFileToCloudPayload } from '@kepler.gl/types' ;
34
35
35
36
import { FILE_CONFLICT_MSG , MapListItem } from '@kepler.gl/cloud-providers' ;
36
37
import { DATASET_HANDLERS } from '@kepler.gl/processors' ;
38
+ import { KeplerTable } from '@kepler.gl/table' ;
37
39
38
40
type ActionPayload < P > = {
39
41
type ?: string ;
@@ -263,6 +265,17 @@ function getDatasetHandler(format) {
263
265
return defaultHandler ;
264
266
}
265
267
268
+ // use custom processors from table class
269
+ const TableClass = getApplicationConfig ( ) . table ?? KeplerTable ;
270
+ if ( typeof TableClass . getFileProcessor === 'function' ) {
271
+ const processorResult = TableClass . getFileProcessor ( null , format ) ;
272
+ if ( ! processorResult . processor ) {
273
+ Console . warn ( `No processor found for format ${ format } , will use csv by default` ) ;
274
+ return defaultHandler ;
275
+ }
276
+ return processorResult . processor ;
277
+ }
278
+
266
279
if ( ! DATASET_HANDLERS [ format ] ) {
267
280
const supportedFormat = Object . keys ( DATASET_FORMATS )
268
281
. map ( k => `'${ k } '` )
@@ -276,19 +289,46 @@ function getDatasetHandler(format) {
276
289
return DATASET_HANDLERS [ format ] ;
277
290
}
278
291
279
- function parseLoadMapResponse ( response , loadParams , provider ) {
292
+ /**
293
+ * A task to handle async processorMethod
294
+ * @param param0
295
+ * @returns
296
+ */
297
+ async function parseLoadMapResponseTask ( {
298
+ response,
299
+ loadParams,
300
+ provider
301
+ } : {
302
+ response : ProviderActions . LoadCloudMapSuccessPayload [ 'response' ] ;
303
+ loadParams : ProviderActions . LoadCloudMapSuccessPayload [ 'loadParams' ] ;
304
+ provider : ProviderActions . LoadCloudMapSuccessPayload [ 'provider' ] ;
305
+ } ) {
280
306
const { map, format} = response ;
281
307
const processorMethod = getDatasetHandler ( format ) ;
282
308
283
- const parsedDatasets = toArray ( map . datasets ) . map ( ds => {
284
- if ( format === DATASET_FORMATS . keplergl ) {
285
- // no need to obtain id, directly pass them in
286
- return processorMethod ( ds ) ;
287
- }
288
- const info = ( ds && ds . info ) || { id : generateHashId ( 6 ) } ;
289
- const data = processorMethod ( ds . data || ds ) ;
290
- return { info, data} ;
291
- } ) ;
309
+ let parsedDatasets : AddDataToMapPayload [ 'datasets' ] = [ ] ;
310
+
311
+ if (
312
+ format === DATASET_FORMATS . keplergl &&
313
+ processorMethod !== DATASET_HANDLERS [ DATASET_FORMATS . keplergl ]
314
+ ) {
315
+ // plugin table provides processor for keplergl map, not single dataset with allData
316
+ const parsedMap = await processorMethod ( map ) ;
317
+ parsedDatasets = parsedMap . datasets ;
318
+ } else {
319
+ const datasets = toArray ( map . datasets ) ;
320
+ parsedDatasets = await Promise . all (
321
+ datasets . map ( async ds => {
322
+ if ( format === DATASET_FORMATS . keplergl ) {
323
+ // no need to obtain id, directly pass them in
324
+ return await processorMethod ( ds ) ;
325
+ }
326
+ const info = ( ds && ds . info ) || { id : generateHashId ( 6 ) } ;
327
+ const data = await processorMethod ( ds . data || ds ) ;
328
+ return { info, data} ;
329
+ } )
330
+ ) ;
331
+ }
292
332
293
333
const info = {
294
334
...map . info ,
@@ -302,11 +342,19 @@ function parseLoadMapResponse(response, loadParams, provider) {
302
342
} ;
303
343
}
304
344
345
+ const PARSE_LOAD_MAP_RESPONSE_TASK = Task . fromPromise (
346
+ parseLoadMapResponseTask ,
347
+ 'PARSE_LOAD_MAP_RESPONSE_TASK'
348
+ ) ;
349
+
350
+ /**
351
+ * Used to load resources stored in a private storage.
352
+ */
305
353
export const loadCloudMapSuccessUpdater = (
306
354
state : ProviderState ,
307
355
action : ActionPayload < ProviderActions . LoadCloudMapSuccessPayload >
308
356
) : ProviderState => {
309
- const { response, loadParams, provider, onSuccess , onError} = action . payload ;
357
+ const { response, loadParams, provider, onError} = action . payload ;
310
358
311
359
const formatError = checkLoadMapResponseError ( response ) ;
312
360
if ( formatError ) {
@@ -316,6 +364,30 @@ export const loadCloudMapSuccessUpdater = (
316
364
} ) ;
317
365
}
318
366
367
+ // processorMethod can be async so create a task
368
+ const parseLoadMapResponseTask = PARSE_LOAD_MAP_RESPONSE_TASK ( {
369
+ response,
370
+ loadParams,
371
+ provider
372
+ } ) . bimap (
373
+ ( datasetsPayload : AddDataToMapPayload ) => {
374
+ return loadCloudMapSuccess2 ( { ...action . payload , datasetsPayload} ) ;
375
+ } ,
376
+ error =>
377
+ exportFileErrorUpdater ( state , {
378
+ payload : { error, provider, onError}
379
+ } )
380
+ ) ;
381
+
382
+ return withTask ( state , parseLoadMapResponseTask ) ;
383
+ } ;
384
+
385
+ export const loadCloudMapSuccess2Updater = (
386
+ state : ProviderState ,
387
+ action : ActionPayload < ProviderActions . LoadCloudMapSuccess2Payload >
388
+ ) : ProviderState => {
389
+ const { datasetsPayload, response, loadParams, provider, onSuccess} = action . payload ;
390
+
319
391
const newState = {
320
392
...state ,
321
393
mapSaved : provider . name ,
@@ -324,10 +396,8 @@ export const loadCloudMapSuccessUpdater = (
324
396
isProviderLoading : false
325
397
} ;
326
398
327
- const payload = parseLoadMapResponse ( response , loadParams , provider ) ;
328
-
329
399
const tasks = [
330
- ACTION_TASK ( ) . map ( ( ) => addDataToMap ( payload ) ) ,
400
+ ACTION_TASK ( ) . map ( ( ) => addDataToMap ( datasetsPayload ) ) ,
331
401
createActionTask ( onSuccess , { response, loadParams, provider} ) ,
332
402
ACTION_TASK ( ) . map ( ( ) => postSaveLoadSuccess ( `Map from ${ provider . name } loaded` ) )
333
403
] . filter ( d => d ) ;
0 commit comments