@@ -13,7 +13,7 @@ import {
1313} from '@/components/ui/dialog'
1414import { Button } from '@/components/ui/button'
1515import { api , ApiError } from '@/lib/api'
16- import { parseMongoQuery } from '@/lib/mongoQueryLang'
16+ import { parseMongoDocuments , parseMongoQuery } from '@/lib/mongoQueryLang'
1717import { serializeMongoValue } from '@/lib/mongoQuerySerialize'
1818import type { DocumentEnvelope , UuidEncoding } from '@shared/types'
1919
@@ -36,15 +36,15 @@ const TITLES: Record<EditorMode, string> = {
3636 view : 'View document' ,
3737 edit : 'Edit document' ,
3838 duplicate : 'Duplicate document' ,
39- insert : 'Insert document '
39+ insert : 'Insert documents '
4040}
4141
4242const DESCRIPTIONS : Record < EditorMode , string > = {
4343 view : 'Read-only — BSON types render as ObjectId / ISODate / UUID / NumberLong / NumberDecimal.' ,
4444 edit : 'Edit using mongo shell syntax — ObjectId("…"), ISODate("…"), NumberLong("…"), UUID/JUUID, regex literals.' ,
4545 duplicate : 'A copy with the original _id removed. Save inserts a new document with a fresh _id.' ,
4646 insert :
47- 'New document — mongo shell syntax . Leave _id out and the server will assign a fresh ObjectId.'
47+ 'Multiple documents, one after another newline, comma-separated or JSON array . Leave _id out for a fresh ObjectId.'
4848}
4949
5050const INSERT_TEMPLATE = '{\n \n}'
@@ -112,16 +112,26 @@ export function DocumentEditorDialog({
112112 setValue ( mode === 'duplicate' ? stripIdShell ( rendered , uuidEncoding , timezone ) : rendered )
113113 } , [ envelope , mode , uuidEncoding , timezone ] )
114114
115- const compiled = useMemo ( ( ) => {
116- if ( mode === 'view' || mode === null ) return { ok : true as const , ejson : '' }
115+ const compiled = useMemo <
116+ { ok : true ; ejson : string ; documents : string [ ] } | { ok : false ; error : string }
117+ > ( ( ) => {
118+ if ( mode === 'view' || mode === null ) return { ok : true , ejson : '' , documents : [ ] }
119+ if ( mode === 'insert' ) {
120+ const parsed = parseMongoDocuments ( value )
121+ if ( ! parsed . ok ) return { ok : false , error : parsed . error }
122+ if ( parsed . documents . length === 0 ) return { ok : false , error : 'Enter at least one document' }
123+ return { ok : true , ejson : '' , documents : parsed . documents }
124+ }
117125 const parsed = parseMongoQuery ( value )
118- if ( ! parsed . ok ) return { ok : false as const , error : parsed . error }
126+ if ( ! parsed . ok ) return { ok : false , error : parsed . error }
119127 if ( parsed . value === null || typeof parsed . value !== 'object' || Array . isArray ( parsed . value ) ) {
120- return { ok : false as const , error : 'Document must be an object' }
128+ return { ok : false , error : 'Document must be an object' }
121129 }
122- return { ok : true as const , ejson : parsed . ejson }
130+ return { ok : true , ejson : parsed . ejson , documents : [ ] }
123131 } , [ value , mode ] )
124132
133+ const manyCount = compiled . ok ? compiled . documents . length : 0
134+
125135 const saveMutation = useMutation ( {
126136 mutationFn : async ( ) => {
127137 if ( ! mode ) throw new Error ( 'No editor mode' )
@@ -137,7 +147,10 @@ export function DocumentEditorDialog({
137147 replacement : compiled . ejson
138148 } )
139149 }
140- if ( mode === 'duplicate' || mode === 'insert' ) {
150+ if ( mode === 'insert' ) {
151+ return api . query . insertMany ( { connectionId, db, coll, documents : compiled . documents } )
152+ }
153+ if ( mode === 'duplicate' ) {
141154 return api . query . insertOne ( { connectionId, db, coll, document : compiled . ejson } )
142155 }
143156 throw new Error ( 'Cannot save in view mode' )
@@ -150,7 +163,7 @@ export function DocumentEditorDialog({
150163 ? 'Document updated'
151164 : mode === 'duplicate'
152165 ? 'Document duplicated'
153- : 'Document inserted'
166+ : `Inserted ${ manyCount } document ${ manyCount === 1 ? '' : 's' } `
154167 toast . success ( successMessage )
155168 onClose ( )
156169 } ,
@@ -172,7 +185,13 @@ export function DocumentEditorDialog({
172185 const parseError = compiled . ok ? null : compiled . error
173186 const isReadOnly = mode === 'view'
174187 const ctaLabel =
175- mode === 'edit' ? 'Save changes' : mode === 'duplicate' ? 'Insert duplicate' : 'Insert document'
188+ mode === 'edit'
189+ ? 'Save changes'
190+ : mode === 'duplicate'
191+ ? 'Insert duplicate'
192+ : manyCount > 0
193+ ? `Insert ${ manyCount } document${ manyCount === 1 ? '' : 's' } `
194+ : 'Insert documents'
176195
177196 return (
178197 < Dialog open = { open } onOpenChange = { handleOpenChange } >
0 commit comments