@@ -9,7 +9,12 @@ import type {
99
1010import type { SchemaThunkAction } from './store' ;
1111import { 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' ;
1318
1419export type SchemaFormat =
1520 | 'standardJSON'
@@ -20,6 +25,8 @@ export type ExportStatus = 'inprogress' | 'complete' | 'error';
2025export type SchemaExportState = {
2126 abortController ?: AbortController ;
2227 isOpen : boolean ;
28+ isLegacyBannerOpen : boolean ;
29+ legacyBannerChoice ?: 'legacy' | 'export' ;
2330 exportedSchema ?: string ;
2431 exportFormat : SchemaFormat ;
2532 errorMessage ?: string ;
@@ -34,11 +41,16 @@ const getInitialState = (): SchemaExportState => ({
3441 exportStatus : 'inprogress' ,
3542 exportedSchema : undefined ,
3643 isOpen : false ,
44+ isLegacyBannerOpen : false ,
45+ legacyBannerChoice : undefined ,
3746} ) ;
3847
3948export const enum SchemaExportActions {
4049 openExportSchema = 'schema-service/schema-export/openExportSchema' ,
4150 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' ,
4254 changeExportSchemaStatus = 'schema-service/schema-export/changeExportSchemaStatus' ,
4355 changeExportSchemaFormatStarted = 'schema-service/schema-export/changeExportSchemaFormatStarted' ,
4456 changeExportSchemaFormatComplete = 'schema-service/schema-export/changeExportSchemaFormatComplete' ,
@@ -263,6 +275,42 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (
263275 } ;
264276 }
265277
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+
266314 if (
267315 isAction < ChangeExportSchemaFormatStartedAction > (
268316 action ,
@@ -319,3 +367,110 @@ export const schemaExportReducer: Reducer<SchemaExportState, Action> = (
319367
320368 return state ;
321369} ;
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