@@ -19,6 +19,7 @@ import { ScrollArea } from '@/components/ui/scroll-area'
1919import { Tooltip , TooltipContent , TooltipTrigger } from '@/components/ui/tooltip'
2020import { createLogger } from '@/lib/logs/console/logger'
2121import { validateName } from '@/lib/utils'
22+ import { useCollaborativeWorkflow } from '@/hooks/use-collaborative-workflow'
2223import { useVariablesStore } from '@/stores/panel/variables/store'
2324import type { Variable , VariableType } from '@/stores/panel/variables/types'
2425import { useWorkflowRegistry } from '@/stores/workflows/registry/store'
@@ -34,19 +35,17 @@ export function Variables() {
3435 deleteVariable,
3536 duplicateVariable,
3637 getVariablesByWorkflowId,
37- loadVariables,
3838 } = useVariablesStore ( )
39+ const {
40+ collaborativeUpdateVariable,
41+ collaborativeAddVariable,
42+ collaborativeDeleteVariable,
43+ collaborativeDuplicateVariable,
44+ } = useCollaborativeWorkflow ( )
3945
4046 // Get variables for the current workflow
4147 const workflowVariables = activeWorkflowId ? getVariablesByWorkflowId ( activeWorkflowId ) : [ ]
4248
43- // Load variables when active workflow changes
44- useEffect ( ( ) => {
45- if ( activeWorkflowId ) {
46- loadVariables ( activeWorkflowId )
47- }
48- } , [ activeWorkflowId , loadVariables ] )
49-
5049 // Track editor references
5150 const editorRefs = useRef < Record < string , HTMLDivElement | null > > ( { } )
5251
@@ -56,16 +55,14 @@ export function Variables() {
5655 // Handle variable name change with validation
5756 const handleVariableNameChange = ( variableId : string , newName : string ) => {
5857 const validatedName = validateName ( newName )
59- updateVariable ( variableId , { name : validatedName } )
58+ collaborativeUpdateVariable ( variableId , ' name' , validatedName )
6059 }
6160
62- // Auto-save when variables are added/edited
6361 const handleAddVariable = ( ) => {
6462 if ( ! activeWorkflowId ) return
6563
66- // Create a default variable - naming is handled in the store
67- const id = addVariable ( {
68- name : '' , // Store will generate an appropriate name
64+ const id = collaborativeAddVariable ( {
65+ name : '' ,
6966 type : 'string' ,
7067 value : '' ,
7168 workflowId : activeWorkflowId ,
@@ -125,46 +122,32 @@ export function Variables() {
125122 }
126123 }
127124
128- // Handle editor value changes - store exactly what user types
129125 const handleEditorChange = ( variable : Variable , newValue : string ) => {
130- // Store the raw value directly, no parsing or formatting
131- updateVariable ( variable . id , {
132- value : newValue ,
133- // Clear any previous validation errors so they'll be recalculated
134- validationError : undefined ,
135- } )
126+ collaborativeUpdateVariable ( variable . id , 'value' , newValue )
136127 }
137128
138- // Only track focus state for UI purposes
139129 const handleEditorBlur = ( variableId : string ) => {
140130 setActiveEditors ( ( prev ) => ( {
141131 ...prev ,
142132 [ variableId ] : false ,
143133 } ) )
144134 }
145135
146- // Track when editor becomes active
147136 const handleEditorFocus = ( variableId : string ) => {
148137 setActiveEditors ( ( prev ) => ( {
149138 ...prev ,
150139 [ variableId ] : true ,
151140 } ) )
152141 }
153142
154- // Always return raw value without any formatting
155143 const formatValue = ( variable : Variable ) => {
156144 if ( variable . value === '' ) return ''
157145
158- // Always return raw value exactly as typed
159146 return typeof variable . value === 'string' ? variable . value : JSON . stringify ( variable . value )
160147 }
161148
162- // Get validation status based on type and value
163149 const getValidationStatus = ( variable : Variable ) : string | undefined => {
164- // Empty values don't need validation
165150 if ( variable . value === '' ) return undefined
166-
167- // Otherwise validate based on type
168151 switch ( variable . type ) {
169152 case 'number' :
170153 return Number . isNaN ( Number ( variable . value ) ) ? 'Not a valid number' : undefined
@@ -174,49 +157,38 @@ export function Variables() {
174157 : undefined
175158 case 'object' :
176159 try {
177- // Handle both JavaScript and JSON syntax
178160 const valueToEvaluate = String ( variable . value ) . trim ( )
179161
180- // Basic security check to prevent arbitrary code execution
181162 if ( ! valueToEvaluate . startsWith ( '{' ) || ! valueToEvaluate . endsWith ( '}' ) ) {
182163 return 'Not a valid object format'
183164 }
184165
185- // Use Function constructor to safely evaluate the object expression
186- // This is safer than eval() and handles all JS object literal syntax
187166 const parsed = new Function ( `return ${ valueToEvaluate } ` ) ( )
188167
189- // Verify it's actually an object (not array or null)
190168 if ( parsed === null || typeof parsed !== 'object' || Array . isArray ( parsed ) ) {
191169 return 'Not a valid object'
192170 }
193171
194- return undefined // Valid object
172+ return undefined
195173 } catch ( e ) {
196174 logger . info ( 'Object parsing error:' , e )
197175 return 'Invalid object syntax'
198176 }
199177 case 'array' :
200178 try {
201- // Use actual JavaScript evaluation instead of trying to convert to JSON
202- // This properly handles all valid JS array syntax including mixed types
203179 const valueToEvaluate = String ( variable . value ) . trim ( )
204180
205- // Basic security check to prevent arbitrary code execution
206181 if ( ! valueToEvaluate . startsWith ( '[' ) || ! valueToEvaluate . endsWith ( ']' ) ) {
207182 return 'Not a valid array format'
208183 }
209184
210- // Use Function constructor to safely evaluate the array expression
211- // This is safer than eval() and handles all JS array syntax correctly
212185 const parsed = new Function ( `return ${ valueToEvaluate } ` ) ( )
213186
214- // Verify it's actually an array
215187 if ( ! Array . isArray ( parsed ) ) {
216188 return 'Not a valid array'
217189 }
218190
219- return undefined // Valid array
191+ return undefined
220192 } catch ( e ) {
221193 logger . info ( 'Array parsing error:' , e )
222194 return 'Invalid array syntax'
@@ -226,9 +198,7 @@ export function Variables() {
226198 }
227199 }
228200
229- // Clear editor refs when variables change
230201 useEffect ( ( ) => {
231- // Clean up any references to deleted variables
232202 Object . keys ( editorRefs . current ) . forEach ( ( id ) => {
233203 if ( ! workflowVariables . some ( ( v ) => v . id === id ) ) {
234204 delete editorRefs . current [ id ]
@@ -276,35 +246,35 @@ export function Variables() {
276246 className = 'min-w-32 rounded-lg border-[#E5E5E5] bg-[#FFFFFF] shadow-xs dark:border-[#414141] dark:bg-[#202020]'
277247 >
278248 < DropdownMenuItem
279- onClick = { ( ) => updateVariable ( variable . id , { type : 'plain' } ) }
249+ onClick = { ( ) => collaborativeUpdateVariable ( variable . id , ' type' , 'plain' ) }
280250 className = 'flex cursor-pointer items-center rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
281251 >
282252 < div className = 'mr-2 w-5 text-center font-[380] text-sm' > Abc</ div >
283253 < span className = 'font-[380]' > Plain</ span >
284254 </ DropdownMenuItem >
285255 < DropdownMenuItem
286- onClick = { ( ) => updateVariable ( variable . id , { type : 'number' } ) }
256+ onClick = { ( ) => collaborativeUpdateVariable ( variable . id , ' type' , 'number' ) }
287257 className = 'flex cursor-pointer items-center rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
288258 >
289259 < div className = 'mr-2 w-5 text-center font-[380] text-sm' > 123</ div >
290260 < span className = 'font-[380]' > Number</ span >
291261 </ DropdownMenuItem >
292262 < DropdownMenuItem
293- onClick = { ( ) => updateVariable ( variable . id , { type : 'boolean' } ) }
263+ onClick = { ( ) => collaborativeUpdateVariable ( variable . id , ' type' , 'boolean' ) }
294264 className = 'flex cursor-pointer items-center rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
295265 >
296266 < div className = 'mr-2 w-5 text-center font-[380] text-sm' > 0/1</ div >
297267 < span className = 'font-[380]' > Boolean</ span >
298268 </ DropdownMenuItem >
299269 < DropdownMenuItem
300- onClick = { ( ) => updateVariable ( variable . id , { type : 'object' } ) }
270+ onClick = { ( ) => collaborativeUpdateVariable ( variable . id , ' type' , 'object' ) }
301271 className = 'flex cursor-pointer items-center rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
302272 >
303273 < div className = 'mr-2 w-5 text-center font-[380] text-sm' > { '{}' } </ div >
304274 < span className = 'font-[380]' > Object</ span >
305275 </ DropdownMenuItem >
306276 < DropdownMenuItem
307- onClick = { ( ) => updateVariable ( variable . id , { type : 'array' } ) }
277+ onClick = { ( ) => collaborativeUpdateVariable ( variable . id , ' type' , 'array' ) }
308278 className = 'flex cursor-pointer items-center rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
309279 >
310280 < div className = 'mr-2 w-5 text-center font-[380] text-sm' > []</ div >
@@ -329,14 +299,14 @@ export function Variables() {
329299 className = 'min-w-32 rounded-lg border-[#E5E5E5] bg-[#FFFFFF] shadow-xs dark:border-[#414141] dark:bg-[#202020]'
330300 >
331301 < DropdownMenuItem
332- onClick = { ( ) => duplicateVariable ( variable . id ) }
302+ onClick = { ( ) => collaborativeDuplicateVariable ( variable . id ) }
333303 className = 'cursor-pointer rounded-md px-3 py-2 font-[380] text-card-foreground text-sm hover:bg-secondary/50 focus:bg-secondary/50'
334304 >
335305 < Copy className = 'mr-2 h-4 w-4 text-muted-foreground' />
336306 Duplicate
337307 </ DropdownMenuItem >
338308 < DropdownMenuItem
339- onClick = { ( ) => deleteVariable ( variable . id ) }
309+ onClick = { ( ) => collaborativeDeleteVariable ( variable . id ) }
340310 className = 'cursor-pointer rounded-md px-3 py-2 font-[380] text-destructive text-sm hover:bg-destructive/10 focus:bg-destructive/10 focus:text-destructive'
341311 >
342312 < Trash className = 'mr-2 h-4 w-4' />
0 commit comments