1- import React , { useEffect , useState } from 'react'
2- import type { ChangeEvent } from 'react'
1+ import { useEffect , useState } from 'react'
2+ import type { ChangeEvent , ClipboardEvent } from 'react'
33import { v4 as uuidv4 } from 'uuid'
44
55// EnvironmentVariable is a single row in the table
@@ -9,7 +9,7 @@ type EnvironmentVariable = {
99 value : string
1010}
1111
12- const INITIAL_ROW_COUNT = 20
12+ const INITIAL_ROW_COUNT = 5
1313const KEY_REGEX = / ^ [ A - Z a - z 0 - 9 _ ] + $ /
1414
1515// createEmptyVariable is a helper function to create an empty row
@@ -40,7 +40,49 @@ export const VarManager = () => {
4040 setRawText ( event . target . value )
4141 }
4242
43+ // Parse lines with multiple vars
44+ const parseLinesToItems = ( text : string ) => {
45+ return text
46+ . split ( / \r ? \n / )
47+ . map ( ( l ) => l . trim ( ) )
48+ . filter ( ( l ) => l && ! l . startsWith ( "#" ) )
49+ . map ( ( l ) => {
50+ const idx = l . indexOf ( "=" )
51+ if ( idx === - 1 ) {
52+ return { key : l , value : "" }
53+ }
54+ return {
55+ key : l . slice ( 0 , idx ) . trim ( ) ,
56+ value : l . slice ( idx + 1 ) . trim ( ) ,
57+ }
58+ } )
59+ }
4360
61+ // onPaste handler for any row's input
62+ const handleRowPaste = (
63+ e : ClipboardEvent < HTMLInputElement > ,
64+ rowIndex : number
65+ ) => {
66+ const clipText = e . clipboardData . getData ( "text/plain" )
67+ if ( ! clipText . includes ( "\n" ) ) {
68+ return
69+ }
70+ e . preventDefault ( )
71+
72+ const items = parseLinesToItems ( clipText )
73+ setVariables ( ( prev ) => {
74+ const next = [ ...prev ]
75+ items . forEach ( ( it , i ) => {
76+ const idx = rowIndex + i
77+ if ( idx < next . length ) {
78+ next [ idx ] = { id : uuidv4 ( ) , key : it . key , value : it . value }
79+ } else {
80+ next . push ( { id : uuidv4 ( ) , key : it . key , value : it . value } )
81+ }
82+ } )
83+ return next
84+ } )
85+ }
4486
4587 // parseAndPopulate parses the raw text for env vars
4688 const parseAndPopulate = ( ) => {
@@ -252,7 +294,7 @@ export const VarManager = () => {
252294 Variables ({ variables . length } )
253295 </ h3 >
254296 < div className = "max-h-[50vh] overflow-y-auto border p-2 rounded bg-gray-850" >
255- { variables . map ( ( row , i ) => (
297+ { variables . map ( ( row , i ) => (
256298 < div
257299 key = { row . id }
258300 className = "flex flex-col sm:flex-row items-start sm:items-center gap-2 mb-2"
@@ -267,6 +309,7 @@ export const VarManager = () => {
267309 onChange = { ( e ) =>
268310 handleVariableChange ( row . id , 'key' , e . target . value )
269311 }
312+ onPaste = { ( e ) => handleRowPaste ( e , i ) }
270313 className = { `w-full text-sm p-1 rounded border ${
271314 rowErrors [ row . id ]
272315 ? 'border-red-500 bg-red-50'
0 commit comments