@dilipod/ui 0.4.11 → 0.4.13

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dilipod/ui",
3
- "version": "0.4.11",
3
+ "version": "0.4.13",
4
4
  "description": "Dilipod Design System - Shared UI components and styles",
5
5
  "author": "Dilipod <hello@dilipod.com>",
6
6
  "license": "MIT",
@@ -48,22 +48,48 @@ export interface N8nWorkflow {
48
48
  tags?: Array<{ name: string }>
49
49
  }
50
50
 
51
+ /**
52
+ * Sim Studio workflow state format
53
+ * Uses blocks (object keyed by ID) and edges (array)
54
+ */
51
55
  export interface SimWorkflow {
52
- name: string
56
+ // Actual Sim Studio state format
57
+ blocks?: Record<string, {
58
+ id: string
59
+ type: string
60
+ name: string
61
+ position?: { x: number; y: number }
62
+ subBlocks?: Record<string, unknown>
63
+ outputs?: Record<string, unknown>
64
+ enabled?: boolean
65
+ }>
66
+ edges?: Array<{
67
+ id?: string
68
+ source?: string
69
+ target?: string
70
+ sourceHandle?: string
71
+ targetHandle?: string
72
+ // Legacy format support
73
+ from?: string
74
+ to?: string
75
+ }>
76
+ loops?: Record<string, unknown>
77
+ parallels?: Record<string, unknown>
78
+ variables?: Record<string, unknown>
79
+ lastSaved?: number
80
+ isDeployed?: boolean
81
+ // Legacy format (for backwards compatibility)
82
+ name?: string
53
83
  description?: string
54
84
  trigger?: {
55
85
  type: string
56
86
  config?: Record<string, unknown>
57
87
  }
58
- nodes: Array<{
88
+ nodes?: Array<{
59
89
  id: string
60
90
  type: string
61
91
  config?: Record<string, unknown>
62
92
  }>
63
- edges?: Array<{
64
- from: string
65
- to: string
66
- }>
67
93
  }
68
94
 
69
95
  export type WorkflowTemplate = 'blank' | 'request_analyzer' | 'documentation_updater' | 'execution_monitor' | 'usage_reporter' | 'custom'
@@ -350,10 +376,38 @@ function N8nWorkflowSummary({ workflow, showFlow = false }: { workflow: N8nWorkf
350
376
  // ============================================
351
377
 
352
378
  function SimWorkflowSummary({ workflow }: { workflow: SimWorkflow }) {
353
- const nodes = workflow.nodes || []
354
-
355
- const aiNodes = nodes.filter(n => n.type === 'llm')
356
- const httpNodes = nodes.filter(n => n.type === 'http_request')
379
+ // Handle actual Sim Studio format (blocks object) or legacy format (nodes array)
380
+ const blocks = workflow.blocks || {}
381
+ const blockList = Object.values(blocks)
382
+ const edges = workflow.edges || []
383
+
384
+ // Fall back to legacy nodes array if no blocks
385
+ const legacyNodes = workflow.nodes || []
386
+ const hasBlocks = blockList.length > 0
387
+ const displayNodes = hasBlocks ? blockList : legacyNodes
388
+
389
+ // Find trigger block (usually 'starter' type)
390
+ const triggerBlock = blockList.find(b => b.type === 'starter' || b.type === 'webhook' || b.type === 'api')
391
+ const triggerType = triggerBlock?.type || workflow.trigger?.type
392
+
393
+ // Count AI and HTTP blocks
394
+ const aiBlocks = blockList.filter(b => b.type === 'agent' || b.type === 'llm' || b.type === 'openai' || b.type === 'anthropic')
395
+ const httpBlocks = blockList.filter(b => b.type === 'api' || b.type === 'http_request')
396
+
397
+ // Check if workflow is empty
398
+ const isEmpty = displayNodes.length === 0
399
+
400
+ if (isEmpty) {
401
+ return (
402
+ <div className="py-8 text-center">
403
+ <TreeStructure size={32} className="mx-auto mb-3 text-muted-foreground/50" />
404
+ <p className="text-sm text-muted-foreground mb-1">No workflow blocks yet</p>
405
+ <p className="text-xs text-muted-foreground">
406
+ Open the workflow in Sim Studio to build it, then click &quot;Pull from Sim&quot; to sync changes.
407
+ </p>
408
+ </div>
409
+ )
410
+ }
357
411
 
358
412
  return (
359
413
  <div className="space-y-4">
@@ -364,55 +418,77 @@ function SimWorkflowSummary({ workflow }: { workflow: SimWorkflow }) {
364
418
  <span className="text-xs font-medium">Trigger</span>
365
419
  </div>
366
420
  <p className="text-sm font-semibold">
367
- {workflow.trigger?.type ? getSimNodeTypeLabel(workflow.trigger.type) : 'Manual'}
421
+ {triggerType ? getSimNodeTypeLabel(triggerType) : 'Manual'}
368
422
  </p>
369
423
  </div>
370
-
424
+
371
425
  <div className="bg-muted/50 rounded-lg p-3">
372
426
  <div className="flex items-center gap-2 text-muted-foreground mb-1">
373
427
  <TreeStructure size={16} />
374
- <span className="text-xs font-medium">Steps</span>
428
+ <span className="text-xs font-medium">Blocks</span>
375
429
  </div>
376
- <p className="text-sm font-semibold">{nodes.length} nodes</p>
430
+ <p className="text-sm font-semibold">{displayNodes.length} blocks</p>
377
431
  </div>
378
-
379
- {aiNodes.length > 0 && (
432
+
433
+ {edges.length > 0 && (
434
+ <div className="bg-muted/50 rounded-lg p-3">
435
+ <div className="flex items-center gap-2 text-muted-foreground mb-1">
436
+ <GitBranch size={16} />
437
+ <span className="text-xs font-medium">Edges</span>
438
+ </div>
439
+ <p className="text-sm font-semibold">{edges.length} connections</p>
440
+ </div>
441
+ )}
442
+
443
+ {aiBlocks.length > 0 && (
380
444
  <div className="bg-purple-50 rounded-lg p-3">
381
445
  <div className="flex items-center gap-2 text-purple-600 mb-1">
382
446
  <Robot size={16} weight="fill" />
383
447
  <span className="text-xs font-medium">AI</span>
384
448
  </div>
385
449
  <p className="text-sm font-semibold text-purple-700">
386
- {aiNodes.length} LLM {aiNodes.length === 1 ? 'node' : 'nodes'}
450
+ {aiBlocks.length} {aiBlocks.length === 1 ? 'block' : 'blocks'}
387
451
  </p>
388
452
  </div>
389
453
  )}
390
-
391
- {httpNodes.length > 0 && (
454
+
455
+ {httpBlocks.length > 0 && (
392
456
  <div className="bg-blue-50 rounded-lg p-3">
393
457
  <div className="flex items-center gap-2 text-blue-600 mb-1">
394
458
  <Globe size={16} weight="fill" />
395
459
  <span className="text-xs font-medium">APIs</span>
396
460
  </div>
397
461
  <p className="text-sm font-semibold text-blue-700">
398
- {httpNodes.length} {httpNodes.length === 1 ? 'request' : 'requests'}
462
+ {httpBlocks.length} {httpBlocks.length === 1 ? 'request' : 'requests'}
399
463
  </p>
400
464
  </div>
401
465
  )}
402
466
  </div>
403
-
467
+
404
468
  <div className="space-y-2">
405
- <h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Workflow Nodes</h4>
469
+ <h4 className="text-xs font-medium text-muted-foreground uppercase tracking-wide">Workflow Blocks</h4>
406
470
  <div className="flex flex-wrap gap-2">
407
- {nodes.map((node) => (
408
- <div
409
- key={node.id}
410
- className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md border text-xs bg-gray-100 text-gray-700 border-gray-300"
411
- >
412
- <Package size={14} />
413
- <span className="font-medium">{getSimNodeTypeLabel(node.type)}</span>
414
- </div>
415
- ))}
471
+ {hasBlocks ? (
472
+ blockList.map((block) => (
473
+ <div
474
+ key={block.id}
475
+ className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md border text-xs bg-gray-100 text-gray-700 border-gray-300"
476
+ >
477
+ <Package size={14} />
478
+ <span className="font-medium">{block.name || getSimNodeTypeLabel(block.type)}</span>
479
+ </div>
480
+ ))
481
+ ) : (
482
+ legacyNodes.map((node) => (
483
+ <div
484
+ key={node.id}
485
+ className="flex items-center gap-1.5 px-2.5 py-1.5 rounded-md border text-xs bg-gray-100 text-gray-700 border-gray-300"
486
+ >
487
+ <Package size={14} />
488
+ <span className="font-medium">{getSimNodeTypeLabel(node.type)}</span>
489
+ </div>
490
+ ))
491
+ )}
416
492
  </div>
417
493
  </div>
418
494
  </div>