@open-mercato/core 0.6.5-develop.4534.1.b459babe6d → 0.6.5-develop.4559.1.839e136509

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 (644) hide show
  1. package/.turbo/turbo-build.log +1 -1
  2. package/AGENTS.md +5 -0
  3. package/dist/generated/entities/role/index.js +3 -1
  4. package/dist/generated/entities/role/index.js.map +2 -2
  5. package/dist/generated/entities/user/index.js +3 -1
  6. package/dist/generated/entities/user/index.js.map +2 -2
  7. package/dist/generated/entity-fields-registry.js +2 -0
  8. package/dist/generated/entity-fields-registry.js.map +2 -2
  9. package/dist/helpers/integration/communicationChannelsFixtures.js.map +2 -2
  10. package/dist/helpers/integration/dbFixtures.js +2 -1
  11. package/dist/helpers/integration/dbFixtures.js.map +2 -2
  12. package/dist/helpers/integration/optimisticLockUi.js +104 -0
  13. package/dist/helpers/integration/optimisticLockUi.js.map +7 -0
  14. package/dist/helpers/integration/salesFixtures.js +17 -0
  15. package/dist/helpers/integration/salesFixtures.js.map +2 -2
  16. package/dist/modules/api_keys/backend/api-keys/page.js +9 -5
  17. package/dist/modules/api_keys/backend/api-keys/page.js.map +2 -2
  18. package/dist/modules/attachments/components/AttachmentPartitionSettings.js +17 -9
  19. package/dist/modules/attachments/components/AttachmentPartitionSettings.js.map +2 -2
  20. package/dist/modules/auth/api/roles/acl/route.js +32 -13
  21. package/dist/modules/auth/api/roles/acl/route.js.map +2 -2
  22. package/dist/modules/auth/api/roles/route.js +3 -1
  23. package/dist/modules/auth/api/roles/route.js.map +2 -2
  24. package/dist/modules/auth/api/sidebar/preferences/route.js +71 -3
  25. package/dist/modules/auth/api/sidebar/preferences/route.js.map +2 -2
  26. package/dist/modules/auth/api/users/acl/route.js +42 -19
  27. package/dist/modules/auth/api/users/acl/route.js.map +2 -2
  28. package/dist/modules/auth/api/users/route.js +3 -1
  29. package/dist/modules/auth/api/users/route.js.map +2 -2
  30. package/dist/modules/auth/backend/roles/[id]/edit/page.js +24 -4
  31. package/dist/modules/auth/backend/roles/[id]/edit/page.js.map +2 -2
  32. package/dist/modules/auth/backend/roles/page.js +8 -4
  33. package/dist/modules/auth/backend/roles/page.js.map +2 -2
  34. package/dist/modules/auth/backend/users/[id]/edit/page.js +27 -5
  35. package/dist/modules/auth/backend/users/[id]/edit/page.js.map +2 -2
  36. package/dist/modules/auth/backend/users/page.js +6 -2
  37. package/dist/modules/auth/backend/users/page.js.map +2 -2
  38. package/dist/modules/auth/components/AclEditor.js +3 -1
  39. package/dist/modules/auth/components/AclEditor.js.map +2 -2
  40. package/dist/modules/auth/data/entities.js +6 -0
  41. package/dist/modules/auth/data/entities.js.map +2 -2
  42. package/dist/modules/auth/services/sidebarPreferencesService.js +32 -4
  43. package/dist/modules/auth/services/sidebarPreferencesService.js.map +2 -2
  44. package/dist/modules/business_rules/api/rules/route.js +28 -0
  45. package/dist/modules/business_rules/api/rules/route.js.map +2 -2
  46. package/dist/modules/business_rules/api/sets/route.js +28 -0
  47. package/dist/modules/business_rules/api/sets/route.js.map +2 -2
  48. package/dist/modules/business_rules/backend/rules/[id]/page.js +11 -4
  49. package/dist/modules/business_rules/backend/rules/[id]/page.js.map +3 -3
  50. package/dist/modules/business_rules/backend/rules/page.js +20 -11
  51. package/dist/modules/business_rules/backend/rules/page.js.map +2 -2
  52. package/dist/modules/business_rules/backend/sets/[id]/page.js +11 -4
  53. package/dist/modules/business_rules/backend/sets/[id]/page.js.map +2 -2
  54. package/dist/modules/business_rules/backend/sets/page.js +20 -11
  55. package/dist/modules/business_rules/backend/sets/page.js.map +2 -2
  56. package/dist/modules/catalog/api/categories/route.js +2 -0
  57. package/dist/modules/catalog/api/categories/route.js.map +2 -2
  58. package/dist/modules/catalog/api/products/route.js +2 -1
  59. package/dist/modules/catalog/api/products/route.js.map +2 -2
  60. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js +2 -0
  61. package/dist/modules/catalog/backend/catalog/categories/[id]/edit/page.js.map +2 -2
  62. package/dist/modules/catalog/backend/catalog/products/[id]/page.js +94 -40
  63. package/dist/modules/catalog/backend/catalog/products/[id]/page.js.map +2 -2
  64. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js +37 -8
  65. package/dist/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.js.map +2 -2
  66. package/dist/modules/catalog/backend/catalog/products/optionSchemaClient.js.map +2 -2
  67. package/dist/modules/catalog/commands/variants.js +32 -31
  68. package/dist/modules/catalog/commands/variants.js.map +2 -2
  69. package/dist/modules/catalog/components/PriceKindSettings.js +12 -5
  70. package/dist/modules/catalog/components/PriceKindSettings.js.map +2 -2
  71. package/dist/modules/catalog/components/categories/CategoriesDataTable.js.map +2 -2
  72. package/dist/modules/catalog/components/products/ProductMediaManager.js.map +2 -2
  73. package/dist/modules/catalog/components/products/ProductsDataTable.js +5 -3
  74. package/dist/modules/catalog/components/products/ProductsDataTable.js.map +2 -2
  75. package/dist/modules/catalog/components/products/productForm.js.map +2 -2
  76. package/dist/modules/catalog/components/products/variantForm.js +2 -1
  77. package/dist/modules/catalog/components/products/variantForm.js.map +2 -2
  78. package/dist/modules/communication_channels/api/post/test-seed/route.js +23 -2
  79. package/dist/modules/communication_channels/api/post/test-seed/route.js.map +2 -2
  80. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js +5 -0
  81. package/dist/modules/communication_channels/backend/profile/communication-channels/page.js.map +2 -2
  82. package/dist/modules/communication_channels/commands/set-primary-channel.js +2 -1
  83. package/dist/modules/communication_channels/commands/set-primary-channel.js.map +2 -2
  84. package/dist/modules/currencies/backend/currencies/[id]/page.js +6 -3
  85. package/dist/modules/currencies/backend/currencies/[id]/page.js.map +2 -2
  86. package/dist/modules/currencies/backend/currencies/page.js +18 -11
  87. package/dist/modules/currencies/backend/currencies/page.js.map +2 -2
  88. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js +1 -0
  89. package/dist/modules/currencies/backend/exchange-rates/[id]/page.js.map +2 -2
  90. package/dist/modules/currencies/backend/exchange-rates/page.js +10 -6
  91. package/dist/modules/currencies/backend/exchange-rates/page.js.map +2 -2
  92. package/dist/modules/currencies/commands/currencies.js +7 -5
  93. package/dist/modules/currencies/commands/currencies.js.map +2 -2
  94. package/dist/modules/currencies/components/CurrencyFetchingConfig.js +26 -19
  95. package/dist/modules/currencies/components/CurrencyFetchingConfig.js.map +2 -2
  96. package/dist/modules/customer_accounts/api/admin/roles/[id].js +28 -5
  97. package/dist/modules/customer_accounts/api/admin/roles/[id].js.map +2 -2
  98. package/dist/modules/customer_accounts/api/admin/roles.js +4 -2
  99. package/dist/modules/customer_accounts/api/admin/roles.js.map +2 -2
  100. package/dist/modules/customer_accounts/api/admin/users/[id].js +28 -5
  101. package/dist/modules/customer_accounts/api/admin/users/[id].js.map +2 -2
  102. package/dist/modules/customer_accounts/api/admin/users.js +2 -0
  103. package/dist/modules/customer_accounts/api/admin/users.js.map +2 -2
  104. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js +16 -8
  105. package/dist/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.js.map +2 -2
  106. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js +8 -4
  107. package/dist/modules/customer_accounts/backend/customer_accounts/roles/page.js.map +2 -2
  108. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js +8 -4
  109. package/dist/modules/customer_accounts/backend/customer_accounts/settings/domain/page.js.map +2 -2
  110. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js +29 -18
  111. package/dist/modules/customer_accounts/backend/customer_accounts/users/[id]/page.js.map +2 -2
  112. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js +18 -11
  113. package/dist/modules/customer_accounts/backend/customer_accounts/users/page.js.map +2 -2
  114. package/dist/modules/customers/api/companies/route.js +13 -2
  115. package/dist/modules/customers/api/companies/route.js.map +2 -2
  116. package/dist/modules/customers/api/deals/route.js +2 -0
  117. package/dist/modules/customers/api/deals/route.js.map +2 -2
  118. package/dist/modules/customers/api/people/route.js +11 -2
  119. package/dist/modules/customers/api/people/route.js.map +2 -2
  120. package/dist/modules/customers/api/todos/route.js +1 -0
  121. package/dist/modules/customers/api/todos/route.js.map +2 -2
  122. package/dist/modules/customers/backend/config/customers/deals/page.js.map +2 -2
  123. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js +34 -21
  124. package/dist/modules/customers/backend/config/customers/pipeline-stages/page.js.map +2 -2
  125. package/dist/modules/customers/backend/customers/companies/[id]/page.js +45 -27
  126. package/dist/modules/customers/backend/customers/companies/[id]/page.js.map +2 -2
  127. package/dist/modules/customers/backend/customers/companies/page.js.map +2 -2
  128. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js +22 -5
  129. package/dist/modules/customers/backend/customers/companies-v2/[id]/page.js.map +2 -2
  130. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js +30 -8
  131. package/dist/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.js.map +2 -2
  132. package/dist/modules/customers/backend/customers/deals/[id]/page.js +1 -0
  133. package/dist/modules/customers/backend/customers/deals/[id]/page.js.map +2 -2
  134. package/dist/modules/customers/backend/customers/deals/page.js +16 -6
  135. package/dist/modules/customers/backend/customers/deals/page.js.map +2 -2
  136. package/dist/modules/customers/backend/customers/deals/pipeline/page.js +62 -39
  137. package/dist/modules/customers/backend/customers/deals/pipeline/page.js.map +2 -2
  138. package/dist/modules/customers/backend/customers/people/[id]/page.js +41 -26
  139. package/dist/modules/customers/backend/customers/people/[id]/page.js.map +2 -2
  140. package/dist/modules/customers/backend/customers/people/page.js.map +2 -2
  141. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js +50 -23
  142. package/dist/modules/customers/backend/customers/people-v2/[id]/page.js.map +2 -2
  143. package/dist/modules/customers/commands/addresses.js +16 -14
  144. package/dist/modules/customers/commands/addresses.js.map +2 -2
  145. package/dist/modules/customers/commands/companies.js +1 -1
  146. package/dist/modules/customers/commands/companies.js.map +2 -2
  147. package/dist/modules/customers/commands/interactions.js +41 -4
  148. package/dist/modules/customers/commands/interactions.js.map +2 -2
  149. package/dist/modules/customers/commands/people.js +1 -1
  150. package/dist/modules/customers/commands/people.js.map +2 -2
  151. package/dist/modules/customers/commands/personCompanyLinks.js +8 -5
  152. package/dist/modules/customers/commands/personCompanyLinks.js.map +2 -2
  153. package/dist/modules/customers/commands/pipeline-stages.js +13 -11
  154. package/dist/modules/customers/commands/pipeline-stages.js.map +3 -3
  155. package/dist/modules/customers/components/AddressFormatSettings.js.map +2 -2
  156. package/dist/modules/customers/components/DictionarySettings.js +20 -13
  157. package/dist/modules/customers/components/DictionarySettings.js.map +2 -2
  158. package/dist/modules/customers/components/DictionarySortSettings.js +4 -0
  159. package/dist/modules/customers/components/DictionarySortSettings.js.map +2 -2
  160. package/dist/modules/customers/components/PipelineSettings.js +38 -23
  161. package/dist/modules/customers/components/PipelineSettings.js.map +2 -2
  162. package/dist/modules/customers/components/detail/ActivityTimeline.js +1 -1
  163. package/dist/modules/customers/components/detail/ActivityTimeline.js.map +2 -2
  164. package/dist/modules/customers/components/detail/AddressesSection.js +4 -0
  165. package/dist/modules/customers/components/detail/AddressesSection.js.map +2 -2
  166. package/dist/modules/customers/components/detail/CompanyPeopleSection.js +28 -22
  167. package/dist/modules/customers/components/detail/CompanyPeopleSection.js.map +2 -2
  168. package/dist/modules/customers/components/detail/DealsSection.js +36 -24
  169. package/dist/modules/customers/components/detail/DealsSection.js.map +2 -2
  170. package/dist/modules/customers/components/detail/EmailCardActions.js +5 -0
  171. package/dist/modules/customers/components/detail/EmailCardActions.js.map +2 -2
  172. package/dist/modules/customers/components/detail/EntityTagsDialog.js +7 -0
  173. package/dist/modules/customers/components/detail/EntityTagsDialog.js.map +2 -2
  174. package/dist/modules/customers/components/detail/ManageTagsDialog.js +34 -22
  175. package/dist/modules/customers/components/detail/ManageTagsDialog.js.map +2 -2
  176. package/dist/modules/customers/components/detail/PersonCompaniesSection.js +41 -29
  177. package/dist/modules/customers/components/detail/PersonCompaniesSection.js.map +2 -2
  178. package/dist/modules/customers/components/detail/RoleAssignmentRow.js +14 -8
  179. package/dist/modules/customers/components/detail/RoleAssignmentRow.js.map +2 -2
  180. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js +14 -6
  181. package/dist/modules/customers/components/detail/ScheduleActivityDialog.js.map +2 -2
  182. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js +29 -13
  183. package/dist/modules/customers/components/detail/hooks/useInteractionMutations.js.map +2 -2
  184. package/dist/modules/customers/components/detail/hooks/useInteractions.js +77 -35
  185. package/dist/modules/customers/components/detail/hooks/useInteractions.js.map +2 -2
  186. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js +25 -17
  187. package/dist/modules/customers/components/detail/hooks/usePersonTasks.js.map +2 -2
  188. package/dist/modules/customers/components/detail/schedule/useScheduleFormState.js.map +2 -2
  189. package/dist/modules/customers/components/formConfig.js.map +2 -2
  190. package/dist/modules/customers/data/guards.js +66 -0
  191. package/dist/modules/customers/data/guards.js.map +7 -0
  192. package/dist/modules/customers/di.js +37 -0
  193. package/dist/modules/customers/di.js.map +2 -2
  194. package/dist/modules/customers/lib/todoCompatibility.js +11 -0
  195. package/dist/modules/customers/lib/todoCompatibility.js.map +2 -2
  196. package/dist/modules/dashboards/components/WidgetVisibilityEditor.js.map +2 -2
  197. package/dist/modules/data_sync/api/options.js +4 -4
  198. package/dist/modules/data_sync/api/options.js.map +2 -2
  199. package/dist/modules/data_sync/api/schedules/route.js +9 -1
  200. package/dist/modules/data_sync/api/schedules/route.js.map +2 -2
  201. package/dist/modules/data_sync/backend/data-sync/page.js +17 -8
  202. package/dist/modules/data_sync/backend/data-sync/page.js.map +2 -2
  203. package/dist/modules/data_sync/components/IntegrationScheduleTab.js +43 -22
  204. package/dist/modules/data_sync/components/IntegrationScheduleTab.js.map +2 -2
  205. package/dist/modules/data_sync/lib/sync-schedule-service.js +9 -0
  206. package/dist/modules/data_sync/lib/sync-schedule-service.js.map +2 -2
  207. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js +8 -1
  208. package/dist/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.js.map +2 -2
  209. package/dist/modules/dictionaries/api/[dictionaryId]/route.js +17 -1
  210. package/dist/modules/dictionaries/api/[dictionaryId]/route.js.map +2 -2
  211. package/dist/modules/dictionaries/components/DictionariesManager.js +31 -10
  212. package/dist/modules/dictionaries/components/DictionariesManager.js.map +2 -2
  213. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js +28 -15
  214. package/dist/modules/dictionaries/components/DictionaryEntriesEditor.js.map +2 -2
  215. package/dist/modules/directory/api/organizations/route.js +3 -0
  216. package/dist/modules/directory/api/organizations/route.js.map +2 -2
  217. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js +2 -0
  218. package/dist/modules/directory/backend/directory/organizations/[id]/edit/page.js.map +2 -2
  219. package/dist/modules/directory/backend/directory/organizations/page.js +9 -5
  220. package/dist/modules/directory/backend/directory/organizations/page.js.map +2 -2
  221. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js +7 -3
  222. package/dist/modules/directory/backend/directory/tenants/[id]/edit/page.js.map +2 -2
  223. package/dist/modules/directory/backend/directory/tenants/page.js +8 -4
  224. package/dist/modules/directory/backend/directory/tenants/page.js.map +2 -2
  225. package/dist/modules/directory/commands/organizations.js +7 -2
  226. package/dist/modules/directory/commands/organizations.js.map +2 -2
  227. package/dist/modules/entities/api/records.js +66 -0
  228. package/dist/modules/entities/api/records.js.map +2 -2
  229. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js +1 -0
  230. package/dist/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.js.map +2 -2
  231. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js +8 -4
  232. package/dist/modules/entities/backend/entities/user/[entityId]/records/page.js.map +2 -2
  233. package/dist/modules/entities/lib/helpers.js +17 -0
  234. package/dist/modules/entities/lib/helpers.js.map +2 -2
  235. package/dist/modules/feature_toggles/api/global/[id]/override/route.js +2 -1
  236. package/dist/modules/feature_toggles/api/global/[id]/override/route.js.map +2 -2
  237. package/dist/modules/feature_toggles/api/overrides/route.js +15 -0
  238. package/dist/modules/feature_toggles/api/overrides/route.js.map +2 -2
  239. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js +15 -14
  240. package/dist/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.js.map +2 -2
  241. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js +20 -12
  242. package/dist/modules/feature_toggles/components/FeatureToggleOverrideCard.js.map +2 -2
  243. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js +6 -2
  244. package/dist/modules/feature_toggles/components/FeatureTogglesTable.js.map +2 -2
  245. package/dist/modules/feature_toggles/components/formConfig.js +2 -1
  246. package/dist/modules/feature_toggles/components/formConfig.js.map +2 -2
  247. package/dist/modules/feature_toggles/components/overrideFormConfig.js +5 -1
  248. package/dist/modules/feature_toggles/components/overrideFormConfig.js.map +2 -2
  249. package/dist/modules/feature_toggles/data/validators.js +7 -4
  250. package/dist/modules/feature_toggles/data/validators.js.map +2 -2
  251. package/dist/modules/inbox_ops/api/settings/route.js +17 -2
  252. package/dist/modules/inbox_ops/api/settings/route.js.map +2 -2
  253. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js +13 -8
  254. package/dist/modules/inbox_ops/backend/inbox-ops/settings/page.js.map +2 -2
  255. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js +9 -4
  256. package/dist/modules/inbox_ops/components/proposals/EditActionDialog.js.map +2 -2
  257. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js +18 -11
  258. package/dist/modules/integrations/backend/integrations/bundle/[id]/page.js.map +2 -2
  259. package/dist/modules/integrations/backend/integrations/page.js +12 -8
  260. package/dist/modules/integrations/backend/integrations/page.js.map +2 -2
  261. package/dist/modules/messages/commands/messages.js +13 -10
  262. package/dist/modules/messages/commands/messages.js.map +2 -2
  263. package/dist/modules/perspectives/api/[tableId]/route.js +39 -30
  264. package/dist/modules/perspectives/api/[tableId]/route.js.map +2 -2
  265. package/dist/modules/perspectives/services/perspectiveService.js +7 -0
  266. package/dist/modules/perspectives/services/perspectiveService.js.map +2 -2
  267. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js +6 -14
  268. package/dist/modules/planner/backend/planner/availability-rulesets/[id]/page.js.map +3 -3
  269. package/dist/modules/planner/backend/planner/availability-rulesets/page.js +4 -2
  270. package/dist/modules/planner/backend/planner/availability-rulesets/page.js.map +2 -2
  271. package/dist/modules/planner/components/AvailabilityRuleSetForm.js +2 -0
  272. package/dist/modules/planner/components/AvailabilityRuleSetForm.js.map +2 -2
  273. package/dist/modules/planner/components/AvailabilityRulesEditor.js +36 -11
  274. package/dist/modules/planner/components/AvailabilityRulesEditor.js.map +2 -2
  275. package/dist/modules/planner/components/AvailabilitySchedule.js +9 -5
  276. package/dist/modules/planner/components/AvailabilitySchedule.js.map +2 -2
  277. package/dist/modules/query_index/lib/engine.js +19 -0
  278. package/dist/modules/query_index/lib/engine.js.map +2 -2
  279. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js +1 -0
  280. package/dist/modules/resources/backend/resources/resource-types/[id]/edit/page.js.map +2 -2
  281. package/dist/modules/resources/backend/resources/resource-types/page.js +4 -2
  282. package/dist/modules/resources/backend/resources/resource-types/page.js.map +2 -2
  283. package/dist/modules/resources/backend/resources/resources/[id]/page.js +14 -3
  284. package/dist/modules/resources/backend/resources/resources/[id]/page.js.map +2 -2
  285. package/dist/modules/resources/backend/resources/resources/page.js +8 -4
  286. package/dist/modules/resources/backend/resources/resources/page.js.map +2 -2
  287. package/dist/modules/resources/components/ResourceCrudForm.js +2 -0
  288. package/dist/modules/resources/components/ResourceCrudForm.js.map +2 -2
  289. package/dist/modules/resources/components/ResourceTypeCrudForm.js +1 -0
  290. package/dist/modules/resources/components/ResourceTypeCrudForm.js.map +2 -2
  291. package/dist/modules/sales/api/documents/factory.js +7 -2
  292. package/dist/modules/sales/api/documents/factory.js.map +2 -2
  293. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js +3 -1
  294. package/dist/modules/sales/backend/sales/channels/[channelId]/edit/page.js.map +2 -2
  295. package/dist/modules/sales/backend/sales/channels/offers/page.js +13 -4
  296. package/dist/modules/sales/backend/sales/channels/offers/page.js.map +2 -2
  297. package/dist/modules/sales/backend/sales/channels/page.js +16 -4
  298. package/dist/modules/sales/backend/sales/channels/page.js.map +2 -2
  299. package/dist/modules/sales/backend/sales/documents/[id]/page.js +68 -22
  300. package/dist/modules/sales/backend/sales/documents/[id]/page.js.map +2 -2
  301. package/dist/modules/sales/backend/sales/documents/create/page.js.map +2 -2
  302. package/dist/modules/sales/commands/documentAddresses.js +181 -2
  303. package/dist/modules/sales/commands/documentAddresses.js.map +2 -2
  304. package/dist/modules/sales/commands/documents.js +29 -1
  305. package/dist/modules/sales/commands/documents.js.map +2 -2
  306. package/dist/modules/sales/commands/returns.js +12 -2
  307. package/dist/modules/sales/commands/returns.js.map +2 -2
  308. package/dist/modules/sales/commands/shared.js +15 -0
  309. package/dist/modules/sales/commands/shared.js.map +2 -2
  310. package/dist/modules/sales/commands/shipments.js +4 -1
  311. package/dist/modules/sales/commands/shipments.js.map +2 -2
  312. package/dist/modules/sales/components/AdjustmentKindSettings.js +19 -11
  313. package/dist/modules/sales/components/AdjustmentKindSettings.js.map +2 -2
  314. package/dist/modules/sales/components/DocumentNumberSettings.js.map +2 -2
  315. package/dist/modules/sales/components/OrderEditingSettings.js.map +2 -2
  316. package/dist/modules/sales/components/PaymentMethodsSettings.js +12 -4
  317. package/dist/modules/sales/components/PaymentMethodsSettings.js.map +2 -2
  318. package/dist/modules/sales/components/ShippingMethodsSettings.js +12 -4
  319. package/dist/modules/sales/components/ShippingMethodsSettings.js.map +2 -2
  320. package/dist/modules/sales/components/StatusSettings.js +18 -11
  321. package/dist/modules/sales/components/StatusSettings.js.map +2 -2
  322. package/dist/modules/sales/components/TaxRatesSettings.js +12 -4
  323. package/dist/modules/sales/components/TaxRatesSettings.js.map +2 -2
  324. package/dist/modules/sales/components/channels/ChannelOfferForm.js +47 -16
  325. package/dist/modules/sales/components/channels/ChannelOfferForm.js.map +2 -2
  326. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js +8 -4
  327. package/dist/modules/sales/components/channels/SalesChannelOffersPanel.js.map +2 -2
  328. package/dist/modules/sales/components/documents/AddressesSection.js +44 -25
  329. package/dist/modules/sales/components/documents/AddressesSection.js.map +2 -2
  330. package/dist/modules/sales/components/documents/AdjustmentsSection.js +43 -23
  331. package/dist/modules/sales/components/documents/AdjustmentsSection.js.map +2 -2
  332. package/dist/modules/sales/components/documents/ItemsSection.js +22 -13
  333. package/dist/modules/sales/components/documents/ItemsSection.js.map +2 -2
  334. package/dist/modules/sales/components/documents/LineItemDialog.js +23 -10
  335. package/dist/modules/sales/components/documents/LineItemDialog.js.map +2 -2
  336. package/dist/modules/sales/components/documents/PaymentDialog.js +29 -14
  337. package/dist/modules/sales/components/documents/PaymentDialog.js.map +2 -2
  338. package/dist/modules/sales/components/documents/PaymentsSection.js +20 -10
  339. package/dist/modules/sales/components/documents/PaymentsSection.js.map +2 -2
  340. package/dist/modules/sales/components/documents/ReturnDialog.js +26 -17
  341. package/dist/modules/sales/components/documents/ReturnDialog.js.map +2 -2
  342. package/dist/modules/sales/components/documents/ReturnsSection.js +3 -1
  343. package/dist/modules/sales/components/documents/ReturnsSection.js.map +2 -2
  344. package/dist/modules/sales/components/documents/SalesDocumentsTable.js +10 -5
  345. package/dist/modules/sales/components/documents/SalesDocumentsTable.js.map +2 -2
  346. package/dist/modules/sales/components/documents/ShipmentDialog.js +21 -7
  347. package/dist/modules/sales/components/documents/ShipmentDialog.js.map +2 -2
  348. package/dist/modules/sales/components/documents/ShipmentsSection.js +19 -10
  349. package/dist/modules/sales/components/documents/ShipmentsSection.js.map +2 -2
  350. package/dist/modules/sales/components/documents/optimisticLock.js +27 -0
  351. package/dist/modules/sales/components/documents/optimisticLock.js.map +7 -0
  352. package/dist/modules/sales/di.js +18 -0
  353. package/dist/modules/sales/di.js.map +2 -2
  354. package/dist/modules/staff/api/job-histories.js +11 -2
  355. package/dist/modules/staff/api/job-histories.js.map +2 -2
  356. package/dist/modules/staff/api/timesheets/time-entries/route.js +11 -4
  357. package/dist/modules/staff/api/timesheets/time-entries/route.js.map +2 -2
  358. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js +13 -8
  359. package/dist/modules/staff/backend/staff/leave-requests/[id]/page.js.map +2 -2
  360. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js +2 -1
  361. package/dist/modules/staff/backend/staff/my-leave-requests/[id]/page.js.map +2 -2
  362. package/dist/modules/staff/backend/staff/team-members/[id]/page.js +7 -4
  363. package/dist/modules/staff/backend/staff/team-members/[id]/page.js.map +2 -2
  364. package/dist/modules/staff/backend/staff/team-members/page.js +4 -2
  365. package/dist/modules/staff/backend/staff/team-members/page.js.map +2 -2
  366. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js +1 -0
  367. package/dist/modules/staff/backend/staff/team-roles/[id]/edit/page.js.map +2 -2
  368. package/dist/modules/staff/backend/staff/team-roles/page.js +4 -2
  369. package/dist/modules/staff/backend/staff/team-roles/page.js.map +2 -2
  370. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js +5 -2
  371. package/dist/modules/staff/backend/staff/teams/[id]/edit/page.js.map +2 -2
  372. package/dist/modules/staff/backend/staff/teams/page.js +12 -3
  373. package/dist/modules/staff/backend/staff/teams/page.js.map +2 -2
  374. package/dist/modules/staff/backend/staff/timesheets/page.js +4 -1
  375. package/dist/modules/staff/backend/staff/timesheets/page.js.map +2 -2
  376. package/dist/modules/staff/backend/staff/timesheets/projects/[id]/page.js.map +2 -2
  377. package/dist/modules/staff/backend/staff/timesheets/projects/page.js +12 -3
  378. package/dist/modules/staff/backend/staff/timesheets/projects/page.js.map +2 -2
  379. package/dist/modules/staff/commands/job-histories.js +40 -3
  380. package/dist/modules/staff/commands/job-histories.js.map +2 -2
  381. package/dist/modules/staff/components/LeaveRequestForm.js +1 -0
  382. package/dist/modules/staff/components/LeaveRequestForm.js.map +2 -2
  383. package/dist/modules/staff/components/TeamForm.js +1 -0
  384. package/dist/modules/staff/components/TeamForm.js.map +2 -2
  385. package/dist/modules/staff/components/TeamMemberForm.js +1 -0
  386. package/dist/modules/staff/components/TeamMemberForm.js.map +2 -2
  387. package/dist/modules/staff/components/TeamRoleForm.js +1 -0
  388. package/dist/modules/staff/components/TeamRoleForm.js.map +2 -2
  389. package/dist/modules/staff/components/detail/JobHistorySection.js +20 -7
  390. package/dist/modules/staff/components/detail/JobHistorySection.js.map +2 -2
  391. package/dist/modules/staff/data/validators.js +7 -1
  392. package/dist/modules/staff/data/validators.js.map +2 -2
  393. package/dist/modules/staff/lib/leaveRequestHelpers.js +2 -1
  394. package/dist/modules/staff/lib/leaveRequestHelpers.js.map +2 -2
  395. package/dist/modules/translations/components/TranslationManager.js +12 -8
  396. package/dist/modules/translations/components/TranslationManager.js.map +2 -2
  397. package/dist/modules/workflows/api/definitions/[id]/route.js +106 -0
  398. package/dist/modules/workflows/api/definitions/[id]/route.js.map +2 -2
  399. package/dist/modules/workflows/backend/definitions/[id]/page.js +11 -3
  400. package/dist/modules/workflows/backend/definitions/[id]/page.js.map +2 -2
  401. package/dist/modules/workflows/backend/definitions/page.js +19 -8
  402. package/dist/modules/workflows/backend/definitions/page.js.map +2 -2
  403. package/dist/modules/workflows/backend/definitions/visual-editor/page.js +29 -16
  404. package/dist/modules/workflows/backend/definitions/visual-editor/page.js.map +2 -2
  405. package/dist/modules/workflows/components/formConfig.js +4 -1
  406. package/dist/modules/workflows/components/formConfig.js.map +2 -2
  407. package/dist/modules/workflows/di.js +12 -0
  408. package/dist/modules/workflows/di.js.map +2 -2
  409. package/generated/entities/role/index.ts +1 -0
  410. package/generated/entities/user/index.ts +1 -0
  411. package/generated/entity-fields-registry.ts +2 -0
  412. package/jest.setup.ts +17 -0
  413. package/package.json +8 -7
  414. package/src/helpers/integration/communicationChannelsFixtures.ts +6 -0
  415. package/src/helpers/integration/dbFixtures.ts +1 -1
  416. package/src/helpers/integration/optimisticLockUi.ts +172 -0
  417. package/src/helpers/integration/salesFixtures.ts +29 -0
  418. package/src/modules/api_keys/backend/api-keys/page.tsx +10 -5
  419. package/src/modules/attachments/components/AttachmentPartitionSettings.tsx +19 -9
  420. package/src/modules/auth/api/roles/acl/route.ts +37 -11
  421. package/src/modules/auth/api/roles/route.ts +2 -0
  422. package/src/modules/auth/api/sidebar/preferences/route.ts +73 -0
  423. package/src/modules/auth/api/users/acl/route.ts +46 -18
  424. package/src/modules/auth/api/users/route.ts +2 -0
  425. package/src/modules/auth/backend/roles/[id]/edit/page.tsx +29 -4
  426. package/src/modules/auth/backend/roles/page.tsx +9 -4
  427. package/src/modules/auth/backend/users/[id]/edit/page.tsx +37 -4
  428. package/src/modules/auth/backend/users/page.tsx +7 -2
  429. package/src/modules/auth/components/AclEditor.tsx +10 -1
  430. package/src/modules/auth/data/entities.ts +7 -1
  431. package/src/modules/auth/services/sidebarPreferencesService.ts +38 -4
  432. package/src/modules/business_rules/api/rules/route.ts +30 -0
  433. package/src/modules/business_rules/api/sets/route.ts +30 -0
  434. package/src/modules/business_rules/backend/rules/[id]/page.tsx +16 -4
  435. package/src/modules/business_rules/backend/rules/page.tsx +20 -11
  436. package/src/modules/business_rules/backend/sets/[id]/page.tsx +16 -4
  437. package/src/modules/business_rules/backend/sets/page.tsx +20 -11
  438. package/src/modules/catalog/api/categories/route.ts +3 -0
  439. package/src/modules/catalog/api/products/route.ts +4 -0
  440. package/src/modules/catalog/backend/catalog/categories/[id]/edit/page.tsx +5 -0
  441. package/src/modules/catalog/backend/catalog/products/[id]/page.tsx +112 -35
  442. package/src/modules/catalog/backend/catalog/products/[productId]/variants/[variantId]/page.tsx +56 -7
  443. package/src/modules/catalog/backend/catalog/products/optionSchemaClient.ts +2 -0
  444. package/src/modules/catalog/commands/variants.ts +32 -32
  445. package/src/modules/catalog/components/PriceKindSettings.tsx +20 -7
  446. package/src/modules/catalog/components/categories/CategoriesDataTable.tsx +1 -0
  447. package/src/modules/catalog/components/products/ProductMediaManager.tsx +2 -0
  448. package/src/modules/catalog/components/products/ProductsDataTable.tsx +8 -4
  449. package/src/modules/catalog/components/products/productForm.ts +3 -0
  450. package/src/modules/catalog/components/products/variantForm.ts +9 -0
  451. package/src/modules/communication_channels/api/post/test-seed/route.ts +28 -1
  452. package/src/modules/communication_channels/backend/profile/communication-channels/page.tsx +5 -0
  453. package/src/modules/communication_channels/commands/set-primary-channel.ts +10 -7
  454. package/src/modules/currencies/backend/currencies/[id]/page.tsx +13 -6
  455. package/src/modules/currencies/backend/currencies/page.tsx +18 -11
  456. package/src/modules/currencies/backend/exchange-rates/[id]/page.tsx +3 -0
  457. package/src/modules/currencies/backend/exchange-rates/page.tsx +10 -6
  458. package/src/modules/currencies/commands/currencies.ts +10 -5
  459. package/src/modules/currencies/components/CurrencyFetchingConfig.tsx +31 -21
  460. package/src/modules/customer_accounts/api/admin/roles/[id].ts +35 -5
  461. package/src/modules/customer_accounts/api/admin/roles.ts +2 -0
  462. package/src/modules/customer_accounts/api/admin/users/[id].ts +38 -5
  463. package/src/modules/customer_accounts/api/admin/users.ts +2 -0
  464. package/src/modules/customer_accounts/backend/customer_accounts/roles/[id]/page.tsx +34 -20
  465. package/src/modules/customer_accounts/backend/customer_accounts/roles/page.tsx +9 -4
  466. package/src/modules/customer_accounts/backend/customer_accounts/settings/domain/page.tsx +11 -4
  467. package/src/modules/customer_accounts/backend/customer_accounts/users/[id]/page.tsx +28 -17
  468. package/src/modules/customer_accounts/backend/customer_accounts/users/page.tsx +19 -11
  469. package/src/modules/customers/AGENTS.md +2 -2
  470. package/src/modules/customers/api/companies/route.ts +14 -1
  471. package/src/modules/customers/api/deals/route.ts +3 -0
  472. package/src/modules/customers/api/people/route.ts +12 -1
  473. package/src/modules/customers/api/todos/route.ts +1 -0
  474. package/src/modules/customers/backend/config/customers/deals/page.tsx +1 -0
  475. package/src/modules/customers/backend/config/customers/pipeline-stages/page.tsx +36 -21
  476. package/src/modules/customers/backend/customers/companies/[id]/page.tsx +52 -27
  477. package/src/modules/customers/backend/customers/companies/page.tsx +2 -0
  478. package/src/modules/customers/backend/customers/companies-v2/[id]/page.tsx +27 -5
  479. package/src/modules/customers/backend/customers/deals/[id]/hooks/useDealFormHandlers.ts +39 -7
  480. package/src/modules/customers/backend/customers/deals/[id]/page.tsx +1 -0
  481. package/src/modules/customers/backend/customers/deals/page.tsx +18 -6
  482. package/src/modules/customers/backend/customers/deals/pipeline/page.tsx +64 -39
  483. package/src/modules/customers/backend/customers/people/[id]/page.tsx +46 -26
  484. package/src/modules/customers/backend/customers/people/page.tsx +2 -0
  485. package/src/modules/customers/backend/customers/people-v2/[id]/page.tsx +84 -24
  486. package/src/modules/customers/commands/addresses.ts +16 -14
  487. package/src/modules/customers/commands/companies.ts +3 -1
  488. package/src/modules/customers/commands/interactions.ts +50 -4
  489. package/src/modules/customers/commands/people.ts +2 -1
  490. package/src/modules/customers/commands/personCompanyLinks.ts +8 -5
  491. package/src/modules/customers/commands/pipeline-stages.ts +16 -16
  492. package/src/modules/customers/components/AddressFormatSettings.tsx +1 -0
  493. package/src/modules/customers/components/DictionarySettings.tsx +18 -13
  494. package/src/modules/customers/components/DictionarySortSettings.tsx +4 -0
  495. package/src/modules/customers/components/PipelineSettings.tsx +42 -21
  496. package/src/modules/customers/components/detail/ActivityTimeline.tsx +3 -3
  497. package/src/modules/customers/components/detail/AddressesSection.tsx +4 -0
  498. package/src/modules/customers/components/detail/CompanyPeopleSection.tsx +2 -0
  499. package/src/modules/customers/components/detail/DealsSection.tsx +4 -0
  500. package/src/modules/customers/components/detail/EmailCardActions.tsx +5 -0
  501. package/src/modules/customers/components/detail/EntityTagsDialog.tsx +7 -0
  502. package/src/modules/customers/components/detail/ManageTagsDialog.tsx +4 -0
  503. package/src/modules/customers/components/detail/PersonCompaniesSection.tsx +4 -0
  504. package/src/modules/customers/components/detail/RoleAssignmentRow.tsx +2 -0
  505. package/src/modules/customers/components/detail/ScheduleActivityDialog.tsx +23 -7
  506. package/src/modules/customers/components/detail/hooks/useInteractionMutations.ts +25 -15
  507. package/src/modules/customers/components/detail/hooks/useInteractions.ts +76 -35
  508. package/src/modules/customers/components/detail/hooks/usePersonTasks.ts +30 -17
  509. package/src/modules/customers/components/detail/schedule/useScheduleFormState.ts +2 -0
  510. package/src/modules/customers/components/detail/types.ts +1 -0
  511. package/src/modules/customers/components/formConfig.tsx +2 -0
  512. package/src/modules/customers/data/guards.ts +67 -0
  513. package/src/modules/customers/di.ts +66 -0
  514. package/src/modules/customers/i18n/de.json +2 -0
  515. package/src/modules/customers/i18n/en.json +2 -0
  516. package/src/modules/customers/i18n/es.json +2 -0
  517. package/src/modules/customers/i18n/pl.json +2 -0
  518. package/src/modules/customers/lib/todoCompatibility.ts +14 -0
  519. package/src/modules/dashboards/components/WidgetVisibilityEditor.tsx +2 -0
  520. package/src/modules/data_sync/api/options.ts +7 -4
  521. package/src/modules/data_sync/api/schedules/route.ts +9 -1
  522. package/src/modules/data_sync/backend/data-sync/page.tsx +18 -5
  523. package/src/modules/data_sync/components/IntegrationScheduleTab.tsx +46 -19
  524. package/src/modules/data_sync/lib/sync-schedule-service.ts +11 -0
  525. package/src/modules/dictionaries/api/[dictionaryId]/entries/[entryId]/route.ts +8 -1
  526. package/src/modules/dictionaries/api/[dictionaryId]/route.ts +23 -0
  527. package/src/modules/dictionaries/components/DictionariesManager.tsx +32 -9
  528. package/src/modules/dictionaries/components/DictionaryEntriesEditor.tsx +30 -14
  529. package/src/modules/dictionaries/i18n/de.json +1 -0
  530. package/src/modules/dictionaries/i18n/en.json +1 -0
  531. package/src/modules/dictionaries/i18n/es.json +1 -0
  532. package/src/modules/dictionaries/i18n/pl.json +1 -0
  533. package/src/modules/directory/api/organizations/route.ts +3 -0
  534. package/src/modules/directory/backend/directory/organizations/[id]/edit/page.tsx +8 -0
  535. package/src/modules/directory/backend/directory/organizations/page.tsx +10 -5
  536. package/src/modules/directory/backend/directory/tenants/[id]/edit/page.tsx +16 -5
  537. package/src/modules/directory/backend/directory/tenants/page.tsx +8 -4
  538. package/src/modules/directory/commands/organizations.ts +7 -4
  539. package/src/modules/entities/api/records.ts +99 -0
  540. package/src/modules/entities/backend/entities/user/[entityId]/records/[recordId]/page.tsx +7 -0
  541. package/src/modules/entities/backend/entities/user/[entityId]/records/page.tsx +8 -4
  542. package/src/modules/entities/lib/helpers.ts +17 -0
  543. package/src/modules/feature_toggles/api/global/[id]/override/route.ts +1 -0
  544. package/src/modules/feature_toggles/api/overrides/route.ts +19 -0
  545. package/src/modules/feature_toggles/backend/feature-toggles/global/[id]/edit/page.tsx +19 -13
  546. package/src/modules/feature_toggles/components/FeatureToggleOverrideCard.tsx +22 -12
  547. package/src/modules/feature_toggles/components/FeatureTogglesTable.tsx +7 -2
  548. package/src/modules/feature_toggles/components/formConfig.tsx +2 -1
  549. package/src/modules/feature_toggles/components/overrideFormConfig.tsx +10 -1
  550. package/src/modules/feature_toggles/data/validators.ts +11 -3
  551. package/src/modules/inbox_ops/api/settings/route.ts +18 -0
  552. package/src/modules/inbox_ops/backend/inbox-ops/settings/page.tsx +15 -10
  553. package/src/modules/inbox_ops/components/proposals/EditActionDialog.tsx +9 -4
  554. package/src/modules/integrations/backend/integrations/bundle/[id]/page.tsx +20 -11
  555. package/src/modules/integrations/backend/integrations/page.tsx +13 -8
  556. package/src/modules/messages/commands/messages.ts +27 -15
  557. package/src/modules/perspectives/api/[tableId]/route.ts +11 -2
  558. package/src/modules/perspectives/services/perspectiveService.ts +13 -1
  559. package/src/modules/planner/backend/planner/availability-rulesets/[id]/page.tsx +16 -14
  560. package/src/modules/planner/backend/planner/availability-rulesets/page.tsx +6 -3
  561. package/src/modules/planner/components/AvailabilityRuleSetForm.tsx +3 -0
  562. package/src/modules/planner/components/AvailabilityRulesEditor.tsx +58 -15
  563. package/src/modules/planner/components/AvailabilitySchedule.tsx +22 -7
  564. package/src/modules/query_index/lib/engine.ts +34 -0
  565. package/src/modules/resources/backend/resources/resource-types/[id]/edit/page.tsx +7 -1
  566. package/src/modules/resources/backend/resources/resource-types/page.tsx +6 -3
  567. package/src/modules/resources/backend/resources/resources/[id]/page.tsx +23 -3
  568. package/src/modules/resources/backend/resources/resources/page.tsx +15 -4
  569. package/src/modules/resources/components/ResourceCrudForm.tsx +3 -0
  570. package/src/modules/resources/components/ResourceTypeCrudForm.tsx +2 -0
  571. package/src/modules/sales/api/documents/factory.ts +13 -1
  572. package/src/modules/sales/backend/sales/channels/[channelId]/edit/page.tsx +6 -0
  573. package/src/modules/sales/backend/sales/channels/offers/page.tsx +10 -4
  574. package/src/modules/sales/backend/sales/channels/page.tsx +19 -4
  575. package/src/modules/sales/backend/sales/documents/[id]/page.tsx +73 -20
  576. package/src/modules/sales/backend/sales/documents/create/page.tsx +2 -0
  577. package/src/modules/sales/commands/documentAddresses.ts +226 -4
  578. package/src/modules/sales/commands/documents.ts +28 -0
  579. package/src/modules/sales/commands/returns.ts +12 -3
  580. package/src/modules/sales/commands/shared.ts +36 -0
  581. package/src/modules/sales/commands/shipments.ts +17 -1
  582. package/src/modules/sales/components/AdjustmentKindSettings.tsx +20 -11
  583. package/src/modules/sales/components/DocumentNumberSettings.tsx +1 -0
  584. package/src/modules/sales/components/OrderEditingSettings.tsx +1 -0
  585. package/src/modules/sales/components/PaymentMethodsSettings.tsx +12 -4
  586. package/src/modules/sales/components/ShippingMethodsSettings.tsx +12 -4
  587. package/src/modules/sales/components/StatusSettings.tsx +20 -11
  588. package/src/modules/sales/components/TaxRatesSettings.tsx +12 -5
  589. package/src/modules/sales/components/channels/ChannelOfferForm.tsx +67 -14
  590. package/src/modules/sales/components/channels/SalesChannelOffersPanel.tsx +7 -4
  591. package/src/modules/sales/components/documents/AddressesSection.tsx +35 -25
  592. package/src/modules/sales/components/documents/AdjustmentsSection.tsx +50 -25
  593. package/src/modules/sales/components/documents/ItemsSection.tsx +24 -13
  594. package/src/modules/sales/components/documents/LineItemDialog.tsx +26 -9
  595. package/src/modules/sales/components/documents/PaymentDialog.tsx +33 -14
  596. package/src/modules/sales/components/documents/PaymentsSection.tsx +22 -10
  597. package/src/modules/sales/components/documents/ReturnDialog.tsx +28 -17
  598. package/src/modules/sales/components/documents/ReturnsSection.tsx +4 -1
  599. package/src/modules/sales/components/documents/SalesDocumentsTable.tsx +11 -4
  600. package/src/modules/sales/components/documents/ShipmentDialog.tsx +23 -8
  601. package/src/modules/sales/components/documents/ShipmentsSection.tsx +20 -10
  602. package/src/modules/sales/components/documents/optimisticLock.ts +34 -0
  603. package/src/modules/sales/components/documents/shipmentTypes.ts +1 -0
  604. package/src/modules/sales/di.ts +35 -0
  605. package/src/modules/sales/i18n/de.json +3 -0
  606. package/src/modules/sales/i18n/en.json +3 -0
  607. package/src/modules/sales/i18n/es.json +3 -0
  608. package/src/modules/sales/i18n/pl.json +3 -0
  609. package/src/modules/staff/api/job-histories.ts +12 -2
  610. package/src/modules/staff/api/timesheets/time-entries/route.ts +16 -4
  611. package/src/modules/staff/backend/staff/leave-requests/[id]/page.tsx +12 -7
  612. package/src/modules/staff/backend/staff/my-leave-requests/[id]/page.tsx +2 -0
  613. package/src/modules/staff/backend/staff/team-members/[id]/page.tsx +16 -5
  614. package/src/modules/staff/backend/staff/team-members/page.tsx +6 -2
  615. package/src/modules/staff/backend/staff/team-roles/[id]/edit/page.tsx +8 -0
  616. package/src/modules/staff/backend/staff/team-roles/page.tsx +6 -2
  617. package/src/modules/staff/backend/staff/teams/[id]/edit/page.tsx +13 -3
  618. package/src/modules/staff/backend/staff/teams/page.tsx +9 -3
  619. package/src/modules/staff/backend/staff/timesheets/page.tsx +10 -1
  620. package/src/modules/staff/backend/staff/timesheets/projects/[id]/page.tsx +4 -0
  621. package/src/modules/staff/backend/staff/timesheets/projects/page.tsx +9 -3
  622. package/src/modules/staff/commands/job-histories.ts +42 -3
  623. package/src/modules/staff/components/LeaveRequestForm.tsx +2 -0
  624. package/src/modules/staff/components/TeamForm.tsx +2 -0
  625. package/src/modules/staff/components/TeamMemberForm.tsx +2 -0
  626. package/src/modules/staff/components/TeamRoleForm.tsx +2 -0
  627. package/src/modules/staff/components/detail/JobHistorySection.tsx +28 -6
  628. package/src/modules/staff/data/validators.ts +6 -0
  629. package/src/modules/staff/i18n/de.json +1 -0
  630. package/src/modules/staff/i18n/en.json +1 -0
  631. package/src/modules/staff/i18n/es.json +1 -0
  632. package/src/modules/staff/i18n/pl.json +1 -0
  633. package/src/modules/staff/lib/leaveRequestHelpers.ts +4 -0
  634. package/src/modules/translations/components/TranslationManager.tsx +13 -8
  635. package/src/modules/workflows/api/definitions/[id]/route.ts +112 -0
  636. package/src/modules/workflows/backend/definitions/[id]/page.tsx +20 -4
  637. package/src/modules/workflows/backend/definitions/page.tsx +20 -9
  638. package/src/modules/workflows/backend/definitions/visual-editor/page.tsx +29 -16
  639. package/src/modules/workflows/components/formConfig.tsx +5 -0
  640. package/src/modules/workflows/di.ts +20 -0
  641. package/src/modules/workflows/i18n/de.json +1 -0
  642. package/src/modules/workflows/i18n/en.json +1 -0
  643. package/src/modules/workflows/i18n/es.json +1 -0
  644. package/src/modules/workflows/i18n/pl.json +1 -0
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../../../src/modules/workflows/backend/definitions/visual-editor/page.tsx"],
4
- "sourcesContent": ["'use client'\n\nimport { WorkflowGraph } from '../../../components/WorkflowGraph'\n// Conditional imports based on feature flag\nimport { NodeEditDialog } from '../../../components/NodeEditDialog'\nimport { EdgeEditDialog } from '../../../components/EdgeEditDialog'\nimport { NodeEditDialogCrudForm } from '../../../components/NodeEditDialogCrudForm'\nimport { EdgeEditDialogCrudForm } from '../../../components/EdgeEditDialogCrudForm'\nimport { Node, Edge, addEdge, Connection, applyNodeChanges, applyEdgeChanges, NodeChange, EdgeChange } from '@xyflow/react'\nimport { useState, useCallback, useEffect } from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { graphToDefinition, definitionToGraph, validateWorkflowGraph, generateStepId, generateTransitionId, ValidationError } from '../../../lib/graph-utils'\nimport { performDeleteEdgeFlow, performDeleteNodeFlow } from '../../../lib/visual-editor-delete-flow'\nimport { workflowDefinitionDataSchema } from '../../../data/validators'\nimport { Page } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs/TagsInput'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Alert, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { apiCall } from '@open-mercato/ui/backend/utils/apiCall'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { CircleQuestionMark, Info, PanelTopClose, PanelTopOpen, Play, Save, Trash2 } from 'lucide-react'\nimport { NODE_TYPE_ICONS, NODE_TYPE_COLORS, NODE_TYPE_LABELS } from '../../../lib/node-type-icons'\nimport { DefinitionTriggersEditor } from '../../../components/DefinitionTriggersEditor'\nimport { MobileVisualEditor } from '../../../components/mobile/MobileVisualEditor'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { WorkflowDefinitionTrigger } from '../../../data/entities'\nimport type { WorkflowMetadataState, WorkflowMetadataHandlers } from '../../../data/types'\nimport * as React from 'react'\n\n/**\n * VisualEditorPage - Visual workflow definition editor\n *\n * Layout:\n * - Page Header: Title, description, and action buttons (Save, Validate, Test)\n * - Workflow Metadata: Collapsible form for workflow details\n * - Page Body:\n * - Left sidebar: Step palette (click to add)\n * - Main canvas: ReactFlow graph editor\n * - Flash Messages: Top-right positioned validation messages\n * - Edit Dialogs: Modal dialogs for editing steps and transitions\n */\nexport default function VisualEditorPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const definitionId = searchParams.get('id')\n const isMobile = useIsMobile()\n\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const [isLoading, setIsLoading] = useState(!!definitionId)\n const [isSaving, setIsSaving] = useState(false)\n const [nodes, setNodes] = useState<Node[]>([])\n const [edges, setEdges] = useState<Edge[]>([])\n const [selectedNode, setSelectedNode] = useState<Node | null>(null)\n const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null)\n const [showMetadata, setShowMetadata] = useState(true)\n const [isCompactViewport, setIsCompactViewport] = useState(false)\n\n // Auto-collapse metadata on compact viewports after hydration\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mediaQuery = window.matchMedia('(max-width: 1279px)')\n const applyViewportMode = () => {\n const compact = mediaQuery.matches\n setIsCompactViewport(compact)\n setShowMetadata(!compact)\n }\n\n applyViewportMode()\n mediaQuery.addEventListener('change', applyViewportMode)\n\n return () => {\n mediaQuery.removeEventListener('change', applyViewportMode)\n }\n }, [])\n const [showNodeDialog, setShowNodeDialog] = useState(false)\n const [showEdgeDialog, setShowEdgeDialog] = useState(false)\n const [showClearConfirm, setShowClearConfirm] = useState(false)\n\n // Workflow metadata state\n const [workflowId, setWorkflowId] = useState('')\n const [workflowName, setWorkflowName] = useState('')\n const [description, setDescription] = useState('')\n const [version, setVersion] = useState(1)\n const [enabled, setEnabled] = useState(true)\n const [category, setCategory] = useState('')\n const [tags, setTags] = useState<string[]>([])\n const [icon, setIcon] = useState('')\n const [effectiveFrom, setEffectiveFrom] = useState('')\n const [effectiveTo, setEffectiveTo] = useState('')\n const [triggers, setTriggers] = useState<WorkflowDefinitionTrigger[]>([])\n const [source, setSource] = useState<'code' | 'code_override' | 'user' | null>(null)\n\n const isCodeOnly = source === 'code'\n const isCodeOverride = source === 'code_override'\n\n // Load existing definition if ID is provided\n useEffect(() => {\n const loadDefinition = async () => {\n if (!definitionId) {\n setIsLoading(false)\n return\n }\n\n try {\n const result = await apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`)\n\n if (!result.ok) {\n flash(`Failed to load workflow: ${result.result?.error || 'Unknown error'}`, 'error')\n setIsLoading(false)\n return\n }\n\n const definition = result.result?.data\n\n // Populate metadata\n setWorkflowId(definition.workflowId)\n setWorkflowName(definition.workflowName || definition.definition.workflowName || '')\n setDescription(definition.description || definition.definition.description || '')\n setVersion(definition.version)\n setEnabled(definition.enabled)\n setCategory(definition.metadata?.category || '')\n setTags(definition.metadata?.tags || [])\n setIcon(definition.metadata?.icon || '')\n setEffectiveFrom(definition.effectiveFrom || '')\n setEffectiveTo(definition.effectiveTo || '')\n\n // Convert definition to graph\n const graph = definitionToGraph(definition.definition)\n setNodes(graph.nodes)\n setEdges(graph.edges)\n\n // Load embedded triggers from definition\n setTriggers(definition.definition?.triggers || [])\n\n // Track source so the editor mirrors the non-visual edit page UX:\n // code \u2192 read-only with Customize button; code_override \u2192 editable\n // with Reset to code; user \u2192 editable, no banner.\n setSource((definition.source as 'code' | 'code_override' | 'user') ?? null)\n } catch (error) {\n console.error('Error loading workflow definition:', error)\n flash('Failed to load workflow definition', 'error')\n } finally {\n setIsLoading(false)\n }\n }\n\n loadDefinition()\n }, [definitionId])\n\n // Handle node changes from ReactFlow\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n if (isCodeOnly) return\n setNodes((nds) => applyNodeChanges(changes, nds))\n }, [isCodeOnly])\n\n // Handle edge changes from ReactFlow\n const handleEdgesChange = useCallback((changes: EdgeChange[]) => {\n if (isCodeOnly) return\n setEdges((eds) => applyEdgeChanges(changes, eds))\n }, [isCodeOnly])\n\n // Handle adding new node from palette\n const handleAddNode = useCallback((nodeType: string) => {\n if (isCodeOnly) return\n const newNode: Node = {\n id: generateStepId(nodeType),\n type: nodeType,\n position: {\n x: 250 + nodes.length * 50,\n y: 100 + nodes.length * 150,\n },\n data: {\n label: getDefaultLabel(nodeType),\n description: '',\n badge: getDefaultBadge(nodeType),\n status: 'pending',\n },\n }\n\n setNodes((nds) => [...nds, newNode])\n }, [nodes.length, isCodeOnly])\n\n // Handle node selection - open edit dialog (suppressed in read-only mode\n // so users can't open the node editor on a code-defined workflow).\n const handleNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {\n if (isCodeOnly) return\n setSelectedNode(node)\n setSelectedEdge(null)\n setShowNodeDialog(true)\n }, [isCodeOnly])\n\n // Handle edge selection - open edit dialog\n const handleEdgeClick = useCallback((_event: React.MouseEvent, edge: Edge) => {\n if (isCodeOnly) return\n setSelectedEdge(edge)\n setSelectedNode(null)\n setShowEdgeDialog(true)\n }, [isCodeOnly])\n\n // Save node updates\n const handleSaveNode = useCallback((nodeId: string, updates: Partial<Node['data']>) => {\n setNodes((nds) =>\n nds.map((node) =>\n node.id === nodeId\n ? { ...node, data: { ...node.data, ...updates } }\n : node\n )\n )\n flash('Node updated successfully', 'success')\n }, [])\n\n // Save edge updates\n const handleSaveEdge = useCallback((edgeId: string, updates: Partial<Edge['data']>) => {\n setEdges((eds) =>\n eds.map((edge) =>\n edge.id === edgeId\n ? { ...edge, data: { ...edge.data, ...updates } }\n : edge\n )\n )\n flash('Transition updated successfully', 'success')\n }, [])\n\n // Delete edge\n const handleDeleteEdge = useCallback(async (edgeId: string) => {\n await performDeleteEdgeFlow(edgeId, {\n confirm,\n t,\n setShowEdgeDialog,\n setSelectedEdge,\n setEdges,\n notifyDeleted: () => flash('Transition deleted successfully', 'success'),\n })\n }, [confirm, t])\n\n // Delete node\n const handleDeleteNode = useCallback(async (nodeId: string) => {\n await performDeleteNodeFlow(nodeId, {\n nodes,\n confirm,\n t,\n setShowNodeDialog,\n setSelectedNode,\n setNodes,\n setEdges,\n notifyDeleted: () => flash('Step deleted successfully', 'success'),\n })\n }, [confirm, nodes, t])\n\n // Handle new connections\n const handleConnect = useCallback((connection: Connection) => {\n const newEdge: Edge = {\n id: generateTransitionId(connection.source!, connection.target!),\n source: connection.source!,\n target: connection.target!,\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n label: '',\n },\n }\n\n setEdges((eds) => addEdge(newEdge, eds))\n }, [])\n\n // Validate workflow\n const handleValidate = useCallback(() => {\n const graphErrors = validateWorkflowGraph(nodes, edges)\n const allErrors: ValidationError[] = [...graphErrors]\n\n // Run Zod schema validation\n try {\n const definitionData = graphToDefinition(nodes, edges, { includePositions: true })\n const result = workflowDefinitionDataSchema.safeParse(definitionData)\n\n if (!result.success) {\n // Convert Zod errors to validation errors\n result.error.issues.forEach((issue) => {\n allErrors.push({\n type: 'error',\n message: `Schema validation: ${issue.path.join('.')} - ${issue.message}`,\n })\n })\n }\n } catch (error) {\n allErrors.push({\n type: 'error',\n message: `Schema validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n })\n }\n\n if (allErrors.length === 0) {\n flash('Validation passed! Your workflow is valid and ready to save.', 'success')\n } else {\n // Show first error/warning message\n const firstError = allErrors[0]\n const errorCount = allErrors.length\n const message = errorCount > 1\n ? `${firstError.message} (and ${errorCount - 1} more ${errorCount === 2 ? 'issue' : 'issues'})`\n : firstError.message\n flash(message, firstError.type === 'error' ? 'error' : 'warning')\n }\n }, [nodes, edges])\n\n // Save workflow definition\n const handleSave = useCallback(async () => {\n // Validate required fields\n if (!workflowId || !workflowName) {\n flash('Workflow ID and Name are required fields', 'error')\n return\n }\n\n // Validate workflow structure\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter(e => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot save: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // Generate definition data and include triggers\n const graphDefinition = graphToDefinition(nodes, edges, { includePositions: true })\n const definitionData = {\n ...graphDefinition,\n triggers: triggers.length > 0 ? triggers : undefined,\n }\n\n // Run Zod schema validation before saving\n const schemaResult = workflowDefinitionDataSchema.safeParse(definitionData)\n if (!schemaResult.success) {\n const firstIssue = schemaResult.error.issues[0]\n flash(`Schema error: ${firstIssue.path.join('.')} - ${firstIssue.message}`, 'error')\n return\n }\n\n setIsSaving(true)\n\n try {\n\n const metadata: any = {}\n if (category) metadata.category = category\n if (tags.length > 0) metadata.tags = tags\n if (icon) metadata.icon = icon\n\n // Determine if creating new or updating existing\n const isUpdate = !!definitionId\n\n let result\n if (isUpdate) {\n // Update existing definition \u2014 send the full editable payload so metadata\n // edits (name, description, version, category, tags, icon, effective\n // dates) actually persist. Previously only `definition` + `enabled`\n // were sent, silently dropping every other field.\n result = await apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n })\n } else {\n // Create new definition\n result = await apiCall<{ data: any; error?: string }>('/api/workflows/definitions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowId,\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n })\n }\n\n if (!result.ok) {\n flash(`Failed to save: ${result.result?.error || 'Unknown error'}`, 'error')\n return\n }\n\n const savedDefinition = result.result?.data\n\n flash(`Workflow ${isUpdate ? 'updated' : 'created'} successfully!`, 'success')\n\n // Redirect to definition detail page after short delay\n setTimeout(() => {\n router.push(`/backend/definitions/${savedDefinition.id}`)\n }, 1500)\n\n } catch (error) {\n console.error('Error saving workflow definition:', error)\n flash('Failed to save workflow definition. Please try again.', 'error')\n } finally {\n setIsSaving(false)\n }\n }, [nodes, edges, workflowId, workflowName, description, version, enabled, category, tags, icon, effectiveFrom, effectiveTo, triggers, definitionId, router])\n\n // Customize a code-defined workflow \u2192 creates an override and reloads the\n // editor pointed at the new UUID. Mirrors the non-visual edit page button.\n const handleCustomize = useCallback(async () => {\n if (!definitionId) return\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/customize`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to customize workflow', 'error')\n return\n }\n const newId = result.result?.data?.id\n if (!newId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(newId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, router])\n\n // Reset a code-override back to its code definition. Mirrors the\n // non-visual edit page action, with the same confirm dialog.\n const handleResetToCode = useCallback(async () => {\n if (!definitionId) return\n const confirmed = await confirm({\n title: t('workflows.actions.resetToCode'),\n description: t('workflows.actions.resetConfirm'),\n confirmText: t('workflows.actions.resetToCode'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/reset-to-code`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to reset workflow', 'error')\n return\n }\n const codeId = result.result?.data?.id || (workflowId ? `code:${workflowId}` : null)\n if (!codeId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(codeId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, workflowId, router, confirm, t])\n\n // Test workflow\n const handleTest = useCallback(() => {\n // First validate\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter((e) => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot test: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // TODO: Implement test logic (create instance, run first step)\n flash('Test functionality will be implemented next', 'info')\n }, [nodes, edges])\n\n // Load example workflow\n const handleLoadExample = useCallback(() => {\n // Set example metadata\n setWorkflowId('approval_workflow')\n setWorkflowName('Simple Approval Workflow')\n setDescription('A basic approval workflow for reviewing and approving requests')\n setVersion(1)\n setEnabled(true)\n setCategory('Approvals')\n setTags(['approval', 'review'])\n\n const exampleNodes: Node[] = [\n {\n id: 'start',\n type: 'start',\n position: { x: 250, y: 50 },\n data: {\n label: 'Start',\n description: 'Workflow begins',\n status: 'pending',\n badge: 'Start',\n },\n },\n {\n id: 'step1',\n type: 'userTask',\n position: { x: 250, y: 250 },\n data: {\n label: 'Review Request',\n description: 'User reviews the incoming request',\n status: 'pending',\n stepNumber: 1,\n badge: 'User Task',\n assignedToRoles: ['Reviewer'],\n },\n },\n {\n id: 'end',\n type: 'end',\n position: { x: 250, y: 450 },\n data: {\n label: 'Complete',\n description: 'Workflow ends',\n status: 'pending',\n badge: 'End',\n },\n },\n ]\n\n const exampleEdges: Edge[] = [\n {\n id: 'e-start-step1',\n source: 'start',\n target: 'step1',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n {\n id: 'e-step1-end',\n source: 'step1',\n target: 'end',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n ]\n\n setNodes(exampleNodes)\n setEdges(exampleEdges)\n flash('Example workflow loaded', 'success')\n }, [])\n\n // Clear canvas\n const handleClear = useCallback(() => {\n if (nodes.length > 0 || edges.length > 0 || workflowId || workflowName) {\n setShowClearConfirm(true)\n }\n }, [nodes.length, edges.length, workflowId, workflowName])\n\n // Confirm clear action\n const confirmClear = useCallback(() => {\n setNodes([])\n setEdges([])\n setWorkflowId('')\n setWorkflowName('')\n setDescription('')\n setVersion(1)\n setEnabled(true)\n setCategory('')\n setTags([])\n setIcon('')\n setEffectiveFrom('')\n setEffectiveTo('')\n setTriggers([])\n setShowClearConfirm(false)\n flash('Canvas cleared', 'success')\n }, [])\n\n // Show loading spinner while loading definition\n if (isLoading) {\n return (\n <Page className=\"flex items-center justify-center min-h-[50vh]\">\n <LoadingMessage label=\"Loading workflow definition...\" />\n </Page>\n )\n }\n\n const metadata: WorkflowMetadataState = {\n workflowId, workflowName, description, version,\n enabled, category, tags, icon,\n effectiveFrom, effectiveTo, triggers,\n }\n\n const metadataHandlers: WorkflowMetadataHandlers = {\n setWorkflowId, setWorkflowName, setDescription, setVersion,\n setEnabled, setCategory, setTags, setIcon,\n setEffectiveFrom, setEffectiveTo, setTriggers,\n }\n\n const sharedDialogs = (\n <>\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <NodeEditDialogCrudForm node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n ) : (\n <NodeEditDialog node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n )}\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <EdgeEditDialogCrudForm edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n ) : (\n <EdgeEditDialog edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n )}\n <Dialog open={showClearConfirm} onOpenChange={setShowClearConfirm}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('workflows.visualEditor.clearTitle')}</DialogTitle>\n <DialogDescription>{t('workflows.visualEditor.clearDescription')}</DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setShowClearConfirm(false)}>{t('common.cancel', 'Cancel')}</Button>\n <Button variant=\"destructive\" onClick={confirmClear}>{t('common.clear', 'Clear')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n\n if (isMobile) {\n return (\n <Page className=\"flex h-[100svh] flex-col space-y-0 overflow-hidden\">\n <MobileVisualEditor\n definitionId={definitionId}\n isSaving={isSaving}\n nodes={nodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n onAddNode={handleAddNode}\n onSave={handleSave}\n onValidate={handleValidate}\n onTest={handleTest}\n onLoadExample={handleLoadExample}\n onClear={handleClear}\n metadata={metadata}\n metadataHandlers={metadataHandlers}\n />\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page className=\"space-y-0 overflow-x-hidden\">\n {/* Page Header */}\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/definitions\"\n backLabel={t('workflows.definitions.backToList', 'Back to definitions')}\n title={definitionId ? (workflowName || t('workflows.definitions.singular')) : t('workflows.backend.definitions.visual_editor.title')}\n subtitle={definitionId\n ? t('workflows.definitions.detail.summary', 'Editing workflow definition')\n : t('workflows.definitions.create.summary', 'Create and edit workflow definitions visually with a drag-and-drop interface')\n }\n actionsContent={\n <div className=\"flex flex-wrap items-center justify-end gap-1 md:gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowMetadata(!showMetadata)}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n >\n {showMetadata ? <PanelTopClose className=\"mr-1.5 h-4 w-4\" /> : <PanelTopOpen className=\"mr-1.5 h-4 w-4\" />}\n {showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleLoadExample}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.visualEditor.loadExample')}\n </Button>\n )}\n {!isCodeOnly && (\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={handleClear}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.clear')}\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.clear')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleValidate}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.validate')}\n >\n <CircleQuestionMark className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.validate')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleTest}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.runTest')}\n </Button>\n )}\n {isCodeOverride && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleResetToCode}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.actions.resetToCode')}\n </Button>\n )}\n {isCodeOnly ? (\n <Button\n size=\"sm\"\n onClick={handleCustomize}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n >\n {t('workflows.actions.customize')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n aria-label={isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n >\n <Save className=\"mr-1.5 h-4 w-4\" />\n {isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n </Button>\n )}\n </div>\n }\n />\n </div>\n\n {/* Source banner (code-defined / customized) */}\n {(isCodeOnly || isCodeOverride) && (\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n {isCodeOnly && (\n <Alert variant=\"info\">\n <AlertTitle>{t('workflows.source.code.readonlyBanner')}</AlertTitle>\n </Alert>\n )}\n {isCodeOverride && (\n <Alert variant=\"warning\">\n <AlertTitle>{t('workflows.source.code_override.banner')}</AlertTitle>\n </Alert>\n )}\n </div>\n )}\n\n {/* Workflow Metadata Form */}\n {showMetadata && (\n <div className={isCompactViewport\n ? 'shrink-0 border-b border-border bg-background px-3 py-2 max-h-[60svh] overflow-y-auto overscroll-contain md:px-6 md:py-3'\n : 'shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3'\n }>\n <fieldset disabled={isCodeOnly} className=\"rounded-lg border bg-card p-3 disabled:opacity-70 md:p-4\">\n <h2 className=\"mb-3 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.workflowMetadata')}</h2>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 md:gap-4\">\n {/* Workflow ID */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowId\" className=\"text-xs\">{t('workflows.form.workflowId')} *</Label>\n <Input\n id=\"workflowId\"\n value={workflowId}\n onChange={(e) => setWorkflowId(e.target.value)}\n placeholder=\"checkout_workflow\"\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n {definitionId && <p className=\"text-overline text-muted-foreground\">{t('workflows.visualEditor.readOnly')}</p>}\n </div>\n\n {/* Workflow Name */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowName\" className=\"text-xs\">{t('workflows.form.workflowName')} *</Label>\n <Input\n id=\"workflowName\"\n value={workflowName}\n onChange={(e) => setWorkflowName(e.target.value)}\n placeholder=\"Checkout Process\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Category */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"category\" className=\"text-xs\">{t('workflows.form.category')}</Label>\n <Input\n id=\"category\"\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n placeholder=\"E-Commerce\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Description */}\n <div className=\"min-w-0 space-y-1 sm:col-span-2 lg:col-span-3\">\n <Label htmlFor=\"description\" className=\"text-xs\">{t('workflows.form.description')}</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('workflows.form.placeholders.description')}\n rows={2}\n className=\"min-h-[60px] text-sm\"\n />\n </div>\n\n {/* Version */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"version\" className=\"text-xs\">{t('workflows.form.version')} *</Label>\n <Input\n id=\"version\"\n type=\"number\"\n value={version}\n onChange={(e) => setVersion(parseInt(e.target.value) || 1)}\n min={1}\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Enabled */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('common.enabled', 'Enabled')}</Label>\n <div className=\"flex h-8 items-center gap-2\">\n <Switch\n id=\"enabled\"\n checked={enabled}\n onCheckedChange={setEnabled}\n />\n <Label htmlFor=\"enabled\" className=\"cursor-pointer text-xs font-normal\">\n {enabled ? t('common.on', 'On') : t('common.off', 'Off')}\n </Label>\n </div>\n </div>\n\n {/* Tags */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('workflows.form.tags')}</Label>\n <TagsInput\n value={tags}\n onChange={setTags}\n placeholder={t('workflows.form.placeholders.tags')}\n />\n </div>\n\n {/* Icon */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"icon\" className=\"text-xs\">{t('workflows.form.icon')}</Label>\n <Input\n id=\"icon\"\n value={icon}\n onChange={(e) => setIcon(e.target.value)}\n placeholder=\"ShoppingCart\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveFrom\" className=\"text-xs\">{t('workflows.form.effectiveFrom')}</Label>\n <Input\n id=\"effectiveFrom\"\n type=\"date\"\n value={effectiveFrom}\n onChange={(e) => setEffectiveFrom(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveTo\" className=\"text-xs\">{t('workflows.form.effectiveTo')}</Label>\n <Input\n id=\"effectiveTo\"\n type=\"date\"\n value={effectiveTo}\n onChange={(e) => setEffectiveTo(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Event Triggers \u2014 also locked when the workflow is code-defined */}\n <fieldset disabled={isCodeOnly} className=\"mt-3 disabled:opacity-70\">\n <DefinitionTriggersEditor\n value={triggers}\n onChange={setTriggers}\n />\n </fieldset>\n </div>\n )}\n\n {/* Main Content */}\n {isCompactViewport ? (\n <div className=\"px-3 py-3 md:px-6 md:py-4\">\n <div className=\"relative min-w-0\">\n <div className=\"h-[64svh] min-h-[360px] rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-lg font-semibold text-foreground\">{t('workflows.visualEditor.startBuilding')}</h2>\n <p className=\"mb-4 text-sm text-muted-foreground\">{t('workflows.visualEditor.tapToAddBelow')}</p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n\n {!isCodeOnly && (\n <div className=\"mt-3 rounded-lg border bg-card p-3\">\n <h2 className=\"mb-2 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-3 text-xs text-muted-foreground\">{t('workflows.visualEditor.tapToAdd')}</p>\n\n <div className=\"flex gap-2 overflow-x-auto pb-1\">\n {(['start', 'userTask', 'automated', 'waitForSignal', 'waitForTimer', 'subWorkflow', 'end'] as const).map((nodeType) => {\n const Icon = NODE_TYPE_ICONS[nodeType]\n return (\n <button\n key={nodeType}\n onClick={() => handleAddNode(nodeType)}\n className=\"flex shrink-0 items-center gap-1 rounded-md border bg-background px-2 py-1 text-xs hover:bg-muted active:bg-muted/50\"\n >\n <Icon className=\"h-3.5 w-3.5\" />\n <span>{NODE_TYPE_LABELS[nodeType].title}</span>\n </button>\n )\n })}\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex min-h-[72svh] min-w-0 flex-1 border-t border-border\">\n {/* Left Sidebar - Step Palette (hidden in read-only mode) */}\n {!isCodeOnly && (\n <div className=\"w-[24rem] shrink-0 overflow-y-auto border-r border-border bg-background p-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-2 text-sm font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-4 text-xs text-muted-foreground\">\n {t('workflows.visualEditor.clickToAdd')}\n </p>\n\n <div className=\"space-y-3\">\n {/* START Step */}\n <button\n onClick={() => handleAddNode('start')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.start} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.start\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.start.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.start.description}</div>\n </button>\n\n {/* USER_TASK Step */}\n <button\n onClick={() => handleAddNode('userTask')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.userTask} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.userTask\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.userTask.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.userTask.description}</div>\n </button>\n\n {/* AUTOMATED Step */}\n <button\n onClick={() => handleAddNode('automated')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.automated} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.automated\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.automated.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.automated.description}</div>\n </button>\n\n {/* WAIT_FOR_SIGNAL Step */}\n <button\n onClick={() => handleAddNode('waitForSignal')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForSignal} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForSignal\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForSignal.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForSignal.description}</div>\n </button>\n\n {/* WAIT_FOR_TIMER Step */}\n <button\n onClick={() => handleAddNode('waitForTimer')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForTimer} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForTimer\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForTimer.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForTimer.description}</div>\n </button>\n\n {/* SUB_WORKFLOW Step */}\n <button\n onClick={() => handleAddNode('subWorkflow')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.subWorkflow} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.subWorkflow\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.subWorkflow.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.subWorkflow.description}</div>\n </button>\n\n {/* END Step */}\n <button\n onClick={() => handleAddNode('end')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.end} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.end\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.end.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.end.description}</div>\n </button>\n </div>\n\n {/* Instructions */}\n <Alert variant=\"info\" className=\"mt-6\">\n <Info className=\"size-4\" />\n <AlertTitle className=\"text-xs\">{t('workflows.visualEditor.howToUse', 'How to use:')}</AlertTitle>\n <div className=\"mt-2\">\n <ul className=\"list-inside list-disc space-y-1 text-xs\">\n <li>{t('workflows.visualEditor.hint.addSteps', 'Click step types to add them')}</li>\n <li>{t('workflows.visualEditor.hint.dragSteps', 'Drag steps to position them')}</li>\n <li>{t('workflows.visualEditor.hint.connectSteps', 'Connect steps by dragging from handles')}</li>\n <li>{t('workflows.visualEditor.hint.editSteps', 'Click steps and transitions to edit them')}</li>\n <li>{t('workflows.visualEditor.hint.validate', 'Validate before saving')}</li>\n </ul>\n </div>\n </Alert>\n </div>\n </div>\n )}\n\n {/* Main Canvas */}\n <div className=\"min-w-0 flex-1 p-6\">\n <div className=\"relative h-[72svh] min-h-[640px]\">\n <div className=\"h-full rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {/* Empty State */}\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-xl font-semibold text-foreground\">\n {t('workflows.visualEditor.startBuilding')}\n </h2>\n <p className=\"mb-4 text-muted-foreground\">\n {t('workflows.visualEditor.clickToAddFromPalette')}\n </p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n}\n\n// Helper functions\nfunction getDefaultLabel(nodeType: string): string {\n const labels: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'New User Task',\n automated: 'New Automated Task',\n decision: 'Decision Point',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return labels[nodeType] || 'New Step'\n}\n\nfunction getDefaultBadge(nodeType: string): string {\n const badges: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'User Task',\n automated: 'Automated',\n decision: 'Decision',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return badges[nodeType] || 'Task'\n}\n\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["'use client'\n\nimport { WorkflowGraph } from '../../../components/WorkflowGraph'\n// Conditional imports based on feature flag\nimport { NodeEditDialog } from '../../../components/NodeEditDialog'\nimport { EdgeEditDialog } from '../../../components/EdgeEditDialog'\nimport { NodeEditDialogCrudForm } from '../../../components/NodeEditDialogCrudForm'\nimport { EdgeEditDialogCrudForm } from '../../../components/EdgeEditDialogCrudForm'\nimport { Node, Edge, addEdge, Connection, applyNodeChanges, applyEdgeChanges, NodeChange, EdgeChange } from '@xyflow/react'\nimport { useState, useCallback, useEffect } from 'react'\nimport { useRouter, useSearchParams } from 'next/navigation'\nimport { graphToDefinition, definitionToGraph, validateWorkflowGraph, generateStepId, generateTransitionId, ValidationError } from '../../../lib/graph-utils'\nimport { performDeleteEdgeFlow, performDeleteNodeFlow } from '../../../lib/visual-editor-delete-flow'\nimport { workflowDefinitionDataSchema } from '../../../data/validators'\nimport { Page } from '@open-mercato/ui/backend/Page'\nimport { Button } from '@open-mercato/ui/primitives/button'\nimport { Input } from '@open-mercato/ui/primitives/input'\nimport { Textarea } from '@open-mercato/ui/primitives/textarea'\nimport { Label } from '@open-mercato/ui/primitives/label'\nimport { Switch } from '@open-mercato/ui/primitives/switch'\nimport {\n Dialog,\n DialogContent,\n DialogDescription,\n DialogFooter,\n DialogHeader,\n DialogTitle,\n} from '@open-mercato/ui/primitives/dialog'\nimport { TagsInput } from '@open-mercato/ui/backend/inputs/TagsInput'\nimport { LoadingMessage } from '@open-mercato/ui/backend/detail'\nimport { Alert, AlertTitle } from '@open-mercato/ui/primitives/alert'\nimport { useConfirmDialog } from '@open-mercato/ui/backend/confirm-dialog'\nimport { useT } from '@open-mercato/shared/lib/i18n/context'\nimport { FormHeader } from '@open-mercato/ui/backend/forms'\nimport { apiCall, withScopedApiRequestHeaders } from '@open-mercato/ui/backend/utils/apiCall'\nimport { buildOptimisticLockHeader } from '@open-mercato/ui/backend/utils/optimisticLock'\nimport { surfaceRecordConflict } from '@open-mercato/ui/backend/conflicts'\nimport { flash } from '@open-mercato/ui/backend/FlashMessages'\nimport { CircleQuestionMark, Info, PanelTopClose, PanelTopOpen, Play, Save, Trash2 } from 'lucide-react'\nimport { NODE_TYPE_ICONS, NODE_TYPE_COLORS, NODE_TYPE_LABELS } from '../../../lib/node-type-icons'\nimport { DefinitionTriggersEditor } from '../../../components/DefinitionTriggersEditor'\nimport { MobileVisualEditor } from '../../../components/mobile/MobileVisualEditor'\nimport { useIsMobile } from '@open-mercato/ui/hooks/useIsMobile'\nimport type { WorkflowDefinitionTrigger } from '../../../data/entities'\nimport type { WorkflowMetadataState, WorkflowMetadataHandlers } from '../../../data/types'\nimport * as React from 'react'\n\n/**\n * VisualEditorPage - Visual workflow definition editor\n *\n * Layout:\n * - Page Header: Title, description, and action buttons (Save, Validate, Test)\n * - Workflow Metadata: Collapsible form for workflow details\n * - Page Body:\n * - Left sidebar: Step palette (click to add)\n * - Main canvas: ReactFlow graph editor\n * - Flash Messages: Top-right positioned validation messages\n * - Edit Dialogs: Modal dialogs for editing steps and transitions\n */\nexport default function VisualEditorPage() {\n const t = useT()\n const router = useRouter()\n const searchParams = useSearchParams()\n const definitionId = searchParams.get('id')\n const isMobile = useIsMobile()\n\n const { confirm, ConfirmDialogElement } = useConfirmDialog()\n\n const [isLoading, setIsLoading] = useState(!!definitionId)\n const [isSaving, setIsSaving] = useState(false)\n const [nodes, setNodes] = useState<Node[]>([])\n const [edges, setEdges] = useState<Edge[]>([])\n const [selectedNode, setSelectedNode] = useState<Node | null>(null)\n const [selectedEdge, setSelectedEdge] = useState<Edge | null>(null)\n const [showMetadata, setShowMetadata] = useState(true)\n const [isCompactViewport, setIsCompactViewport] = useState(false)\n\n // Auto-collapse metadata on compact viewports after hydration\n useEffect(() => {\n if (typeof window === 'undefined') return\n const mediaQuery = window.matchMedia('(max-width: 1279px)')\n const applyViewportMode = () => {\n const compact = mediaQuery.matches\n setIsCompactViewport(compact)\n setShowMetadata(!compact)\n }\n\n applyViewportMode()\n mediaQuery.addEventListener('change', applyViewportMode)\n\n return () => {\n mediaQuery.removeEventListener('change', applyViewportMode)\n }\n }, [])\n const [showNodeDialog, setShowNodeDialog] = useState(false)\n const [showEdgeDialog, setShowEdgeDialog] = useState(false)\n const [showClearConfirm, setShowClearConfirm] = useState(false)\n\n // Workflow metadata state\n const [workflowId, setWorkflowId] = useState('')\n const [workflowName, setWorkflowName] = useState('')\n const [description, setDescription] = useState('')\n const [version, setVersion] = useState(1)\n const [enabled, setEnabled] = useState(true)\n const [category, setCategory] = useState('')\n const [tags, setTags] = useState<string[]>([])\n const [icon, setIcon] = useState('')\n const [effectiveFrom, setEffectiveFrom] = useState('')\n const [effectiveTo, setEffectiveTo] = useState('')\n const [triggers, setTriggers] = useState<WorkflowDefinitionTrigger[]>([])\n const [source, setSource] = useState<'code' | 'code_override' | 'user' | null>(null)\n const [updatedAt, setUpdatedAt] = useState<string | null>(null)\n\n const isCodeOnly = source === 'code'\n const isCodeOverride = source === 'code_override'\n\n // Load existing definition if ID is provided\n useEffect(() => {\n const loadDefinition = async () => {\n if (!definitionId) {\n setIsLoading(false)\n return\n }\n\n try {\n const result = await apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`)\n\n if (!result.ok) {\n flash(`Failed to load workflow: ${result.result?.error || 'Unknown error'}`, 'error')\n setIsLoading(false)\n return\n }\n\n const definition = result.result?.data\n\n // Populate metadata\n setWorkflowId(definition.workflowId)\n setWorkflowName(definition.workflowName || definition.definition.workflowName || '')\n setDescription(definition.description || definition.definition.description || '')\n setVersion(definition.version)\n setEnabled(definition.enabled)\n setCategory(definition.metadata?.category || '')\n setTags(definition.metadata?.tags || [])\n setIcon(definition.metadata?.icon || '')\n setEffectiveFrom(definition.effectiveFrom || '')\n setEffectiveTo(definition.effectiveTo || '')\n\n // Convert definition to graph\n const graph = definitionToGraph(definition.definition)\n setNodes(graph.nodes)\n setEdges(graph.edges)\n\n // Load embedded triggers from definition\n setTriggers(definition.definition?.triggers || [])\n\n // Track source so the editor mirrors the non-visual edit page UX:\n // code \u2192 read-only with Customize button; code_override \u2192 editable\n // with Reset to code; user \u2192 editable, no banner.\n setSource((definition.source as 'code' | 'code_override' | 'user') ?? null)\n setUpdatedAt(typeof definition.updatedAt === 'string' ? definition.updatedAt : null)\n } catch (error) {\n console.error('Error loading workflow definition:', error)\n flash('Failed to load workflow definition', 'error')\n } finally {\n setIsLoading(false)\n }\n }\n\n loadDefinition()\n }, [definitionId])\n\n // Handle node changes from ReactFlow\n const handleNodesChange = useCallback((changes: NodeChange[]) => {\n if (isCodeOnly) return\n setNodes((nds) => applyNodeChanges(changes, nds))\n }, [isCodeOnly])\n\n // Handle edge changes from ReactFlow\n const handleEdgesChange = useCallback((changes: EdgeChange[]) => {\n if (isCodeOnly) return\n setEdges((eds) => applyEdgeChanges(changes, eds))\n }, [isCodeOnly])\n\n // Handle adding new node from palette\n const handleAddNode = useCallback((nodeType: string) => {\n if (isCodeOnly) return\n const newNode: Node = {\n id: generateStepId(nodeType),\n type: nodeType,\n position: {\n x: 250 + nodes.length * 50,\n y: 100 + nodes.length * 150,\n },\n data: {\n label: getDefaultLabel(nodeType),\n description: '',\n badge: getDefaultBadge(nodeType),\n status: 'pending',\n },\n }\n\n setNodes((nds) => [...nds, newNode])\n }, [nodes.length, isCodeOnly])\n\n // Handle node selection - open edit dialog (suppressed in read-only mode\n // so users can't open the node editor on a code-defined workflow).\n const handleNodeClick = useCallback((_event: React.MouseEvent, node: Node) => {\n if (isCodeOnly) return\n setSelectedNode(node)\n setSelectedEdge(null)\n setShowNodeDialog(true)\n }, [isCodeOnly])\n\n // Handle edge selection - open edit dialog\n const handleEdgeClick = useCallback((_event: React.MouseEvent, edge: Edge) => {\n if (isCodeOnly) return\n setSelectedEdge(edge)\n setSelectedNode(null)\n setShowEdgeDialog(true)\n }, [isCodeOnly])\n\n // Save node updates\n const handleSaveNode = useCallback((nodeId: string, updates: Partial<Node['data']>) => {\n setNodes((nds) =>\n nds.map((node) =>\n node.id === nodeId\n ? { ...node, data: { ...node.data, ...updates } }\n : node\n )\n )\n flash('Node updated successfully', 'success')\n }, [])\n\n // Save edge updates\n const handleSaveEdge = useCallback((edgeId: string, updates: Partial<Edge['data']>) => {\n setEdges((eds) =>\n eds.map((edge) =>\n edge.id === edgeId\n ? { ...edge, data: { ...edge.data, ...updates } }\n : edge\n )\n )\n flash('Transition updated successfully', 'success')\n }, [])\n\n // Delete edge\n const handleDeleteEdge = useCallback(async (edgeId: string) => {\n await performDeleteEdgeFlow(edgeId, {\n confirm,\n t,\n setShowEdgeDialog,\n setSelectedEdge,\n setEdges,\n notifyDeleted: () => flash('Transition deleted successfully', 'success'),\n })\n }, [confirm, t])\n\n // Delete node\n const handleDeleteNode = useCallback(async (nodeId: string) => {\n await performDeleteNodeFlow(nodeId, {\n nodes,\n confirm,\n t,\n setShowNodeDialog,\n setSelectedNode,\n setNodes,\n setEdges,\n notifyDeleted: () => flash('Step deleted successfully', 'success'),\n })\n }, [confirm, nodes, t])\n\n // Handle new connections\n const handleConnect = useCallback((connection: Connection) => {\n const newEdge: Edge = {\n id: generateTransitionId(connection.source!, connection.target!),\n source: connection.source!,\n target: connection.target!,\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n label: '',\n },\n }\n\n setEdges((eds) => addEdge(newEdge, eds))\n }, [])\n\n // Validate workflow\n const handleValidate = useCallback(() => {\n const graphErrors = validateWorkflowGraph(nodes, edges)\n const allErrors: ValidationError[] = [...graphErrors]\n\n // Run Zod schema validation\n try {\n const definitionData = graphToDefinition(nodes, edges, { includePositions: true })\n const result = workflowDefinitionDataSchema.safeParse(definitionData)\n\n if (!result.success) {\n // Convert Zod errors to validation errors\n result.error.issues.forEach((issue) => {\n allErrors.push({\n type: 'error',\n message: `Schema validation: ${issue.path.join('.')} - ${issue.message}`,\n })\n })\n }\n } catch (error) {\n allErrors.push({\n type: 'error',\n message: `Schema validation failed: ${error instanceof Error ? error.message : 'Unknown error'}`,\n })\n }\n\n if (allErrors.length === 0) {\n flash('Validation passed! Your workflow is valid and ready to save.', 'success')\n } else {\n // Show first error/warning message\n const firstError = allErrors[0]\n const errorCount = allErrors.length\n const message = errorCount > 1\n ? `${firstError.message} (and ${errorCount - 1} more ${errorCount === 2 ? 'issue' : 'issues'})`\n : firstError.message\n flash(message, firstError.type === 'error' ? 'error' : 'warning')\n }\n }, [nodes, edges])\n\n // Save workflow definition\n const handleSave = useCallback(async () => {\n // Validate required fields\n if (!workflowId || !workflowName) {\n flash('Workflow ID and Name are required fields', 'error')\n return\n }\n\n // Validate workflow structure\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter(e => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot save: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // Generate definition data and include triggers\n const graphDefinition = graphToDefinition(nodes, edges, { includePositions: true })\n const definitionData = {\n ...graphDefinition,\n triggers: triggers.length > 0 ? triggers : undefined,\n }\n\n // Run Zod schema validation before saving\n const schemaResult = workflowDefinitionDataSchema.safeParse(definitionData)\n if (!schemaResult.success) {\n const firstIssue = schemaResult.error.issues[0]\n flash(`Schema error: ${firstIssue.path.join('.')} - ${firstIssue.message}`, 'error')\n return\n }\n\n setIsSaving(true)\n\n try {\n\n const metadata: any = {}\n if (category) metadata.category = category\n if (tags.length > 0) metadata.tags = tags\n if (icon) metadata.icon = icon\n\n // Determine if creating new or updating existing\n const isUpdate = !!definitionId\n\n let result\n if (isUpdate) {\n // Update existing definition \u2014 send the full editable payload so metadata\n // edits (name, description, version, category, tags, icon, effective\n // dates) actually persist. Previously only `definition` + `enabled`\n // were sent, silently dropping every other field.\n result = await withScopedApiRequestHeaders(\n buildOptimisticLockHeader(updatedAt),\n () => apiCall<{ data: any; error?: string }>(`/api/workflows/definitions/${definitionId}`, {\n method: 'PUT',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n }),\n )\n } else {\n // Create new definition\n result = await apiCall<{ data: any; error?: string }>('/api/workflows/definitions', {\n method: 'POST',\n headers: { 'Content-Type': 'application/json' },\n body: JSON.stringify({\n workflowId,\n workflowName,\n description: description || null,\n version,\n definition: definitionData,\n metadata: Object.keys(metadata).length > 0 ? metadata : null,\n enabled,\n effectiveFrom: effectiveFrom || null,\n effectiveTo: effectiveTo || null,\n }),\n })\n }\n\n if (!result.ok) {\n const conflictError = Object.assign(new Error(t('workflows.messages.saveFailed', 'Failed to save')), {\n status: result.status,\n ...(result.result && typeof result.result === 'object' ? result.result : {}),\n })\n if (!surfaceRecordConflict(conflictError, t)) {\n flash(`Failed to save: ${result.result?.error || 'Unknown error'}`, 'error')\n }\n return\n }\n\n const savedDefinition = result.result?.data\n\n flash(`Workflow ${isUpdate ? 'updated' : 'created'} successfully!`, 'success')\n\n // Redirect to definition detail page after short delay\n setTimeout(() => {\n router.push(`/backend/definitions/${savedDefinition.id}`)\n }, 1500)\n\n } catch (error) {\n console.error('Error saving workflow definition:', error)\n flash('Failed to save workflow definition. Please try again.', 'error')\n } finally {\n setIsSaving(false)\n }\n }, [nodes, edges, workflowId, workflowName, description, version, enabled, category, tags, icon, effectiveFrom, effectiveTo, triggers, definitionId, updatedAt, router])\n\n // Customize a code-defined workflow \u2192 creates an override and reloads the\n // editor pointed at the new UUID. Mirrors the non-visual edit page button.\n const handleCustomize = useCallback(async () => {\n if (!definitionId) return\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/customize`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to customize workflow', 'error')\n return\n }\n const newId = result.result?.data?.id\n if (!newId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(newId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, router])\n\n // Reset a code-override back to its code definition. Mirrors the\n // non-visual edit page action, with the same confirm dialog.\n const handleResetToCode = useCallback(async () => {\n if (!definitionId) return\n const confirmed = await confirm({\n title: t('workflows.actions.resetToCode'),\n description: t('workflows.actions.resetConfirm'),\n confirmText: t('workflows.actions.resetToCode'),\n variant: 'destructive',\n })\n if (!confirmed) return\n\n setIsSaving(true)\n try {\n const result = await apiCall<{ data?: { id?: string }; error?: string }>(\n `/api/workflows/definitions/${definitionId}/reset-to-code`,\n { method: 'POST' },\n )\n if (!result.ok) {\n flash(result.result?.error || 'Failed to reset workflow', 'error')\n return\n }\n const codeId = result.result?.data?.id || (workflowId ? `code:${workflowId}` : null)\n if (!codeId) return\n router.push(`/backend/definitions/visual-editor?id=${encodeURIComponent(codeId)}`)\n router.refresh()\n } finally {\n setIsSaving(false)\n }\n }, [definitionId, workflowId, router, confirm, t])\n\n // Test workflow\n const handleTest = useCallback(() => {\n // First validate\n const errors = validateWorkflowGraph(nodes, edges)\n const criticalErrors = errors.filter((e) => e.type === 'error')\n if (criticalErrors.length > 0) {\n flash(`Cannot test: ${criticalErrors.length} validation error(s) found. Please fix them first.`, 'error')\n return\n }\n\n // TODO: Implement test logic (create instance, run first step)\n flash('Test functionality will be implemented next', 'info')\n }, [nodes, edges])\n\n // Load example workflow\n const handleLoadExample = useCallback(() => {\n // Set example metadata\n setWorkflowId('approval_workflow')\n setWorkflowName('Simple Approval Workflow')\n setDescription('A basic approval workflow for reviewing and approving requests')\n setVersion(1)\n setEnabled(true)\n setCategory('Approvals')\n setTags(['approval', 'review'])\n\n const exampleNodes: Node[] = [\n {\n id: 'start',\n type: 'start',\n position: { x: 250, y: 50 },\n data: {\n label: 'Start',\n description: 'Workflow begins',\n status: 'pending',\n badge: 'Start',\n },\n },\n {\n id: 'step1',\n type: 'userTask',\n position: { x: 250, y: 250 },\n data: {\n label: 'Review Request',\n description: 'User reviews the incoming request',\n status: 'pending',\n stepNumber: 1,\n badge: 'User Task',\n assignedToRoles: ['Reviewer'],\n },\n },\n {\n id: 'end',\n type: 'end',\n position: { x: 250, y: 450 },\n data: {\n label: 'Complete',\n description: 'Workflow ends',\n status: 'pending',\n badge: 'End',\n },\n },\n ]\n\n const exampleEdges: Edge[] = [\n {\n id: 'e-start-step1',\n source: 'start',\n target: 'step1',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n {\n id: 'e-step1-end',\n source: 'step1',\n target: 'end',\n type: 'smoothstep',\n data: {\n trigger: 'auto',\n preConditions: [],\n postConditions: [],\n activities: [],\n },\n },\n ]\n\n setNodes(exampleNodes)\n setEdges(exampleEdges)\n flash('Example workflow loaded', 'success')\n }, [])\n\n // Clear canvas\n const handleClear = useCallback(() => {\n if (nodes.length > 0 || edges.length > 0 || workflowId || workflowName) {\n setShowClearConfirm(true)\n }\n }, [nodes.length, edges.length, workflowId, workflowName])\n\n // Confirm clear action\n const confirmClear = useCallback(() => {\n setNodes([])\n setEdges([])\n setWorkflowId('')\n setWorkflowName('')\n setDescription('')\n setVersion(1)\n setEnabled(true)\n setCategory('')\n setTags([])\n setIcon('')\n setEffectiveFrom('')\n setEffectiveTo('')\n setTriggers([])\n setShowClearConfirm(false)\n flash('Canvas cleared', 'success')\n }, [])\n\n // Show loading spinner while loading definition\n if (isLoading) {\n return (\n <Page className=\"flex items-center justify-center min-h-[50vh]\">\n <LoadingMessage label=\"Loading workflow definition...\" />\n </Page>\n )\n }\n\n const metadata: WorkflowMetadataState = {\n workflowId, workflowName, description, version,\n enabled, category, tags, icon,\n effectiveFrom, effectiveTo, triggers,\n }\n\n const metadataHandlers: WorkflowMetadataHandlers = {\n setWorkflowId, setWorkflowName, setDescription, setVersion,\n setEnabled, setCategory, setTags, setIcon,\n setEffectiveFrom, setEffectiveTo, setTriggers,\n }\n\n const sharedDialogs = (\n <>\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <NodeEditDialogCrudForm node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n ) : (\n <NodeEditDialog node={selectedNode} isOpen={showNodeDialog} onClose={() => setShowNodeDialog(false)} onSave={handleSaveNode} onDelete={handleDeleteNode} />\n )}\n {process.env.NEXT_PUBLIC_WORKFLOW_CRUDFORM_ENABLED === 'true' ? (\n <EdgeEditDialogCrudForm edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n ) : (\n <EdgeEditDialog edge={selectedEdge} isOpen={showEdgeDialog} onClose={() => setShowEdgeDialog(false)} onSave={handleSaveEdge} onDelete={handleDeleteEdge} />\n )}\n <Dialog open={showClearConfirm} onOpenChange={setShowClearConfirm}>\n <DialogContent className=\"sm:max-w-md\">\n <DialogHeader>\n <DialogTitle>{t('workflows.visualEditor.clearTitle')}</DialogTitle>\n <DialogDescription>{t('workflows.visualEditor.clearDescription')}</DialogDescription>\n </DialogHeader>\n <DialogFooter>\n <Button variant=\"outline\" onClick={() => setShowClearConfirm(false)}>{t('common.cancel', 'Cancel')}</Button>\n <Button variant=\"destructive\" onClick={confirmClear}>{t('common.clear', 'Clear')}</Button>\n </DialogFooter>\n </DialogContent>\n </Dialog>\n </>\n )\n\n if (isMobile) {\n return (\n <Page className=\"flex h-[100svh] flex-col space-y-0 overflow-hidden\">\n <MobileVisualEditor\n definitionId={definitionId}\n isSaving={isSaving}\n nodes={nodes}\n edges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n onAddNode={handleAddNode}\n onSave={handleSave}\n onValidate={handleValidate}\n onTest={handleTest}\n onLoadExample={handleLoadExample}\n onClear={handleClear}\n metadata={metadata}\n metadataHandlers={metadataHandlers}\n />\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n }\n\n return (\n <Page className=\"space-y-0 overflow-x-hidden\">\n {/* Page Header */}\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n <FormHeader\n mode=\"detail\"\n backHref=\"/backend/definitions\"\n backLabel={t('workflows.definitions.backToList', 'Back to definitions')}\n title={definitionId ? (workflowName || t('workflows.definitions.singular')) : t('workflows.backend.definitions.visual_editor.title')}\n subtitle={definitionId\n ? t('workflows.definitions.detail.summary', 'Editing workflow definition')\n : t('workflows.definitions.create.summary', 'Create and edit workflow definitions visually with a drag-and-drop interface')\n }\n actionsContent={\n <div className=\"flex flex-wrap items-center justify-end gap-1 md:gap-2\">\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={() => setShowMetadata(!showMetadata)}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n >\n {showMetadata ? <PanelTopClose className=\"mr-1.5 h-4 w-4\" /> : <PanelTopOpen className=\"mr-1.5 h-4 w-4\" />}\n {showMetadata ? t('workflows.visualEditor.hideMetadata') : t('workflows.visualEditor.showMetadata')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleLoadExample}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.visualEditor.loadExample')}\n </Button>\n )}\n {!isCodeOnly && (\n <Button\n variant=\"destructive\"\n size=\"sm\"\n onClick={handleClear}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.clear')}\n >\n <Trash2 className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.clear')}\n </Button>\n )}\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleValidate}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs\"\n aria-label={t('workflows.visualEditor.validate')}\n >\n <CircleQuestionMark className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.validate')}\n </Button>\n {!isCodeOnly && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleTest}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n <Play className=\"mr-1.5 h-4 w-4\" />\n {t('workflows.visualEditor.runTest')}\n </Button>\n )}\n {isCodeOverride && (\n <Button\n variant=\"outline\"\n size=\"sm\"\n onClick={handleResetToCode}\n disabled={isSaving}\n className=\"h-8 text-xs\"\n >\n {t('workflows.actions.resetToCode')}\n </Button>\n )}\n {isCodeOnly ? (\n <Button\n size=\"sm\"\n onClick={handleCustomize}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n >\n {t('workflows.actions.customize')}\n </Button>\n ) : (\n <Button\n size=\"sm\"\n onClick={handleSave}\n disabled={isSaving}\n className=\"h-8 px-2 text-xs md:px-3\"\n aria-label={isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n >\n <Save className=\"mr-1.5 h-4 w-4\" />\n {isSaving ? t('workflows.mobile.saving') : definitionId ? t('workflows.common.update') : t('workflows.common.save')}\n </Button>\n )}\n </div>\n }\n />\n </div>\n\n {/* Source banner (code-defined / customized) */}\n {(isCodeOnly || isCodeOverride) && (\n <div className=\"shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3\">\n {isCodeOnly && (\n <Alert variant=\"info\">\n <AlertTitle>{t('workflows.source.code.readonlyBanner')}</AlertTitle>\n </Alert>\n )}\n {isCodeOverride && (\n <Alert variant=\"warning\">\n <AlertTitle>{t('workflows.source.code_override.banner')}</AlertTitle>\n </Alert>\n )}\n </div>\n )}\n\n {/* Workflow Metadata Form */}\n {showMetadata && (\n <div className={isCompactViewport\n ? 'shrink-0 border-b border-border bg-background px-3 py-2 max-h-[60svh] overflow-y-auto overscroll-contain md:px-6 md:py-3'\n : 'shrink-0 border-b border-border bg-background px-3 py-2 md:px-6 md:py-3'\n }>\n <fieldset disabled={isCodeOnly} className=\"rounded-lg border bg-card p-3 disabled:opacity-70 md:p-4\">\n <h2 className=\"mb-3 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.workflowMetadata')}</h2>\n <div className=\"grid grid-cols-1 gap-3 sm:grid-cols-2 lg:grid-cols-3 md:gap-4\">\n {/* Workflow ID */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowId\" className=\"text-xs\">{t('workflows.form.workflowId')} *</Label>\n <Input\n id=\"workflowId\"\n value={workflowId}\n onChange={(e) => setWorkflowId(e.target.value)}\n placeholder=\"checkout_workflow\"\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n {definitionId && <p className=\"text-overline text-muted-foreground\">{t('workflows.visualEditor.readOnly')}</p>}\n </div>\n\n {/* Workflow Name */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"workflowName\" className=\"text-xs\">{t('workflows.form.workflowName')} *</Label>\n <Input\n id=\"workflowName\"\n value={workflowName}\n onChange={(e) => setWorkflowName(e.target.value)}\n placeholder=\"Checkout Process\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Category */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"category\" className=\"text-xs\">{t('workflows.form.category')}</Label>\n <Input\n id=\"category\"\n value={category}\n onChange={(e) => setCategory(e.target.value)}\n placeholder=\"E-Commerce\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Description */}\n <div className=\"min-w-0 space-y-1 sm:col-span-2 lg:col-span-3\">\n <Label htmlFor=\"description\" className=\"text-xs\">{t('workflows.form.description')}</Label>\n <Textarea\n id=\"description\"\n value={description}\n onChange={(e) => setDescription(e.target.value)}\n placeholder={t('workflows.form.placeholders.description')}\n rows={2}\n className=\"min-h-[60px] text-sm\"\n />\n </div>\n\n {/* Version */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"version\" className=\"text-xs\">{t('workflows.form.version')} *</Label>\n <Input\n id=\"version\"\n type=\"number\"\n value={version}\n onChange={(e) => setVersion(parseInt(e.target.value) || 1)}\n min={1}\n disabled={!!definitionId}\n className=\"h-8 text-sm\"\n />\n </div>\n\n {/* Enabled */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('common.enabled', 'Enabled')}</Label>\n <div className=\"flex h-8 items-center gap-2\">\n <Switch\n id=\"enabled\"\n checked={enabled}\n onCheckedChange={setEnabled}\n />\n <Label htmlFor=\"enabled\" className=\"cursor-pointer text-xs font-normal\">\n {enabled ? t('common.on', 'On') : t('common.off', 'Off')}\n </Label>\n </div>\n </div>\n\n {/* Tags */}\n <div className=\"min-w-0 space-y-1\">\n <Label className=\"text-xs\">{t('workflows.form.tags')}</Label>\n <TagsInput\n value={tags}\n onChange={setTags}\n placeholder={t('workflows.form.placeholders.tags')}\n />\n </div>\n\n {/* Icon */}\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"icon\" className=\"text-xs\">{t('workflows.form.icon')}</Label>\n <Input\n id=\"icon\"\n value={icon}\n onChange={(e) => setIcon(e.target.value)}\n placeholder=\"ShoppingCart\"\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveFrom\" className=\"text-xs\">{t('workflows.form.effectiveFrom')}</Label>\n <Input\n id=\"effectiveFrom\"\n type=\"date\"\n value={effectiveFrom}\n onChange={(e) => setEffectiveFrom(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n\n <div className=\"min-w-0 space-y-1\">\n <Label htmlFor=\"effectiveTo\" className=\"text-xs\">{t('workflows.form.effectiveTo')}</Label>\n <Input\n id=\"effectiveTo\"\n type=\"date\"\n value={effectiveTo}\n onChange={(e) => setEffectiveTo(e.target.value)}\n className=\"h-8 text-sm\"\n />\n </div>\n </div>\n </fieldset>\n\n {/* Event Triggers \u2014 also locked when the workflow is code-defined */}\n <fieldset disabled={isCodeOnly} className=\"mt-3 disabled:opacity-70\">\n <DefinitionTriggersEditor\n value={triggers}\n onChange={setTriggers}\n />\n </fieldset>\n </div>\n )}\n\n {/* Main Content */}\n {isCompactViewport ? (\n <div className=\"px-3 py-3 md:px-6 md:py-4\">\n <div className=\"relative min-w-0\">\n <div className=\"h-[64svh] min-h-[360px] rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-lg font-semibold text-foreground\">{t('workflows.visualEditor.startBuilding')}</h2>\n <p className=\"mb-4 text-sm text-muted-foreground\">{t('workflows.visualEditor.tapToAddBelow')}</p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n\n {!isCodeOnly && (\n <div className=\"mt-3 rounded-lg border bg-card p-3\">\n <h2 className=\"mb-2 text-xs font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-3 text-xs text-muted-foreground\">{t('workflows.visualEditor.tapToAdd')}</p>\n\n <div className=\"flex gap-2 overflow-x-auto pb-1\">\n {(['start', 'userTask', 'automated', 'waitForSignal', 'waitForTimer', 'subWorkflow', 'end'] as const).map((nodeType) => {\n const Icon = NODE_TYPE_ICONS[nodeType]\n return (\n <button\n key={nodeType}\n onClick={() => handleAddNode(nodeType)}\n className=\"flex shrink-0 items-center gap-1 rounded-md border bg-background px-2 py-1 text-xs hover:bg-muted active:bg-muted/50\"\n >\n <Icon className=\"h-3.5 w-3.5\" />\n <span>{NODE_TYPE_LABELS[nodeType].title}</span>\n </button>\n )\n })}\n </div>\n </div>\n )}\n </div>\n ) : (\n <div className=\"flex min-h-[72svh] min-w-0 flex-1 border-t border-border\">\n {/* Left Sidebar - Step Palette (hidden in read-only mode) */}\n {!isCodeOnly && (\n <div className=\"w-[24rem] shrink-0 overflow-y-auto border-r border-border bg-background p-6\">\n <div className=\"rounded-lg border bg-card p-4\">\n <h2 className=\"mb-2 text-sm font-semibold uppercase text-muted-foreground\">{t('workflows.visualEditor.stepPalette')}</h2>\n <p className=\"mb-4 text-xs text-muted-foreground\">\n {t('workflows.visualEditor.clickToAdd')}\n </p>\n\n <div className=\"space-y-3\">\n {/* START Step */}\n <button\n onClick={() => handleAddNode('start')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.start} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.start\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.start.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.start.description}</div>\n </button>\n\n {/* USER_TASK Step */}\n <button\n onClick={() => handleAddNode('userTask')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.userTask} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.userTask\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.userTask.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.userTask.description}</div>\n </button>\n\n {/* AUTOMATED Step */}\n <button\n onClick={() => handleAddNode('automated')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.automated} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.automated\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.automated.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.automated.description}</div>\n </button>\n\n {/* WAIT_FOR_SIGNAL Step */}\n <button\n onClick={() => handleAddNode('waitForSignal')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForSignal} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForSignal\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForSignal.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForSignal.description}</div>\n </button>\n\n {/* WAIT_FOR_TIMER Step */}\n <button\n onClick={() => handleAddNode('waitForTimer')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.waitForTimer} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.waitForTimer\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.waitForTimer.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.waitForTimer.description}</div>\n </button>\n\n {/* SUB_WORKFLOW Step */}\n <button\n onClick={() => handleAddNode('subWorkflow')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.subWorkflow} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.subWorkflow\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.subWorkflow.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.subWorkflow.description}</div>\n </button>\n\n {/* END Step */}\n <button\n onClick={() => handleAddNode('end')}\n className=\"group relative w-full cursor-pointer rounded-xl border-2 border-border bg-background px-4 py-3 text-left transition-all hover:border-muted-foreground/30 hover:shadow-md\"\n >\n <div className={`absolute right-2 top-2 ${NODE_TYPE_COLORS.end} opacity-60 transition-opacity group-hover:opacity-100`}>\n {(() => {\n const Icon = NODE_TYPE_ICONS.end\n return <Icon className=\"h-4 w-4\" />\n })()}\n </div>\n <div className=\"text-sm font-semibold text-foreground\">{NODE_TYPE_LABELS.end.title}</div>\n <div className=\"mt-0.5 text-xs text-muted-foreground\">{NODE_TYPE_LABELS.end.description}</div>\n </button>\n </div>\n\n {/* Instructions */}\n <Alert variant=\"info\" className=\"mt-6\">\n <Info className=\"size-4\" />\n <AlertTitle className=\"text-xs\">{t('workflows.visualEditor.howToUse', 'How to use:')}</AlertTitle>\n <div className=\"mt-2\">\n <ul className=\"list-inside list-disc space-y-1 text-xs\">\n <li>{t('workflows.visualEditor.hint.addSteps', 'Click step types to add them')}</li>\n <li>{t('workflows.visualEditor.hint.dragSteps', 'Drag steps to position them')}</li>\n <li>{t('workflows.visualEditor.hint.connectSteps', 'Connect steps by dragging from handles')}</li>\n <li>{t('workflows.visualEditor.hint.editSteps', 'Click steps and transitions to edit them')}</li>\n <li>{t('workflows.visualEditor.hint.validate', 'Validate before saving')}</li>\n </ul>\n </div>\n </Alert>\n </div>\n </div>\n )}\n\n {/* Main Canvas */}\n <div className=\"min-w-0 flex-1 p-6\">\n <div className=\"relative h-[72svh] min-h-[640px]\">\n <div className=\"h-full rounded-lg border bg-card\">\n <WorkflowGraph\n initialNodes={nodes}\n initialEdges={edges}\n onNodesChange={handleNodesChange}\n onEdgesChange={handleEdgesChange}\n onNodeClick={handleNodeClick}\n onEdgeClick={handleEdgeClick}\n onConnect={handleConnect}\n editable={!isCodeOnly}\n height=\"100%\"\n />\n </div>\n\n {/* Empty State */}\n {nodes.length === 0 && (\n <div className=\"pointer-events-none absolute inset-0 flex items-center justify-center px-4\">\n <div className=\"text-center\">\n <h2 className=\"mb-2 text-xl font-semibold text-foreground\">\n {t('workflows.visualEditor.startBuilding')}\n </h2>\n <p className=\"mb-4 text-muted-foreground\">\n {t('workflows.visualEditor.clickToAddFromPalette')}\n </p>\n <button\n onClick={handleLoadExample}\n className=\"pointer-events-auto text-sm text-primary hover:underline\"\n >\n {t('workflows.visualEditor.loadExampleWorkflow')}\n </button>\n </div>\n </div>\n )}\n </div>\n </div>\n </div>\n )}\n {sharedDialogs}\n {ConfirmDialogElement}\n </Page>\n )\n}\n\n// Helper functions\nfunction getDefaultLabel(nodeType: string): string {\n const labels: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'New User Task',\n automated: 'New Automated Task',\n decision: 'Decision Point',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return labels[nodeType] || 'New Step'\n}\n\nfunction getDefaultBadge(nodeType: string): string {\n const badges: Record<string, string> = {\n start: 'Start',\n end: 'End',\n userTask: 'User Task',\n automated: 'Automated',\n decision: 'Decision',\n waitForSignal: 'Wait for Signal',\n waitForTimer: 'Wait for Timer',\n }\n return badges[nodeType] || 'Task'\n}\n\n"],
5
+ "mappings": "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",
6
6
  "names": ["metadata"]
7
7
  }
@@ -167,6 +167,7 @@ function createFormGroups(t, StepsEditorComponent, TransitionsEditorComponent) {
167
167
  }
168
168
  import { toDateInputValue } from "@open-mercato/shared/lib/date/format";
169
169
  function parseWorkflowToFormValues(workflow) {
170
+ const updatedAt = workflow.updatedAt ?? workflow.updated_at ?? null;
170
171
  const metadata = workflow.metadata || {};
171
172
  return {
172
173
  workflowId: workflow.workflowId || "",
@@ -182,7 +183,9 @@ function parseWorkflowToFormValues(workflow) {
182
183
  "metadata.icon": metadata.icon || "",
183
184
  steps: workflow.definition?.steps || [],
184
185
  transitions: workflow.definition?.transitions || [],
185
- triggers: workflow.definition?.triggers || []
186
+ triggers: workflow.definition?.triggers || [],
187
+ id: workflow.id,
188
+ updatedAt: typeof updatedAt === "string" ? updatedAt : updatedAt ? String(updatedAt) : null
186
189
  };
187
190
  }
188
191
  function buildWorkflowPayload(values) {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../../src/modules/workflows/components/formConfig.tsx"],
4
- "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport type { CrudField, CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport type { WorkflowDefinitionTrigger } from '../data/entities'\n\n/**\n * Form Values Type\n * Represents the structure of form data for creating/editing workflow definitions\n */\nexport type WorkflowDefinitionFormValues = {\n workflowId: string\n workflowName: string\n description?: string | null\n version: number\n enabled: boolean\n effectiveFrom?: string | null\n effectiveTo?: string | null\n // Metadata fields are declared on the form with dot-path ids\n // (`metadata.category`, `metadata.tags`, `metadata.icon`). CrudForm only\n // collapses dot-paths for injected/custom fields, so declared base fields are\n // carried as flat keys end-to-end; buildWorkflowPayload reassembles them into\n // the nested metadata object the API expects. See issue #2503.\n 'metadata.category'?: string\n 'metadata.tags'?: string[]\n 'metadata.icon'?: string\n steps: any[]\n transitions: any[]\n triggers: WorkflowDefinitionTrigger[]\n}\n\n/**\n * Form Validation Schema\n * Extends the API schema with additional client-side validation\n */\nexport const workflowDefinitionFormSchema = z.object({\n workflowId: z.string()\n .min(1, 'Workflow ID is required')\n .max(100, 'Workflow ID must be 100 characters or less')\n .regex(/^[a-z0-9_.-]+$/, 'Workflow ID must contain only lowercase letters, numbers, hyphens, underscores, and dots'),\n workflowName: z.string()\n .min(1, 'Workflow name is required')\n .max(200, 'Workflow name must be 200 characters or less'),\n description: z.string()\n .max(5000, 'Description must be 5000 characters or less')\n .optional()\n .nullable(),\n version: z.number().int().min(1),\n enabled: z.boolean(),\n effectiveFrom: z.string().optional().nullable(),\n effectiveTo: z.string().optional().nullable(),\n // Flat dot-path keys mirror the field ids so CrudForm's non-strict\n // schema.safeParse keeps them instead of stripping them before onSubmit.\n 'metadata.category': z.string().max(50).optional(),\n 'metadata.tags': z.array(z.string()).optional(),\n 'metadata.icon': z.string().max(50).optional(),\n steps: z.array(z.any()),\n transitions: z.array(z.any()),\n triggers: z.array(z.any()).default([]),\n})\n\n/**\n * Default Form Values\n */\nexport const defaultFormValues: WorkflowDefinitionFormValues = {\n workflowId: '',\n workflowName: '',\n description: null,\n version: 1,\n enabled: true,\n effectiveFrom: null,\n effectiveTo: null,\n 'metadata.category': '',\n 'metadata.tags': [],\n 'metadata.icon': '',\n steps: [],\n transitions: [],\n triggers: [],\n}\n\n/**\n * Create Field Definitions\n * Returns field configurations for the CrudForm\n */\nexport function createFieldDefinitions(t: (key: string) => string): CrudField[] {\n return [\n {\n id: 'workflowId',\n label: t('workflows.form.workflowId'),\n type: 'text',\n required: true,\n placeholder: t('workflows.form.placeholders.workflowId'),\n description: t('workflows.form.descriptions.workflowId'),\n },\n {\n id: 'workflowName',\n label: t('workflows.form.workflowName'),\n type: 'text',\n required: true,\n placeholder: t('workflows.form.placeholders.workflowName'),\n },\n {\n id: 'description',\n label: t('workflows.form.description'),\n type: 'textarea',\n placeholder: t('workflows.form.placeholders.description'),\n },\n {\n id: 'version',\n label: t('workflows.form.version'),\n type: 'number',\n required: true,\n description: t('workflows.form.descriptions.version'),\n },\n {\n id: 'enabled',\n label: t('workflows.form.enabled'),\n type: 'checkbox',\n description: t('workflows.form.descriptions.enabled'),\n },\n {\n id: 'effectiveFrom',\n label: t('workflows.form.effectiveFrom'),\n type: 'date',\n description: t('workflows.form.descriptions.effectiveFrom'),\n },\n {\n id: 'effectiveTo',\n label: t('workflows.form.effectiveTo'),\n type: 'date',\n description: t('workflows.form.descriptions.effectiveTo'),\n },\n {\n id: 'metadata.category',\n label: t('workflows.form.category'),\n type: 'text',\n placeholder: t('workflows.form.placeholders.category'),\n },\n {\n id: 'metadata.tags',\n label: t('workflows.form.tags'),\n type: 'tags',\n placeholder: t('workflows.form.placeholders.tags'),\n description: t('workflows.form.descriptions.tags'),\n },\n {\n id: 'metadata.icon',\n label: t('workflows.form.icon'),\n type: 'text',\n placeholder: t('workflows.form.placeholders.icon'),\n description: t('workflows.form.descriptions.icon'),\n },\n ]\n}\n\n/**\n * Create Form Groups\n * Returns grouped layout configuration for the CrudForm\n */\nexport function createFormGroups(\n t: (key: string) => string,\n StepsEditorComponent: React.ComponentType<any>,\n TransitionsEditorComponent: React.ComponentType<any>\n): CrudFormGroup[] {\n // Wrapper components to adapt CrudForm props\n const StepsEditorWrapper = (props: { value: any; setValue: (v: any) => void; error?: string; values?: any }) => {\n return <StepsEditorComponent value={props.value} onChange={props.setValue} error={props.error} />\n }\n\n const TransitionsEditorWrapper = (props: { value: any; setValue: (v: any) => void; error?: string; values?: any }) => {\n // Pass the steps from values (all form values) so transitions can reference them\n return <TransitionsEditorComponent value={props.value} onChange={props.setValue} steps={props.values?.steps || []} error={props.error} />\n }\n\n return [\n {\n id: 'basic',\n title: t('workflows.form.groups.basic'),\n column: 1,\n fields: [\n 'workflowId',\n 'workflowName',\n 'description',\n 'version',\n 'enabled',\n ],\n },\n {\n id: 'metadata',\n title: t('workflows.form.groups.metadata'),\n column: 1,\n fields: [\n 'metadata.category',\n 'metadata.tags',\n 'metadata.icon',\n 'effectiveFrom',\n 'effectiveTo',\n ],\n },\n {\n id: 'steps',\n title: t('workflows.form.groups.steps'),\n column: 1,\n fields: [\n {\n id: 'steps',\n label: t('workflows.form.stepsLabel'),\n type: 'custom',\n required: true,\n component: StepsEditorWrapper,\n },\n ],\n },\n {\n id: 'transitions',\n title: t('workflows.form.groups.transitions'),\n column: 1,\n fields: [\n {\n id: 'transitions',\n label: t('workflows.form.transitionsLabel'),\n type: 'custom',\n required: true,\n component: TransitionsEditorWrapper,\n },\n ],\n },\n ]\n}\n\nimport { toDateInputValue } from '@open-mercato/shared/lib/date/format'\n\n/**\n * Parse workflow definition to form values\n */\nexport function parseWorkflowToFormValues(workflow: any): WorkflowDefinitionFormValues {\n const metadata = workflow.metadata || {}\n return {\n workflowId: workflow.workflowId || '',\n workflowName: workflow.workflowName || '',\n description: workflow.description || null,\n version: workflow.version || 1,\n enabled: workflow.enabled ?? true,\n effectiveFrom: toDateInputValue(workflow.effectiveFrom),\n effectiveTo: toDateInputValue(workflow.effectiveTo),\n // Hydrate the flat dot-path keys the CrudForm inputs actually read.\n 'metadata.category': metadata.category || '',\n 'metadata.tags': Array.isArray(metadata.tags) ? metadata.tags : [],\n 'metadata.icon': metadata.icon || '',\n steps: workflow.definition?.steps || [],\n transitions: workflow.definition?.transitions || [],\n triggers: workflow.definition?.triggers || [],\n }\n}\n\n/**\n * Build API payload from form values\n */\nexport function buildWorkflowPayload(values: WorkflowDefinitionFormValues) {\n const triggers = values.triggers ?? []\n // Collapse the flat dot-path keys back into the nested metadata object the API\n // expects. Empty category/icon are dropped so they don't persist as blanks.\n const category = (values['metadata.category'] || '').trim()\n const icon = (values['metadata.icon'] || '').trim()\n const tags = Array.isArray(values['metadata.tags']) ? values['metadata.tags'] : []\n const metadata = {\n tags,\n ...(category ? { category } : {}),\n ...(icon ? { icon } : {}),\n }\n return {\n workflowId: values.workflowId,\n workflowName: values.workflowName,\n description: values.description || null,\n version: values.version,\n enabled: values.enabled,\n effectiveFrom: values.effectiveFrom || null,\n effectiveTo: values.effectiveTo || null,\n metadata,\n definition: {\n steps: values.steps,\n transitions: values.transitions,\n ...(triggers.length > 0 ? { triggers } : {}),\n },\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["\"use client\"\n\nimport * as React from 'react'\nimport { z } from 'zod'\nimport type { CrudField, CrudFormGroup } from '@open-mercato/ui/backend/CrudForm'\nimport type { WorkflowDefinitionTrigger } from '../data/entities'\n\n/**\n * Form Values Type\n * Represents the structure of form data for creating/editing workflow definitions\n */\nexport type WorkflowDefinitionFormValues = {\n workflowId: string\n workflowName: string\n description?: string | null\n version: number\n enabled: boolean\n effectiveFrom?: string | null\n effectiveTo?: string | null\n // Metadata fields are declared on the form with dot-path ids\n // (`metadata.category`, `metadata.tags`, `metadata.icon`). CrudForm only\n // collapses dot-paths for injected/custom fields, so declared base fields are\n // carried as flat keys end-to-end; buildWorkflowPayload reassembles them into\n // the nested metadata object the API expects. See issue #2503.\n 'metadata.category'?: string\n 'metadata.tags'?: string[]\n 'metadata.icon'?: string\n steps: any[]\n transitions: any[]\n triggers: WorkflowDefinitionTrigger[]\n id?: string\n updatedAt?: string | null\n}\n\n/**\n * Form Validation Schema\n * Extends the API schema with additional client-side validation\n */\nexport const workflowDefinitionFormSchema = z.object({\n workflowId: z.string()\n .min(1, 'Workflow ID is required')\n .max(100, 'Workflow ID must be 100 characters or less')\n .regex(/^[a-z0-9_.-]+$/, 'Workflow ID must contain only lowercase letters, numbers, hyphens, underscores, and dots'),\n workflowName: z.string()\n .min(1, 'Workflow name is required')\n .max(200, 'Workflow name must be 200 characters or less'),\n description: z.string()\n .max(5000, 'Description must be 5000 characters or less')\n .optional()\n .nullable(),\n version: z.number().int().min(1),\n enabled: z.boolean(),\n effectiveFrom: z.string().optional().nullable(),\n effectiveTo: z.string().optional().nullable(),\n // Flat dot-path keys mirror the field ids so CrudForm's non-strict\n // schema.safeParse keeps them instead of stripping them before onSubmit.\n 'metadata.category': z.string().max(50).optional(),\n 'metadata.tags': z.array(z.string()).optional(),\n 'metadata.icon': z.string().max(50).optional(),\n steps: z.array(z.any()),\n transitions: z.array(z.any()),\n triggers: z.array(z.any()).default([]),\n})\n\n/**\n * Default Form Values\n */\nexport const defaultFormValues: WorkflowDefinitionFormValues = {\n workflowId: '',\n workflowName: '',\n description: null,\n version: 1,\n enabled: true,\n effectiveFrom: null,\n effectiveTo: null,\n 'metadata.category': '',\n 'metadata.tags': [],\n 'metadata.icon': '',\n steps: [],\n transitions: [],\n triggers: [],\n}\n\n/**\n * Create Field Definitions\n * Returns field configurations for the CrudForm\n */\nexport function createFieldDefinitions(t: (key: string) => string): CrudField[] {\n return [\n {\n id: 'workflowId',\n label: t('workflows.form.workflowId'),\n type: 'text',\n required: true,\n placeholder: t('workflows.form.placeholders.workflowId'),\n description: t('workflows.form.descriptions.workflowId'),\n },\n {\n id: 'workflowName',\n label: t('workflows.form.workflowName'),\n type: 'text',\n required: true,\n placeholder: t('workflows.form.placeholders.workflowName'),\n },\n {\n id: 'description',\n label: t('workflows.form.description'),\n type: 'textarea',\n placeholder: t('workflows.form.placeholders.description'),\n },\n {\n id: 'version',\n label: t('workflows.form.version'),\n type: 'number',\n required: true,\n description: t('workflows.form.descriptions.version'),\n },\n {\n id: 'enabled',\n label: t('workflows.form.enabled'),\n type: 'checkbox',\n description: t('workflows.form.descriptions.enabled'),\n },\n {\n id: 'effectiveFrom',\n label: t('workflows.form.effectiveFrom'),\n type: 'date',\n description: t('workflows.form.descriptions.effectiveFrom'),\n },\n {\n id: 'effectiveTo',\n label: t('workflows.form.effectiveTo'),\n type: 'date',\n description: t('workflows.form.descriptions.effectiveTo'),\n },\n {\n id: 'metadata.category',\n label: t('workflows.form.category'),\n type: 'text',\n placeholder: t('workflows.form.placeholders.category'),\n },\n {\n id: 'metadata.tags',\n label: t('workflows.form.tags'),\n type: 'tags',\n placeholder: t('workflows.form.placeholders.tags'),\n description: t('workflows.form.descriptions.tags'),\n },\n {\n id: 'metadata.icon',\n label: t('workflows.form.icon'),\n type: 'text',\n placeholder: t('workflows.form.placeholders.icon'),\n description: t('workflows.form.descriptions.icon'),\n },\n ]\n}\n\n/**\n * Create Form Groups\n * Returns grouped layout configuration for the CrudForm\n */\nexport function createFormGroups(\n t: (key: string) => string,\n StepsEditorComponent: React.ComponentType<any>,\n TransitionsEditorComponent: React.ComponentType<any>\n): CrudFormGroup[] {\n // Wrapper components to adapt CrudForm props\n const StepsEditorWrapper = (props: { value: any; setValue: (v: any) => void; error?: string; values?: any }) => {\n return <StepsEditorComponent value={props.value} onChange={props.setValue} error={props.error} />\n }\n\n const TransitionsEditorWrapper = (props: { value: any; setValue: (v: any) => void; error?: string; values?: any }) => {\n // Pass the steps from values (all form values) so transitions can reference them\n return <TransitionsEditorComponent value={props.value} onChange={props.setValue} steps={props.values?.steps || []} error={props.error} />\n }\n\n return [\n {\n id: 'basic',\n title: t('workflows.form.groups.basic'),\n column: 1,\n fields: [\n 'workflowId',\n 'workflowName',\n 'description',\n 'version',\n 'enabled',\n ],\n },\n {\n id: 'metadata',\n title: t('workflows.form.groups.metadata'),\n column: 1,\n fields: [\n 'metadata.category',\n 'metadata.tags',\n 'metadata.icon',\n 'effectiveFrom',\n 'effectiveTo',\n ],\n },\n {\n id: 'steps',\n title: t('workflows.form.groups.steps'),\n column: 1,\n fields: [\n {\n id: 'steps',\n label: t('workflows.form.stepsLabel'),\n type: 'custom',\n required: true,\n component: StepsEditorWrapper,\n },\n ],\n },\n {\n id: 'transitions',\n title: t('workflows.form.groups.transitions'),\n column: 1,\n fields: [\n {\n id: 'transitions',\n label: t('workflows.form.transitionsLabel'),\n type: 'custom',\n required: true,\n component: TransitionsEditorWrapper,\n },\n ],\n },\n ]\n}\n\nimport { toDateInputValue } from '@open-mercato/shared/lib/date/format'\n\n/**\n * Parse workflow definition to form values\n */\nexport function parseWorkflowToFormValues(workflow: any): WorkflowDefinitionFormValues {\n const updatedAt = workflow.updatedAt ?? workflow.updated_at ?? null\n const metadata = workflow.metadata || {}\n return {\n workflowId: workflow.workflowId || '',\n workflowName: workflow.workflowName || '',\n description: workflow.description || null,\n version: workflow.version || 1,\n enabled: workflow.enabled ?? true,\n effectiveFrom: toDateInputValue(workflow.effectiveFrom),\n effectiveTo: toDateInputValue(workflow.effectiveTo),\n // Hydrate the flat dot-path keys the CrudForm inputs actually read.\n 'metadata.category': metadata.category || '',\n 'metadata.tags': Array.isArray(metadata.tags) ? metadata.tags : [],\n 'metadata.icon': metadata.icon || '',\n steps: workflow.definition?.steps || [],\n transitions: workflow.definition?.transitions || [],\n triggers: workflow.definition?.triggers || [],\n id: workflow.id,\n updatedAt: typeof updatedAt === 'string' ? updatedAt : updatedAt ? String(updatedAt) : null,\n }\n}\n\n/**\n * Build API payload from form values\n */\nexport function buildWorkflowPayload(values: WorkflowDefinitionFormValues) {\n const triggers = values.triggers ?? []\n // Collapse the flat dot-path keys back into the nested metadata object the API\n // expects. Empty category/icon are dropped so they don't persist as blanks.\n const category = (values['metadata.category'] || '').trim()\n const icon = (values['metadata.icon'] || '').trim()\n const tags = Array.isArray(values['metadata.tags']) ? values['metadata.tags'] : []\n const metadata = {\n tags,\n ...(category ? { category } : {}),\n ...(icon ? { icon } : {}),\n }\n return {\n workflowId: values.workflowId,\n workflowName: values.workflowName,\n description: values.description || null,\n version: values.version,\n enabled: values.enabled,\n effectiveFrom: values.effectiveFrom || null,\n effectiveTo: values.effectiveTo || null,\n metadata,\n definition: {\n steps: values.steps,\n transitions: values.transitions,\n ...(triggers.length > 0 ? { triggers } : {}),\n },\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -1,4 +1,7 @@
1
1
  import { asFunction } from "awilix";
2
+ import { createGenericOptimisticLockReader } from "@open-mercato/shared/lib/crud/optimistic-lock";
3
+ import { registerOptimisticLockReaders } from "@open-mercato/shared/lib/crud/optimistic-lock-store";
4
+ import { WorkflowDefinition } from "./data/entities.js";
2
5
  import * as workflowExecutor from "./lib/workflow-executor.js";
3
6
  import * as stepHandler from "./lib/step-handler.js";
4
7
  import * as transitionHandler from "./lib/transition-handler.js";
@@ -6,6 +9,15 @@ import * as activityExecutor from "./lib/activity-executor.js";
6
9
  import * as eventLogger from "./lib/event-logger.js";
7
10
  import * as signalHandler from "./lib/signal-handler.js";
8
11
  import * as timerHandler from "./lib/timer-handler.js";
12
+ registerOptimisticLockReaders({
13
+ "workflows.definition": createGenericOptimisticLockReader({
14
+ entity: WorkflowDefinition,
15
+ idField: "id",
16
+ tenantField: "tenantId",
17
+ orgField: "organizationId",
18
+ softDeleteField: "deletedAt"
19
+ })
20
+ });
9
21
  function register(container) {
10
22
  container.register({
11
23
  workflowExecutor: asFunction(() => workflowExecutor).scoped(),
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../../src/modules/workflows/di.ts"],
4
- "sourcesContent": ["/**\n * Workflows Module - Dependency Injection\n *\n * Register workflow engine services in the DI container.\n */\n\nimport type { AwilixContainer } from 'awilix'\nimport { asFunction } from 'awilix'\nimport * as workflowExecutor from './lib/workflow-executor'\nimport * as stepHandler from './lib/step-handler'\nimport * as transitionHandler from './lib/transition-handler'\nimport * as activityExecutor from './lib/activity-executor'\nimport * as eventLogger from './lib/event-logger'\nimport * as signalHandler from './lib/signal-handler'\nimport * as timerHandler from './lib/timer-handler'\n\nexport function register(container: AwilixContainer): void {\n container.register({\n workflowExecutor: asFunction(() => workflowExecutor).scoped(),\n stepHandler: asFunction(() => stepHandler).scoped(),\n transitionHandler: asFunction(() => transitionHandler).scoped(),\n activityExecutor: asFunction(() => activityExecutor).scoped(),\n eventLogger: asFunction(() => eventLogger).scoped(),\n signalHandler: asFunction(() => signalHandler).scoped(),\n timerHandler: asFunction(() => timerHandler).scoped(),\n })\n}\n"],
5
- "mappings": "AAOA,SAAS,kBAAkB;AAC3B,YAAY,sBAAsB;AAClC,YAAY,iBAAiB;AAC7B,YAAY,uBAAuB;AACnC,YAAY,sBAAsB;AAClC,YAAY,iBAAiB;AAC7B,YAAY,mBAAmB;AAC/B,YAAY,kBAAkB;AAEvB,SAAS,SAAS,WAAkC;AACzD,YAAU,SAAS;AAAA,IACjB,kBAAkB,WAAW,MAAM,gBAAgB,EAAE,OAAO;AAAA,IAC5D,aAAa,WAAW,MAAM,WAAW,EAAE,OAAO;AAAA,IAClD,mBAAmB,WAAW,MAAM,iBAAiB,EAAE,OAAO;AAAA,IAC9D,kBAAkB,WAAW,MAAM,gBAAgB,EAAE,OAAO;AAAA,IAC5D,aAAa,WAAW,MAAM,WAAW,EAAE,OAAO;AAAA,IAClD,eAAe,WAAW,MAAM,aAAa,EAAE,OAAO;AAAA,IACtD,cAAc,WAAW,MAAM,YAAY,EAAE,OAAO;AAAA,EACtD,CAAC;AACH;",
4
+ "sourcesContent": ["/**\n * Workflows Module - Dependency Injection\n *\n * Register workflow engine services in the DI container.\n */\n\nimport type { AwilixContainer } from 'awilix'\nimport { asFunction } from 'awilix'\nimport { createGenericOptimisticLockReader } from '@open-mercato/shared/lib/crud/optimistic-lock'\nimport { registerOptimisticLockReaders } from '@open-mercato/shared/lib/crud/optimistic-lock-store'\nimport { WorkflowDefinition } from './data/entities'\nimport * as workflowExecutor from './lib/workflow-executor'\nimport * as stepHandler from './lib/step-handler'\nimport * as transitionHandler from './lib/transition-handler'\nimport * as activityExecutor from './lib/activity-executor'\nimport * as eventLogger from './lib/event-logger'\nimport * as signalHandler from './lib/signal-handler'\nimport * as timerHandler from './lib/timer-handler'\n\n// Register the `workflows.definition` optimistic-lock reader at module-DI load\n// time (top-level, like sales/customers) so it is present in the global reader\n// store before any request-scoped `crudMutationGuardService` snapshots\n// `getAllOptimisticLockReaders()`. Registering it only as a side-effect of\n// importing the definition route module left it absent from that snapshot, so\n// the guard short-circuited and the visual editor's stale saves overwrote with\n// no 409 and no conflict bar.\nregisterOptimisticLockReaders({\n 'workflows.definition': createGenericOptimisticLockReader({\n entity: WorkflowDefinition,\n idField: 'id',\n tenantField: 'tenantId',\n orgField: 'organizationId',\n softDeleteField: 'deletedAt',\n }),\n})\n\nexport function register(container: AwilixContainer): void {\n container.register({\n workflowExecutor: asFunction(() => workflowExecutor).scoped(),\n stepHandler: asFunction(() => stepHandler).scoped(),\n transitionHandler: asFunction(() => transitionHandler).scoped(),\n activityExecutor: asFunction(() => activityExecutor).scoped(),\n eventLogger: asFunction(() => eventLogger).scoped(),\n signalHandler: asFunction(() => signalHandler).scoped(),\n timerHandler: asFunction(() => timerHandler).scoped(),\n })\n}\n"],
5
+ "mappings": "AAOA,SAAS,kBAAkB;AAC3B,SAAS,yCAAyC;AAClD,SAAS,qCAAqC;AAC9C,SAAS,0BAA0B;AACnC,YAAY,sBAAsB;AAClC,YAAY,iBAAiB;AAC7B,YAAY,uBAAuB;AACnC,YAAY,sBAAsB;AAClC,YAAY,iBAAiB;AAC7B,YAAY,mBAAmB;AAC/B,YAAY,kBAAkB;AAS9B,8BAA8B;AAAA,EAC5B,wBAAwB,kCAAkC;AAAA,IACxD,QAAQ;AAAA,IACR,SAAS;AAAA,IACT,aAAa;AAAA,IACb,UAAU;AAAA,IACV,iBAAiB;AAAA,EACnB,CAAC;AACH,CAAC;AAEM,SAAS,SAAS,WAAkC;AACzD,YAAU,SAAS;AAAA,IACjB,kBAAkB,WAAW,MAAM,gBAAgB,EAAE,OAAO;AAAA,IAC5D,aAAa,WAAW,MAAM,WAAW,EAAE,OAAO;AAAA,IAClD,mBAAmB,WAAW,MAAM,iBAAiB,EAAE,OAAO;AAAA,IAC9D,kBAAkB,WAAW,MAAM,gBAAgB,EAAE,OAAO;AAAA,IAC5D,aAAa,WAAW,MAAM,WAAW,EAAE,OAAO;AAAA,IAClD,eAAe,WAAW,MAAM,aAAa,EAAE,OAAO;AAAA,IACtD,cAAc,WAAW,MAAM,YAAY,EAAE,OAAO;AAAA,EACtD,CAAC;AACH;",
6
6
  "names": []
7
7
  }
@@ -2,4 +2,5 @@ export const id = "id";
2
2
  export const name = "name";
3
3
  export const tenant_id = "tenant_id";
4
4
  export const created_at = "created_at";
5
+ export const updated_at = "updated_at";
5
6
  export const deleted_at = "deleted_at";
@@ -8,4 +8,5 @@ export const password_hash = "password_hash";
8
8
  export const is_confirmed = "is_confirmed";
9
9
  export const last_login_at = "last_login_at";
10
10
  export const created_at = "created_at";
11
+ export const updated_at = "updated_at";
11
12
  export const deleted_at = "deleted_at";
@@ -1713,6 +1713,7 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
1713
1713
  "name": "name",
1714
1714
  "tenant_id": "tenant_id",
1715
1715
  "created_at": "created_at",
1716
+ "updated_at": "updated_at",
1716
1717
  "deleted_at": "deleted_at"
1717
1718
  },
1718
1719
  "role_acl": {
@@ -2806,6 +2807,7 @@ export const entityFieldsRegistry: Record<string, Record<string, string>> = {
2806
2807
  "is_confirmed": "is_confirmed",
2807
2808
  "last_login_at": "last_login_at",
2808
2809
  "created_at": "created_at",
2810
+ "updated_at": "updated_at",
2809
2811
  "deleted_at": "deleted_at"
2810
2812
  },
2811
2813
  "user_acl": {
package/jest.setup.ts CHANGED
@@ -18,6 +18,23 @@ if (typeof globalThis.WritableStream === 'undefined') {
18
18
  ;(globalThis as any).WritableStream = WritableStream
19
19
  }
20
20
 
21
+ // jsdom doesn't implement `window.matchMedia`. Components that read viewport
22
+ // breakpoints (e.g. `useIsMobile`, `CollapsibleZoneLayout`) call it during
23
+ // render via `useSyncExternalStore`, which throws without this shim. Default to
24
+ // "not matching" (desktop) — tests that need a specific breakpoint override it.
25
+ if (typeof window !== 'undefined' && typeof window.matchMedia !== 'function') {
26
+ ;(window as any).matchMedia = (query: string) => ({
27
+ matches: false,
28
+ media: query,
29
+ onchange: null,
30
+ addEventListener: () => {},
31
+ removeEventListener: () => {},
32
+ addListener: () => {},
33
+ removeListener: () => {},
34
+ dispatchEvent: () => false,
35
+ })
36
+ }
37
+
21
38
  jest.mock('react-markdown', () => ({
22
39
  __esModule: true,
23
40
  default: ({ children }: { children?: unknown }) => children ?? null,