@open-mercato/core 0.6.6-develop.6094.1.28b081ea16 → 0.6.6-develop.6121.1.5797a901b3

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.
Files changed (317) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/dist/generated/entities/catalog_product/index.js +52 -0
  3. package/dist/generated/entities/catalog_product/index.js.map +2 -2
  4. package/dist/generated/entities/catalog_product_variant/index.js +4 -0
  5. package/dist/generated/entities/catalog_product_variant/index.js.map +2 -2
  6. package/dist/generated/entity-fields-registry.js +28 -0
  7. package/dist/generated/entity-fields-registry.js.map +2 -2
  8. package/dist/modules/catalog/api/products/route.js +103 -33
  9. package/dist/modules/catalog/api/products/route.js.map +2 -2
  10. package/dist/modules/catalog/api/variants/route.js +4 -0
  11. package/dist/modules/catalog/api/variants/route.js.map +2 -2
  12. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +46 -2
  13. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  14. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +4 -0
  15. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  16. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js +2 -0
  17. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/create/page.js.map +2 -2
  18. package/dist/modules/catalog/backend/catalog/products/create/page.js +42 -2
  19. package/dist/modules/catalog/backend/catalog/products/create/page.js.map +2 -2
  20. package/dist/modules/catalog/commands/products.js +251 -14
  21. package/dist/modules/catalog/commands/products.js.map +2 -2
  22. package/dist/modules/catalog/commands/variants.js +72 -1
  23. package/dist/modules/catalog/commands/variants.js.map +2 -2
  24. package/dist/modules/catalog/components/products/ProductComplianceSection.js +500 -0
  25. package/dist/modules/catalog/components/products/ProductComplianceSection.js.map +7 -0
  26. package/dist/modules/catalog/components/products/VariantBuilder.js +39 -1
  27. package/dist/modules/catalog/components/products/VariantBuilder.js.map +2 -2
  28. package/dist/modules/catalog/components/products/productForm.js +164 -2
  29. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  30. package/dist/modules/catalog/components/products/variantForm.js +2 -0
  31. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  32. package/dist/modules/catalog/data/entities.js +93 -0
  33. package/dist/modules/catalog/data/entities.js.map +2 -2
  34. package/dist/modules/catalog/data/types.js +28 -0
  35. package/dist/modules/catalog/data/types.js.map +2 -2
  36. package/dist/modules/catalog/data/validators.js +100 -5
  37. package/dist/modules/catalog/data/validators.js.map +2 -2
  38. package/dist/modules/catalog/lib/gtin.js +61 -0
  39. package/dist/modules/catalog/lib/gtin.js.map +7 -0
  40. package/dist/modules/catalog/migrations/Migration20260611090000.js +17 -0
  41. package/dist/modules/catalog/migrations/Migration20260611090000.js.map +7 -0
  42. package/dist/modules/catalog/translations.js +1 -1
  43. package/dist/modules/catalog/translations.js.map +2 -2
  44. package/dist/modules/configs/api/cache/route.js +60 -10
  45. package/dist/modules/configs/api/cache/route.js.map +3 -3
  46. package/dist/modules/configs/components/CachePanel.js +52 -29
  47. package/dist/modules/configs/components/CachePanel.js.map +2 -2
  48. package/dist/modules/currencies/api/currencies/options/route.js +18 -4
  49. package/dist/modules/currencies/api/currencies/options/route.js.map +2 -2
  50. package/dist/modules/currencies/services/rateFetchingService.js +35 -18
  51. package/dist/modules/currencies/services/rateFetchingService.js.map +2 -2
  52. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +16 -16
  53. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  54. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +1 -1
  55. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  56. package/dist/modules/customers/backend/calendar/page.js +10 -0
  57. package/dist/modules/customers/backend/calendar/page.js.map +7 -0
  58. package/dist/modules/customers/backend/calendar/page.meta.js +25 -0
  59. package/dist/modules/customers/backend/calendar/page.meta.js.map +7 -0
  60. package/dist/modules/customers/cli.js +1 -0
  61. package/dist/modules/customers/cli.js.map +2 -2
  62. package/dist/modules/customers/components/calendar/AgendaList.js +182 -0
  63. package/dist/modules/customers/components/calendar/AgendaList.js.map +7 -0
  64. package/dist/modules/customers/components/calendar/CalendarEventEditor.js +331 -0
  65. package/dist/modules/customers/components/calendar/CalendarEventEditor.js.map +7 -0
  66. package/dist/modules/customers/components/calendar/CalendarFooter.js +48 -0
  67. package/dist/modules/customers/components/calendar/CalendarFooter.js.map +7 -0
  68. package/dist/modules/customers/components/calendar/CalendarHeader.js +36 -0
  69. package/dist/modules/customers/components/calendar/CalendarHeader.js.map +7 -0
  70. package/dist/modules/customers/components/calendar/CalendarScreen.js +516 -0
  71. package/dist/modules/customers/components/calendar/CalendarScreen.js.map +7 -0
  72. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js +163 -0
  73. package/dist/modules/customers/components/calendar/CalendarSettingsModal.js.map +7 -0
  74. package/dist/modules/customers/components/calendar/CalendarTabs.js +60 -0
  75. package/dist/modules/customers/components/calendar/CalendarTabs.js.map +7 -0
  76. package/dist/modules/customers/components/calendar/CalendarToolbar.js +262 -0
  77. package/dist/modules/customers/components/calendar/CalendarToolbar.js.map +7 -0
  78. package/dist/modules/customers/components/calendar/EventBlock.js +149 -0
  79. package/dist/modules/customers/components/calendar/EventBlock.js.map +7 -0
  80. package/dist/modules/customers/components/calendar/EventPeekPopover.js +72 -0
  81. package/dist/modules/customers/components/calendar/EventPeekPopover.js.map +7 -0
  82. package/dist/modules/customers/components/calendar/MonthGrid.js +214 -0
  83. package/dist/modules/customers/components/calendar/MonthGrid.js.map +7 -0
  84. package/dist/modules/customers/components/calendar/ShortcutsDialog.js +44 -0
  85. package/dist/modules/customers/components/calendar/ShortcutsDialog.js.map +7 -0
  86. package/dist/modules/customers/components/calendar/TimeGrid.js +410 -0
  87. package/dist/modules/customers/components/calendar/TimeGrid.js.map +7 -0
  88. package/dist/modules/customers/components/calendar/UpcomingCards.js +175 -0
  89. package/dist/modules/customers/components/calendar/UpcomingCards.js.map +7 -0
  90. package/dist/modules/customers/components/calendar/editor/CategoryField.js +75 -0
  91. package/dist/modules/customers/components/calendar/editor/CategoryField.js.map +7 -0
  92. package/dist/modules/customers/components/calendar/editor/LocationField.js +30 -0
  93. package/dist/modules/customers/components/calendar/editor/LocationField.js.map +7 -0
  94. package/dist/modules/customers/components/calendar/editor/PeopleField.js +135 -0
  95. package/dist/modules/customers/components/calendar/editor/PeopleField.js.map +7 -0
  96. package/dist/modules/customers/components/calendar/editor/RelatedToField.js +218 -0
  97. package/dist/modules/customers/components/calendar/editor/RelatedToField.js.map +7 -0
  98. package/dist/modules/customers/components/calendar/editor/RepeatField.js +119 -0
  99. package/dist/modules/customers/components/calendar/editor/RepeatField.js.map +7 -0
  100. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js +83 -0
  101. package/dist/modules/customers/components/calendar/editor/ScheduleSection.js.map +7 -0
  102. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js +44 -0
  103. package/dist/modules/customers/components/calendar/editor/SegmentGroup.js.map +7 -0
  104. package/dist/modules/customers/components/calendar/editor/hooks.js +132 -0
  105. package/dist/modules/customers/components/calendar/editor/hooks.js.map +7 -0
  106. package/dist/modules/customers/components/calendar/editor/inputs.js +160 -0
  107. package/dist/modules/customers/components/calendar/editor/inputs.js.map +7 -0
  108. package/dist/modules/customers/components/calendar/editor/lookups.js +107 -0
  109. package/dist/modules/customers/components/calendar/editor/lookups.js.map +7 -0
  110. package/dist/modules/customers/components/calendar/types.js +30 -0
  111. package/dist/modules/customers/components/calendar/types.js.map +7 -0
  112. package/dist/modules/customers/components/calendar/useCalendarItems.js +131 -0
  113. package/dist/modules/customers/components/calendar/useCalendarItems.js.map +7 -0
  114. package/dist/modules/customers/components/calendar/useCalendarPreferences.js +41 -0
  115. package/dist/modules/customers/components/calendar/useCalendarPreferences.js.map +7 -0
  116. package/dist/modules/customers/lib/calendar/categories.js +28 -0
  117. package/dist/modules/customers/lib/calendar/categories.js.map +7 -0
  118. package/dist/modules/customers/lib/calendar/conflicts.js +72 -0
  119. package/dist/modules/customers/lib/calendar/conflicts.js.map +7 -0
  120. package/dist/modules/customers/lib/calendar/editorPayload.js +271 -0
  121. package/dist/modules/customers/lib/calendar/editorPayload.js.map +7 -0
  122. package/dist/modules/customers/lib/calendar/grid.js +48 -0
  123. package/dist/modules/customers/lib/calendar/grid.js.map +7 -0
  124. package/dist/modules/customers/lib/calendar/layout.js +39 -0
  125. package/dist/modules/customers/lib/calendar/layout.js.map +7 -0
  126. package/dist/modules/customers/lib/calendar/mapItem.js +79 -0
  127. package/dist/modules/customers/lib/calendar/mapItem.js.map +7 -0
  128. package/dist/modules/customers/lib/calendar/preferences.js +71 -0
  129. package/dist/modules/customers/lib/calendar/preferences.js.map +7 -0
  130. package/dist/modules/customers/lib/calendar/range.js +46 -0
  131. package/dist/modules/customers/lib/calendar/range.js.map +7 -0
  132. package/dist/modules/customers/lib/calendar/recurrence.js +113 -0
  133. package/dist/modules/customers/lib/calendar/recurrence.js.map +7 -0
  134. package/dist/modules/dashboards/services/widgetDataService.js +5 -5
  135. package/dist/modules/dashboards/services/widgetDataService.js.map +2 -2
  136. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +61 -1
  137. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  138. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js +33 -1
  139. package/dist/modules/dictionaries/api/[dictionaryId]/entries/route.js.map +2 -2
  140. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +61 -1
  141. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  142. package/dist/modules/dictionaries/api/route.js +33 -1
  143. package/dist/modules/dictionaries/api/route.js.map +2 -2
  144. package/dist/modules/feature_toggles/lib/queries.js +36 -52
  145. package/dist/modules/feature_toggles/lib/queries.js.map +2 -2
  146. package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js +32 -1
  147. package/dist/modules/perspectives/api/[tableId]/[perspectiveId]/route.js.map +2 -2
  148. package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js +32 -1
  149. package/dist/modules/perspectives/api/[tableId]/roles/[roleId]/route.js.map +2 -2
  150. package/dist/modules/perspectives/api/[tableId]/route.js +73 -2
  151. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  152. package/dist/modules/perspectives/services/perspectiveService.js +5 -3
  153. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  154. package/dist/modules/planner/api/access.js +9 -0
  155. package/dist/modules/planner/api/access.js.map +2 -2
  156. package/dist/modules/planner/api/availability-date-specific.js +22 -1
  157. package/dist/modules/planner/api/availability-date-specific.js.map +2 -2
  158. package/dist/modules/planner/api/availability-weekly.js +22 -1
  159. package/dist/modules/planner/api/availability-weekly.js.map +2 -2
  160. package/dist/modules/resources/api/resources/tags/assign/route.js +39 -0
  161. package/dist/modules/resources/api/resources/tags/assign/route.js.map +2 -2
  162. package/dist/modules/resources/api/resources/tags/unassign/route.js +39 -0
  163. package/dist/modules/resources/api/resources/tags/unassign/route.js.map +2 -2
  164. package/dist/modules/sales/api/settings/document-numbers/route.js +33 -1
  165. package/dist/modules/sales/api/settings/document-numbers/route.js.map +2 -2
  166. package/dist/modules/sales/api/settings/order-editing/route.js +35 -3
  167. package/dist/modules/sales/api/settings/order-editing/route.js.map +2 -2
  168. package/dist/modules/staff/api/leave-requests/accept/route.js +41 -0
  169. package/dist/modules/staff/api/leave-requests/accept/route.js.map +2 -2
  170. package/dist/modules/staff/api/leave-requests/reject/route.js +41 -0
  171. package/dist/modules/staff/api/leave-requests/reject/route.js.map +2 -2
  172. package/dist/modules/staff/api/team-members/self/route.js +40 -0
  173. package/dist/modules/staff/api/team-members/self/route.js.map +2 -2
  174. package/dist/modules/staff/api/team-members/tags/assign/route.js +41 -0
  175. package/dist/modules/staff/api/team-members/tags/assign/route.js.map +2 -2
  176. package/dist/modules/staff/api/team-members/tags/unassign/route.js +41 -0
  177. package/dist/modules/staff/api/team-members/tags/unassign/route.js.map +2 -2
  178. package/dist/modules/translations/api/[entityType]/[entityId]/route.js +61 -1
  179. package/dist/modules/translations/api/[entityType]/[entityId]/route.js.map +2 -2
  180. package/dist/modules/translations/api/context.js +7 -0
  181. package/dist/modules/translations/api/context.js.map +2 -2
  182. package/dist/modules/translations/api/put/locales.js +33 -1
  183. package/dist/modules/translations/api/put/locales.js.map +2 -2
  184. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +6 -7
  185. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  186. package/dist/modules/workflows/backend/instances/[id]/page.js.map +1 -1
  187. package/dist/modules/workflows/components/EdgeEditDialog.js.map +1 -1
  188. package/dist/modules/workflows/components/EdgeEditDialogCrudForm.js.map +1 -1
  189. package/dist/modules/workflows/components/NodeEditDialog.js.map +1 -1
  190. package/dist/modules/workflows/components/NodeEditDialogCrudForm.js.map +1 -1
  191. package/dist/modules/workflows/components/WorkflowGraph.js.map +1 -1
  192. package/dist/modules/workflows/components/WorkflowGraphImpl.js +17 -9
  193. package/dist/modules/workflows/components/WorkflowGraphImpl.js.map +2 -2
  194. package/dist/modules/workflows/components/mobile/MobileVisualEditor.js.map +1 -1
  195. package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js +8 -0
  196. package/dist/modules/workflows/frontend/checkout-demo/deriveCurrentStep.js.map +7 -0
  197. package/dist/modules/workflows/frontend/checkout-demo/page.js +2 -20
  198. package/dist/modules/workflows/frontend/checkout-demo/page.js.map +2 -2
  199. package/dist/modules/workflows/lib/graph-utils.js +8 -0
  200. package/dist/modules/workflows/lib/graph-utils.js.map +2 -2
  201. package/generated/entities/catalog_product/index.ts +26 -0
  202. package/generated/entities/catalog_product_variant/index.ts +2 -0
  203. package/generated/entity-fields-registry.ts +28 -0
  204. package/package.json +7 -7
  205. package/src/modules/catalog/api/products/route.ts +123 -39
  206. package/src/modules/catalog/api/variants/route.ts +4 -0
  207. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +43 -0
  208. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +14 -0
  209. package/src/modules/catalog/backend/catalog/products/[productId]/variants/create/page.tsx +2 -0
  210. package/src/modules/catalog/backend/catalog/products/create/page.tsx +41 -0
  211. package/src/modules/catalog/commands/products.ts +307 -2
  212. package/src/modules/catalog/commands/variants.ts +90 -1
  213. package/src/modules/catalog/components/products/ProductComplianceSection.tsx +497 -0
  214. package/src/modules/catalog/components/products/VariantBuilder.tsx +43 -0
  215. package/src/modules/catalog/components/products/productForm.ts +262 -0
  216. package/src/modules/catalog/components/products/variantForm.ts +4 -0
  217. package/src/modules/catalog/data/entities.ts +97 -0
  218. package/src/modules/catalog/data/types.ts +36 -0
  219. package/src/modules/catalog/data/validators.ts +159 -3
  220. package/src/modules/catalog/i18n/de.json +64 -0
  221. package/src/modules/catalog/i18n/en.json +64 -0
  222. package/src/modules/catalog/i18n/es.json +64 -0
  223. package/src/modules/catalog/i18n/pl.json +64 -0
  224. package/src/modules/catalog/lib/gtin.ts +66 -0
  225. package/src/modules/catalog/migrations/.snapshot-open-mercato.json +457 -0
  226. package/src/modules/catalog/migrations/Migration20260611090000.ts +17 -0
  227. package/src/modules/catalog/translations.ts +1 -1
  228. package/src/modules/configs/api/cache/route.ts +72 -10
  229. package/src/modules/configs/components/CachePanel.tsx +59 -29
  230. package/src/modules/currencies/api/currencies/options/route.ts +22 -4
  231. package/src/modules/currencies/services/rateFetchingService.ts +63 -26
  232. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +18 -18
  233. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +1 -1
  234. package/src/modules/customer_accounts/i18n/de.json +1 -1
  235. package/src/modules/customer_accounts/i18n/en.json +1 -1
  236. package/src/modules/customer_accounts/i18n/es.json +1 -1
  237. package/src/modules/customer_accounts/i18n/pl.json +1 -1
  238. package/src/modules/customers/backend/calendar/page.meta.ts +23 -0
  239. package/src/modules/customers/backend/calendar/page.tsx +12 -0
  240. package/src/modules/customers/cli.ts +1 -0
  241. package/src/modules/customers/components/calendar/AgendaList.tsx +219 -0
  242. package/src/modules/customers/components/calendar/CalendarEventEditor.tsx +386 -0
  243. package/src/modules/customers/components/calendar/CalendarFooter.tsx +61 -0
  244. package/src/modules/customers/components/calendar/CalendarHeader.tsx +40 -0
  245. package/src/modules/customers/components/calendar/CalendarScreen.tsx +590 -0
  246. package/src/modules/customers/components/calendar/CalendarSettingsModal.tsx +207 -0
  247. package/src/modules/customers/components/calendar/CalendarTabs.tsx +63 -0
  248. package/src/modules/customers/components/calendar/CalendarToolbar.tsx +295 -0
  249. package/src/modules/customers/components/calendar/EventBlock.tsx +205 -0
  250. package/src/modules/customers/components/calendar/EventPeekPopover.tsx +100 -0
  251. package/src/modules/customers/components/calendar/MonthGrid.tsx +236 -0
  252. package/src/modules/customers/components/calendar/ShortcutsDialog.tsx +57 -0
  253. package/src/modules/customers/components/calendar/TimeGrid.tsx +510 -0
  254. package/src/modules/customers/components/calendar/UpcomingCards.tsx +220 -0
  255. package/src/modules/customers/components/calendar/editor/CategoryField.tsx +79 -0
  256. package/src/modules/customers/components/calendar/editor/LocationField.tsx +37 -0
  257. package/src/modules/customers/components/calendar/editor/PeopleField.tsx +148 -0
  258. package/src/modules/customers/components/calendar/editor/RelatedToField.tsx +242 -0
  259. package/src/modules/customers/components/calendar/editor/RepeatField.tsx +132 -0
  260. package/src/modules/customers/components/calendar/editor/ScheduleSection.tsx +110 -0
  261. package/src/modules/customers/components/calendar/editor/SegmentGroup.tsx +50 -0
  262. package/src/modules/customers/components/calendar/editor/hooks.ts +162 -0
  263. package/src/modules/customers/components/calendar/editor/inputs.tsx +158 -0
  264. package/src/modules/customers/components/calendar/editor/lookups.ts +160 -0
  265. package/src/modules/customers/components/calendar/types.ts +163 -0
  266. package/src/modules/customers/components/calendar/useCalendarItems.ts +162 -0
  267. package/src/modules/customers/components/calendar/useCalendarPreferences.ts +52 -0
  268. package/src/modules/customers/i18n/de.json +195 -0
  269. package/src/modules/customers/i18n/en.json +195 -0
  270. package/src/modules/customers/i18n/es.json +195 -0
  271. package/src/modules/customers/i18n/pl.json +195 -0
  272. package/src/modules/customers/lib/calendar/categories.ts +26 -0
  273. package/src/modules/customers/lib/calendar/conflicts.ts +117 -0
  274. package/src/modules/customers/lib/calendar/editorPayload.ts +388 -0
  275. package/src/modules/customers/lib/calendar/grid.ts +50 -0
  276. package/src/modules/customers/lib/calendar/layout.ts +47 -0
  277. package/src/modules/customers/lib/calendar/mapItem.ts +94 -0
  278. package/src/modules/customers/lib/calendar/preferences.ts +95 -0
  279. package/src/modules/customers/lib/calendar/range.ts +45 -0
  280. package/src/modules/customers/lib/calendar/recurrence.ts +137 -0
  281. package/src/modules/dashboards/services/widgetDataService.ts +8 -6
  282. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +61 -1
  283. package/src/modules/dictionaries/api/[dictionaryId]/entries/route.ts +33 -1
  284. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +65 -1
  285. package/src/modules/dictionaries/api/route.ts +36 -1
  286. package/src/modules/feature_toggles/lib/queries.ts +41 -60
  287. package/src/modules/perspectives/api/[tableId]/[perspectiveId]/route.ts +34 -1
  288. package/src/modules/perspectives/api/[tableId]/roles/[roleId]/route.ts +34 -1
  289. package/src/modules/perspectives/api/[tableId]/route.ts +107 -32
  290. package/src/modules/perspectives/services/perspectiveService.ts +9 -5
  291. package/src/modules/planner/api/access.ts +9 -0
  292. package/src/modules/planner/api/availability-date-specific.ts +22 -1
  293. package/src/modules/planner/api/availability-weekly.ts +22 -1
  294. package/src/modules/resources/api/resources/tags/assign/route.ts +42 -0
  295. package/src/modules/resources/api/resources/tags/unassign/route.ts +42 -0
  296. package/src/modules/sales/api/settings/document-numbers/route.ts +35 -1
  297. package/src/modules/sales/api/settings/order-editing/route.ts +37 -3
  298. package/src/modules/staff/api/leave-requests/accept/route.ts +45 -0
  299. package/src/modules/staff/api/leave-requests/reject/route.ts +45 -0
  300. package/src/modules/staff/api/team-members/self/route.ts +43 -0
  301. package/src/modules/staff/api/team-members/tags/assign/route.ts +45 -0
  302. package/src/modules/staff/api/team-members/tags/unassign/route.ts +45 -0
  303. package/src/modules/translations/api/[entityType]/[entityId]/route.ts +65 -1
  304. package/src/modules/translations/api/context.ts +7 -0
  305. package/src/modules/translations/api/put/locales.ts +35 -1
  306. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +11 -9
  307. package/src/modules/workflows/backend/instances/[id]/page.tsx +1 -1
  308. package/src/modules/workflows/components/EdgeEditDialog.tsx +1 -1
  309. package/src/modules/workflows/components/EdgeEditDialogCrudForm.tsx +1 -1
  310. package/src/modules/workflows/components/NodeEditDialog.tsx +1 -1
  311. package/src/modules/workflows/components/NodeEditDialogCrudForm.tsx +1 -1
  312. package/src/modules/workflows/components/WorkflowGraph.tsx +2 -2
  313. package/src/modules/workflows/components/WorkflowGraphImpl.tsx +27 -13
  314. package/src/modules/workflows/components/mobile/MobileVisualEditor.tsx +3 -3
  315. package/src/modules/workflows/frontend/checkout-demo/deriveCurrentStep.ts +12 -0
  316. package/src/modules/workflows/frontend/checkout-demo/page.tsx +3 -23
  317. package/src/modules/workflows/lib/graph-utils.ts +21 -1
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/workflows/backend/instances/%5Bid%5D/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport Link from 'next/link'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { WorkflowInstance, WorkflowEvent, WorkflowDefinition } from '../../../data/entities'\nimport { WorkflowGraphReadOnly } from '../../../components/WorkflowGraph'\nimport { WorkflowLegend } from '../../../components/WorkflowLegend'\nimport { MobileInstanceOverview } from '../../../components/mobile/MobileInstanceOverview'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport { definitionToGraph } from '../../../lib/graph-utils'\nimport { Node } from '@xyflow/react'\nimport { RecordNotFoundState, ErrorMessage } from '@open-mercato/ui/backend/detail'\n\nexport default function WorkflowInstanceDetailPage({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const isMobile = useIsMobile()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n\n const { data: instance, isLoading, error } = useQuery({\n queryKey: ['workflow-instance', id],\n queryFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${id}`)\n if (!response.ok) {\n const httpErr = new Error(\n response.status === 404\n ? t('workflows.instances.detail.notFound', 'Workflow instance not found.')\n : t('workflows.instances.loadFailed', 'Failed to load workflow instance.')\n ) as Error & { status: number }\n httpErr.status = response.status\n throw httpErr\n }\n const data = await response.json()\n return data.data as WorkflowInstance\n },\n enabled: !!id,\n })\n\n const { data: events = [], isLoading: eventsLoading } = useQuery({\n queryKey: ['workflow-events', instance?.id],\n queryFn: async () => {\n const response = await apiFetch(\n `/api/workflows/events?workflowInstanceId=${instance!.id}&sortField=occurredAt&sortDir=desc&pageSize=100`\n )\n if (!response.ok) {\n throw new Error('Failed to fetch events')\n }\n const data = await response.json()\n return (data.items || []) as WorkflowEvent[]\n },\n enabled: !!instance?.id,\n })\n\n const { data: workflowDefinition, isLoading: definitionLoading } = useQuery({\n queryKey: ['workflow-definition-for-instance', instance?.definitionId],\n queryFn: async () => {\n // Fetch definition by ID\n const response = await apiFetch(`/api/workflows/definitions/${instance!.definitionId}`)\n if (!response.ok) {\n console.error('Failed to fetch workflow definition:', response.statusText)\n return null\n }\n const result = await response.json()\n return result.data as WorkflowDefinition\n },\n enabled: !!instance?.definitionId,\n })\n\n const calculateDuration = (startedAt: string | Date, completedAt: string | Date | null | undefined) => {\n const start = typeof startedAt === 'string' ? new Date(startedAt).getTime() : startedAt.getTime()\n const end = completedAt ? (typeof completedAt === 'string' ? new Date(completedAt).getTime() : completedAt.getTime()) : Date.now()\n const duration = end - start\n\n if (duration < 1000) {\n return `${duration}ms`\n } else if (duration < 60000) {\n return `${Math.floor(duration / 1000)}s`\n } else if (duration < 3600000) {\n return `${Math.floor(duration / 60000)}m ${Math.floor((duration % 60000) / 1000)}s`\n } else {\n const hours = Math.floor(duration / 3600000)\n const minutes = Math.floor((duration % 3600000) / 60000)\n return `${hours}h ${minutes}m`\n }\n }\n\n const getStatusBadgeClass = (status: WorkflowInstance['status']) => {\n switch (status) {\n case 'RUNNING':\n return 'bg-blue-100 text-blue-800'\n case 'PAUSED':\n return 'bg-yellow-100 text-yellow-800'\n case 'WAITING_FOR_ACTIVITIES':\n return 'bg-cyan-100 text-cyan-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'FAILED':\n return 'bg-red-100 text-red-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n case 'COMPENSATING':\n return 'bg-orange-100 text-orange-800'\n case 'COMPENSATED':\n return 'bg-purple-100 text-purple-800'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const getEventTypeBadgeClass = (eventType: string) => {\n if (eventType.includes('COMPENSATION') || eventType.includes('Compensation')) {\n return 'bg-orange-100 text-orange-800'\n } else if (eventType.includes('STARTED') || eventType.includes('ENTERED')) {\n return 'bg-blue-100 text-blue-800'\n } else if (eventType.includes('COMPLETED') || eventType.includes('EXITED')) {\n return 'bg-green-100 text-green-800'\n } else if (eventType.includes('FAILED') || eventType.includes('REJECTED')) {\n return 'bg-red-100 text-red-800'\n } else if (eventType.includes('CANCELLED')) {\n return 'bg-muted text-foreground'\n } else if (eventType.includes('PAUSED')) {\n return 'bg-yellow-100 text-yellow-800'\n } else {\n return 'bg-muted text-foreground'\n }\n }\n\n const cancelMutation = useMutation({\n mutationFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${instance!.id}/cancel`, {\n method: 'POST',\n })\n if (!response.ok) {\n throw new Error(t('workflows.instances.cancelFailed'))\n }\n return response.json()\n },\n onSuccess: () => {\n flash(t('workflows.instances.messages.cancelled'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instance', id] })\n },\n onError: (error) => {\n console.error('Error cancelling instance:', error)\n flash(t('workflows.instances.cancelFailed'), 'error')\n },\n })\n\n const retryMutation = useMutation({\n mutationFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${instance!.id}/retry`, {\n method: 'POST',\n })\n if (!response.ok) {\n throw new Error(t('workflows.instances.retryFailed'))\n }\n return response.json()\n },\n onSuccess: () => {\n flash(t('workflows.instances.messages.retried'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instance', id] })\n },\n onError: (error) => {\n console.error('Error retrying instance:', error)\n flash(t('workflows.instances.retryFailed'), 'error')\n },\n })\n\n const handleCancel = async () => {\n if (!instance) return\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirmCancel'),\n variant: 'destructive',\n })\n if (!confirmed) {\n return\n }\n cancelMutation.mutate()\n }\n\n const handleRetry = async () => {\n if (!instance) return\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirmRetry'),\n variant: 'default',\n })\n if (!confirmed) {\n return\n }\n retryMutation.mutate()\n }\n\n // Generate graph with execution status\n const { graphNodes, graphEdges } = React.useMemo(() => {\n if (!workflowDefinition?.definition) {\n return { graphNodes: [], graphEdges: [] }\n }\n\n // Convert definition to graph\n const { nodes, edges } = definitionToGraph(workflowDefinition.definition, { autoLayout: true })\n\n // Determine step statuses from events\n const stepStatuses = new Map<string, 'completed' | 'active' | 'pending' | 'failed' | 'skipped'>()\n const stepTimings = new Map<string, { startedAt?: Date; completedAt?: Date }>()\n\n // Process events to determine status\n for (const event of events) {\n const stepId = event.eventData?.stepId || event.eventData?.toStepId\n if (!stepId) continue\n\n if (event.eventType === 'STEP_ENTERED' || event.eventType === 'StepEntered') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), startedAt: new Date(event.occurredAt) })\n if (!stepStatuses.has(stepId)) {\n stepStatuses.set(stepId, 'active')\n }\n } else if (event.eventType === 'STEP_COMPLETED' || event.eventType === 'STEP_EXITED' || event.eventType === 'StepExited') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), completedAt: new Date(event.occurredAt) })\n stepStatuses.set(stepId, 'completed')\n } else if (event.eventType === 'STEP_FAILED' || event.eventType === 'StepFailed') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), completedAt: new Date(event.occurredAt) })\n stepStatuses.set(stepId, 'failed')\n }\n }\n\n // Mark current step as active\n if (instance?.currentStepId && !stepStatuses.has(instance.currentStepId)) {\n stepStatuses.set(instance.currentStepId, 'active')\n } else if (instance?.currentStepId && stepStatuses.get(instance.currentStepId) !== 'completed') {\n stepStatuses.set(instance.currentStepId, 'active')\n }\n\n // Mark all other steps as pending, with special handling for START/END\n for (const node of nodes) {\n if (!stepStatuses.has(node.id)) {\n const nodeType = node.type\n const isCurrentStep = instance?.currentStepId === node.id\n\n if (nodeType === 'start') {\n // START node is completed if we've moved past it\n // It's active if we're still at start (edge case)\n if (isCurrentStep) {\n stepStatuses.set(node.id, 'active')\n } else {\n stepStatuses.set(node.id, 'completed')\n }\n } else if (nodeType === 'end') {\n // END node is completed if we've reached it\n // Or if workflow is in COMPLETED status\n if (isCurrentStep || instance?.status === 'COMPLETED') {\n stepStatuses.set(node.id, 'completed')\n } else {\n stepStatuses.set(node.id, 'pending')\n }\n } else {\n // All other nodes without events are pending\n stepStatuses.set(node.id, 'pending')\n }\n }\n }\n\n // Apply styles to nodes based on status\n const styledNodes: Node[] = nodes.map((node) => {\n const status = stepStatuses.get(node.id) || 'pending'\n const timing = stepTimings.get(node.id)\n\n // Calculate duration for tooltip\n const duration = timing?.startedAt && timing?.completedAt\n ? calculateDuration(timing.startedAt, timing.completedAt)\n : timing?.startedAt\n ? calculateDuration(timing.startedAt, null)\n : null\n\n // Build tooltip content\n let tooltipContent = `${node.data.label || node.id}\\n`\n tooltipContent += `Status: ${status}\\n`\n if (timing?.startedAt) {\n tooltipContent += `Started: ${timing.startedAt.toLocaleString()}\\n`\n }\n if (timing?.completedAt) {\n tooltipContent += `Completed: ${timing.completedAt.toLocaleString()}\\n`\n }\n if (duration) {\n tooltipContent += `Duration: ${duration}`\n }\n\n // Define colors and styles based on status\n let style: React.CSSProperties = {}\n switch (status) {\n case 'completed':\n style = {\n backgroundColor: '#10B981', // green-500\n color: 'white',\n borderColor: '#059669', // green-600\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'active':\n style = {\n backgroundColor: '#3B82F6', // blue-500\n color: 'white',\n borderColor: '#1D4ED8', // blue-700\n borderWidth: '3px',\n borderRadius: '16px',\n boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.3)',\n }\n break\n case 'failed':\n style = {\n backgroundColor: '#EF4444', // red-500\n color: 'white',\n borderColor: '#B91C1C', // red-700\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'skipped':\n style = {\n backgroundColor: '#FEF3C7', // yellow-100\n color: '#78350F', // yellow-900\n borderColor: '#F59E0B', // yellow-500\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'pending':\n default:\n style = {\n backgroundColor: '#E5E7EB', // gray-200\n color: '#374151', // gray-700\n borderColor: '#9CA3AF', // gray-400\n borderWidth: '2px',\n borderRadius: '8px',\n }\n break\n }\n\n return {\n ...node,\n data: {\n ...node.data,\n status,\n timing,\n duration,\n tooltip: tooltipContent,\n },\n style,\n }\n })\n\n return { graphNodes: styledNodes, graphEdges: edges }\n }, [workflowDefinition, events, instance?.currentStepId])\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('workflows.instances.detail.loading') || 'Loading workflow instance...'}</span>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n const isNotFound = !isLoading && (error as (Error & { status?: number }) | null)?.status === 404\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('workflows.instances.detail.notFound', 'Workflow instance not found.')}\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.actions.backToList', 'Back to instances')}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n if (error || !instance) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={(error as Error | null)?.message ?? t('workflows.instances.loadFailed', 'Failed to load workflow instance.')}\n action={\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/instances\">{t('workflows.instances.actions.backToList', 'Back to instances')}</Link>\n </Button>\n }\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n const canCancel = ['RUNNING', 'PAUSED'].includes(instance.status)\n const canRetry = instance.status === 'FAILED'\n const actionLoading = cancelMutation.isPending || retryMutation.isPending\n\n if (isMobile) {\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.backToList', 'Back to instances')}\n entityTypeLabel={t('workflows.instances.detail.type', 'Workflow instance')}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{instance.workflowId}</span>\n <span className=\"font-mono text-sm text-muted-foreground\">#{instance.id.slice(0, 8)}</span>\n </div>\n }\n menuActions={[\n ...(canCancel ? [{\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: handleCancel,\n disabled: actionLoading,\n }] : []),\n ...(canRetry ? [{\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: handleRetry,\n disabled: actionLoading,\n }] : []),\n ]}\n />\n <MobileInstanceOverview\n instance={instance}\n events={events}\n graphNodes={graphNodes}\n graphEdges={graphEdges}\n definitionLoading={definitionLoading}\n hasDefinition={!!workflowDefinition}\n getStatusBadgeClass={getStatusBadgeClass}\n getEventTypeBadgeClass={getEventTypeBadgeClass}\n calculateDuration={calculateDuration}\n />\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.backToList', 'Back to instances')}\n entityTypeLabel={t('workflows.instances.detail.type', 'Workflow instance')}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{instance.workflowId}</span>\n <span className=\"font-mono text-sm text-muted-foreground\">#{instance.id.slice(0, 8)}</span>\n </div>\n }\n menuActions={[\n ...(canCancel ? [{\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: handleCancel,\n disabled: actionLoading,\n }] : []),\n ...(canRetry ? [{\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: handleRetry,\n disabled: actionLoading,\n }] : []),\n ]}\n />\n\n {/* Execution Summary */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.overview')}\n </h2>\n <dl className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.workflowId')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n <div className=\"font-mono\">{instance.workflowId}</div>\n <div className=\"text-xs text-muted-foreground\">v{instance.version}</div>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.status')}\n </dt>\n <dd className=\"mt-1\">\n <span\n className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(\n instance.status\n )}`}\n >\n {t(`workflows.instances.status.${instance.status}`)}\n </span>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.currentStep')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground font-mono\">\n {instance.currentStepId || '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.correlationKey')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {instance.correlationKey || '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.startedAt')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {new Date(instance.startedAt).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.completedAt')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {instance.completedAt ? new Date(instance.completedAt).toLocaleString() : '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.duration')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {calculateDuration(instance.startedAt, instance.completedAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.retryCount')}\n </dt>\n <dd className=\"mt-1\">\n <span className={instance.retryCount > 0 ? 'text-orange-600 font-medium text-sm' : 'text-sm text-foreground'}>\n {instance.retryCount}\n </span>\n </dd>\n </div>\n </dl>\n </div>\n\n {/* Visual Workflow Graph */}\n {definitionLoading && (\n <div className=\"rounded-lg border bg-card p-6\">\n <div className=\"flex items-center justify-center py-8\">\n <Spinner className=\"h-6 w-6\" />\n <span className=\"ml-2 text-sm text-muted-foreground\">Loading workflow visualization...</span>\n </div>\n </div>\n )}\n {!definitionLoading && workflowDefinition && graphNodes.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4 md:p-6\">\n <h2 className=\"text-lg font-semibold text-foreground mb-4\">\n {t('workflows.instances.sections.visualFlow') || 'Visual Workflow Flow'}\n </h2>\n\n <div className=\"flex flex-col gap-4 lg:flex-row lg:gap-6\">\n {/* Left Sidebar - Legend */}\n <div className=\"order-2 lg:order-1 lg:w-64 lg:flex-shrink-0\">\n <WorkflowLegend />\n </div>\n\n {/* Main Visualization */}\n <div className=\"order-1 lg:order-2 flex-1 border rounded-lg overflow-hidden h-[62svh] min-h-[360px] lg:h-[800px]\">\n <WorkflowGraphReadOnly\n nodes={graphNodes}\n edges={graphEdges}\n height=\"100%\"\n />\n </div>\n </div>\n </div>\n )}\n {!definitionLoading && !workflowDefinition && instance && (\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.visualFlow') || 'Visual Workflow Flow'}\n </h2>\n <div className=\"flex items-center justify-center py-8 text-muted-foreground\">\n <p className=\"text-sm\">Workflow definition not found (ID: {instance.definitionId})</p>\n </div>\n </div>\n )}\n\n\n {/* Compensation Status */}\n {(instance.status === 'COMPENSATING' || instance.status === 'COMPENSATED') && (\n <div className=\"rounded-lg border border-orange-300 bg-orange-50 p-6\">\n <h2 className=\"text-lg font-semibold mb-4 text-orange-800\">\n {t('workflows.instances.sections.compensation') || 'Compensation (Saga Pattern)'}\n </h2>\n <div className=\"space-y-4\">\n <p className=\"text-sm text-orange-700\">\n {instance.status === 'COMPENSATING'\n ? (t('workflows.instances.compensation.inProgress') || 'Workflow is currently executing compensation activities to rollback changes.')\n : (t('workflows.instances.compensation.completed') || 'Compensation has been completed. All changes have been rolled back.')}\n </p>\n\n {/* Show compensation activities from events */}\n {events.filter(e =>\n e.eventType.includes('COMPENSATION') ||\n e.eventType.includes('Compensation')\n ).length > 0 && (\n <div className=\"mt-4\">\n <h3 className=\"text-sm font-medium text-orange-800 mb-2\">\n {t('workflows.instances.compensation.activities') || 'Compensation Activities'}\n </h3>\n <div className=\"space-y-2\">\n {events\n .filter(e => e.eventType.includes('COMPENSATION') || e.eventType.includes('Compensation'))\n .reverse()\n .map((event) => (\n <div key={event.id} className=\"flex items-start gap-2 p-2 bg-card rounded border border-orange-200\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {event.eventType}\n </span>\n <span className=\"text-xs text-orange-600\">\n {new Date(event.occurredAt).toLocaleTimeString()}\n </span>\n {event.eventData?.activityName && (\n <span className=\"text-xs text-orange-700 font-medium\">\n {event.eventData.activityName}\n </span>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Error Message (if present) */}\n {instance.errorMessage && (\n <div className=\"rounded-lg border border-destructive bg-destructive/5 p-6\">\n <h2 className=\"text-lg font-semibold mb-4 text-destructive\">\n {t('workflows.instances.fields.lastError')}\n </h2>\n <pre className=\"text-sm text-destructive whitespace-pre-wrap font-mono\">\n {instance.errorMessage}\n </pre>\n {instance.errorDetails && (\n <div className=\"mt-4\">\n <JsonDisplay\n data={instance.errorDetails}\n className=\"border-destructive/20 bg-destructive/5\"\n maxInitialDepth={1}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Context */}\n <JsonDisplay\n data={instance.context}\n title={t('workflows.instances.sections.context')}\n />\n\n {/* Metadata */}\n {instance.metadata && Object.keys(instance.metadata).length > 0 && (\n <JsonDisplay\n data={instance.metadata}\n title={t('workflows.instances.sections.metadata')}\n />\n )}\n\n {/* Execution Timeline */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.executionTimeline') || 'Execution Timeline'}\n </h2>\n {eventsLoading ? (\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n <span className=\"text-sm\">{t('common.loading')}</span>\n </div>\n ) : events.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.instances.noExecutionHistory')}\n </p>\n ) : (\n <div className=\"space-y-2\">\n {events\n .filter(\n (e) =>\n e.eventType.includes('STEP_') ||\n e.eventType.includes('WORKFLOW_STARTED') ||\n e.eventType.includes('WORKFLOW_COMPLETED') ||\n e.eventType.includes('WORKFLOW_FAILED')\n )\n .reverse()\n .map((event, idx) => (\n <div key={event.id} className=\"flex items-start gap-3 p-3 bg-muted rounded-lg border\">\n <div className=\"flex-shrink-0 w-8 h-8 rounded-full bg-background border-2 border-border flex items-center justify-center text-xs font-medium\">\n {idx + 1}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {t(`workflows.events.types.${event.eventType}`) || event.eventType}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {new Date(event.occurredAt).toLocaleTimeString()}\n </span>\n </div>\n {event.eventData && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {event.eventData.toStepId && `-> ${event.eventData.toStepId}`}\n {event.eventData.fromStepId && `${event.eventData.fromStepId} -> ${event.eventData.toStepId}`}\n </p>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Event Log */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.executionHistory')}\n </h2>\n {eventsLoading ? (\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n <span className=\"text-sm\">{t('common.loading')}</span>\n </div>\n ) : events.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.instances.noExecutionHistory')}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border\">\n <table className=\"min-w-full divide-y divide-border\">\n <thead className=\"bg-muted\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.occurredAt')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.eventType')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.eventData')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.userId')}\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-background divide-y divide-border\">\n {events.map((event) => (\n <tr key={event.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3 whitespace-nowrap text-sm text-foreground\">\n {new Date(event.occurredAt).toLocaleString()}\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span\n className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {t(`workflows.events.types.${event.eventType}`) || event.eventType}\n </span>\n </td>\n <td className=\"px-4 py-3 text-sm\">\n <details className=\"cursor-pointer\">\n <summary className=\"text-primary hover:underline\">\n {t('common.details')}\n </summary>\n <div className=\"mt-2\">\n <JsonDisplay\n data={event.eventData}\n showCopy={false}\n maxInitialDepth={1}\n />\n </div>\n </details>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap text-sm text-muted-foreground\">\n {event.userId || '-'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
4
+ "sourcesContent": ["'use client'\n\nimport * as React from 'react'\nimport { useQuery, useMutation, useQueryClient } from '@tanstack/react-query'\nimport Link from 'next/link'\nimport { Page, PageBody } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { Spinner } from '@open-mercato/ui/primitives/spinner'\nimport { JsonDisplay } from '@open-mercato/ui/backend/JsonDisplay'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { apiFetch } from '@open-mercato/ui/backend/utils/api'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport type { WorkflowInstance, WorkflowEvent, WorkflowDefinition } from '../../../data/entities'\nimport { WorkflowGraphReadOnly } from '../../../components/WorkflowGraph'\nimport { WorkflowLegend } from '../../../components/WorkflowLegend'\nimport { MobileInstanceOverview } from '../../../components/mobile/MobileInstanceOverview'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport { definitionToGraph } from '../../../lib/graph-utils'\nimport type { Node } from '@xyflow/react'\nimport { RecordNotFoundState, ErrorMessage } from '@open-mercato/ui/backend/detail'\n\nexport default function WorkflowInstanceDetailPage({ params }: { params?: { id?: string } }) {\n const id = params?.id\n const t = useT()\n const isMobile = useIsMobile()\n const queryClient = useQueryClient()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n\n const { data: instance, isLoading, error } = useQuery({\n queryKey: ['workflow-instance', id],\n queryFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${id}`)\n if (!response.ok) {\n const httpErr = new Error(\n response.status === 404\n ? t('workflows.instances.detail.notFound', 'Workflow instance not found.')\n : t('workflows.instances.loadFailed', 'Failed to load workflow instance.')\n ) as Error & { status: number }\n httpErr.status = response.status\n throw httpErr\n }\n const data = await response.json()\n return data.data as WorkflowInstance\n },\n enabled: !!id,\n })\n\n const { data: events = [], isLoading: eventsLoading } = useQuery({\n queryKey: ['workflow-events', instance?.id],\n queryFn: async () => {\n const response = await apiFetch(\n `/api/workflows/events?workflowInstanceId=${instance!.id}&sortField=occurredAt&sortDir=desc&pageSize=100`\n )\n if (!response.ok) {\n throw new Error('Failed to fetch events')\n }\n const data = await response.json()\n return (data.items || []) as WorkflowEvent[]\n },\n enabled: !!instance?.id,\n })\n\n const { data: workflowDefinition, isLoading: definitionLoading } = useQuery({\n queryKey: ['workflow-definition-for-instance', instance?.definitionId],\n queryFn: async () => {\n // Fetch definition by ID\n const response = await apiFetch(`/api/workflows/definitions/${instance!.definitionId}`)\n if (!response.ok) {\n console.error('Failed to fetch workflow definition:', response.statusText)\n return null\n }\n const result = await response.json()\n return result.data as WorkflowDefinition\n },\n enabled: !!instance?.definitionId,\n })\n\n const calculateDuration = (startedAt: string | Date, completedAt: string | Date | null | undefined) => {\n const start = typeof startedAt === 'string' ? new Date(startedAt).getTime() : startedAt.getTime()\n const end = completedAt ? (typeof completedAt === 'string' ? new Date(completedAt).getTime() : completedAt.getTime()) : Date.now()\n const duration = end - start\n\n if (duration < 1000) {\n return `${duration}ms`\n } else if (duration < 60000) {\n return `${Math.floor(duration / 1000)}s`\n } else if (duration < 3600000) {\n return `${Math.floor(duration / 60000)}m ${Math.floor((duration % 60000) / 1000)}s`\n } else {\n const hours = Math.floor(duration / 3600000)\n const minutes = Math.floor((duration % 3600000) / 60000)\n return `${hours}h ${minutes}m`\n }\n }\n\n const getStatusBadgeClass = (status: WorkflowInstance['status']) => {\n switch (status) {\n case 'RUNNING':\n return 'bg-blue-100 text-blue-800'\n case 'PAUSED':\n return 'bg-yellow-100 text-yellow-800'\n case 'WAITING_FOR_ACTIVITIES':\n return 'bg-cyan-100 text-cyan-800'\n case 'COMPLETED':\n return 'bg-green-100 text-green-800'\n case 'FAILED':\n return 'bg-red-100 text-red-800'\n case 'CANCELLED':\n return 'bg-muted text-foreground'\n case 'COMPENSATING':\n return 'bg-orange-100 text-orange-800'\n case 'COMPENSATED':\n return 'bg-purple-100 text-purple-800'\n default:\n return 'bg-muted text-muted-foreground'\n }\n }\n\n const getEventTypeBadgeClass = (eventType: string) => {\n if (eventType.includes('COMPENSATION') || eventType.includes('Compensation')) {\n return 'bg-orange-100 text-orange-800'\n } else if (eventType.includes('STARTED') || eventType.includes('ENTERED')) {\n return 'bg-blue-100 text-blue-800'\n } else if (eventType.includes('COMPLETED') || eventType.includes('EXITED')) {\n return 'bg-green-100 text-green-800'\n } else if (eventType.includes('FAILED') || eventType.includes('REJECTED')) {\n return 'bg-red-100 text-red-800'\n } else if (eventType.includes('CANCELLED')) {\n return 'bg-muted text-foreground'\n } else if (eventType.includes('PAUSED')) {\n return 'bg-yellow-100 text-yellow-800'\n } else {\n return 'bg-muted text-foreground'\n }\n }\n\n const cancelMutation = useMutation({\n mutationFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${instance!.id}/cancel`, {\n method: 'POST',\n })\n if (!response.ok) {\n throw new Error(t('workflows.instances.cancelFailed'))\n }\n return response.json()\n },\n onSuccess: () => {\n flash(t('workflows.instances.messages.cancelled'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instance', id] })\n },\n onError: (error) => {\n console.error('Error cancelling instance:', error)\n flash(t('workflows.instances.cancelFailed'), 'error')\n },\n })\n\n const retryMutation = useMutation({\n mutationFn: async () => {\n const response = await apiFetch(`/api/workflows/instances/${instance!.id}/retry`, {\n method: 'POST',\n })\n if (!response.ok) {\n throw new Error(t('workflows.instances.retryFailed'))\n }\n return response.json()\n },\n onSuccess: () => {\n flash(t('workflows.instances.messages.retried'), 'success')\n queryClient.invalidateQueries({ queryKey: ['workflow-instance', id] })\n },\n onError: (error) => {\n console.error('Error retrying instance:', error)\n flash(t('workflows.instances.retryFailed'), 'error')\n },\n })\n\n const handleCancel = async () => {\n if (!instance) return\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirmCancel'),\n variant: 'destructive',\n })\n if (!confirmed) {\n return\n }\n cancelMutation.mutate()\n }\n\n const handleRetry = async () => {\n if (!instance) return\n const confirmed = await confirmDialog({\n title: t('workflows.instances.confirmRetry'),\n variant: 'default',\n })\n if (!confirmed) {\n return\n }\n retryMutation.mutate()\n }\n\n // Generate graph with execution status\n const { graphNodes, graphEdges } = React.useMemo(() => {\n if (!workflowDefinition?.definition) {\n return { graphNodes: [], graphEdges: [] }\n }\n\n // Convert definition to graph\n const { nodes, edges } = definitionToGraph(workflowDefinition.definition, { autoLayout: true })\n\n // Determine step statuses from events\n const stepStatuses = new Map<string, 'completed' | 'active' | 'pending' | 'failed' | 'skipped'>()\n const stepTimings = new Map<string, { startedAt?: Date; completedAt?: Date }>()\n\n // Process events to determine status\n for (const event of events) {\n const stepId = event.eventData?.stepId || event.eventData?.toStepId\n if (!stepId) continue\n\n if (event.eventType === 'STEP_ENTERED' || event.eventType === 'StepEntered') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), startedAt: new Date(event.occurredAt) })\n if (!stepStatuses.has(stepId)) {\n stepStatuses.set(stepId, 'active')\n }\n } else if (event.eventType === 'STEP_COMPLETED' || event.eventType === 'STEP_EXITED' || event.eventType === 'StepExited') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), completedAt: new Date(event.occurredAt) })\n stepStatuses.set(stepId, 'completed')\n } else if (event.eventType === 'STEP_FAILED' || event.eventType === 'StepFailed') {\n stepTimings.set(stepId, { ...stepTimings.get(stepId), completedAt: new Date(event.occurredAt) })\n stepStatuses.set(stepId, 'failed')\n }\n }\n\n // Mark current step as active\n if (instance?.currentStepId && !stepStatuses.has(instance.currentStepId)) {\n stepStatuses.set(instance.currentStepId, 'active')\n } else if (instance?.currentStepId && stepStatuses.get(instance.currentStepId) !== 'completed') {\n stepStatuses.set(instance.currentStepId, 'active')\n }\n\n // Mark all other steps as pending, with special handling for START/END\n for (const node of nodes) {\n if (!stepStatuses.has(node.id)) {\n const nodeType = node.type\n const isCurrentStep = instance?.currentStepId === node.id\n\n if (nodeType === 'start') {\n // START node is completed if we've moved past it\n // It's active if we're still at start (edge case)\n if (isCurrentStep) {\n stepStatuses.set(node.id, 'active')\n } else {\n stepStatuses.set(node.id, 'completed')\n }\n } else if (nodeType === 'end') {\n // END node is completed if we've reached it\n // Or if workflow is in COMPLETED status\n if (isCurrentStep || instance?.status === 'COMPLETED') {\n stepStatuses.set(node.id, 'completed')\n } else {\n stepStatuses.set(node.id, 'pending')\n }\n } else {\n // All other nodes without events are pending\n stepStatuses.set(node.id, 'pending')\n }\n }\n }\n\n // Apply styles to nodes based on status\n const styledNodes: Node[] = nodes.map((node) => {\n const status = stepStatuses.get(node.id) || 'pending'\n const timing = stepTimings.get(node.id)\n\n // Calculate duration for tooltip\n const duration = timing?.startedAt && timing?.completedAt\n ? calculateDuration(timing.startedAt, timing.completedAt)\n : timing?.startedAt\n ? calculateDuration(timing.startedAt, null)\n : null\n\n // Build tooltip content\n let tooltipContent = `${node.data.label || node.id}\\n`\n tooltipContent += `Status: ${status}\\n`\n if (timing?.startedAt) {\n tooltipContent += `Started: ${timing.startedAt.toLocaleString()}\\n`\n }\n if (timing?.completedAt) {\n tooltipContent += `Completed: ${timing.completedAt.toLocaleString()}\\n`\n }\n if (duration) {\n tooltipContent += `Duration: ${duration}`\n }\n\n // Define colors and styles based on status\n let style: React.CSSProperties = {}\n switch (status) {\n case 'completed':\n style = {\n backgroundColor: '#10B981', // green-500\n color: 'white',\n borderColor: '#059669', // green-600\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'active':\n style = {\n backgroundColor: '#3B82F6', // blue-500\n color: 'white',\n borderColor: '#1D4ED8', // blue-700\n borderWidth: '3px',\n borderRadius: '16px',\n boxShadow: '0 0 0 3px rgba(59, 130, 246, 0.3)',\n }\n break\n case 'failed':\n style = {\n backgroundColor: '#EF4444', // red-500\n color: 'white',\n borderColor: '#B91C1C', // red-700\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'skipped':\n style = {\n backgroundColor: '#FEF3C7', // yellow-100\n color: '#78350F', // yellow-900\n borderColor: '#F59E0B', // yellow-500\n borderWidth: '3px',\n borderRadius: '16px',\n }\n break\n case 'pending':\n default:\n style = {\n backgroundColor: '#E5E7EB', // gray-200\n color: '#374151', // gray-700\n borderColor: '#9CA3AF', // gray-400\n borderWidth: '2px',\n borderRadius: '8px',\n }\n break\n }\n\n return {\n ...node,\n data: {\n ...node.data,\n status,\n timing,\n duration,\n tooltip: tooltipContent,\n },\n style,\n }\n })\n\n return { graphNodes: styledNodes, graphEdges: edges }\n }, [workflowDefinition, events, instance?.currentStepId])\n\n if (isLoading) {\n return (\n <Page>\n <PageBody>\n <div className=\"flex h-[50vh] flex-col items-center justify-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-6 w-6\" />\n <span>{t('workflows.instances.detail.loading') || 'Loading workflow instance...'}</span>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n const isNotFound = !isLoading && (error as (Error & { status?: number }) | null)?.status === 404\n\n if (isNotFound) {\n return (\n <Page>\n <PageBody>\n <RecordNotFoundState\n label={t('workflows.instances.detail.notFound', 'Workflow instance not found.')}\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.actions.backToList', 'Back to instances')}\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n if (error || !instance) {\n return (\n <Page>\n <PageBody>\n <ErrorMessage\n label={(error as Error | null)?.message ?? t('workflows.instances.loadFailed', 'Failed to load workflow instance.')}\n action={\n <Button asChild variant=\"outline\" size=\"sm\">\n <Link href=\"/backend/instances\">{t('workflows.instances.actions.backToList', 'Back to instances')}</Link>\n </Button>\n }\n />\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n const canCancel = ['RUNNING', 'PAUSED'].includes(instance.status)\n const canRetry = instance.status === 'FAILED'\n const actionLoading = cancelMutation.isPending || retryMutation.isPending\n\n if (isMobile) {\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-4\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.backToList', 'Back to instances')}\n entityTypeLabel={t('workflows.instances.detail.type', 'Workflow instance')}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{instance.workflowId}</span>\n <span className=\"font-mono text-sm text-muted-foreground\">#{instance.id.slice(0, 8)}</span>\n </div>\n }\n menuActions={[\n ...(canCancel ? [{\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: handleCancel,\n disabled: actionLoading,\n }] : []),\n ...(canRetry ? [{\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: handleRetry,\n disabled: actionLoading,\n }] : []),\n ]}\n />\n <MobileInstanceOverview\n instance={instance}\n events={events}\n graphNodes={graphNodes}\n graphEdges={graphEdges}\n definitionLoading={definitionLoading}\n hasDefinition={!!workflowDefinition}\n getStatusBadgeClass={getStatusBadgeClass}\n getEventTypeBadgeClass={getEventTypeBadgeClass}\n calculateDuration={calculateDuration}\n />\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page>\n <PageBody>\n <div className=\"space-y-6\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/instances\"\n backLabel={t('workflows.instances.backToList', 'Back to instances')}\n entityTypeLabel={t('workflows.instances.detail.type', 'Workflow instance')}\n title={\n <div className=\"flex flex-wrap items-center gap-2\">\n <span>{instance.workflowId}</span>\n <span className=\"font-mono text-sm text-muted-foreground\">#{instance.id.slice(0, 8)}</span>\n </div>\n }\n menuActions={[\n ...(canCancel ? [{\n id: 'cancel',\n label: t('workflows.instances.actions.cancel'),\n onSelect: handleCancel,\n disabled: actionLoading,\n }] : []),\n ...(canRetry ? [{\n id: 'retry',\n label: t('workflows.instances.actions.retry'),\n onSelect: handleRetry,\n disabled: actionLoading,\n }] : []),\n ]}\n />\n\n {/* Execution Summary */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.overview')}\n </h2>\n <dl className=\"grid grid-cols-1 md:grid-cols-2 gap-4\">\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.workflowId')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n <div className=\"font-mono\">{instance.workflowId}</div>\n <div className=\"text-xs text-muted-foreground\">v{instance.version}</div>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.status')}\n </dt>\n <dd className=\"mt-1\">\n <span\n className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getStatusBadgeClass(\n instance.status\n )}`}\n >\n {t(`workflows.instances.status.${instance.status}`)}\n </span>\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.currentStep')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground font-mono\">\n {instance.currentStepId || '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.correlationKey')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {instance.correlationKey || '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.startedAt')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {new Date(instance.startedAt).toLocaleString()}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.completedAt')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {instance.completedAt ? new Date(instance.completedAt).toLocaleString() : '-'}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.duration')}\n </dt>\n <dd className=\"mt-1 text-sm text-foreground\">\n {calculateDuration(instance.startedAt, instance.completedAt)}\n </dd>\n </div>\n <div>\n <dt className=\"text-sm font-medium text-muted-foreground\">\n {t('workflows.instances.fields.retryCount')}\n </dt>\n <dd className=\"mt-1\">\n <span className={instance.retryCount > 0 ? 'text-orange-600 font-medium text-sm' : 'text-sm text-foreground'}>\n {instance.retryCount}\n </span>\n </dd>\n </div>\n </dl>\n </div>\n\n {/* Visual Workflow Graph */}\n {definitionLoading && (\n <div className=\"rounded-lg border bg-card p-6\">\n <div className=\"flex items-center justify-center py-8\">\n <Spinner className=\"h-6 w-6\" />\n <span className=\"ml-2 text-sm text-muted-foreground\">Loading workflow visualization...</span>\n </div>\n </div>\n )}\n {!definitionLoading && workflowDefinition && graphNodes.length > 0 && (\n <div className=\"rounded-lg border bg-card p-4 md:p-6\">\n <h2 className=\"text-lg font-semibold text-foreground mb-4\">\n {t('workflows.instances.sections.visualFlow') || 'Visual Workflow Flow'}\n </h2>\n\n <div className=\"flex flex-col gap-4 lg:flex-row lg:gap-6\">\n {/* Left Sidebar - Legend */}\n <div className=\"order-2 lg:order-1 lg:w-64 lg:flex-shrink-0\">\n <WorkflowLegend />\n </div>\n\n {/* Main Visualization */}\n <div className=\"order-1 lg:order-2 flex-1 border rounded-lg overflow-hidden h-[62svh] min-h-[360px] lg:h-[800px]\">\n <WorkflowGraphReadOnly\n nodes={graphNodes}\n edges={graphEdges}\n height=\"100%\"\n />\n </div>\n </div>\n </div>\n )}\n {!definitionLoading && !workflowDefinition && instance && (\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.visualFlow') || 'Visual Workflow Flow'}\n </h2>\n <div className=\"flex items-center justify-center py-8 text-muted-foreground\">\n <p className=\"text-sm\">Workflow definition not found (ID: {instance.definitionId})</p>\n </div>\n </div>\n )}\n\n\n {/* Compensation Status */}\n {(instance.status === 'COMPENSATING' || instance.status === 'COMPENSATED') && (\n <div className=\"rounded-lg border border-orange-300 bg-orange-50 p-6\">\n <h2 className=\"text-lg font-semibold mb-4 text-orange-800\">\n {t('workflows.instances.sections.compensation') || 'Compensation (Saga Pattern)'}\n </h2>\n <div className=\"space-y-4\">\n <p className=\"text-sm text-orange-700\">\n {instance.status === 'COMPENSATING'\n ? (t('workflows.instances.compensation.inProgress') || 'Workflow is currently executing compensation activities to rollback changes.')\n : (t('workflows.instances.compensation.completed') || 'Compensation has been completed. All changes have been rolled back.')}\n </p>\n\n {/* Show compensation activities from events */}\n {events.filter(e =>\n e.eventType.includes('COMPENSATION') ||\n e.eventType.includes('Compensation')\n ).length > 0 && (\n <div className=\"mt-4\">\n <h3 className=\"text-sm font-medium text-orange-800 mb-2\">\n {t('workflows.instances.compensation.activities') || 'Compensation Activities'}\n </h3>\n <div className=\"space-y-2\">\n {events\n .filter(e => e.eventType.includes('COMPENSATION') || e.eventType.includes('Compensation'))\n .reverse()\n .map((event) => (\n <div key={event.id} className=\"flex items-start gap-2 p-2 bg-card rounded border border-orange-200\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {event.eventType}\n </span>\n <span className=\"text-xs text-orange-600\">\n {new Date(event.occurredAt).toLocaleTimeString()}\n </span>\n {event.eventData?.activityName && (\n <span className=\"text-xs text-orange-700 font-medium\">\n {event.eventData.activityName}\n </span>\n )}\n </div>\n ))}\n </div>\n </div>\n )}\n </div>\n </div>\n )}\n\n {/* Error Message (if present) */}\n {instance.errorMessage && (\n <div className=\"rounded-lg border border-destructive bg-destructive/5 p-6\">\n <h2 className=\"text-lg font-semibold mb-4 text-destructive\">\n {t('workflows.instances.fields.lastError')}\n </h2>\n <pre className=\"text-sm text-destructive whitespace-pre-wrap font-mono\">\n {instance.errorMessage}\n </pre>\n {instance.errorDetails && (\n <div className=\"mt-4\">\n <JsonDisplay\n data={instance.errorDetails}\n className=\"border-destructive/20 bg-destructive/5\"\n maxInitialDepth={1}\n />\n </div>\n )}\n </div>\n )}\n\n {/* Context */}\n <JsonDisplay\n data={instance.context}\n title={t('workflows.instances.sections.context')}\n />\n\n {/* Metadata */}\n {instance.metadata && Object.keys(instance.metadata).length > 0 && (\n <JsonDisplay\n data={instance.metadata}\n title={t('workflows.instances.sections.metadata')}\n />\n )}\n\n {/* Execution Timeline */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.executionTimeline') || 'Execution Timeline'}\n </h2>\n {eventsLoading ? (\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n <span className=\"text-sm\">{t('common.loading')}</span>\n </div>\n ) : events.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.instances.noExecutionHistory')}\n </p>\n ) : (\n <div className=\"space-y-2\">\n {events\n .filter(\n (e) =>\n e.eventType.includes('STEP_') ||\n e.eventType.includes('WORKFLOW_STARTED') ||\n e.eventType.includes('WORKFLOW_COMPLETED') ||\n e.eventType.includes('WORKFLOW_FAILED')\n )\n .reverse()\n .map((event, idx) => (\n <div key={event.id} className=\"flex items-start gap-3 p-3 bg-muted rounded-lg border\">\n <div className=\"flex-shrink-0 w-8 h-8 rounded-full bg-background border-2 border-border flex items-center justify-center text-xs font-medium\">\n {idx + 1}\n </div>\n <div className=\"flex-1 min-w-0\">\n <div className=\"flex items-center gap-2\">\n <span\n className={`inline-flex items-center px-2 py-0.5 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {t(`workflows.events.types.${event.eventType}`) || event.eventType}\n </span>\n <span className=\"text-xs text-muted-foreground\">\n {new Date(event.occurredAt).toLocaleTimeString()}\n </span>\n </div>\n {event.eventData && (\n <p className=\"mt-1 text-xs text-muted-foreground\">\n {event.eventData.toStepId && `-> ${event.eventData.toStepId}`}\n {event.eventData.fromStepId && `${event.eventData.fromStepId} -> ${event.eventData.toStepId}`}\n </p>\n )}\n </div>\n </div>\n ))}\n </div>\n )}\n </div>\n\n {/* Event Log */}\n <div className=\"rounded-lg border bg-card p-6\">\n <h2 className=\"text-lg font-semibold mb-4\">\n {t('workflows.instances.sections.executionHistory')}\n </h2>\n {eventsLoading ? (\n <div className=\"flex items-center gap-2 text-muted-foreground\">\n <Spinner className=\"h-4 w-4\" />\n <span className=\"text-sm\">{t('common.loading')}</span>\n </div>\n ) : events.length === 0 ? (\n <p className=\"text-sm text-muted-foreground\">\n {t('workflows.instances.noExecutionHistory')}\n </p>\n ) : (\n <div className=\"overflow-x-auto rounded-lg border\">\n <table className=\"min-w-full divide-y divide-border\">\n <thead className=\"bg-muted\">\n <tr>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.occurredAt')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.eventType')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.eventData')}\n </th>\n <th className=\"px-4 py-3 text-left text-xs font-medium uppercase tracking-wider text-muted-foreground\">\n {t('workflows.events.userId')}\n </th>\n </tr>\n </thead>\n <tbody className=\"bg-background divide-y divide-border\">\n {events.map((event) => (\n <tr key={event.id} className=\"hover:bg-muted/50\">\n <td className=\"px-4 py-3 whitespace-nowrap text-sm text-foreground\">\n {new Date(event.occurredAt).toLocaleString()}\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap\">\n <span\n className={`inline-flex items-center px-2 py-1 rounded text-xs font-medium ${getEventTypeBadgeClass(\n event.eventType\n )}`}\n >\n {t(`workflows.events.types.${event.eventType}`) || event.eventType}\n </span>\n </td>\n <td className=\"px-4 py-3 text-sm\">\n <details className=\"cursor-pointer\">\n <summary className=\"text-primary hover:underline\">\n {t('common.details')}\n </summary>\n <div className=\"mt-2\">\n <JsonDisplay\n data={event.eventData}\n showCopy={false}\n maxInitialDepth={1}\n />\n </div>\n </details>\n </td>\n <td className=\"px-4 py-3 whitespace-nowrap text-sm text-muted-foreground\">\n {event.userId || '-'}\n </td>\n </tr>\n ))}\n </tbody>\n </table>\n </div>\n )}\n </div>\n </div>\n </PageBody>\n {ConfirmDialogElement}\n </Page>\n )\n}\n"],
5
5
  "mappings": "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",
6
6
  "names": ["error"]
7
7
  }
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/workflows/components/EdgeEditDialog.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport {Edge} from '@xyflow/react'\nimport {useEffect, useState} from 'react'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle\n} from '@open-mercato/ui/primitives/dialog'\nimport {Button} from '@open-mercato/ui/primitives/button'\nimport {Input} from '@open-mercato/ui/primitives/input'\nimport {Label} from '@open-mercato/ui/primitives/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport {Badge} from '@open-mercato/ui/primitives/badge'\nimport {Separator} from '@open-mercato/ui/primitives/separator'\nimport {Plus, Trash2} from 'lucide-react'\nimport {type BusinessRule, BusinessRulesSelector} from './BusinessRulesSelector'\nimport {JsonBuilder} from '@open-mercato/ui/backend/JsonBuilder'\nimport {useT} from '@open-mercato/shared/lib/i18n/context'\nimport {useDialogKeyHandler} from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport {useConfirmDialog} from '@open-mercato/ui/backend/confirm-dialog'\n\nexport interface EdgeEditDialogProps {\n edge: Edge | null\n isOpen: boolean\n onClose: () => void\n onSave: (edgeId: string, updates: Partial<Edge['data']>) => void\n onDelete: (edgeId: string) => void\n}\n\ninterface TransitionCondition {\n ruleId: string\n required: boolean\n}\n\n/**\n * EdgeEditDialog - Modal dialog for editing transition properties\n *\n * Allows editing:\n * - Label\n * - Trigger type (auto, manual, signal, timer)\n * - Pre-conditions (guard rules)\n * - Post-conditions (validation rules)\n * - Activities\n * - Business rules integration\n */\nexport function EdgeEditDialog({ edge, isOpen, onClose, onSave, onDelete }: EdgeEditDialogProps) {\n const t = useT()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [transitionName, setTransitionName] = useState('')\n const [trigger, setTrigger] = useState('auto')\n const [priority, setPriority] = useState('100')\n const [continueOnActivityFailure, setContinueOnActivityFailure] = useState(false)\n const [preConditions, setPreConditions] = useState<TransitionCondition[]>([])\n const [postConditions, setPostConditions] = useState<TransitionCondition[]>([])\n const [showAdvanced, setShowAdvanced] = useState(false)\n const [advancedConfig, setAdvancedConfig] = useState<Record<string, any>>({})\n const [activities, setActivities] = useState<any[]>([])\n const [expandedActivities, setExpandedActivities] = useState<Set<number>>(new Set())\n const [expandedPreConditions, setExpandedPreConditions] = useState<Set<number>>(new Set())\n const [expandedPostConditions, setExpandedPostConditions] = useState<Set<number>>(new Set())\n const [showRuleSelector, setShowRuleSelector] = useState(false)\n const [ruleSelectorMode, setRuleSelectorMode] = useState<'pre' | 'post'>('pre')\n const [ruleDetailsCache, setRuleDetailsCache] = useState<Map<string, BusinessRule>>(new Map())\n\n // Generate a readable name from edge ID (e.g., \"start_to_cart\" -> \"Start to Cart\")\n const generateNameFromId = (edgeId: string): string => {\n return edgeId\n .split('_to_')\n .map(part => part.split('_').map(word =>\n word.charAt(0).toUpperCase() + word.slice(1)\n ).join(' '))\n .join(' \u2192 ')\n }\n\n // Load edge data when dialog opens\n useEffect(() => {\n if (edge && isOpen) {\n const edgeData = edge.data as any\n\n // Try to get transition name from various sources\n let loadedTransitionName = ''\n if (edgeData?.transitionName && edgeData.transitionName !== '') {\n loadedTransitionName = edgeData.transitionName\n } else if (edgeData?.label && edgeData.label !== '' && edgeData.label !== undefined) {\n loadedTransitionName = edgeData.label\n } else {\n // Generate a name from the edge ID as fallback\n loadedTransitionName = generateNameFromId(edge.id)\n }\n\n setTransitionName(loadedTransitionName)\n\n setTrigger(edgeData?.trigger || 'auto')\n setPriority((edgeData?.priority || 100).toString())\n setContinueOnActivityFailure(edgeData?.continueOnActivityFailure !== undefined ? edgeData.continueOnActivityFailure : false)\n\n // Handle pre/post conditions - convert from various formats\n const rawPreConditions = edgeData?.preConditions || []\n const rawPostConditions = edgeData?.postConditions || []\n\n // Convert to TransitionCondition format\n setPreConditions(Array.isArray(rawPreConditions)\n ? rawPreConditions.map((c: any) =>\n typeof c === 'string' ? { ruleId: c, required: true } : c\n )\n : []\n )\n setPostConditions(Array.isArray(rawPostConditions)\n ? rawPostConditions.map((c: any) =>\n typeof c === 'string' ? { ruleId: c, required: true } : c\n )\n : []\n )\n\n setActivities(edgeData?.activities || [])\n\n // Load advanced config (activities, etc.)\n const advancedFields: any = {}\n if (edgeData?.activities && edgeData.activities.length > 0) {\n advancedFields.activities = edgeData.activities\n }\n setAdvancedConfig(advancedFields)\n setExpandedActivities(new Set())\n setExpandedPreConditions(new Set())\n setExpandedPostConditions(new Set())\n }\n }, [edge, isOpen])\n\n const toggleActivity = (index: number) => {\n const newExpanded = new Set(expandedActivities)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedActivities(newExpanded)\n }\n\n const addActivity = () => {\n const newActivity = {\n activityId: `activity_${Date.now()}`,\n activityName: t('workflows.common.newActivity'),\n activityType: 'CALL_API',\n config: {},\n timeout: '',\n retryPolicy: {\n maxAttempts: 3,\n initialIntervalMs: 1000,\n backoffCoefficient: 2,\n maxIntervalMs: 10000,\n },\n }\n setActivities([...activities, newActivity])\n // Auto-expand the new activity\n const newExpanded = new Set(expandedActivities)\n newExpanded.add(activities.length)\n setExpandedActivities(newExpanded)\n }\n\n const removeActivity = async (index: number) => {\n const confirmed = await confirmDialog({\n title: t('workflows.edgeEditor.confirmRemoveActivity'),\n variant: 'destructive',\n })\n if (confirmed) {\n setActivities(activities.filter((_, i) => i !== index))\n // Remove from expanded set\n const newExpanded = new Set(expandedActivities)\n newExpanded.delete(index)\n setExpandedActivities(newExpanded)\n }\n }\n\n const updateActivity = (index: number, field: string, value: any) => {\n const updated = [...activities]\n updated[index] = { ...updated[index], [field]: value }\n setActivities(updated)\n }\n\n const updateActivityRetryPolicy = (index: number, field: string, value: any) => {\n const updated = [...activities]\n updated[index] = {\n ...updated[index],\n retryPolicy: {\n ...updated[index].retryPolicy,\n [field]: value,\n },\n }\n setActivities(updated)\n }\n\n // Business Rules Management\n const togglePreCondition = (index: number) => {\n const newExpanded = new Set(expandedPreConditions)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedPreConditions(newExpanded)\n }\n\n const togglePostCondition = (index: number) => {\n const newExpanded = new Set(expandedPostConditions)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedPostConditions(newExpanded)\n }\n\n const openRuleSelector = (mode: 'pre' | 'post') => {\n setRuleSelectorMode(mode)\n setShowRuleSelector(true)\n }\n\n const closeRuleSelector = () => {\n setShowRuleSelector(false)\n }\n\n const handleRuleSelected = (ruleId: string, rule: BusinessRule) => {\n // Cache the rule details for display\n setRuleDetailsCache(prev => new Map(prev).set(ruleId, rule))\n\n if (ruleSelectorMode === 'pre') {\n if (!preConditions.find(c => c.ruleId === ruleId)) {\n setPreConditions([...preConditions, { ruleId, required: true }])\n }\n } else {\n if (!postConditions.find(c => c.ruleId === ruleId)) {\n setPostConditions([...postConditions, { ruleId, required: true }])\n }\n }\n closeRuleSelector()\n }\n\n const removePreCondition = (index: number) => {\n setPreConditions(preConditions.filter((_, i) => i !== index))\n const newExpanded = new Set(expandedPreConditions)\n newExpanded.delete(index)\n setExpandedPreConditions(newExpanded)\n }\n\n const removePostCondition = (index: number) => {\n setPostConditions(postConditions.filter((_, i) => i !== index))\n const newExpanded = new Set(expandedPostConditions)\n newExpanded.delete(index)\n setExpandedPostConditions(newExpanded)\n }\n\n const updatePreCondition = (index: number, field: keyof TransitionCondition, value: any) => {\n const updated = [...preConditions]\n updated[index] = { ...updated[index], [field]: value }\n setPreConditions(updated)\n }\n\n const updatePostCondition = (index: number, field: keyof TransitionCondition, value: any) => {\n const updated = [...postConditions]\n updated[index] = { ...updated[index], [field]: value }\n setPostConditions(updated)\n }\n\n const getBusinessRuleDetails = (ruleId: string): BusinessRule | null => {\n return ruleDetailsCache.get(ruleId) || null\n }\n\n const handleSave = () => {\n if (!edge) return\n\n const updates: Partial<Edge['data']> = {\n transitionName,\n label: transitionName, // Keep label for backward compatibility\n trigger,\n priority: parseInt(priority) || 100,\n continueOnActivityFailure,\n preConditions: preConditions.length > 0 ? preConditions : undefined,\n postConditions: postConditions.length > 0 ? postConditions : undefined,\n activities: activities.length > 0 ? activities : undefined,\n }\n\n // Merge advanced config\n if (advancedConfig && Object.keys(advancedConfig).length > 0) {\n Object.assign(updates, advancedConfig)\n }\n\n onSave(edge.id, updates)\n onClose()\n }\n\n const handleDelete = () => {\n if (!edge) return\n onDelete(edge.id)\n }\n\n const handleKeyDown = useDialogKeyHandler({ onConfirm: handleSave, onCancel: onClose })\n\n if (!isOpen || !edge) return null\n\n const triggerVariant = trigger === 'auto' ? 'default' : trigger === 'manual' ? 'secondary' : 'outline'\n\n return (\n <Dialog open={isOpen} onOpenChange={onClose}>\n <DialogContent className=\"sm:max-w-4xl max-h-[90vh] overflow-y-auto\" onKeyDown={handleKeyDown}>\n <DialogHeader>\n <div className=\"flex items-center gap-2 mb-2\">\n <DialogTitle>{t('workflows.edgeEditor.title')}</DialogTitle>\n <Badge variant={triggerVariant} className=\"text-xs\">\n {t(`workflows.transitions.triggers.${trigger}`)}\n </Badge>\n </div>\n <div className=\"space-y-1\">\n <DialogDescription>\n {t('workflows.edgeEditor.description')}\n </DialogDescription>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium\">{t('workflows.edgeEditor.id')}:</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.id}</code>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium\">{t('workflows.edgeEditor.flow')}:</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.source}</code>\n <span>\u2192</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.target}</code>\n </div>\n </div>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n {/* Transition Name */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"transitionName\">{t('workflows.edgeEditor.transitionName')}</Label>\n <Input\n id=\"transitionName\"\n type=\"text\"\n value={transitionName}\n onChange={(e) => setTransitionName(e.target.value)}\n placeholder={t('workflows.edgeEditor.transitionNamePlaceholder', { name: generateNameFromId(edge.id) })}\n autoFocus\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.transitionNameHint')}\n </p>\n </div>\n\n {/* Trigger Type */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"trigger\">{t('workflows.edgeEditor.triggerType')}</Label>\n <Select value={trigger} onValueChange={(value) => setTrigger(value)}>\n <SelectTrigger id=\"trigger\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"auto\">{t('workflows.transitions.triggers.auto')}</SelectItem>\n <SelectItem value=\"manual\">{t('workflows.transitions.triggers.manual')}</SelectItem>\n <SelectItem value=\"signal\">{t('workflows.transitions.triggers.signal')}</SelectItem>\n <SelectItem value=\"timer\">{t('workflows.transitions.triggers.timer')}</SelectItem>\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">\n {t(`workflows.edgeEditor.triggerDescriptions.${trigger}`)}\n </p>\n </div>\n\n {/* Priority */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"priority\">{t('workflows.edgeEditor.priority')}</Label>\n <Input\n id=\"priority\"\n type=\"number\"\n value={priority}\n onChange={(e) => setPriority(e.target.value)}\n placeholder=\"100\"\n min=\"0\"\n max=\"9999\"\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.priorityHint')}\n </p>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"continueOnActivityFailure\"\n checked={continueOnActivityFailure}\n onChange={(e) => setContinueOnActivityFailure(e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <Label htmlFor=\"continueOnActivityFailure\" className=\"font-normal cursor-pointer\">\n {t('workflows.edgeEditor.continueOnActivityFailure')}\n </Label>\n </div>\n <p className=\"text-xs text-muted-foreground ml-6\">\n {t('workflows.edgeEditor.continueOnActivityFailureHint')}\n </p>\n </div>\n\n <Separator />\n\n {/* Pre-conditions (Business Rules) */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold\">\n {t('workflows.edgeEditor.preConditions')} ({preConditions.length})\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.preConditionsHint')}\n </p>\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => openRuleSelector('pre')}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addRule')}\n </Button>\n </div>\n\n {preConditions.length === 0 && (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.edgeEditor.noPreConditions')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {preConditions.map((condition, index) => {\n const isExpanded = expandedPreConditions.has(index)\n const rule = getBusinessRuleDetails(condition.ruleId)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => togglePreCondition(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {rule?.ruleName || condition.ruleId}\n </span>\n {condition.required && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('workflows.edgeEditor.required')}\n </span>\n )}\n {rule && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800\">\n {rule.ruleType}\n </span>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.ruleId')}: <code className=\"bg-white px-1 rounded\">{condition.ruleId}</code>\n </p>\n {rule?.description && (\n <p className=\"text-xs text-gray-500 mt-1 line-clamp-1\">{rule.description}</p>\n )}\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.ruleId')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={condition.ruleId}\n onChange={(e) => updatePreCondition(index, 'ruleId', e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-xs font-medium text-gray-700\">\n <input\n type=\"checkbox\"\n checked={condition.required}\n onChange={(e) => updatePreCondition(index, 'required', e.target.checked)}\n className=\"rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n />\n {t('workflows.edgeEditor.requiredCheckbox')}\n </label>\n </div>\n\n {rule && (\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.businessRuleDetails')}</h4>\n <dl className=\"space-y-1 text-xs\">\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Name:</dt>\n <dd className=\"text-gray-900\">{rule.ruleName}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Type:</dt>\n <dd className=\"text-gray-900\">{rule.ruleType}</dd>\n </div>\n {rule.ruleCategory && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Category:</dt>\n <dd className=\"text-gray-900\">{rule.ruleCategory}</dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Entity Type:</dt>\n <dd className=\"text-gray-900 font-mono text-xs\">{rule.entityType}</dd>\n </div>\n {rule.eventType && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Event Type:</dt>\n <dd className=\"text-gray-900\">{rule.eventType}</dd>\n </div>\n )}\n {rule.description && (\n <div className=\"mt-2 pt-2 border-t border-gray-200\">\n <dt className=\"font-medium text-gray-700 mb-1\">Description:</dt>\n <dd className=\"text-gray-600\">{rule.description}</dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removePreCondition(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removePreCondition')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Post-conditions (Business Rules) */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold\">\n {t('workflows.edgeEditor.postConditions')} ({postConditions.length})\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.postConditionsHint')}\n </p>\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => openRuleSelector('post')}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addRule')}\n </Button>\n </div>\n\n {postConditions.length === 0 && (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.edgeEditor.noPostConditions')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {postConditions.map((condition, index) => {\n const isExpanded = expandedPostConditions.has(index)\n const rule = getBusinessRuleDetails(condition.ruleId)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => togglePostCondition(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {rule?.ruleName || condition.ruleId}\n </span>\n {condition.required && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('workflows.edgeEditor.required')}\n </span>\n )}\n {rule && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800\">\n {rule.ruleType}\n </span>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.ruleId')}: <code className=\"bg-white px-1 rounded\">{condition.ruleId}</code>\n </p>\n {rule?.description && (\n <p className=\"text-xs text-gray-500 mt-1 line-clamp-1\">{rule.description}</p>\n )}\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.ruleId')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={condition.ruleId}\n onChange={(e) => updatePostCondition(index, 'ruleId', e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-xs font-medium text-gray-700\">\n <input\n type=\"checkbox\"\n checked={condition.required}\n onChange={(e) => updatePostCondition(index, 'required', e.target.checked)}\n className=\"rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n />\n {t('workflows.edgeEditor.requiredPostCheckbox')}\n </label>\n </div>\n\n {rule && (\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.businessRuleDetails')}</h4>\n <dl className=\"space-y-1 text-xs\">\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Name:</dt>\n <dd className=\"text-gray-900\">{rule.ruleName}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Type:</dt>\n <dd className=\"text-gray-900\">{rule.ruleType}</dd>\n </div>\n {rule.ruleCategory && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Category:</dt>\n <dd className=\"text-gray-900\">{rule.ruleCategory}</dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Entity Type:</dt>\n <dd className=\"text-gray-900 font-mono text-xs\">{rule.entityType}</dd>\n </div>\n {rule.eventType && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Event Type:</dt>\n <dd className=\"text-gray-900\">{rule.eventType}</dd>\n </div>\n )}\n {rule.description && (\n <div className=\"mt-2 pt-2 border-t border-gray-200\">\n <dt className=\"font-medium text-gray-700 mb-1\">Description:</dt>\n <dd className=\"text-gray-600\">{rule.description}</dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removePostCondition(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removePostCondition')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Activities Section */}\n <div className=\"border-t border-gray-200 pt-4 mt-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-gray-900\">\n {t('workflows.edgeEditor.activities')} ({activities.length})\n </h3>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={addActivity}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addActivity')}\n </Button>\n </div>\n\n {activities.length === 0 && (\n <div className=\"p-4 text-center text-sm text-gray-500 bg-gray-50 rounded-lg border border-gray-200\">\n {t('workflows.edgeEditor.noActivities')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {activities.map((activity, index) => {\n const isExpanded = expandedActivities.has(index)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => toggleActivity(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {activity.activityName || activity.label || activity.activityId || `Activity ${index + 1}`}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {activity.activityType}\n </Badge>\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.activityId')}: <code className=\"bg-white px-1 rounded\">{activity.activityId}</code>\n </p>\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n {/* Activity ID */}\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityId')} *</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.activityId}\n onChange={(e) => updateActivity(index, 'activityId', e.target.value)}\n placeholder={t('workflows.edgeEditor.activityIdPlaceholder')}\n />\n </div>\n\n {/* Activity Name */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityName')} *</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.activityName || ''}\n onChange={(e) => updateActivity(index, 'activityName', e.target.value)}\n placeholder={t('workflows.edgeEditor.activityNamePlaceholder')}\n />\n </div>\n\n {/* Activity Type */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityType')} *</label>\n <Select\n value={activity.activityType}\n onValueChange={(value) => updateActivity(index, 'activityType', value)}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"SEND_EMAIL\">{t('workflows.activities.types.SEND_EMAIL')}</SelectItem>\n <SelectItem value=\"CALL_API\">{t('workflows.activities.types.CALL_API')}</SelectItem>\n <SelectItem value=\"UPDATE_ENTITY\">{t('workflows.activities.types.UPDATE_ENTITY')}</SelectItem>\n <SelectItem value=\"EMIT_EVENT\">{t('workflows.activities.types.EMIT_EVENT')}</SelectItem>\n <SelectItem value=\"CALL_WEBHOOK\">{t('workflows.activities.types.CALL_WEBHOOK')}</SelectItem>\n <SelectItem value=\"EXECUTE_FUNCTION\">{t('workflows.activities.types.EXECUTE_FUNCTION')}</SelectItem>\n <SelectItem value=\"WAIT\">{t('workflows.activities.types.WAIT')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Timeout */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.timeout')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.timeout || ''}\n onChange={(e) => updateActivity(index, 'timeout', e.target.value)}\n placeholder={t('workflows.edgeEditor.timeoutPlaceholder')}\n />\n <p className=\"text-xs text-gray-500 mt-0.5\">{t('workflows.edgeEditor.timeoutHint')}</p>\n </div>\n\n {/* Retry Policy */}\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.retryPolicy')}</h4>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.maxAttempts')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.maxAttempts || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'maxAttempts', parseInt(e.target.value) || 0)}\n placeholder=\"3\"\n min=\"1\"\n max=\"10\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.initialInterval')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.initialIntervalMs || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'initialIntervalMs', parseInt(e.target.value) || 0)}\n placeholder=\"1000\"\n min=\"0\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.backoffCoefficient')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n step=\"0.1\"\n value={activity.retryPolicy?.backoffCoefficient || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'backoffCoefficient', parseFloat(e.target.value) || 1)}\n placeholder=\"2\"\n min=\"1\"\n max=\"10\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.maxInterval')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.maxIntervalMs || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'maxIntervalMs', parseInt(e.target.value) || 0)}\n placeholder=\"10000\"\n min=\"0\"\n />\n </div>\n </div>\n </div>\n\n {/* Activity Flags */}\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.activityOptions')}</h4>\n <div className=\"space-y-2\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={`activity-async-${index}`}\n checked={activity.async || false}\n onChange={(e) => updateActivity(index, 'async', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <label htmlFor={`activity-async-${index}`} className=\"text-xs text-gray-700 cursor-pointer\">\n {t('workflows.edgeEditor.asyncOption')}\n </label>\n </div>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={`activity-compensate-${index}`}\n checked={activity.compensate || false}\n onChange={(e) => updateActivity(index, 'compensate', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <label htmlFor={`activity-compensate-${index}`} className=\"text-xs text-gray-700 cursor-pointer\">\n {t('workflows.edgeEditor.compensateOption')}\n </label>\n </div>\n </div>\n </div>\n\n {/* Configuration */}\n <div className=\"border-t border-gray-200 pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.configurationJson')}</label>\n <JsonBuilder\n value={activity.config || {}}\n onChange={(config) => {\n const updated = [...activities]\n updated[index] = { ...updated[index], config }\n setActivities(updated)\n }}\n />\n <p className=\"text-xs text-gray-500 mt-0.5\">{t('workflows.edgeEditor.configurationHint')}</p>\n </div>\n\n {/* Delete Button */}\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removeActivity(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removeActivity')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Advanced Configuration */}\n <div className=\"border-t border-gray-200 pt-4 mt-4\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced(!showAdvanced)}\n className=\"flex items-center justify-between w-full text-left\"\n >\n <h3 className=\"text-sm font-semibold text-gray-900\">\n {t('workflows.edgeEditor.advancedConfiguration')}\n </h3>\n <svg\n className={`w-5 h-5 transition-transform ${showAdvanced ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {showAdvanced && (\n <div className=\"mt-3\">\n <JsonBuilder\n value={advancedConfig}\n onChange={setAdvancedConfig}\n />\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('workflows.edgeEditor.advancedConfigHint')}\n </p>\n </div>\n )}\n </div>\n </div>\n\n <DialogFooter className=\"flex justify-between\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={handleDelete}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.deleteTransition')}\n </Button>\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n >\n {t('workflows.edgeEditor.cancel')}\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n >\n {t('workflows.edgeEditor.saveChanges')}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n\n {/* Business Rule Selector - Using generic component */}\n <BusinessRulesSelector\n isOpen={showRuleSelector}\n onClose={closeRuleSelector}\n onSelect={handleRuleSelected}\n excludeRuleIds={\n ruleSelectorMode === 'pre'\n ? preConditions.map(c => c.ruleId)\n : postConditions.map(c => c.ruleId)\n }\n title={t('workflows.edgeEditor.selectBusinessRule')}\n description={t('workflows.edgeEditor.selectBusinessRuleDescription', {\n mode: ruleSelectorMode === 'pre'\n ? t('workflows.edgeEditor.preConditions').toLowerCase()\n : t('workflows.edgeEditor.postConditions').toLowerCase()\n })}\n />\n {ConfirmDialogElement}\n </Dialog>\n )\n}\n"],
4
+ "sourcesContent": ["'use client'\n\nimport type {Edge} from '@xyflow/react'\nimport {useEffect, useState} from 'react'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle\n} from '@open-mercato/ui/primitives/dialog'\nimport {Button} from '@open-mercato/ui/primitives/button'\nimport {Input} from '@open-mercato/ui/primitives/input'\nimport {Label} from '@open-mercato/ui/primitives/label'\nimport {\n Select,\n SelectContent,\n SelectItem,\n SelectTrigger,\n SelectValue,\n} from '@open-mercato/ui/primitives/select'\nimport {Badge} from '@open-mercato/ui/primitives/badge'\nimport {Separator} from '@open-mercato/ui/primitives/separator'\nimport {Plus, Trash2} from 'lucide-react'\nimport {type BusinessRule, BusinessRulesSelector} from './BusinessRulesSelector'\nimport {JsonBuilder} from '@open-mercato/ui/backend/JsonBuilder'\nimport {useT} from '@open-mercato/shared/lib/i18n/context'\nimport {useDialogKeyHandler} from '@open-mercato/ui/hooks/useDialogKeyHandler'\nimport {useConfirmDialog} from '@open-mercato/ui/backend/confirm-dialog'\n\nexport interface EdgeEditDialogProps {\n edge: Edge | null\n isOpen: boolean\n onClose: () => void\n onSave: (edgeId: string, updates: Partial<Edge['data']>) => void\n onDelete: (edgeId: string) => void\n}\n\ninterface TransitionCondition {\n ruleId: string\n required: boolean\n}\n\n/**\n * EdgeEditDialog - Modal dialog for editing transition properties\n *\n * Allows editing:\n * - Label\n * - Trigger type (auto, manual, signal, timer)\n * - Pre-conditions (guard rules)\n * - Post-conditions (validation rules)\n * - Activities\n * - Business rules integration\n */\nexport function EdgeEditDialog({ edge, isOpen, onClose, onSave, onDelete }: EdgeEditDialogProps) {\n const t = useT()\n const { confirm: confirmDialog, ConfirmDialogElement } = useConfirmDialog()\n const [transitionName, setTransitionName] = useState('')\n const [trigger, setTrigger] = useState('auto')\n const [priority, setPriority] = useState('100')\n const [continueOnActivityFailure, setContinueOnActivityFailure] = useState(false)\n const [preConditions, setPreConditions] = useState<TransitionCondition[]>([])\n const [postConditions, setPostConditions] = useState<TransitionCondition[]>([])\n const [showAdvanced, setShowAdvanced] = useState(false)\n const [advancedConfig, setAdvancedConfig] = useState<Record<string, any>>({})\n const [activities, setActivities] = useState<any[]>([])\n const [expandedActivities, setExpandedActivities] = useState<Set<number>>(new Set())\n const [expandedPreConditions, setExpandedPreConditions] = useState<Set<number>>(new Set())\n const [expandedPostConditions, setExpandedPostConditions] = useState<Set<number>>(new Set())\n const [showRuleSelector, setShowRuleSelector] = useState(false)\n const [ruleSelectorMode, setRuleSelectorMode] = useState<'pre' | 'post'>('pre')\n const [ruleDetailsCache, setRuleDetailsCache] = useState<Map<string, BusinessRule>>(new Map())\n\n // Generate a readable name from edge ID (e.g., \"start_to_cart\" -> \"Start to Cart\")\n const generateNameFromId = (edgeId: string): string => {\n return edgeId\n .split('_to_')\n .map(part => part.split('_').map(word =>\n word.charAt(0).toUpperCase() + word.slice(1)\n ).join(' '))\n .join(' \u2192 ')\n }\n\n // Load edge data when dialog opens\n useEffect(() => {\n if (edge && isOpen) {\n const edgeData = edge.data as any\n\n // Try to get transition name from various sources\n let loadedTransitionName = ''\n if (edgeData?.transitionName && edgeData.transitionName !== '') {\n loadedTransitionName = edgeData.transitionName\n } else if (edgeData?.label && edgeData.label !== '' && edgeData.label !== undefined) {\n loadedTransitionName = edgeData.label\n } else {\n // Generate a name from the edge ID as fallback\n loadedTransitionName = generateNameFromId(edge.id)\n }\n\n setTransitionName(loadedTransitionName)\n\n setTrigger(edgeData?.trigger || 'auto')\n setPriority((edgeData?.priority || 100).toString())\n setContinueOnActivityFailure(edgeData?.continueOnActivityFailure !== undefined ? edgeData.continueOnActivityFailure : false)\n\n // Handle pre/post conditions - convert from various formats\n const rawPreConditions = edgeData?.preConditions || []\n const rawPostConditions = edgeData?.postConditions || []\n\n // Convert to TransitionCondition format\n setPreConditions(Array.isArray(rawPreConditions)\n ? rawPreConditions.map((c: any) =>\n typeof c === 'string' ? { ruleId: c, required: true } : c\n )\n : []\n )\n setPostConditions(Array.isArray(rawPostConditions)\n ? rawPostConditions.map((c: any) =>\n typeof c === 'string' ? { ruleId: c, required: true } : c\n )\n : []\n )\n\n setActivities(edgeData?.activities || [])\n\n // Load advanced config (activities, etc.)\n const advancedFields: any = {}\n if (edgeData?.activities && edgeData.activities.length > 0) {\n advancedFields.activities = edgeData.activities\n }\n setAdvancedConfig(advancedFields)\n setExpandedActivities(new Set())\n setExpandedPreConditions(new Set())\n setExpandedPostConditions(new Set())\n }\n }, [edge, isOpen])\n\n const toggleActivity = (index: number) => {\n const newExpanded = new Set(expandedActivities)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedActivities(newExpanded)\n }\n\n const addActivity = () => {\n const newActivity = {\n activityId: `activity_${Date.now()}`,\n activityName: t('workflows.common.newActivity'),\n activityType: 'CALL_API',\n config: {},\n timeout: '',\n retryPolicy: {\n maxAttempts: 3,\n initialIntervalMs: 1000,\n backoffCoefficient: 2,\n maxIntervalMs: 10000,\n },\n }\n setActivities([...activities, newActivity])\n // Auto-expand the new activity\n const newExpanded = new Set(expandedActivities)\n newExpanded.add(activities.length)\n setExpandedActivities(newExpanded)\n }\n\n const removeActivity = async (index: number) => {\n const confirmed = await confirmDialog({\n title: t('workflows.edgeEditor.confirmRemoveActivity'),\n variant: 'destructive',\n })\n if (confirmed) {\n setActivities(activities.filter((_, i) => i !== index))\n // Remove from expanded set\n const newExpanded = new Set(expandedActivities)\n newExpanded.delete(index)\n setExpandedActivities(newExpanded)\n }\n }\n\n const updateActivity = (index: number, field: string, value: any) => {\n const updated = [...activities]\n updated[index] = { ...updated[index], [field]: value }\n setActivities(updated)\n }\n\n const updateActivityRetryPolicy = (index: number, field: string, value: any) => {\n const updated = [...activities]\n updated[index] = {\n ...updated[index],\n retryPolicy: {\n ...updated[index].retryPolicy,\n [field]: value,\n },\n }\n setActivities(updated)\n }\n\n // Business Rules Management\n const togglePreCondition = (index: number) => {\n const newExpanded = new Set(expandedPreConditions)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedPreConditions(newExpanded)\n }\n\n const togglePostCondition = (index: number) => {\n const newExpanded = new Set(expandedPostConditions)\n if (newExpanded.has(index)) {\n newExpanded.delete(index)\n } else {\n newExpanded.add(index)\n }\n setExpandedPostConditions(newExpanded)\n }\n\n const openRuleSelector = (mode: 'pre' | 'post') => {\n setRuleSelectorMode(mode)\n setShowRuleSelector(true)\n }\n\n const closeRuleSelector = () => {\n setShowRuleSelector(false)\n }\n\n const handleRuleSelected = (ruleId: string, rule: BusinessRule) => {\n // Cache the rule details for display\n setRuleDetailsCache(prev => new Map(prev).set(ruleId, rule))\n\n if (ruleSelectorMode === 'pre') {\n if (!preConditions.find(c => c.ruleId === ruleId)) {\n setPreConditions([...preConditions, { ruleId, required: true }])\n }\n } else {\n if (!postConditions.find(c => c.ruleId === ruleId)) {\n setPostConditions([...postConditions, { ruleId, required: true }])\n }\n }\n closeRuleSelector()\n }\n\n const removePreCondition = (index: number) => {\n setPreConditions(preConditions.filter((_, i) => i !== index))\n const newExpanded = new Set(expandedPreConditions)\n newExpanded.delete(index)\n setExpandedPreConditions(newExpanded)\n }\n\n const removePostCondition = (index: number) => {\n setPostConditions(postConditions.filter((_, i) => i !== index))\n const newExpanded = new Set(expandedPostConditions)\n newExpanded.delete(index)\n setExpandedPostConditions(newExpanded)\n }\n\n const updatePreCondition = (index: number, field: keyof TransitionCondition, value: any) => {\n const updated = [...preConditions]\n updated[index] = { ...updated[index], [field]: value }\n setPreConditions(updated)\n }\n\n const updatePostCondition = (index: number, field: keyof TransitionCondition, value: any) => {\n const updated = [...postConditions]\n updated[index] = { ...updated[index], [field]: value }\n setPostConditions(updated)\n }\n\n const getBusinessRuleDetails = (ruleId: string): BusinessRule | null => {\n return ruleDetailsCache.get(ruleId) || null\n }\n\n const handleSave = () => {\n if (!edge) return\n\n const updates: Partial<Edge['data']> = {\n transitionName,\n label: transitionName, // Keep label for backward compatibility\n trigger,\n priority: parseInt(priority) || 100,\n continueOnActivityFailure,\n preConditions: preConditions.length > 0 ? preConditions : undefined,\n postConditions: postConditions.length > 0 ? postConditions : undefined,\n activities: activities.length > 0 ? activities : undefined,\n }\n\n // Merge advanced config\n if (advancedConfig && Object.keys(advancedConfig).length > 0) {\n Object.assign(updates, advancedConfig)\n }\n\n onSave(edge.id, updates)\n onClose()\n }\n\n const handleDelete = () => {\n if (!edge) return\n onDelete(edge.id)\n }\n\n const handleKeyDown = useDialogKeyHandler({ onConfirm: handleSave, onCancel: onClose })\n\n if (!isOpen || !edge) return null\n\n const triggerVariant = trigger === 'auto' ? 'default' : trigger === 'manual' ? 'secondary' : 'outline'\n\n return (\n <Dialog open={isOpen} onOpenChange={onClose}>\n <DialogContent className=\"sm:max-w-4xl max-h-[90vh] overflow-y-auto\" onKeyDown={handleKeyDown}>\n <DialogHeader>\n <div className=\"flex items-center gap-2 mb-2\">\n <DialogTitle>{t('workflows.edgeEditor.title')}</DialogTitle>\n <Badge variant={triggerVariant} className=\"text-xs\">\n {t(`workflows.transitions.triggers.${trigger}`)}\n </Badge>\n </div>\n <div className=\"space-y-1\">\n <DialogDescription>\n {t('workflows.edgeEditor.description')}\n </DialogDescription>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium\">{t('workflows.edgeEditor.id')}:</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.id}</code>\n </div>\n <div className=\"flex items-center gap-2 text-xs text-muted-foreground\">\n <span className=\"font-medium\">{t('workflows.edgeEditor.flow')}:</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.source}</code>\n <span>\u2192</span>\n <code className=\"px-1.5 py-0.5 rounded bg-muted font-mono\">{edge.target}</code>\n </div>\n </div>\n </DialogHeader>\n\n <div className=\"space-y-4\">\n {/* Transition Name */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"transitionName\">{t('workflows.edgeEditor.transitionName')}</Label>\n <Input\n id=\"transitionName\"\n type=\"text\"\n value={transitionName}\n onChange={(e) => setTransitionName(e.target.value)}\n placeholder={t('workflows.edgeEditor.transitionNamePlaceholder', { name: generateNameFromId(edge.id) })}\n autoFocus\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.transitionNameHint')}\n </p>\n </div>\n\n {/* Trigger Type */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"trigger\">{t('workflows.edgeEditor.triggerType')}</Label>\n <Select value={trigger} onValueChange={(value) => setTrigger(value)}>\n <SelectTrigger id=\"trigger\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"auto\">{t('workflows.transitions.triggers.auto')}</SelectItem>\n <SelectItem value=\"manual\">{t('workflows.transitions.triggers.manual')}</SelectItem>\n <SelectItem value=\"signal\">{t('workflows.transitions.triggers.signal')}</SelectItem>\n <SelectItem value=\"timer\">{t('workflows.transitions.triggers.timer')}</SelectItem>\n </SelectContent>\n </Select>\n <p className=\"text-xs text-muted-foreground\">\n {t(`workflows.edgeEditor.triggerDescriptions.${trigger}`)}\n </p>\n </div>\n\n {/* Priority */}\n <div className=\"space-y-2\">\n <Label htmlFor=\"priority\">{t('workflows.edgeEditor.priority')}</Label>\n <Input\n id=\"priority\"\n type=\"number\"\n value={priority}\n onChange={(e) => setPriority(e.target.value)}\n placeholder=\"100\"\n min=\"0\"\n max=\"9999\"\n />\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.priorityHint')}\n </p>\n </div>\n\n <div className=\"space-y-2\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id=\"continueOnActivityFailure\"\n checked={continueOnActivityFailure}\n onChange={(e) => setContinueOnActivityFailure(e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <Label htmlFor=\"continueOnActivityFailure\" className=\"font-normal cursor-pointer\">\n {t('workflows.edgeEditor.continueOnActivityFailure')}\n </Label>\n </div>\n <p className=\"text-xs text-muted-foreground ml-6\">\n {t('workflows.edgeEditor.continueOnActivityFailureHint')}\n </p>\n </div>\n\n <Separator />\n\n {/* Pre-conditions (Business Rules) */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold\">\n {t('workflows.edgeEditor.preConditions')} ({preConditions.length})\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.preConditionsHint')}\n </p>\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => openRuleSelector('pre')}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addRule')}\n </Button>\n </div>\n\n {preConditions.length === 0 && (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.edgeEditor.noPreConditions')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {preConditions.map((condition, index) => {\n const isExpanded = expandedPreConditions.has(index)\n const rule = getBusinessRuleDetails(condition.ruleId)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => togglePreCondition(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {rule?.ruleName || condition.ruleId}\n </span>\n {condition.required && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('workflows.edgeEditor.required')}\n </span>\n )}\n {rule && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800\">\n {rule.ruleType}\n </span>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.ruleId')}: <code className=\"bg-white px-1 rounded\">{condition.ruleId}</code>\n </p>\n {rule?.description && (\n <p className=\"text-xs text-gray-500 mt-1 line-clamp-1\">{rule.description}</p>\n )}\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.ruleId')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={condition.ruleId}\n onChange={(e) => updatePreCondition(index, 'ruleId', e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-xs font-medium text-gray-700\">\n <input\n type=\"checkbox\"\n checked={condition.required}\n onChange={(e) => updatePreCondition(index, 'required', e.target.checked)}\n className=\"rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n />\n {t('workflows.edgeEditor.requiredCheckbox')}\n </label>\n </div>\n\n {rule && (\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.businessRuleDetails')}</h4>\n <dl className=\"space-y-1 text-xs\">\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Name:</dt>\n <dd className=\"text-gray-900\">{rule.ruleName}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Type:</dt>\n <dd className=\"text-gray-900\">{rule.ruleType}</dd>\n </div>\n {rule.ruleCategory && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Category:</dt>\n <dd className=\"text-gray-900\">{rule.ruleCategory}</dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Entity Type:</dt>\n <dd className=\"text-gray-900 font-mono text-xs\">{rule.entityType}</dd>\n </div>\n {rule.eventType && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Event Type:</dt>\n <dd className=\"text-gray-900\">{rule.eventType}</dd>\n </div>\n )}\n {rule.description && (\n <div className=\"mt-2 pt-2 border-t border-gray-200\">\n <dt className=\"font-medium text-gray-700 mb-1\">Description:</dt>\n <dd className=\"text-gray-600\">{rule.description}</dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removePreCondition(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removePreCondition')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Post-conditions (Business Rules) */}\n <div className=\"space-y-3\">\n <div className=\"flex items-center justify-between\">\n <div>\n <h3 className=\"text-sm font-semibold\">\n {t('workflows.edgeEditor.postConditions')} ({postConditions.length})\n </h3>\n <p className=\"text-xs text-muted-foreground\">\n {t('workflows.edgeEditor.postConditionsHint')}\n </p>\n </div>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={() => openRuleSelector('post')}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addRule')}\n </Button>\n </div>\n\n {postConditions.length === 0 && (\n <div className=\"p-4 text-center text-sm text-muted-foreground bg-muted rounded-lg border\">\n {t('workflows.edgeEditor.noPostConditions')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {postConditions.map((condition, index) => {\n const isExpanded = expandedPostConditions.has(index)\n const rule = getBusinessRuleDetails(condition.ruleId)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => togglePostCondition(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {rule?.ruleName || condition.ruleId}\n </span>\n {condition.required && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-red-100 text-red-800\">\n {t('workflows.edgeEditor.required')}\n </span>\n )}\n {rule && (\n <span className=\"inline-flex items-center px-2 py-0.5 rounded text-xs font-medium bg-purple-100 text-purple-800\">\n {rule.ruleType}\n </span>\n )}\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.ruleId')}: <code className=\"bg-white px-1 rounded\">{condition.ruleId}</code>\n </p>\n {rule?.description && (\n <p className=\"text-xs text-gray-500 mt-1 line-clamp-1\">{rule.description}</p>\n )}\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.ruleId')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={condition.ruleId}\n onChange={(e) => updatePostCondition(index, 'ruleId', e.target.value)}\n />\n </div>\n\n <div>\n <label className=\"flex items-center gap-2 text-xs font-medium text-gray-700\">\n <input\n type=\"checkbox\"\n checked={condition.required}\n onChange={(e) => updatePostCondition(index, 'required', e.target.checked)}\n className=\"rounded border-gray-300 text-blue-600 focus-visible:ring-ring\"\n />\n {t('workflows.edgeEditor.requiredPostCheckbox')}\n </label>\n </div>\n\n {rule && (\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.businessRuleDetails')}</h4>\n <dl className=\"space-y-1 text-xs\">\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Name:</dt>\n <dd className=\"text-gray-900\">{rule.ruleName}</dd>\n </div>\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Type:</dt>\n <dd className=\"text-gray-900\">{rule.ruleType}</dd>\n </div>\n {rule.ruleCategory && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Category:</dt>\n <dd className=\"text-gray-900\">{rule.ruleCategory}</dd>\n </div>\n )}\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Entity Type:</dt>\n <dd className=\"text-gray-900 font-mono text-xs\">{rule.entityType}</dd>\n </div>\n {rule.eventType && (\n <div className=\"flex justify-between\">\n <dt className=\"font-medium text-gray-700\">Event Type:</dt>\n <dd className=\"text-gray-900\">{rule.eventType}</dd>\n </div>\n )}\n {rule.description && (\n <div className=\"mt-2 pt-2 border-t border-gray-200\">\n <dt className=\"font-medium text-gray-700 mb-1\">Description:</dt>\n <dd className=\"text-gray-600\">{rule.description}</dd>\n </div>\n )}\n </dl>\n </div>\n )}\n\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removePostCondition(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removePostCondition')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Activities Section */}\n <div className=\"border-t border-gray-200 pt-4 mt-4\">\n <div className=\"flex items-center justify-between mb-3\">\n <h3 className=\"text-sm font-semibold text-gray-900\">\n {t('workflows.edgeEditor.activities')} ({activities.length})\n </h3>\n <Button\n type=\"button\"\n size=\"sm\"\n onClick={addActivity}\n >\n <Plus className=\"size-3\" />\n {t('workflows.edgeEditor.addActivity')}\n </Button>\n </div>\n\n {activities.length === 0 && (\n <div className=\"p-4 text-center text-sm text-gray-500 bg-gray-50 rounded-lg border border-gray-200\">\n {t('workflows.edgeEditor.noActivities')}\n </div>\n )}\n\n <div className=\"space-y-2\">\n {activities.map((activity, index) => {\n const isExpanded = expandedActivities.has(index)\n return (\n <div key={index} className=\"border border-gray-200 rounded-lg bg-gray-50\">\n <button\n type=\"button\"\n onClick={() => toggleActivity(index)}\n className=\"w-full px-4 py-3 text-left flex items-center justify-between hover:bg-gray-100 transition-colors rounded-t-lg\"\n >\n <div className=\"flex-1\">\n <div className=\"flex items-center gap-2\">\n <span className=\"text-sm font-semibold text-gray-900\">\n {activity.activityName || activity.label || activity.activityId || `Activity ${index + 1}`}\n </span>\n <Badge variant=\"secondary\" className=\"text-xs\">\n {activity.activityType}\n </Badge>\n </div>\n <p className=\"text-xs text-gray-600 mt-1\">\n {t('workflows.edgeEditor.activityId')}: <code className=\"bg-white px-1 rounded\">{activity.activityId}</code>\n </p>\n </div>\n <svg\n className={`w-5 h-5 text-gray-400 transition-transform ${isExpanded ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n\n {isExpanded && (\n <div className=\"px-4 pb-4 space-y-3 border-t border-gray-200 bg-white\">\n {/* Activity ID */}\n <div className=\"pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityId')} *</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.activityId}\n onChange={(e) => updateActivity(index, 'activityId', e.target.value)}\n placeholder={t('workflows.edgeEditor.activityIdPlaceholder')}\n />\n </div>\n\n {/* Activity Name */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityName')} *</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.activityName || ''}\n onChange={(e) => updateActivity(index, 'activityName', e.target.value)}\n placeholder={t('workflows.edgeEditor.activityNamePlaceholder')}\n />\n </div>\n\n {/* Activity Type */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.activityType')} *</label>\n <Select\n value={activity.activityType}\n onValueChange={(value) => updateActivity(index, 'activityType', value)}\n >\n <SelectTrigger size=\"sm\">\n <SelectValue />\n </SelectTrigger>\n <SelectContent>\n <SelectItem value=\"SEND_EMAIL\">{t('workflows.activities.types.SEND_EMAIL')}</SelectItem>\n <SelectItem value=\"CALL_API\">{t('workflows.activities.types.CALL_API')}</SelectItem>\n <SelectItem value=\"UPDATE_ENTITY\">{t('workflows.activities.types.UPDATE_ENTITY')}</SelectItem>\n <SelectItem value=\"EMIT_EVENT\">{t('workflows.activities.types.EMIT_EVENT')}</SelectItem>\n <SelectItem value=\"CALL_WEBHOOK\">{t('workflows.activities.types.CALL_WEBHOOK')}</SelectItem>\n <SelectItem value=\"EXECUTE_FUNCTION\">{t('workflows.activities.types.EXECUTE_FUNCTION')}</SelectItem>\n <SelectItem value=\"WAIT\">{t('workflows.activities.types.WAIT')}</SelectItem>\n </SelectContent>\n </Select>\n </div>\n\n {/* Timeout */}\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.timeout')}</label>\n <Input\n type=\"text\"\n size=\"sm\"\n value={activity.timeout || ''}\n onChange={(e) => updateActivity(index, 'timeout', e.target.value)}\n placeholder={t('workflows.edgeEditor.timeoutPlaceholder')}\n />\n <p className=\"text-xs text-gray-500 mt-0.5\">{t('workflows.edgeEditor.timeoutHint')}</p>\n </div>\n\n {/* Retry Policy */}\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.retryPolicy')}</h4>\n <div className=\"grid grid-cols-1 sm:grid-cols-2 gap-2\">\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.maxAttempts')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.maxAttempts || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'maxAttempts', parseInt(e.target.value) || 0)}\n placeholder=\"3\"\n min=\"1\"\n max=\"10\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.initialInterval')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.initialIntervalMs || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'initialIntervalMs', parseInt(e.target.value) || 0)}\n placeholder=\"1000\"\n min=\"0\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.backoffCoefficient')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n step=\"0.1\"\n value={activity.retryPolicy?.backoffCoefficient || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'backoffCoefficient', parseFloat(e.target.value) || 1)}\n placeholder=\"2\"\n min=\"1\"\n max=\"10\"\n />\n </div>\n <div>\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.maxInterval')}</label>\n <Input\n type=\"number\"\n size=\"sm\"\n value={activity.retryPolicy?.maxIntervalMs || ''}\n onChange={(e) => updateActivityRetryPolicy(index, 'maxIntervalMs', parseInt(e.target.value) || 0)}\n placeholder=\"10000\"\n min=\"0\"\n />\n </div>\n </div>\n </div>\n\n {/* Activity Flags */}\n <div className=\"border-t border-gray-200 pt-3\">\n <h4 className=\"text-xs font-semibold text-gray-900 mb-2\">{t('workflows.edgeEditor.activityOptions')}</h4>\n <div className=\"space-y-2\">\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={`activity-async-${index}`}\n checked={activity.async || false}\n onChange={(e) => updateActivity(index, 'async', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <label htmlFor={`activity-async-${index}`} className=\"text-xs text-gray-700 cursor-pointer\">\n {t('workflows.edgeEditor.asyncOption')}\n </label>\n </div>\n <div className=\"flex items-center space-x-2\">\n <input\n type=\"checkbox\"\n id={`activity-compensate-${index}`}\n checked={activity.compensate || false}\n onChange={(e) => updateActivity(index, 'compensate', e.target.checked)}\n className=\"h-4 w-4 rounded border-gray-300\"\n />\n <label htmlFor={`activity-compensate-${index}`} className=\"text-xs text-gray-700 cursor-pointer\">\n {t('workflows.edgeEditor.compensateOption')}\n </label>\n </div>\n </div>\n </div>\n\n {/* Configuration */}\n <div className=\"border-t border-gray-200 pt-3\">\n <label className=\"block text-xs font-medium text-gray-700 mb-1\">{t('workflows.edgeEditor.configurationJson')}</label>\n <JsonBuilder\n value={activity.config || {}}\n onChange={(config) => {\n const updated = [...activities]\n updated[index] = { ...updated[index], config }\n setActivities(updated)\n }}\n />\n <p className=\"text-xs text-gray-500 mt-0.5\">{t('workflows.edgeEditor.configurationHint')}</p>\n </div>\n\n {/* Delete Button */}\n <div className=\"border-t border-gray-200 pt-3\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n size=\"sm\"\n onClick={() => removeActivity(index)}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.removeActivity')}\n </Button>\n </div>\n </div>\n )}\n </div>\n )\n })}\n </div>\n </div>\n\n {/* Advanced Configuration */}\n <div className=\"border-t border-gray-200 pt-4 mt-4\">\n <button\n type=\"button\"\n onClick={() => setShowAdvanced(!showAdvanced)}\n className=\"flex items-center justify-between w-full text-left\"\n >\n <h3 className=\"text-sm font-semibold text-gray-900\">\n {t('workflows.edgeEditor.advancedConfiguration')}\n </h3>\n <svg\n className={`w-5 h-5 transition-transform ${showAdvanced ? 'rotate-180' : ''}`}\n fill=\"none\"\n stroke=\"currentColor\"\n viewBox=\"0 0 24 24\"\n >\n <path strokeLinecap=\"round\" strokeLinejoin=\"round\" strokeWidth={2} d=\"M19 9l-7 7-7-7\" />\n </svg>\n </button>\n {showAdvanced && (\n <div className=\"mt-3\">\n <JsonBuilder\n value={advancedConfig}\n onChange={setAdvancedConfig}\n />\n <p className=\"text-xs text-gray-500 mt-1\">\n {t('workflows.edgeEditor.advancedConfigHint')}\n </p>\n </div>\n )}\n </div>\n </div>\n\n <DialogFooter className=\"flex justify-between\">\n <Button\n type=\"button\"\n variant=\"destructive\"\n onClick={handleDelete}\n >\n <Trash2 className=\"size-4\" />\n {t('workflows.edgeEditor.deleteTransition')}\n </Button>\n <div className=\"flex gap-2\">\n <Button\n type=\"button\"\n variant=\"outline\"\n onClick={onClose}\n >\n {t('workflows.edgeEditor.cancel')}\n </Button>\n <Button\n type=\"button\"\n onClick={handleSave}\n >\n {t('workflows.edgeEditor.saveChanges')}\n </Button>\n </div>\n </DialogFooter>\n </DialogContent>\n\n {/* Business Rule Selector - Using generic component */}\n <BusinessRulesSelector\n isOpen={showRuleSelector}\n onClose={closeRuleSelector}\n onSelect={handleRuleSelected}\n excludeRuleIds={\n ruleSelectorMode === 'pre'\n ? preConditions.map(c => c.ruleId)\n : postConditions.map(c => c.ruleId)\n }\n title={t('workflows.edgeEditor.selectBusinessRule')}\n description={t('workflows.edgeEditor.selectBusinessRuleDescription', {\n mode: ruleSelectorMode === 'pre'\n ? t('workflows.edgeEditor.preConditions').toLowerCase()\n : t('workflows.edgeEditor.postConditions').toLowerCase()\n })}\n />\n {ConfirmDialogElement}\n </Dialog>\n )\n}\n"],
5
5
  "mappings": ";AA2TU,SACE,KADF;AAxTV,SAAQ,WAAW,gBAAe;AAClC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAQ,cAAa;AACrB,SAAQ,aAAY;AACpB,SAAQ,aAAY;AACpB;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAQ,aAAY;AACpB,SAAQ,iBAAgB;AACxB,SAAQ,MAAM,cAAa;AAC3B,SAA2B,6BAA4B;AACvD,SAAQ,mBAAkB;AAC1B,SAAQ,YAAW;AACnB,SAAQ,2BAA0B;AAClC,SAAQ,wBAAuB;AA0BxB,SAAS,eAAe,EAAE,MAAM,QAAQ,SAAS,QAAQ,SAAS,GAAwB;AAC/F,QAAM,IAAI,KAAK;AACf,QAAM,EAAE,SAAS,eAAe,qBAAqB,IAAI,iBAAiB;AAC1E,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAS,EAAE;AACvD,QAAM,CAAC,SAAS,UAAU,IAAI,SAAS,MAAM;AAC7C,QAAM,CAAC,UAAU,WAAW,IAAI,SAAS,KAAK;AAC9C,QAAM,CAAC,2BAA2B,4BAA4B,IAAI,SAAS,KAAK;AAChF,QAAM,CAAC,eAAe,gBAAgB,IAAI,SAAgC,CAAC,CAAC;AAC5E,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAAgC,CAAC,CAAC;AAC9E,QAAM,CAAC,cAAc,eAAe,IAAI,SAAS,KAAK;AACtD,QAAM,CAAC,gBAAgB,iBAAiB,IAAI,SAA8B,CAAC,CAAC;AAC5E,QAAM,CAAC,YAAY,aAAa,IAAI,SAAgB,CAAC,CAAC;AACtD,QAAM,CAAC,oBAAoB,qBAAqB,IAAI,SAAsB,oBAAI,IAAI,CAAC;AACnF,QAAM,CAAC,uBAAuB,wBAAwB,IAAI,SAAsB,oBAAI,IAAI,CAAC;AACzF,QAAM,CAAC,wBAAwB,yBAAyB,IAAI,SAAsB,oBAAI,IAAI,CAAC;AAC3F,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAS,KAAK;AAC9D,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAyB,KAAK;AAC9E,QAAM,CAAC,kBAAkB,mBAAmB,IAAI,SAAoC,oBAAI,IAAI,CAAC;AAG7F,QAAM,qBAAqB,CAAC,WAA2B;AACrD,WAAO,OACJ,MAAM,MAAM,EACZ,IAAI,UAAQ,KAAK,MAAM,GAAG,EAAE;AAAA,MAAI,UAC/B,KAAK,OAAO,CAAC,EAAE,YAAY,IAAI,KAAK,MAAM,CAAC;AAAA,IAC7C,EAAE,KAAK,GAAG,CAAC,EACV,KAAK,UAAK;AAAA,EACf;AAGA,YAAU,MAAM;AACd,QAAI,QAAQ,QAAQ;AAClB,YAAM,WAAW,KAAK;AAGtB,UAAI,uBAAuB;AAC3B,UAAI,UAAU,kBAAkB,SAAS,mBAAmB,IAAI;AAC9D,+BAAuB,SAAS;AAAA,MAClC,WAAW,UAAU,SAAS,SAAS,UAAU,MAAM,SAAS,UAAU,QAAW;AACnF,+BAAuB,SAAS;AAAA,MAClC,OAAO;AAEL,+BAAuB,mBAAmB,KAAK,EAAE;AAAA,MACnD;AAEA,wBAAkB,oBAAoB;AAEtC,iBAAW,UAAU,WAAW,MAAM;AACtC,mBAAa,UAAU,YAAY,KAAK,SAAS,CAAC;AAClD,mCAA6B,UAAU,8BAA8B,SAAY,SAAS,4BAA4B,KAAK;AAG3H,YAAM,mBAAmB,UAAU,iBAAiB,CAAC;AACrD,YAAM,oBAAoB,UAAU,kBAAkB,CAAC;AAGvD;AAAA,QAAiB,MAAM,QAAQ,gBAAgB,IAC3C,iBAAiB;AAAA,UAAI,CAAC,MACpB,OAAO,MAAM,WAAW,EAAE,QAAQ,GAAG,UAAU,KAAK,IAAI;AAAA,QAC1D,IACA,CAAC;AAAA,MACL;AACA;AAAA,QAAkB,MAAM,QAAQ,iBAAiB,IAC7C,kBAAkB;AAAA,UAAI,CAAC,MACrB,OAAO,MAAM,WAAW,EAAE,QAAQ,GAAG,UAAU,KAAK,IAAI;AAAA,QAC1D,IACA,CAAC;AAAA,MACL;AAEA,oBAAc,UAAU,cAAc,CAAC,CAAC;AAGxC,YAAM,iBAAsB,CAAC;AAC7B,UAAI,UAAU,cAAc,SAAS,WAAW,SAAS,GAAG;AAC1D,uBAAe,aAAa,SAAS;AAAA,MACvC;AACA,wBAAkB,cAAc;AAChC,4BAAsB,oBAAI,IAAI,CAAC;AAC/B,+BAAyB,oBAAI,IAAI,CAAC;AAClC,gCAA0B,oBAAI,IAAI,CAAC;AAAA,IACrC;AAAA,EACF,GAAG,CAAC,MAAM,MAAM,CAAC;AAEjB,QAAM,iBAAiB,CAAC,UAAkB;AACxC,UAAM,cAAc,IAAI,IAAI,kBAAkB;AAC9C,QAAI,YAAY,IAAI,KAAK,GAAG;AAC1B,kBAAY,OAAO,KAAK;AAAA,IAC1B,OAAO;AACL,kBAAY,IAAI,KAAK;AAAA,IACvB;AACA,0BAAsB,WAAW;AAAA,EACnC;AAEA,QAAM,cAAc,MAAM;AACxB,UAAM,cAAc;AAAA,MAClB,YAAY,YAAY,KAAK,IAAI,CAAC;AAAA,MAClC,cAAc,EAAE,8BAA8B;AAAA,MAC9C,cAAc;AAAA,MACd,QAAQ,CAAC;AAAA,MACT,SAAS;AAAA,MACT,aAAa;AAAA,QACX,aAAa;AAAA,QACb,mBAAmB;AAAA,QACnB,oBAAoB;AAAA,QACpB,eAAe;AAAA,MACjB;AAAA,IACF;AACA,kBAAc,CAAC,GAAG,YAAY,WAAW,CAAC;AAE1C,UAAM,cAAc,IAAI,IAAI,kBAAkB;AAC9C,gBAAY,IAAI,WAAW,MAAM;AACjC,0BAAsB,WAAW;AAAA,EACnC;AAEA,QAAM,iBAAiB,OAAO,UAAkB;AAC9C,UAAM,YAAY,MAAM,cAAc;AAAA,MACpC,OAAO,EAAE,4CAA4C;AAAA,MACrD,SAAS;AAAA,IACX,CAAC;AACD,QAAI,WAAW;AACb,oBAAc,WAAW,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAEtD,YAAM,cAAc,IAAI,IAAI,kBAAkB;AAC9C,kBAAY,OAAO,KAAK;AACxB,4BAAsB,WAAW;AAAA,IACnC;AAAA,EACF;AAEA,QAAM,iBAAiB,CAAC,OAAe,OAAe,UAAe;AACnE,UAAM,UAAU,CAAC,GAAG,UAAU;AAC9B,YAAQ,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG,CAAC,KAAK,GAAG,MAAM;AACrD,kBAAc,OAAO;AAAA,EACvB;AAEA,QAAM,4BAA4B,CAAC,OAAe,OAAe,UAAe;AAC9E,UAAM,UAAU,CAAC,GAAG,UAAU;AAC9B,YAAQ,KAAK,IAAI;AAAA,MACf,GAAG,QAAQ,KAAK;AAAA,MAChB,aAAa;AAAA,QACX,GAAG,QAAQ,KAAK,EAAE;AAAA,QAClB,CAAC,KAAK,GAAG;AAAA,MACX;AAAA,IACF;AACA,kBAAc,OAAO;AAAA,EACvB;AAGA,QAAM,qBAAqB,CAAC,UAAkB;AAC5C,UAAM,cAAc,IAAI,IAAI,qBAAqB;AACjD,QAAI,YAAY,IAAI,KAAK,GAAG;AAC1B,kBAAY,OAAO,KAAK;AAAA,IAC1B,OAAO;AACL,kBAAY,IAAI,KAAK;AAAA,IACvB;AACA,6BAAyB,WAAW;AAAA,EACtC;AAEA,QAAM,sBAAsB,CAAC,UAAkB;AAC7C,UAAM,cAAc,IAAI,IAAI,sBAAsB;AAClD,QAAI,YAAY,IAAI,KAAK,GAAG;AAC1B,kBAAY,OAAO,KAAK;AAAA,IAC1B,OAAO;AACL,kBAAY,IAAI,KAAK;AAAA,IACvB;AACA,8BAA0B,WAAW;AAAA,EACvC;AAEA,QAAM,mBAAmB,CAAC,SAAyB;AACjD,wBAAoB,IAAI;AACxB,wBAAoB,IAAI;AAAA,EAC1B;AAEA,QAAM,oBAAoB,MAAM;AAC9B,wBAAoB,KAAK;AAAA,EAC3B;AAEA,QAAM,qBAAqB,CAAC,QAAgB,SAAuB;AAEjE,wBAAoB,UAAQ,IAAI,IAAI,IAAI,EAAE,IAAI,QAAQ,IAAI,CAAC;AAE3D,QAAI,qBAAqB,OAAO;AAC9B,UAAI,CAAC,cAAc,KAAK,OAAK,EAAE,WAAW,MAAM,GAAG;AACjD,yBAAiB,CAAC,GAAG,eAAe,EAAE,QAAQ,UAAU,KAAK,CAAC,CAAC;AAAA,MACjE;AAAA,IACF,OAAO;AACL,UAAI,CAAC,eAAe,KAAK,OAAK,EAAE,WAAW,MAAM,GAAG;AAClD,0BAAkB,CAAC,GAAG,gBAAgB,EAAE,QAAQ,UAAU,KAAK,CAAC,CAAC;AAAA,MACnE;AAAA,IACF;AACA,sBAAkB;AAAA,EACpB;AAEA,QAAM,qBAAqB,CAAC,UAAkB;AAC5C,qBAAiB,cAAc,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAC5D,UAAM,cAAc,IAAI,IAAI,qBAAqB;AACjD,gBAAY,OAAO,KAAK;AACxB,6BAAyB,WAAW;AAAA,EACtC;AAEA,QAAM,sBAAsB,CAAC,UAAkB;AAC7C,sBAAkB,eAAe,OAAO,CAAC,GAAG,MAAM,MAAM,KAAK,CAAC;AAC9D,UAAM,cAAc,IAAI,IAAI,sBAAsB;AAClD,gBAAY,OAAO,KAAK;AACxB,8BAA0B,WAAW;AAAA,EACvC;AAEA,QAAM,qBAAqB,CAAC,OAAe,OAAkC,UAAe;AAC1F,UAAM,UAAU,CAAC,GAAG,aAAa;AACjC,YAAQ,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG,CAAC,KAAK,GAAG,MAAM;AACrD,qBAAiB,OAAO;AAAA,EAC1B;AAEA,QAAM,sBAAsB,CAAC,OAAe,OAAkC,UAAe;AAC3F,UAAM,UAAU,CAAC,GAAG,cAAc;AAClC,YAAQ,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG,CAAC,KAAK,GAAG,MAAM;AACrD,sBAAkB,OAAO;AAAA,EAC3B;AAEA,QAAM,yBAAyB,CAAC,WAAwC;AACtE,WAAO,iBAAiB,IAAI,MAAM,KAAK;AAAA,EACzC;AAEA,QAAM,aAAa,MAAM;AACvB,QAAI,CAAC,KAAM;AAEX,UAAM,UAAiC;AAAA,MACrC;AAAA,MACA,OAAO;AAAA;AAAA,MACP;AAAA,MACA,UAAU,SAAS,QAAQ,KAAK;AAAA,MAChC;AAAA,MACA,eAAe,cAAc,SAAS,IAAI,gBAAgB;AAAA,MAC1D,gBAAgB,eAAe,SAAS,IAAI,iBAAiB;AAAA,MAC7D,YAAY,WAAW,SAAS,IAAI,aAAa;AAAA,IACnD;AAGA,QAAI,kBAAkB,OAAO,KAAK,cAAc,EAAE,SAAS,GAAG;AAC5D,aAAO,OAAO,SAAS,cAAc;AAAA,IACvC;AAEA,WAAO,KAAK,IAAI,OAAO;AACvB,YAAQ;AAAA,EACV;AAEA,QAAM,eAAe,MAAM;AACzB,QAAI,CAAC,KAAM;AACX,aAAS,KAAK,EAAE;AAAA,EAClB;AAEA,QAAM,gBAAgB,oBAAoB,EAAE,WAAW,YAAY,UAAU,QAAQ,CAAC;AAEtF,MAAI,CAAC,UAAU,CAAC,KAAM,QAAO;AAE7B,QAAM,iBAAiB,YAAY,SAAS,YAAY,YAAY,WAAW,cAAc;AAE7F,SACE,qBAAC,UAAO,MAAM,QAAQ,cAAc,SAClC;AAAA,yBAAC,iBAAc,WAAU,6CAA4C,WAAW,eAC9E;AAAA,2BAAC,gBACC;AAAA,6BAAC,SAAI,WAAU,gCACb;AAAA,8BAAC,eAAa,YAAE,4BAA4B,GAAE;AAAA,UAC9C,oBAAC,SAAM,SAAS,gBAAgB,WAAU,WACvC,YAAE,kCAAkC,OAAO,EAAE,GAChD;AAAA,WACF;AAAA,QACA,qBAAC,SAAI,WAAU,aACb;AAAA,8BAAC,qBACE,YAAE,kCAAkC,GACvC;AAAA,UACA,qBAAC,SAAI,WAAU,yDACb;AAAA,iCAAC,UAAK,WAAU,eAAe;AAAA,gBAAE,yBAAyB;AAAA,cAAE;AAAA,eAAC;AAAA,YAC7D,oBAAC,UAAK,WAAU,4CAA4C,eAAK,IAAG;AAAA,aACtE;AAAA,UACA,qBAAC,SAAI,WAAU,yDACb;AAAA,iCAAC,UAAK,WAAU,eAAe;AAAA,gBAAE,2BAA2B;AAAA,cAAE;AAAA,eAAC;AAAA,YAC/D,oBAAC,UAAK,WAAU,4CAA4C,eAAK,QAAO;AAAA,YACxE,oBAAC,UAAK,oBAAC;AAAA,YACP,oBAAC,UAAK,WAAU,4CAA4C,eAAK,QAAO;AAAA,aAC1E;AAAA,WACF;AAAA,SACF;AAAA,MAEA,qBAAC,SAAI,WAAU,aAEX;AAAA,6BAAC,SAAI,WAAU,aACb;AAAA,8BAAC,SAAM,SAAQ,kBAAkB,YAAE,qCAAqC,GAAE;AAAA,UAC1E;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,kBAAkB,EAAE,OAAO,KAAK;AAAA,cACjD,aAAa,EAAE,kDAAkD,EAAE,MAAM,mBAAmB,KAAK,EAAE,EAAE,CAAC;AAAA,cACtG,WAAS;AAAA;AAAA,UACX;AAAA,UACA,oBAAC,OAAE,WAAU,iCACV,YAAE,yCAAyC,GAC9C;AAAA,WACF;AAAA,QAGA,qBAAC,SAAI,WAAU,aACb;AAAA,8BAAC,SAAM,SAAQ,WAAW,YAAE,kCAAkC,GAAE;AAAA,UAChE,qBAAC,UAAO,OAAO,SAAS,eAAe,CAAC,UAAU,WAAW,KAAK,GAChE;AAAA,gCAAC,iBAAc,IAAG,WAChB,8BAAC,eAAY,GACf;AAAA,YACA,qBAAC,iBACC;AAAA,kCAAC,cAAW,OAAM,QAAQ,YAAE,qCAAqC,GAAE;AAAA,cACnE,oBAAC,cAAW,OAAM,UAAU,YAAE,uCAAuC,GAAE;AAAA,cACvE,oBAAC,cAAW,OAAM,UAAU,YAAE,uCAAuC,GAAE;AAAA,cACvE,oBAAC,cAAW,OAAM,SAAS,YAAE,sCAAsC,GAAE;AAAA,eACvE;AAAA,aACF;AAAA,UACA,oBAAC,OAAE,WAAU,iCACV,YAAE,4CAA4C,OAAO,EAAE,GAC1D;AAAA,WACF;AAAA,QAGA,qBAAC,SAAI,WAAU,aACb;AAAA,8BAAC,SAAM,SAAQ,YAAY,YAAE,+BAA+B,GAAE;AAAA,UAC9D;AAAA,YAAC;AAAA;AAAA,cACC,IAAG;AAAA,cACH,MAAK;AAAA,cACL,OAAO;AAAA,cACP,UAAU,CAAC,MAAM,YAAY,EAAE,OAAO,KAAK;AAAA,cAC3C,aAAY;AAAA,cACZ,KAAI;AAAA,cACJ,KAAI;AAAA;AAAA,UACN;AAAA,UACA,oBAAC,OAAE,WAAU,iCACV,YAAE,mCAAmC,GACxC;AAAA,WACF;AAAA,QAEA,qBAAC,SAAI,WAAU,aACb;AAAA,+BAAC,SAAI,WAAU,+BACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,IAAG;AAAA,gBACH,SAAS;AAAA,gBACT,UAAU,CAAC,MAAM,6BAA6B,EAAE,OAAO,OAAO;AAAA,gBAC9D,WAAU;AAAA;AAAA,YACZ;AAAA,YACA,oBAAC,SAAM,SAAQ,6BAA4B,WAAU,8BAClD,YAAE,gDAAgD,GACrD;AAAA,aACF;AAAA,UACA,oBAAC,OAAE,WAAU,sCACV,YAAE,oDAAoD,GACzD;AAAA,WACF;AAAA,QAEA,oBAAC,aAAU;AAAA,QAGX,qBAAC,SAAI,WAAU,aACb;AAAA,+BAAC,SAAI,WAAU,qCACb;AAAA,iCAAC,SACC;AAAA,mCAAC,QAAG,WAAU,yBACX;AAAA,kBAAE,oCAAoC;AAAA,gBAAE;AAAA,gBAAG,cAAc;AAAA,gBAAO;AAAA,iBACnE;AAAA,cACA,oBAAC,OAAE,WAAU,iCACV,YAAE,wCAAwC,GAC7C;AAAA,eACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAS,MAAM,iBAAiB,KAAK;AAAA,gBAErC;AAAA,sCAAC,QAAK,WAAU,UAAS;AAAA,kBACxB,EAAE,8BAA8B;AAAA;AAAA;AAAA,YACnC;AAAA,aACF;AAAA,UAEC,cAAc,WAAW,KACxB,oBAAC,SAAI,WAAU,4EACZ,YAAE,sCAAsC,GAC3C;AAAA,UAGF,oBAAC,SAAI,WAAU,aACZ,wBAAc,IAAI,CAAC,WAAW,UAAU;AACvC,kBAAM,aAAa,sBAAsB,IAAI,KAAK;AAClD,kBAAM,OAAO,uBAAuB,UAAU,MAAM;AACpD,mBACE,qBAAC,SAAgB,WAAU,gDACzB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAM,mBAAmB,KAAK;AAAA,kBACvC,WAAU;AAAA,kBAEV;AAAA,yCAAC,SAAI,WAAU,UACb;AAAA,2CAAC,SAAI,WAAU,2BACb;AAAA,4CAAC,UAAK,WAAU,uCACb,gBAAM,YAAY,UAAU,QAC/B;AAAA,wBACC,UAAU,YACT,oBAAC,UAAK,WAAU,4FACb,YAAE,+BAA+B,GACpC;AAAA,wBAED,QACC,oBAAC,UAAK,WAAU,kGACb,eAAK,UACR;AAAA,yBAEJ;AAAA,sBACA,qBAAC,OAAE,WAAU,8BACV;AAAA,0BAAE,6BAA6B;AAAA,wBAAE;AAAA,wBAAE,oBAAC,UAAK,WAAU,yBAAyB,oBAAU,QAAO;AAAA,yBAChG;AAAA,sBACC,MAAM,eACL,oBAAC,OAAE,WAAU,2CAA2C,eAAK,aAAY;AAAA,uBAE7E;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,8CAA8C,aAAa,eAAe,EAAE;AAAA,wBACvF,MAAK;AAAA,wBACL,QAAO;AAAA,wBACP,SAAQ;AAAA,wBAER,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,kBAAiB;AAAA;AAAA,oBACxF;AAAA;AAAA;AAAA,cACF;AAAA,cAEC,cACC,qBAAC,SAAI,WAAU,yDACb;AAAA,qCAAC,SAAI,WAAU,QACb;AAAA,sCAAC,WAAM,WAAU,gDAAgD,YAAE,6BAA6B,GAAE;AAAA,kBAClG;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,OAAO,UAAU;AAAA,sBACjB,UAAU,CAAC,MAAM,mBAAmB,OAAO,UAAU,EAAE,OAAO,KAAK;AAAA;AAAA,kBACrE;AAAA,mBACF;AAAA,gBAEA,oBAAC,SACC,+BAAC,WAAM,WAAU,6DACf;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS,UAAU;AAAA,sBACnB,UAAU,CAAC,MAAM,mBAAmB,OAAO,YAAY,EAAE,OAAO,OAAO;AAAA,sBACvE,WAAU;AAAA;AAAA,kBACZ;AAAA,kBACC,EAAE,uCAAuC;AAAA,mBAC5C,GACF;AAAA,gBAEC,QACC,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,QAAG,WAAU,4CAA4C,YAAE,0CAA0C,GAAE;AAAA,kBACxG,qBAAC,QAAG,WAAU,qBACZ;AAAA,yCAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,mBAAK;AAAA,sBAC/C,oBAAC,QAAG,WAAU,iBAAiB,eAAK,UAAS;AAAA,uBAC/C;AAAA,oBACA,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,mBAAK;AAAA,sBAC/C,oBAAC,QAAG,WAAU,iBAAiB,eAAK,UAAS;AAAA,uBAC/C;AAAA,oBACC,KAAK,gBACJ,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,uBAAS;AAAA,sBACnD,oBAAC,QAAG,WAAU,iBAAiB,eAAK,cAAa;AAAA,uBACnD;AAAA,oBAEF,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,0BAAY;AAAA,sBACtD,oBAAC,QAAG,WAAU,mCAAmC,eAAK,YAAW;AAAA,uBACnE;AAAA,oBACC,KAAK,aACJ,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,yBAAW;AAAA,sBACrD,oBAAC,QAAG,WAAU,iBAAiB,eAAK,WAAU;AAAA,uBAChD;AAAA,oBAED,KAAK,eACJ,qBAAC,SAAI,WAAU,sCACb;AAAA,0CAAC,QAAG,WAAU,kCAAiC,0BAAY;AAAA,sBAC3D,oBAAC,QAAG,WAAU,iBAAiB,eAAK,aAAY;AAAA,uBAClD;AAAA,qBAEJ;AAAA,mBACF;AAAA,gBAGF,oBAAC,SAAI,WAAU,iCACb;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,SAAS,MAAM,mBAAmB,KAAK;AAAA,oBAEvC;AAAA,0CAAC,UAAO,WAAU,UAAS;AAAA,sBAC1B,EAAE,yCAAyC;AAAA;AAAA;AAAA,gBAC9C,GACF;AAAA,iBACF;AAAA,iBAhHM,KAkHV;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA,QAGA,qBAAC,SAAI,WAAU,aACb;AAAA,+BAAC,SAAI,WAAU,qCACb;AAAA,iCAAC,SACC;AAAA,mCAAC,QAAG,WAAU,yBACX;AAAA,kBAAE,qCAAqC;AAAA,gBAAE;AAAA,gBAAG,eAAe;AAAA,gBAAO;AAAA,iBACrE;AAAA,cACA,oBAAC,OAAE,WAAU,iCACV,YAAE,yCAAyC,GAC9C;AAAA,eACF;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAS,MAAM,iBAAiB,MAAM;AAAA,gBAEtC;AAAA,sCAAC,QAAK,WAAU,UAAS;AAAA,kBACxB,EAAE,8BAA8B;AAAA;AAAA;AAAA,YACnC;AAAA,aACF;AAAA,UAEC,eAAe,WAAW,KACzB,oBAAC,SAAI,WAAU,4EACZ,YAAE,uCAAuC,GAC5C;AAAA,UAGF,oBAAC,SAAI,WAAU,aACZ,yBAAe,IAAI,CAAC,WAAW,UAAU;AACxC,kBAAM,aAAa,uBAAuB,IAAI,KAAK;AACnD,kBAAM,OAAO,uBAAuB,UAAU,MAAM;AACpD,mBACE,qBAAC,SAAgB,WAAU,gDACzB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAM,oBAAoB,KAAK;AAAA,kBACxC,WAAU;AAAA,kBAEV;AAAA,yCAAC,SAAI,WAAU,UACb;AAAA,2CAAC,SAAI,WAAU,2BACb;AAAA,4CAAC,UAAK,WAAU,uCACb,gBAAM,YAAY,UAAU,QAC/B;AAAA,wBACC,UAAU,YACT,oBAAC,UAAK,WAAU,4FACb,YAAE,+BAA+B,GACpC;AAAA,wBAED,QACC,oBAAC,UAAK,WAAU,kGACb,eAAK,UACR;AAAA,yBAEJ;AAAA,sBACA,qBAAC,OAAE,WAAU,8BACV;AAAA,0BAAE,6BAA6B;AAAA,wBAAE;AAAA,wBAAE,oBAAC,UAAK,WAAU,yBAAyB,oBAAU,QAAO;AAAA,yBAChG;AAAA,sBACC,MAAM,eACL,oBAAC,OAAE,WAAU,2CAA2C,eAAK,aAAY;AAAA,uBAE7E;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,8CAA8C,aAAa,eAAe,EAAE;AAAA,wBACvF,MAAK;AAAA,wBACL,QAAO;AAAA,wBACP,SAAQ;AAAA,wBAER,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,kBAAiB;AAAA;AAAA,oBACxF;AAAA;AAAA;AAAA,cACF;AAAA,cAEC,cACC,qBAAC,SAAI,WAAU,yDACb;AAAA,qCAAC,SAAI,WAAU,QACb;AAAA,sCAAC,WAAM,WAAU,gDAAgD,YAAE,6BAA6B,GAAE;AAAA,kBAClG;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,OAAO,UAAU;AAAA,sBACjB,UAAU,CAAC,MAAM,oBAAoB,OAAO,UAAU,EAAE,OAAO,KAAK;AAAA;AAAA,kBACtE;AAAA,mBACF;AAAA,gBAEA,oBAAC,SACC,+BAAC,WAAM,WAAU,6DACf;AAAA;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,SAAS,UAAU;AAAA,sBACnB,UAAU,CAAC,MAAM,oBAAoB,OAAO,YAAY,EAAE,OAAO,OAAO;AAAA,sBACxE,WAAU;AAAA;AAAA,kBACZ;AAAA,kBACC,EAAE,2CAA2C;AAAA,mBAChD,GACF;AAAA,gBAEC,QACC,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,QAAG,WAAU,4CAA4C,YAAE,0CAA0C,GAAE;AAAA,kBACxG,qBAAC,QAAG,WAAU,qBACZ;AAAA,yCAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,mBAAK;AAAA,sBAC/C,oBAAC,QAAG,WAAU,iBAAiB,eAAK,UAAS;AAAA,uBAC/C;AAAA,oBACA,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,mBAAK;AAAA,sBAC/C,oBAAC,QAAG,WAAU,iBAAiB,eAAK,UAAS;AAAA,uBAC/C;AAAA,oBACC,KAAK,gBACJ,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,uBAAS;AAAA,sBACnD,oBAAC,QAAG,WAAU,iBAAiB,eAAK,cAAa;AAAA,uBACnD;AAAA,oBAEF,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,0BAAY;AAAA,sBACtD,oBAAC,QAAG,WAAU,mCAAmC,eAAK,YAAW;AAAA,uBACnE;AAAA,oBACC,KAAK,aACJ,qBAAC,SAAI,WAAU,wBACb;AAAA,0CAAC,QAAG,WAAU,6BAA4B,yBAAW;AAAA,sBACrD,oBAAC,QAAG,WAAU,iBAAiB,eAAK,WAAU;AAAA,uBAChD;AAAA,oBAED,KAAK,eACJ,qBAAC,SAAI,WAAU,sCACb;AAAA,0CAAC,QAAG,WAAU,kCAAiC,0BAAY;AAAA,sBAC3D,oBAAC,QAAG,WAAU,iBAAiB,eAAK,aAAY;AAAA,uBAClD;AAAA,qBAEJ;AAAA,mBACF;AAAA,gBAGF,oBAAC,SAAI,WAAU,iCACb;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,SAAS,MAAM,oBAAoB,KAAK;AAAA,oBAExC;AAAA,0CAAC,UAAO,WAAU,UAAS;AAAA,sBAC1B,EAAE,0CAA0C;AAAA;AAAA;AAAA,gBAC/C,GACF;AAAA,iBACF;AAAA,iBAhHM,KAkHV;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA,QAGA,qBAAC,SAAI,WAAU,sCACb;AAAA,+BAAC,SAAI,WAAU,0CACb;AAAA,iCAAC,QAAG,WAAU,uCACX;AAAA,gBAAE,iCAAiC;AAAA,cAAE;AAAA,cAAG,WAAW;AAAA,cAAO;AAAA,eAC7D;AAAA,YACA;AAAA,cAAC;AAAA;AAAA,gBACC,MAAK;AAAA,gBACL,MAAK;AAAA,gBACL,SAAS;AAAA,gBAET;AAAA,sCAAC,QAAK,WAAU,UAAS;AAAA,kBACxB,EAAE,kCAAkC;AAAA;AAAA;AAAA,YACvC;AAAA,aACF;AAAA,UAEC,WAAW,WAAW,KACrB,oBAAC,SAAI,WAAU,sFACZ,YAAE,mCAAmC,GACxC;AAAA,UAGF,oBAAC,SAAI,WAAU,aACZ,qBAAW,IAAI,CAAC,UAAU,UAAU;AACnC,kBAAM,aAAa,mBAAmB,IAAI,KAAK;AAC/C,mBACE,qBAAC,SAAgB,WAAU,gDACzB;AAAA;AAAA,gBAAC;AAAA;AAAA,kBACC,MAAK;AAAA,kBACL,SAAS,MAAM,eAAe,KAAK;AAAA,kBACnC,WAAU;AAAA,kBAEV;AAAA,yCAAC,SAAI,WAAU,UACb;AAAA,2CAAC,SAAI,WAAU,2BACb;AAAA,4CAAC,UAAK,WAAU,uCACb,mBAAS,gBAAgB,SAAS,SAAS,SAAS,cAAc,YAAY,QAAQ,CAAC,IAC1F;AAAA,wBACA,oBAAC,SAAM,SAAQ,aAAY,WAAU,WAClC,mBAAS,cACZ;AAAA,yBACF;AAAA,sBACA,qBAAC,OAAE,WAAU,8BACV;AAAA,0BAAE,iCAAiC;AAAA,wBAAE;AAAA,wBAAE,oBAAC,UAAK,WAAU,yBAAyB,mBAAS,YAAW;AAAA,yBACvG;AAAA,uBACF;AAAA,oBACA;AAAA,sBAAC;AAAA;AAAA,wBACC,WAAW,8CAA8C,aAAa,eAAe,EAAE;AAAA,wBACvF,MAAK;AAAA,wBACL,QAAO;AAAA,wBACP,SAAQ;AAAA,wBAER,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,kBAAiB;AAAA;AAAA,oBACxF;AAAA;AAAA;AAAA,cACF;AAAA,cAEC,cACC,qBAAC,SAAI,WAAU,yDAEb;AAAA,qCAAC,SAAI,WAAU,QACb;AAAA,uCAAC,WAAM,WAAU,gDAAgD;AAAA,sBAAE,iCAAiC;AAAA,oBAAE;AAAA,qBAAE;AAAA,kBACxG;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,OAAO,SAAS;AAAA,sBAChB,UAAU,CAAC,MAAM,eAAe,OAAO,cAAc,EAAE,OAAO,KAAK;AAAA,sBACnE,aAAa,EAAE,4CAA4C;AAAA;AAAA,kBAC7D;AAAA,mBACF;AAAA,gBAGA,qBAAC,SACC;AAAA,uCAAC,WAAM,WAAU,gDAAgD;AAAA,sBAAE,mCAAmC;AAAA,oBAAE;AAAA,qBAAE;AAAA,kBAC1G;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,OAAO,SAAS,gBAAgB;AAAA,sBAChC,UAAU,CAAC,MAAM,eAAe,OAAO,gBAAgB,EAAE,OAAO,KAAK;AAAA,sBACrE,aAAa,EAAE,8CAA8C;AAAA;AAAA,kBAC/D;AAAA,mBACF;AAAA,gBAGA,qBAAC,SACC;AAAA,uCAAC,WAAM,WAAU,gDAAgD;AAAA,sBAAE,mCAAmC;AAAA,oBAAE;AAAA,qBAAE;AAAA,kBAC1G;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO,SAAS;AAAA,sBAChB,eAAe,CAAC,UAAU,eAAe,OAAO,gBAAgB,KAAK;AAAA,sBAErE;AAAA,4CAAC,iBAAc,MAAK,MAClB,8BAAC,eAAY,GACf;AAAA,wBACA,qBAAC,iBACC;AAAA,8CAAC,cAAW,OAAM,cAAc,YAAE,uCAAuC,GAAE;AAAA,0BAC3E,oBAAC,cAAW,OAAM,YAAY,YAAE,qCAAqC,GAAE;AAAA,0BACvE,oBAAC,cAAW,OAAM,iBAAiB,YAAE,0CAA0C,GAAE;AAAA,0BACjF,oBAAC,cAAW,OAAM,cAAc,YAAE,uCAAuC,GAAE;AAAA,0BAC3E,oBAAC,cAAW,OAAM,gBAAgB,YAAE,yCAAyC,GAAE;AAAA,0BAC/E,oBAAC,cAAW,OAAM,oBAAoB,YAAE,6CAA6C,GAAE;AAAA,0BACvF,oBAAC,cAAW,OAAM,QAAQ,YAAE,iCAAiC,GAAE;AAAA,2BACjE;AAAA;AAAA;AAAA,kBACF;AAAA,mBACF;AAAA,gBAGA,qBAAC,SACC;AAAA,sCAAC,WAAM,WAAU,gDAAgD,YAAE,8BAA8B,GAAE;AAAA,kBACnG;AAAA,oBAAC;AAAA;AAAA,sBACC,MAAK;AAAA,sBACL,MAAK;AAAA,sBACL,OAAO,SAAS,WAAW;AAAA,sBAC3B,UAAU,CAAC,MAAM,eAAe,OAAO,WAAW,EAAE,OAAO,KAAK;AAAA,sBAChE,aAAa,EAAE,yCAAyC;AAAA;AAAA,kBAC1D;AAAA,kBACA,oBAAC,OAAE,WAAU,gCAAgC,YAAE,kCAAkC,GAAE;AAAA,mBACrF;AAAA,gBAGA,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,QAAG,WAAU,4CAA4C,YAAE,kCAAkC,GAAE;AAAA,kBAChG,qBAAC,SAAI,WAAU,yCACb;AAAA,yCAAC,SACC;AAAA,0CAAC,WAAM,WAAU,gDAAgD,YAAE,kCAAkC,GAAE;AAAA,sBACvG;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,OAAO,SAAS,aAAa,eAAe;AAAA,0BAC5C,UAAU,CAAC,MAAM,0BAA0B,OAAO,eAAe,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,0BAC9F,aAAY;AAAA,0BACZ,KAAI;AAAA,0BACJ,KAAI;AAAA;AAAA,sBACN;AAAA,uBACF;AAAA,oBACA,qBAAC,SACC;AAAA,0CAAC,WAAM,WAAU,gDAAgD,YAAE,sCAAsC,GAAE;AAAA,sBAC3G;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,OAAO,SAAS,aAAa,qBAAqB;AAAA,0BAClD,UAAU,CAAC,MAAM,0BAA0B,OAAO,qBAAqB,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,0BACpG,aAAY;AAAA,0BACZ,KAAI;AAAA;AAAA,sBACN;AAAA,uBACF;AAAA,oBACA,qBAAC,SACC;AAAA,0CAAC,WAAM,WAAU,gDAAgD,YAAE,yCAAyC,GAAE;AAAA,sBAC9G;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,OAAO,SAAS,aAAa,sBAAsB;AAAA,0BACnD,UAAU,CAAC,MAAM,0BAA0B,OAAO,sBAAsB,WAAW,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,0BACvG,aAAY;AAAA,0BACZ,KAAI;AAAA,0BACJ,KAAI;AAAA;AAAA,sBACN;AAAA,uBACF;AAAA,oBACA,qBAAC,SACC;AAAA,0CAAC,WAAM,WAAU,gDAAgD,YAAE,kCAAkC,GAAE;AAAA,sBACvG;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,MAAK;AAAA,0BACL,OAAO,SAAS,aAAa,iBAAiB;AAAA,0BAC9C,UAAU,CAAC,MAAM,0BAA0B,OAAO,iBAAiB,SAAS,EAAE,OAAO,KAAK,KAAK,CAAC;AAAA,0BAChG,aAAY;AAAA,0BACZ,KAAI;AAAA;AAAA,sBACN;AAAA,uBACF;AAAA,qBACF;AAAA,mBACF;AAAA,gBAGA,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,QAAG,WAAU,4CAA4C,YAAE,sCAAsC,GAAE;AAAA,kBACpG,qBAAC,SAAI,WAAU,aACb;AAAA,yCAAC,SAAI,WAAU,+BACb;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,IAAI,kBAAkB,KAAK;AAAA,0BAC3B,SAAS,SAAS,SAAS;AAAA,0BAC3B,UAAU,CAAC,MAAM,eAAe,OAAO,SAAS,EAAE,OAAO,OAAO;AAAA,0BAChE,WAAU;AAAA;AAAA,sBACZ;AAAA,sBACA,oBAAC,WAAM,SAAS,kBAAkB,KAAK,IAAI,WAAU,wCAClD,YAAE,kCAAkC,GACvC;AAAA,uBACF;AAAA,oBACA,qBAAC,SAAI,WAAU,+BACb;AAAA;AAAA,wBAAC;AAAA;AAAA,0BACC,MAAK;AAAA,0BACL,IAAI,uBAAuB,KAAK;AAAA,0BAChC,SAAS,SAAS,cAAc;AAAA,0BAChC,UAAU,CAAC,MAAM,eAAe,OAAO,cAAc,EAAE,OAAO,OAAO;AAAA,0BACrE,WAAU;AAAA;AAAA,sBACZ;AAAA,sBACA,oBAAC,WAAM,SAAS,uBAAuB,KAAK,IAAI,WAAU,wCACvD,YAAE,uCAAuC,GAC5C;AAAA,uBACF;AAAA,qBACF;AAAA,mBACF;AAAA,gBAGA,qBAAC,SAAI,WAAU,iCACb;AAAA,sCAAC,WAAM,WAAU,gDAAgD,YAAE,wCAAwC,GAAE;AAAA,kBAC7G;AAAA,oBAAC;AAAA;AAAA,sBACC,OAAO,SAAS,UAAU,CAAC;AAAA,sBAC3B,UAAU,CAAC,WAAW;AACpB,8BAAM,UAAU,CAAC,GAAG,UAAU;AAC9B,gCAAQ,KAAK,IAAI,EAAE,GAAG,QAAQ,KAAK,GAAG,OAAO;AAC7C,sCAAc,OAAO;AAAA,sBACvB;AAAA;AAAA,kBACF;AAAA,kBACA,oBAAC,OAAE,WAAU,gCAAgC,YAAE,wCAAwC,GAAE;AAAA,mBAC3F;AAAA,gBAGA,oBAAC,SAAI,WAAU,iCACb;AAAA,kBAAC;AAAA;AAAA,oBACC,MAAK;AAAA,oBACL,SAAQ;AAAA,oBACR,MAAK;AAAA,oBACL,SAAS,MAAM,eAAe,KAAK;AAAA,oBAEnC;AAAA,0CAAC,UAAO,WAAU,UAAS;AAAA,sBAC1B,EAAE,qCAAqC;AAAA;AAAA;AAAA,gBAC1C,GACF;AAAA,iBACF;AAAA,iBAzMM,KA2MV;AAAA,UAEJ,CAAC,GACH;AAAA,WACF;AAAA,QAGA,qBAAC,SAAI,WAAU,sCACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS,MAAM,gBAAgB,CAAC,YAAY;AAAA,cAC5C,WAAU;AAAA,cAEV;AAAA,oCAAC,QAAG,WAAU,uCACX,YAAE,4CAA4C,GACjD;AAAA,gBACA;AAAA,kBAAC;AAAA;AAAA,oBACC,WAAW,gCAAgC,eAAe,eAAe,EAAE;AAAA,oBAC3E,MAAK;AAAA,oBACL,QAAO;AAAA,oBACP,SAAQ;AAAA,oBAER,8BAAC,UAAK,eAAc,SAAQ,gBAAe,SAAQ,aAAa,GAAG,GAAE,kBAAiB;AAAA;AAAA,gBACxF;AAAA;AAAA;AAAA,UACF;AAAA,UACC,gBACC,qBAAC,SAAI,WAAU,QACb;AAAA;AAAA,cAAC;AAAA;AAAA,gBACC,OAAO;AAAA,gBACP,UAAU;AAAA;AAAA,YACZ;AAAA,YACA,oBAAC,OAAE,WAAU,8BACV,YAAE,yCAAyC,GAC9C;AAAA,aACF;AAAA,WAEJ;AAAA,SACJ;AAAA,MAEA,qBAAC,gBAAa,WAAU,wBACtB;AAAA;AAAA,UAAC;AAAA;AAAA,YACC,MAAK;AAAA,YACL,SAAQ;AAAA,YACR,SAAS;AAAA,YAET;AAAA,kCAAC,UAAO,WAAU,UAAS;AAAA,cAC1B,EAAE,uCAAuC;AAAA;AAAA;AAAA,QAC5C;AAAA,QACA,qBAAC,SAAI,WAAU,cACb;AAAA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAQ;AAAA,cACR,SAAS;AAAA,cAER,YAAE,6BAA6B;AAAA;AAAA,UAClC;AAAA,UACA;AAAA,YAAC;AAAA;AAAA,cACC,MAAK;AAAA,cACL,SAAS;AAAA,cAER,YAAE,kCAAkC;AAAA;AAAA,UACvC;AAAA,WACF;AAAA,SACF;AAAA,OACF;AAAA,IAGA;AAAA,MAAC;AAAA;AAAA,QACC,QAAQ;AAAA,QACR,SAAS;AAAA,QACT,UAAU;AAAA,QACV,gBACE,qBAAqB,QACjB,cAAc,IAAI,OAAK,EAAE,MAAM,IAC/B,eAAe,IAAI,OAAK,EAAE,MAAM;AAAA,QAEtC,OAAO,EAAE,yCAAyC;AAAA,QAClD,aAAa,EAAE,sDAAsD;AAAA,UACnE,MAAM,qBAAqB,QACvB,EAAE,oCAAoC,EAAE,YAAY,IACpD,EAAE,qCAAqC,EAAE,YAAY;AAAA,QAC3D,CAAC;AAAA;AAAA,IACH;AAAA,IACC;AAAA,KACH;AAEJ;",
6
6
  "names": []
7
7
  }