@@ -9,7 +9,12 @@ import type {
9
9
10
10
import type { SchemaThunkAction } from './store' ;
11
11
import { isAction } from '../utils' ;
12
- import type { SchemaAccessor } from '../modules/schema-analysis' ;
12
+ import {
13
+ calculateSchemaDepth ,
14
+ schemaContainsGeoData ,
15
+ type SchemaAccessor ,
16
+ } from '../modules/schema-analysis' ;
17
+ import { openToast } from '@mongodb-js/compass-components' ;
13
18
14
19
export type SchemaFormat =
15
20
| 'standardJSON'
@@ -20,6 +25,8 @@ export type ExportStatus = 'inprogress' | 'complete' | 'error';
20
25
export type SchemaExportState = {
21
26
abortController ?: AbortController ;
22
27
isOpen : boolean ;
28
+ isLegacyBannerOpen : boolean ;
29
+ legacyBannerChoice ?: 'legacy' | 'export' ;
23
30
exportedSchema ?: string ;
24
31
exportFormat : SchemaFormat ;
25
32
errorMessage ?: string ;
@@ -34,11 +41,16 @@ const getInitialState = (): SchemaExportState => ({
34
41
exportStatus : 'inprogress' ,
35
42
exportedSchema : undefined ,
36
43
isOpen : false ,
44
+ isLegacyBannerOpen : false ,
45
+ legacyBannerChoice : undefined ,
37
46
} ) ;
38
47
39
48
export const enum SchemaExportActions {
40
49
openExportSchema = 'schema-service/schema-export/openExportSchema' ,
41
50
closeExportSchema = 'schema-service/schema-export/closeExportSchema' ,
51
+ openLegacyBanner = 'schema-service/schema-export/openLegacyBanner' ,
52
+ closeLegacyBanner = 'schema-service/schema-export/closeLegacyBanner' ,
53
+ setLegacyBannerChoice = 'schema-service/schema-export/setLegacyBannerChoice' ,
42
54
changeExportSchemaStatus = 'schema-service/schema-export/changeExportSchemaStatus' ,
43
55
changeExportSchemaFormatStarted = 'schema-service/schema-export/changeExportSchemaFormatStarted' ,
44
56
changeExportSchemaFormatComplete = 'schema-service/schema-export/changeExportSchemaFormatComplete' ,
@@ -263,6 +275,42 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (
263
275
} ;
264
276
}
265
277
278
+ if (
279
+ isAction < openLegacyBannerAction > (
280
+ action ,
281
+ SchemaExportActions . openLegacyBanner
282
+ )
283
+ ) {
284
+ return {
285
+ ...state ,
286
+ isLegacyBannerOpen : true ,
287
+ } ;
288
+ }
289
+
290
+ if (
291
+ isAction < closeLegacyBannerAction > (
292
+ action ,
293
+ SchemaExportActions . closeLegacyBanner
294
+ )
295
+ ) {
296
+ return {
297
+ ...state ,
298
+ isLegacyBannerOpen : false ,
299
+ } ;
300
+ }
301
+
302
+ if (
303
+ isAction < setLegacyBannerChoiceAction > (
304
+ action ,
305
+ SchemaExportActions . setLegacyBannerChoice
306
+ )
307
+ ) {
308
+ return {
309
+ ...state ,
310
+ legacyBannerChoice : action . choice ,
311
+ } ;
312
+ }
313
+
266
314
if (
267
315
isAction < ChangeExportSchemaFormatStartedAction > (
268
316
action ,
@@ -319,3 +367,110 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (
319
367
320
368
return state ;
321
369
} ;
370
+
371
+ // TODO clean out when phase out is confirmed COMPASS-8692
372
+ export type openLegacyBannerAction = {
373
+ type : SchemaExportActions . openLegacyBanner ;
374
+ } ;
375
+
376
+ export const openLegacyBanner = ( ) : SchemaThunkAction < void > => {
377
+ return ( dispatch , getState ) => {
378
+ const choiceInState = getState ( ) . schemaExport . legacyBannerChoice ;
379
+ const savedChoice = choiceInState || localStorage . getItem ( localStorageId ) ;
380
+ if ( savedChoice ) {
381
+ if ( savedChoice !== choiceInState ) {
382
+ dispatch ( {
383
+ type : SchemaExportActions . setLegacyBannerChoice ,
384
+ choice : savedChoice ,
385
+ } ) ;
386
+ }
387
+ if ( savedChoice === 'legacy' ) {
388
+ dispatch ( confirmedLegacySchemaShare ( ) ) ;
389
+ return ;
390
+ }
391
+ if ( savedChoice === 'export' ) {
392
+ dispatch ( openExportSchema ( ) ) ;
393
+ return ;
394
+ }
395
+ }
396
+ dispatch ( { type : SchemaExportActions . openLegacyBanner } ) ;
397
+ } ;
398
+ } ;
399
+
400
+ export type closeLegacyBannerAction = {
401
+ type : SchemaExportActions . closeLegacyBanner ;
402
+ } ;
403
+
404
+ export type setLegacyBannerChoiceAction = {
405
+ type : SchemaExportActions . setLegacyBannerChoice ;
406
+ choice : 'legacy' | 'export' ;
407
+ } ;
408
+
409
+ const localStorageId = 'schemaExportLegacyBannerChoice' ;
410
+
411
+ export const switchToSchemaExport = ( ) : SchemaThunkAction < void > => {
412
+ return ( dispatch ) => {
413
+ dispatch ( { type : SchemaExportActions . closeLegacyBanner } ) ;
414
+ dispatch ( openExportSchema ( ) ) ;
415
+ } ;
416
+ } ;
417
+
418
+ export const confirmedLegacySchemaShare = ( ) : SchemaThunkAction < void > => {
419
+ return ( dispatch , getState , { namespace } ) => {
420
+ const {
421
+ schemaAnalysis : { schema } ,
422
+ } = getState ( ) ;
423
+ const hasSchema = schema !== null ;
424
+ if ( hasSchema ) {
425
+ void navigator . clipboard . writeText ( JSON . stringify ( schema , null , ' ' ) ) ;
426
+ }
427
+ dispatch ( _trackSchemaShared ( hasSchema ) ) ;
428
+ dispatch ( { type : SchemaExportActions . closeLegacyBanner } ) ;
429
+ openToast (
430
+ 'share-schema' ,
431
+ hasSchema
432
+ ? {
433
+ variant : 'success' ,
434
+ title : 'Schema Copied' ,
435
+ description : `The schema definition of ${ namespace } has been copied to your clipboard in JSON format.` ,
436
+ timeout : 5_000 ,
437
+ }
438
+ : {
439
+ variant : 'warning' ,
440
+ title : 'Analyze Schema First' ,
441
+ description :
442
+ 'Please analyze the schema in the schema tab before sharing the schema.' ,
443
+ }
444
+ ) ;
445
+ } ;
446
+ } ;
447
+
448
+ export const _trackSchemaShared = (
449
+ hasSchema : boolean
450
+ ) : SchemaThunkAction < void > => {
451
+ return ( dispatch , getState , { track, connectionInfoRef } ) => {
452
+ const {
453
+ schemaAnalysis : { schema } ,
454
+ } = getState ( ) ;
455
+ // Use a function here to a) ensure that the calculations here
456
+ // are only made when telemetry is enabled and b) that errors from
457
+ // those calculations are caught and logged rather than displayed to
458
+ // users as errors from the core schema sharing logic.
459
+ const trackEvent = ( ) => ( {
460
+ has_schema : hasSchema ,
461
+ schema_width : schema ?. fields ?. length ?? 0 ,
462
+ schema_depth : schema ? calculateSchemaDepth ( schema ) : 0 ,
463
+ geo_data : schema ? schemaContainsGeoData ( schema ) : false ,
464
+ } ) ;
465
+ track ( 'Schema Exported' , trackEvent , connectionInfoRef . current ) ;
466
+ } ;
467
+ } ;
468
+
469
+ export const stopShowingLegacyBanner = (
470
+ choice : 'legacy' | 'export'
471
+ ) : SchemaThunkAction < void > => {
472
+ return ( dispatch ) => {
473
+ localStorage . setItem ( localStorageId , choice ) ;
474
+ dispatch ( { type : SchemaExportActions . setLegacyBannerChoice , choice } ) ;
475
+ } ;
476
+ } ;
0 commit comments