1- import React , { useCallback , useEffect , useRef , useState } from 'react' ;
1+ import React from 'react' ;
22import {
33 Button ,
44 css ,
@@ -13,19 +13,17 @@ import {
1313 RadioGroup ,
1414 spacing ,
1515 SpinLoader ,
16- openToast ,
1716} from '@mongodb-js/compass-components' ;
17+ import type { ExportDiagramFormat } from '../store/export-diagram' ;
1818import {
1919 closeExportModal ,
20- selectCurrentModel ,
21- getCurrentDiagramFromState ,
22- } from '../store/diagram' ;
20+ exportDiagram ,
21+ selectFormat ,
22+ } from '../store/export- diagram' ;
2323import { connect } from 'react-redux' ;
2424import type { DataModelingState } from '../store/reducer' ;
25- import type { StaticModel } from '../services/data-model-storage' ;
26- import { exportToJson , exportToPng } from '../services/export-diagram' ;
2725import { useDiagram } from '@mongodb-js/diagramming' ;
28- import { isCancelError } from '@mongodb-js/compass-utils ' ;
26+ import type { DiagramInstance } from '@mongodb-js/diagramming ' ;
2927
3028const nbsp = '\u00a0' ;
3129
@@ -52,79 +50,27 @@ const footerStyles = css({
5250
5351type ExportDiagramModalProps = {
5452 isModalOpen : boolean ;
55- diagramLabel : string ;
56- model : StaticModel | null ;
53+ isExporting : boolean ;
54+ exportFormat ?: ExportDiagramFormat ;
55+ onExportDiagram : ( diagramInstance : DiagramInstance ) => void ;
56+ onSelectFormat : ( format : ExportDiagramFormat ) => void ;
5757 onCloseClick : ( ) => void ;
5858} ;
5959
6060const ExportDiagramModal = ( {
6161 isModalOpen,
62- diagramLabel,
63- model,
62+ isExporting,
63+ exportFormat,
64+ onExportDiagram,
65+ onSelectFormat,
6466 onCloseClick,
6567} : ExportDiagramModalProps ) => {
66- const [ exportFormat , setExportFormat ] = useState < 'png' | 'json' | null > ( null ) ;
6768 const diagram = useDiagram ( ) ;
68- const [ isExporting , setIsExporting ] = useState ( false ) ;
69- const abortControllerRef = useRef < AbortController | null > ( null ) ;
70- useEffect ( ( ) => {
71- const cleanup = ( ) => {
72- if ( abortControllerRef . current ) {
73- abortControllerRef . current . abort ( ) ;
74- abortControllerRef . current = null ;
75- }
76- } ;
77- const abortController = new AbortController ( ) ;
78- if ( isModalOpen ) {
79- abortControllerRef . current = abortController ;
80- } else {
81- cleanup ( ) ;
82- }
83- return cleanup ;
84- } , [ isModalOpen ] ) ;
85-
86- const onClose = useCallback ( ( ) => {
87- setIsExporting ( false ) ;
88- abortControllerRef . current ?. abort ( ) ;
89- abortControllerRef . current = null ;
90- onCloseClick ( ) ;
91- } , [ onCloseClick ] ) ;
92-
93- const onExport = useCallback ( async ( ) => {
94- try {
95- if ( ! exportFormat || ! model ) {
96- return ;
97- }
98- setIsExporting ( true ) ;
99- if ( exportFormat === 'json' ) {
100- exportToJson ( diagramLabel , model ) ;
101- } else if ( exportFormat === 'png' ) {
102- await exportToPng (
103- diagramLabel ,
104- diagram ,
105- abortControllerRef . current ?. signal
106- ) ;
107- }
108- } catch ( error ) {
109- if ( isCancelError ( error ) ) {
110- return ;
111- }
112- openToast ( 'export-diagram-error' , {
113- variant : 'warning' ,
114- title : 'Export failed' ,
115- description : `An error occurred while exporting the diagram: ${
116- ( error as Error ) . message
117- } `,
118- } ) ;
119- } finally {
120- onClose ( ) ;
121- }
122- } , [ exportFormat , onClose , model , diagram , diagramLabel ] ) ;
12369
12470 return (
12571 < Modal
12672 open = { isModalOpen }
127- setOpen = { onClose }
73+ setOpen = { onCloseClick }
12874 data-testid = "export-diagram-modal"
12975 >
13076 < ModalHeader
@@ -153,7 +99,7 @@ const ExportDiagramModal = ({
15399 checked = { exportFormat === 'png' }
154100 value = "png"
155101 aria-label = "PNG"
156- onClick = { ( ) => setExportFormat ( 'png' ) }
102+ onClick = { ( ) => onSelectFormat ( 'png' ) }
157103 >
158104 PNG
159105 </ Radio >
@@ -164,7 +110,7 @@ const ExportDiagramModal = ({
164110 checked = { exportFormat === 'json' }
165111 value = "json"
166112 aria-label = "JSON"
167- onClick = { ( ) => setExportFormat ( 'json' ) }
113+ onClick = { ( ) => onSelectFormat ( 'json' ) }
168114 >
169115 JSON
170116 </ Radio >
@@ -175,15 +121,19 @@ const ExportDiagramModal = ({
175121 < ModalFooter className = { footerStyles } >
176122 < Button
177123 variant = "primary"
178- onClick = { ( ) => void onExport ( ) }
124+ onClick = { ( ) => onExportDiagram ( diagram ) }
179125 data-testid = "export-button"
180- disabled = { ! exportFormat || ! model }
126+ disabled = { ! exportFormat }
181127 loadingIndicator = { < SpinLoader /> }
182128 isLoading = { isExporting }
183129 >
184130 Export
185131 </ Button >
186- < Button variant = "default" onClick = { onClose } data-testid = "cancel-button" >
132+ < Button
133+ variant = "default"
134+ onClick = { onCloseClick }
135+ data-testid = "cancel-button"
136+ >
187137 Cancel
188138 </ Button >
189139 </ ModalFooter >
@@ -193,17 +143,18 @@ const ExportDiagramModal = ({
193143
194144export default connect (
195145 ( state : DataModelingState ) => {
196- const { diagram } = state ;
197- const model = diagram
198- ? selectCurrentModel ( getCurrentDiagramFromState ( state ) )
199- : null ;
146+ const {
147+ exportDiagram : { isExporting, isModalOpen, exportFormat } ,
148+ } = state ;
200149 return {
201- model ,
202- diagramLabel : diagram ?. name ?? 'Schema Preview' ,
203- isModalOpen : Boolean ( diagram ?. isExportModalOpen ) ,
150+ isModalOpen ,
151+ isExporting ,
152+ exportFormat ,
204153 } ;
205154 } ,
206155 {
207156 onCloseClick : closeExportModal ,
157+ onSelectFormat : selectFormat ,
158+ onExportDiagram : exportDiagram ,
208159 }
209160) ( ExportDiagramModal ) ;
0 commit comments