@@ -7,8 +7,12 @@ import {
77 ModalFooter ,
88 ModalHeader ,
99 css ,
10+ cx ,
1011 spacing ,
1112 FormFieldContainer ,
13+ Body ,
14+ palette ,
15+ useDarkMode ,
1216} from '@mongodb-js/compass-components' ;
1317import { useTrackOnChange } from '@mongodb-js/compass-logging' ;
1418
@@ -31,6 +35,7 @@ import formatNumber from '../utils/format-number';
3135import {
3236 startImport ,
3337 cancelImport ,
38+ skipCSVAnalyze ,
3439 selectImportFileName ,
3540 setDelimiter ,
3641 setStopOnErrors ,
@@ -44,6 +49,7 @@ import type { RootImportState } from '../stores/import-store';
4449import type { CSVDelimiter , FieldFromCSV } from '../modules/import' ;
4550import { ImportFileInput } from './import-file-input' ;
4651import type { CSVParsableFieldType } from '../utils/csv' ;
52+ import { SpinLoader } from '@mongodb-js/compass-components' ;
4753
4854/**
4955 * Progress messages.
@@ -61,11 +67,41 @@ const closeButtonStyles = css({
6167 marginRight : spacing [ 2 ] ,
6268} ) ;
6369
70+ const analyzeStyles = css ( {
71+ display : 'flex' ,
72+ flexDirection : 'column' ,
73+ alignItems : 'center' ,
74+ padding : `${ spacing [ 4 ] } px 0` ,
75+ } ) ;
76+
77+ const analyzeStylesDark = css ( {
78+ backgroundColor : palette . gray . dark3 ,
79+ } ) ;
80+
81+ const analyzeStylesLight = css ( {
82+ backgroundColor : palette . gray . light3 ,
83+ } ) ;
84+
85+ const loaderStyles = css ( {
86+ marginTop : spacing [ 3 ] ,
87+ display : 'flex' ,
88+ flexDirection : 'row' ,
89+ gap : spacing [ 1 ] ,
90+ alignItems : 'center' ,
91+ } ) ;
92+
93+ const explanationTextStyles = css ( {
94+ margin : `${ spacing [ 3 ] } px 0` ,
95+ width : '350px' ,
96+ textAlign : 'center' ,
97+ } ) ;
98+
6499type ImportModalProps = {
65100 isOpen : boolean ;
66101 ns : string ;
67102 startImport : ( ) => void ;
68103 cancelImport : ( ) => void ;
104+ skipCSVAnalyze : ( ) => void ;
69105 closeImport : ( ) => void ;
70106 errors : Error [ ] ;
71107 status : ProcessStatus ;
@@ -92,6 +128,9 @@ type ImportModalProps = {
92128 guesstimatedDocsTotal : number ;
93129 guesstimatedDocsProcessed : number ;
94130
131+ analyzeBytesProcessed : number ;
132+ analyzeBytesTotal : number ;
133+
95134 /**
96135 * See `<ImportPreview />`
97136 */
@@ -114,6 +153,8 @@ function ImportModal({
114153 cancelImport,
115154 closeImport,
116155
156+ skipCSVAnalyze,
157+
117158 errors,
118159 status,
119160
@@ -133,6 +174,9 @@ function ImportModal({
133174 guesstimatedDocsTotal,
134175 guesstimatedDocsProcessed,
135176
177+ analyzeBytesProcessed,
178+ analyzeBytesTotal,
179+
136180 fields,
137181 values,
138182 toggleIncludeField,
@@ -141,18 +185,11 @@ function ImportModal({
141185 csvAnalyzed,
142186} : ImportModalProps ) {
143187 const modalBodyRef = useRef < HTMLDivElement > ( null ) ;
144- const handleCancel = useCallback ( ( ) => {
145- cancelImport ( ) ;
146- } , [ cancelImport ] ) ;
147188
148189 const handleClose = useCallback ( ( ) => {
149- handleCancel ( ) ;
190+ cancelImport ( ) ;
150191 closeImport ( ) ;
151- } , [ closeImport , handleCancel ] ) ;
152-
153- const handleImportBtnClicked = useCallback ( ( ) => {
154- startImport ( ) ;
155- } , [ startImport ] ) ;
192+ } , [ closeImport , cancelImport ] ) ;
156193
157194 // docsTotal is set to actual value only at the very end of processing a
158195 // stream of documents
@@ -184,6 +221,8 @@ function ImportModal({
184221 React
185222 ) ;
186223
224+ const darkMode = useDarkMode ( ) ;
225+
187226 if ( isOpen && ! fileName && errors . length === 0 ) {
188227 // Show the file input when we don't have a file to import yet.
189228 return (
@@ -216,18 +255,45 @@ function ImportModal({
216255 ignoreBlanks = { ignoreBlanks }
217256 setIgnoreBlanks = { setIgnoreBlanks }
218257 />
219- { fileType === 'csv' && (
258+ { fileType === 'csv' && csvAnalyzed && (
220259 < FormFieldContainer >
221260 < ImportPreview
222261 loaded = { previewLoaded }
223- analyzed = { csvAnalyzed }
224262 onFieldCheckedChanged = { toggleIncludeField }
225263 setFieldType = { setFieldType }
226264 values = { values }
227265 fields = { fields as FieldFromCSV [ ] }
228266 />
229267 </ FormFieldContainer >
230268 ) }
269+
270+ { fileType === 'csv' && ! csvAnalyzed && (
271+ < FormFieldContainer
272+ className = { cx (
273+ analyzeStyles ,
274+ darkMode ? analyzeStylesDark : analyzeStylesLight
275+ ) }
276+ >
277+ < Body weight = "medium" > Detecting field types</ Body >
278+ { analyzeBytesTotal && (
279+ < div className = { loaderStyles } >
280+ < SpinLoader />
281+ < Body >
282+ { Math . round (
283+ ( analyzeBytesProcessed / analyzeBytesTotal ) * 100
284+ ) }
285+ %
286+ </ Body >
287+ </ div >
288+ ) }
289+ < Body className = { explanationTextStyles } >
290+ We are scanning your CSV file row by row to detect the field
291+ types. You can skip this step and manually assign field types at
292+ any point during the process.
293+ </ Body >
294+ < Button onClick = { skipCSVAnalyze } > Skip</ Button >
295+ </ FormFieldContainer >
296+ ) }
231297 < ProgressBar
232298 status = { status }
233299 withErrors = { errors . length > 0 }
@@ -269,7 +335,7 @@ function ImportModal({
269335 < >
270336 < Button
271337 data-testid = "import-button"
272- onClick = { handleImportBtnClicked }
338+ onClick = { startImport }
273339 disabled = {
274340 ! fileName ||
275341 status === STARTED ||
@@ -308,6 +374,8 @@ const mapStateToProps = (state: RootImportState) => ({
308374 docsWritten : state . importData . docsWritten ,
309375 guesstimatedDocsTotal : state . importData . guesstimatedDocsTotal ,
310376 guesstimatedDocsProcessed : state . importData . guesstimatedDocsProcessed ,
377+ analyzeBytesProcessed : state . importData . analyzeBytesProcessed ,
378+ analyzeBytesTotal : state . importData . analyzeBytesTotal ,
311379 delimiter : state . importData . delimiter ,
312380 stopOnErrors : state . importData . stopOnErrors ,
313381 ignoreBlanks : state . importData . ignoreBlanks ,
@@ -323,6 +391,7 @@ const mapStateToProps = (state: RootImportState) => ({
323391export default connect ( mapStateToProps , {
324392 startImport,
325393 cancelImport,
394+ skipCSVAnalyze,
326395 selectImportFileName,
327396 setDelimiter,
328397 setStopOnErrors,
0 commit comments