Skip to content

Commit 2592ee9

Browse files
committed
import/export variables
1 parent c661756 commit 2592ee9

File tree

7 files changed

+100
-3
lines changed

7 files changed

+100
-3
lines changed

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/create-menu/create-menu.tsx

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -215,6 +215,24 @@ export function CreateMenu({ onCreateWorkflow, isCreatingWorkflow = false }: Cre
215215
continue
216216
}
217217

218+
if (workflowData.variables && workflowData.variables.length > 0) {
219+
const variablesPayload = workflowData.variables.map((v: any) => ({
220+
id: crypto.randomUUID(),
221+
workflowId: newWorkflowId,
222+
name: v.name,
223+
type: v.type,
224+
value: v.value,
225+
}))
226+
227+
await fetch(`/api/workflows/${newWorkflowId}/variables`, {
228+
method: 'POST',
229+
headers: {
230+
'Content-Type': 'application/json',
231+
},
232+
body: JSON.stringify({ variables: variablesPayload }),
233+
})
234+
}
235+
218236
logger.info(`Imported workflow: ${workflowName}`)
219237
} catch (error) {
220238
logger.error(`Failed to import ${workflow.name}:`, error)
@@ -257,6 +275,24 @@ export function CreateMenu({ onCreateWorkflow, isCreatingWorkflow = false }: Cre
257275
continue
258276
}
259277

278+
if (workflowData.variables && workflowData.variables.length > 0) {
279+
const variablesPayload = workflowData.variables.map((v: any) => ({
280+
id: crypto.randomUUID(),
281+
workflowId: newWorkflowId,
282+
name: v.name,
283+
type: v.type,
284+
value: v.value,
285+
}))
286+
287+
await fetch(`/api/workflows/${newWorkflowId}/variables`, {
288+
method: 'POST',
289+
headers: {
290+
'Content-Type': 'application/json',
291+
},
292+
body: JSON.stringify({ variables: variablesPayload }),
293+
})
294+
}
295+
260296
logger.info(`Imported workflow: ${workflowName}`)
261297
} catch (error) {
262298
logger.error(`Failed to import ${workflow.name}:`, error)
@@ -266,6 +302,9 @@ export function CreateMenu({ onCreateWorkflow, isCreatingWorkflow = false }: Cre
266302

267303
const { loadWorkflows } = useWorkflowRegistry.getState()
268304
await loadWorkflows(workspaceId)
305+
306+
const { fetchFolders } = useFolderStore.getState()
307+
await fetchFolders(workspaceId)
269308
} catch (error) {
270309
logger.error('Failed to import workflows:', error)
271310
} finally {

apps/sim/app/workspace/[workspaceId]/w/components/sidebar/components/workspace-selector/workspace-selector.tsx

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -341,6 +341,12 @@ export function WorkspaceSelector({
341341
folderId?: string | null
342342
}
343343
state: any
344+
variables?: Array<{
345+
id: string
346+
name: string
347+
type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'plain'
348+
value: any
349+
}>
344350
}> = []
345351

346352
for (const workflow of workflows) {
@@ -357,6 +363,18 @@ export function WorkspaceSelector({
357363
continue
358364
}
359365

366+
const variablesResponse = await fetch(`/api/workflows/${workflow.id}/variables`)
367+
let workflowVariables: any[] = []
368+
if (variablesResponse.ok) {
369+
const variablesData = await variablesResponse.json()
370+
workflowVariables = Object.values(variablesData?.data || {}).map((v: any) => ({
371+
id: v.id,
372+
name: v.name,
373+
type: v.type,
374+
value: v.value,
375+
}))
376+
}
377+
360378
workflowsToExport.push({
361379
workflow: {
362380
id: workflow.id,
@@ -365,6 +383,7 @@ export function WorkspaceSelector({
365383
folderId: workflow.folderId,
366384
},
367385
state: workflowData.state,
386+
variables: workflowVariables,
368387
})
369388
} catch (error) {
370389
logger.error(`Failed to export workflow ${workflow.id}:`, error)

apps/sim/lib/workflows/import-export.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,12 @@ export interface WorkflowExportData {
1313
folderId?: string | null
1414
}
1515
state: WorkflowState
16+
variables?: Array<{
17+
id: string
18+
name: string
19+
type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'plain'
20+
value: any
21+
}>
1622
}
1723

1824
export interface FolderExportData {
@@ -79,6 +85,7 @@ export async function exportWorkspaceToZip(
7985
description: workflow.workflow.description,
8086
exportedAt: new Date().toISOString(),
8187
},
88+
variables: workflow.variables,
8289
}
8390

8491
const exportState = sanitizeForExport(workflowState)

apps/sim/lib/workflows/json-sanitizer.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,12 @@ export interface ExportWorkflowState {
5454
description?: string
5555
exportedAt?: string
5656
}
57+
variables?: Array<{
58+
id: string
59+
name: string
60+
type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'plain'
61+
value: any
62+
}>
5763
}
5864
}
5965

@@ -381,6 +387,7 @@ export function sanitizeForExport(state: WorkflowState): ExportWorkflowState {
381387
loops: state.loops || {},
382388
parallels: state.parallels || {},
383389
metadata: state.metadata,
390+
variables: state.variables,
384391
})
385392
)
386393

apps/sim/stores/workflows/json/importer.ts

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ const logger = createLogger('WorkflowJsonImporter')
88
* Generate new IDs for all blocks and edges to avoid conflicts
99
*/
1010
function regenerateIds(workflowState: WorkflowState): WorkflowState {
11+
const { metadata, variables } = workflowState
1112
const blockIdMap = new Map<string, string>()
1213
const newBlocks: WorkflowState['blocks'] = {}
1314

@@ -99,6 +100,8 @@ function regenerateIds(workflowState: WorkflowState): WorkflowState {
99100
edges: newEdges,
100101
loops: newLoops,
101102
parallels: newParallels,
103+
metadata,
104+
variables,
102105
}
103106
}
104107

@@ -206,11 +209,18 @@ export function parseWorkflowJson(
206209
edges: workflowData.edges || [],
207210
loops: workflowData.loops || {},
208211
parallels: workflowData.parallels || {},
212+
metadata: workflowData.metadata,
213+
variables: Array.isArray(workflowData.variables) ? workflowData.variables : undefined,
209214
}
210215

211216
// Regenerate IDs if requested (default: true)
212217
if (regenerateIdsFlag) {
213-
workflowState = regenerateIds(workflowState)
218+
const regeneratedState = regenerateIds(workflowState)
219+
workflowState = {
220+
...regeneratedState,
221+
metadata: workflowState.metadata,
222+
variables: workflowState.variables,
223+
}
214224
logger.info('Regenerated IDs for imported workflow to avoid conflicts')
215225
}
216226

apps/sim/stores/workflows/json/store.ts

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,13 +39,24 @@ export const useWorkflowJsonStore = create<WorkflowJsonStore>()(
3939
}
4040

4141
const workflowMetadata = workflows[activeWorkflowId]
42+
const { useVariablesStore } = require('@/stores/panel/variables/store')
43+
const workflowVariables = useVariablesStore
44+
.getState()
45+
.getVariablesByWorkflowId(activeWorkflowId)
46+
4247
const workflowState = {
4348
...workflow.state,
4449
metadata: {
4550
name: workflowMetadata?.name,
4651
description: workflowMetadata?.description,
4752
exportedAt: new Date().toISOString(),
4853
},
54+
variables: workflowVariables.map((v: any) => ({
55+
id: v.id,
56+
name: v.name,
57+
type: v.type,
58+
value: v.value,
59+
})),
4960
}
5061

5162
const exportState: ExportWorkflowState = sanitizeForExport(workflowState)

apps/sim/stores/workflows/workflow/types.ts

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -158,12 +158,16 @@ export interface WorkflowState {
158158
description?: string
159159
exportedAt?: string
160160
}
161+
variables?: Array<{
162+
id: string
163+
name: string
164+
type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'plain'
165+
value: any
166+
}>
161167
isDeployed?: boolean
162168
deployedAt?: Date
163-
// New field for per-workflow deployment status
164169
deploymentStatuses?: Record<string, DeploymentStatus>
165170
needsRedeployment?: boolean
166-
// Drag state for undo/redo
167171
dragStartPosition?: DragStartPosition | null
168172
}
169173

0 commit comments

Comments
 (0)