@rytass/bpm-core-react 0.18.0 → 0.19.0

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 (283) hide show
  1. package/CHANGELOG.md +45 -0
  2. package/dist/chunks/{FormBuilderView-BVKY1j_0.js → FormBuilderView-Djlm3y4S.js} +485 -481
  3. package/dist/chunks/FormBuilderView-Djlm3y4S.js.map +1 -0
  4. package/dist/chunks/FormBuilderView-G6uRSywl.cjs +3 -0
  5. package/dist/chunks/FormBuilderView-G6uRSywl.cjs.map +1 -0
  6. package/dist/chunks/{FormRendererView-BsTwZkqU.js → FormRendererView-DHfVgbo6.js} +511 -274
  7. package/dist/chunks/FormRendererView-DHfVgbo6.js.map +1 -0
  8. package/dist/chunks/FormRendererView-DwfFbaip.cjs +6 -0
  9. package/dist/chunks/FormRendererView-DwfFbaip.cjs.map +1 -0
  10. package/dist/chunks/admin-pickers-BjbkBpSJ.cjs +2 -0
  11. package/dist/chunks/admin-pickers-BjbkBpSJ.cjs.map +1 -0
  12. package/dist/chunks/{admin-pickers-Djq3h-UR.js → admin-pickers-DfGxsjpp.js} +42 -42
  13. package/dist/chunks/admin-pickers-DfGxsjpp.js.map +1 -0
  14. package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js → approval-instance-list-page-BnI4t5mD.js} +7 -8
  15. package/dist/chunks/{approval-instance-list-page-CPXMP3PL.js.map → approval-instance-list-page-BnI4t5mD.js.map} +1 -1
  16. package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs → approval-instance-list-page-fqvmkBlg.cjs} +2 -2
  17. package/dist/chunks/{approval-instance-list-page-ax0pm8bt.cjs.map → approval-instance-list-page-fqvmkBlg.cjs.map} +1 -1
  18. package/dist/chunks/auth-provider-4BeCw7cI.cjs.map +1 -1
  19. package/dist/chunks/{auth-provider-B5oPmvk2.js → auth-provider-C2b-5mGt.js} +2 -3
  20. package/dist/chunks/{auth-provider-B5oPmvk2.js.map → auth-provider-C2b-5mGt.js.map} +1 -1
  21. package/dist/chunks/{bpm-form-field-Cao0rMol.js → bpm-form-field-9B-Det0u.js} +2 -3
  22. package/dist/chunks/{bpm-form-field-Cao0rMol.js.map → bpm-form-field-9B-Det0u.js.map} +1 -1
  23. package/dist/chunks/bpm-form-field-Bc6k4ZEO.cjs.map +1 -1
  24. package/dist/chunks/{categories-riC33J_j.js → categories-BAdxjNSA.js} +14 -15
  25. package/dist/chunks/{categories-riC33J_j.js.map → categories-BAdxjNSA.js.map} +1 -1
  26. package/dist/chunks/{categories-AxxhqjLZ.cjs → categories-DQUtVEiV.cjs} +2 -2
  27. package/dist/chunks/{categories-AxxhqjLZ.cjs.map → categories-DQUtVEiV.cjs.map} +1 -1
  28. package/dist/chunks/{compose-B1GlrZW9.js → compose-D6zBIc2Z.js} +131 -148
  29. package/dist/chunks/compose-D6zBIc2Z.js.map +1 -0
  30. package/dist/chunks/compose-NH6dsFXD.cjs +2 -0
  31. package/dist/chunks/compose-NH6dsFXD.cjs.map +1 -0
  32. package/dist/chunks/{dashboard-page-DdBvV6YI.js → dashboard-page-BoqNhjT_.js} +5 -6
  33. package/dist/chunks/{dashboard-page-DdBvV6YI.js.map → dashboard-page-BoqNhjT_.js.map} +1 -1
  34. package/dist/chunks/{dashboard-page-BWQBSGDq.cjs → dashboard-page-D7YJ3udk.cjs} +2 -2
  35. package/dist/chunks/{dashboard-page-BWQBSGDq.cjs.map → dashboard-page-D7YJ3udk.cjs.map} +1 -1
  36. package/dist/chunks/{delegations-MxF3uJGW.js → delegations-BfhCDz5e.js} +15 -16
  37. package/dist/chunks/{delegations-MxF3uJGW.js.map → delegations-BfhCDz5e.js.map} +1 -1
  38. package/dist/chunks/{delegations-Ckf03icM.cjs → delegations-BmFGcuhA.cjs} +2 -2
  39. package/dist/chunks/{delegations-Ckf03icM.cjs.map → delegations-BmFGcuhA.cjs.map} +1 -1
  40. package/dist/chunks/{delegations-V9HIe3_P.cjs → delegations-CcS0SHbf.cjs} +2 -2
  41. package/dist/chunks/{delegations-V9HIe3_P.cjs.map → delegations-CcS0SHbf.cjs.map} +1 -1
  42. package/dist/chunks/{delegations-xUt1tj8d.js → delegations-DBh5TT6G.js} +16 -17
  43. package/dist/chunks/{delegations-xUt1tj8d.js.map → delegations-DBh5TT6G.js.map} +1 -1
  44. package/dist/chunks/designer-Be9UI9Tg.cjs +65 -0
  45. package/dist/chunks/designer-Be9UI9Tg.cjs.map +1 -0
  46. package/dist/chunks/{designer-BCLrjb4H.js → designer-uhC_7m2i.js} +1791 -1407
  47. package/dist/chunks/designer-uhC_7m2i.js.map +1 -0
  48. package/dist/chunks/detail-6uw5dmTi.cjs +5 -0
  49. package/dist/chunks/detail-6uw5dmTi.cjs.map +1 -0
  50. package/dist/chunks/{detail-4F39ggBn.js → detail-_GeKqNC-.js} +1012 -972
  51. package/dist/chunks/detail-_GeKqNC-.js.map +1 -0
  52. package/dist/chunks/{format-date-time-CB-LxzqT.js → format-date-time-B0LdmWg4.js} +2 -3
  53. package/dist/chunks/{format-date-time-CB-LxzqT.js.map → format-date-time-B0LdmWg4.js.map} +1 -1
  54. package/dist/chunks/format-date-time-D-cx5M8z.cjs.map +1 -1
  55. package/dist/chunks/{format-member-label-DudVI55w.js → format-member-label-C73FuP-d.js} +2 -3
  56. package/dist/chunks/{format-member-label-DudVI55w.js.map → format-member-label-C73FuP-d.js.map} +1 -1
  57. package/dist/chunks/format-member-label-t7ANTF62.cjs.map +1 -1
  58. package/dist/chunks/{approver-filled-form-Dm3Iw7iw.cjs → instance-error-message-DTARGbGo.cjs} +2 -2
  59. package/dist/chunks/instance-error-message-DTARGbGo.cjs.map +1 -0
  60. package/dist/chunks/{approver-filled-form-ZEwpmsHJ.js → instance-error-message-q6gy5evy.js} +50 -38
  61. package/dist/chunks/instance-error-message-q6gy5evy.js.map +1 -0
  62. package/dist/chunks/language-provider-Bdnx3Gxl.cjs.map +1 -1
  63. package/dist/chunks/{language-provider-B3cEbLe4.js → language-provider-phkWOapf.js} +2 -3
  64. package/dist/chunks/{language-provider-B3cEbLe4.js.map → language-provider-phkWOapf.js.map} +1 -1
  65. package/dist/chunks/{login-C6qlTC6F.js → login-D6cc3bo7.js} +4 -5
  66. package/dist/chunks/{login-C6qlTC6F.js.map → login-D6cc3bo7.js.map} +1 -1
  67. package/dist/chunks/{login-AtVxZBsC.cjs → login-uvVcltrS.cjs} +2 -2
  68. package/dist/chunks/{login-AtVxZBsC.cjs.map → login-uvVcltrS.cjs.map} +1 -1
  69. package/dist/chunks/notifications-Bc4mgSds.cjs.map +1 -1
  70. package/dist/chunks/{notifications-DJ5wzCye.js → notifications-Cvme5Qbl.js} +2 -3
  71. package/dist/chunks/{notifications-DJ5wzCye.js.map → notifications-Cvme5Qbl.js.map} +1 -1
  72. package/dist/chunks/orgs-B_2J2tLX.cjs +2 -0
  73. package/dist/chunks/{orgs-BeeDDWL1.cjs.map → orgs-B_2J2tLX.cjs.map} +1 -1
  74. package/dist/chunks/{orgs-8hje_l2n.js → orgs-DqxMds26.js} +48 -49
  75. package/dist/chunks/{orgs-8hje_l2n.js.map → orgs-DqxMds26.js.map} +1 -1
  76. package/dist/chunks/{providers-B_d5tbCL.js → providers-BbCs23sk.js} +21 -25
  77. package/dist/chunks/{providers-B_d5tbCL.js.map → providers-BbCs23sk.js.map} +1 -1
  78. package/dist/chunks/{providers-chuJvMgv.cjs → providers-D_KAgOOu.cjs} +2 -2
  79. package/dist/chunks/{providers-chuJvMgv.cjs.map → providers-D_KAgOOu.cjs.map} +1 -1
  80. package/dist/chunks/router-adapter--gYs13E8.cjs.map +1 -1
  81. package/dist/chunks/{router-adapter-DftlFTOd.js → router-adapter-CkxCyzf5.js} +2 -3
  82. package/dist/chunks/{router-adapter-DftlFTOd.js.map → router-adapter-CkxCyzf5.js.map} +1 -1
  83. package/dist/chunks/{routes-config-yZbESPlw.js → routes-config-BcNaWJWJ.js} +2 -3
  84. package/dist/chunks/{routes-config-yZbESPlw.js.map → routes-config-BcNaWJWJ.js.map} +1 -1
  85. package/dist/chunks/routes-config-C1j_vFKo.cjs.map +1 -1
  86. package/dist/chunks/task-decision-3d17ZvZE.js +29 -0
  87. package/dist/chunks/task-decision-3d17ZvZE.js.map +1 -0
  88. package/dist/chunks/task-decision-CqZ4WQOC.cjs +2 -0
  89. package/dist/chunks/task-decision-CqZ4WQOC.cjs.map +1 -0
  90. package/dist/chunks/{use-bpm-member-D57LKe_u.js → use-bpm-member-BPzcNU1g.js} +3 -4
  91. package/dist/chunks/{use-bpm-member-D57LKe_u.js.map → use-bpm-member-BPzcNU1g.js.map} +1 -1
  92. package/dist/chunks/use-bpm-member-DpNAQtNC.cjs.map +1 -1
  93. package/dist/chunks/{users-Pl6hY5Y5.js → users-BBtiZ9QQ.js} +22 -25
  94. package/dist/chunks/{users-Pl6hY5Y5.js.map → users-BBtiZ9QQ.js.map} +1 -1
  95. package/dist/chunks/{users-O2L_M3BK.cjs → users-EqSzDhuj.cjs} +2 -2
  96. package/dist/chunks/{users-O2L_M3BK.cjs.map → users-EqSzDhuj.cjs.map} +1 -1
  97. package/dist/components/admin-picker-options.d.cts +11 -0
  98. package/dist/components/admin-picker-options.d.ts +11 -0
  99. package/dist/components/admin-pickers.d.cts +2 -11
  100. package/dist/components/admin-pickers.d.ts +2 -11
  101. package/dist/index.cjs +1 -1
  102. package/dist/index.cjs.map +1 -1
  103. package/dist/index.js +17 -19
  104. package/dist/index.js.map +1 -1
  105. package/dist/lib/task-decision.d.cts +16 -0
  106. package/dist/lib/task-decision.d.ts +16 -0
  107. package/dist/lib/use-org-unit-names.d.cts +10 -0
  108. package/dist/lib/use-org-unit-names.d.ts +10 -0
  109. package/dist/next/index.cjs +1 -1
  110. package/dist/next/index.cjs.map +1 -1
  111. package/dist/next/index.js +7 -8
  112. package/dist/next/index.js.map +1 -1
  113. package/dist/next/workflow-chat-route.cjs +19 -1
  114. package/dist/next/workflow-chat-route.cjs.map +1 -1
  115. package/dist/next/workflow-chat-route.js +2 -3
  116. package/dist/next/workflow-chat-route.js.map +1 -1
  117. package/dist/pages/admin/delegations/index.cjs +1 -1
  118. package/dist/pages/admin/delegations/index.cjs.map +1 -1
  119. package/dist/pages/admin/delegations/index.js +2 -3
  120. package/dist/pages/admin/orgs/index.cjs +1 -1
  121. package/dist/pages/admin/orgs/index.cjs.map +1 -1
  122. package/dist/pages/admin/orgs/index.js +2 -3
  123. package/dist/pages/admin/users/index.cjs +1 -1
  124. package/dist/pages/admin/users/index.cjs.map +1 -1
  125. package/dist/pages/admin/users/index.js +2 -3
  126. package/dist/pages/admin/webhook-endpoints/index.cjs.map +1 -1
  127. package/dist/pages/admin/webhook-endpoints/index.js +1 -2
  128. package/dist/pages/cc/index.cjs.map +1 -1
  129. package/dist/pages/cc/index.js +1 -2
  130. package/dist/pages/dashboard/index.cjs.map +1 -1
  131. package/dist/pages/dashboard/index.js +1 -2
  132. package/dist/pages/delegations/index.cjs +1 -1
  133. package/dist/pages/delegations/index.cjs.map +1 -1
  134. package/dist/pages/delegations/index.js +2 -3
  135. package/dist/pages/inbox/index.cjs.map +1 -1
  136. package/dist/pages/inbox/index.js +1 -2
  137. package/dist/pages/instances/detail/index.cjs +1 -1
  138. package/dist/pages/instances/detail/index.cjs.map +1 -1
  139. package/dist/pages/instances/detail/index.js +2 -3
  140. package/dist/pages/instances/new/index.cjs.map +1 -1
  141. package/dist/pages/instances/new/index.js +1 -2
  142. package/dist/pages/login/index.cjs +1 -1
  143. package/dist/pages/login/index.cjs.map +1 -1
  144. package/dist/pages/login/index.js +2 -3
  145. package/dist/pages/root/index.cjs.map +1 -1
  146. package/dist/pages/root/index.js +1 -2
  147. package/dist/pages/search/index.cjs.map +1 -1
  148. package/dist/pages/search/index.js +1 -2
  149. package/dist/pages/sent/index.cjs.map +1 -1
  150. package/dist/pages/sent/index.js +1 -2
  151. package/dist/pages/settings/notifications/index.cjs.map +1 -1
  152. package/dist/pages/settings/notifications/index.js +2 -3
  153. package/dist/pages/templates/categories/index.cjs +1 -1
  154. package/dist/pages/templates/categories/index.cjs.map +1 -1
  155. package/dist/pages/templates/categories/index.js +2 -3
  156. package/dist/pages/templates/compose/index.cjs +1 -1
  157. package/dist/pages/templates/compose/index.cjs.map +1 -1
  158. package/dist/pages/templates/compose/index.js +2 -3
  159. package/dist/pages/templates/designer/index.cjs +1 -1
  160. package/dist/pages/templates/designer/index.cjs.map +1 -1
  161. package/dist/pages/templates/designer/index.js +2 -3
  162. package/dist/pages/templates/index.cjs.map +1 -1
  163. package/dist/pages/templates/index.js +1 -2
  164. package/dist/pages/templates/versions/index.cjs.map +1 -1
  165. package/dist/pages/templates/versions/index.js +1 -2
  166. package/dist/views/admin/delegations/index.cjs +1 -1
  167. package/dist/views/admin/delegations/index.js +1 -1
  168. package/dist/views/admin/index.cjs +1 -1
  169. package/dist/views/admin/index.js +3 -3
  170. package/dist/views/admin/orgs/index.cjs +1 -1
  171. package/dist/views/admin/orgs/index.js +1 -1
  172. package/dist/views/admin/users/index.cjs +1 -1
  173. package/dist/views/admin/users/index.js +1 -1
  174. package/dist/views/admin/webhook-endpoints/index.cjs +1 -1
  175. package/dist/views/admin/webhook-endpoints/index.cjs.map +1 -1
  176. package/dist/views/admin/webhook-endpoints/index.js +52 -53
  177. package/dist/views/admin/webhook-endpoints/index.js.map +1 -1
  178. package/dist/views/cc/index.cjs +1 -1
  179. package/dist/views/cc/index.cjs.map +1 -1
  180. package/dist/views/cc/index.js +2 -3
  181. package/dist/views/dashboard/index.cjs +1 -1
  182. package/dist/views/dashboard/index.cjs.map +1 -1
  183. package/dist/views/dashboard/index.js +2 -3
  184. package/dist/views/delegations/index.cjs +1 -1
  185. package/dist/views/delegations/index.js +1 -1
  186. package/dist/views/forms/builder/index.cjs +1 -1
  187. package/dist/views/forms/builder/index.js +1 -1
  188. package/dist/views/forms/renderer/FormRendererView.d.cts +24 -1
  189. package/dist/views/forms/renderer/FormRendererView.d.ts +24 -1
  190. package/dist/views/forms/renderer/file-upload-field.d.cts +84 -0
  191. package/dist/views/forms/renderer/file-upload-field.d.ts +84 -0
  192. package/dist/views/forms/renderer/form-value-readers.d.cts +7 -0
  193. package/dist/views/forms/renderer/form-value-readers.d.ts +7 -0
  194. package/dist/views/forms/renderer/index.cjs +1 -1
  195. package/dist/views/forms/renderer/index.d.cts +1 -0
  196. package/dist/views/forms/renderer/index.d.ts +1 -0
  197. package/dist/views/forms/renderer/index.js +1 -1
  198. package/dist/views/forms/renderer/org-unit-field-options.d.cts +44 -0
  199. package/dist/views/forms/renderer/org-unit-field-options.d.ts +44 -0
  200. package/dist/views/forms/renderer/org-unit-field.d.cts +23 -0
  201. package/dist/views/forms/renderer/org-unit-field.d.ts +23 -0
  202. package/dist/views/inbox/index.cjs +1 -1
  203. package/dist/views/inbox/index.cjs.map +1 -1
  204. package/dist/views/inbox/index.js +133 -137
  205. package/dist/views/inbox/index.js.map +1 -1
  206. package/dist/views/instances/approver-filled-form.d.cts +9 -2
  207. package/dist/views/instances/approver-filled-form.d.ts +9 -2
  208. package/dist/views/instances/detail/index.cjs +1 -1
  209. package/dist/views/instances/detail/index.js +1 -1
  210. package/dist/views/instances/detail/sections/InstanceFormSection.d.cts +19 -2
  211. package/dist/views/instances/detail/sections/InstanceFormSection.d.ts +19 -2
  212. package/dist/views/instances/detail/sections/InstanceHistorySection.d.cts +8 -1
  213. package/dist/views/instances/detail/sections/InstanceHistorySection.d.ts +8 -1
  214. package/dist/views/instances/detail/sections/container-helpers.d.cts +0 -1
  215. package/dist/views/instances/detail/sections/container-helpers.d.ts +0 -1
  216. package/dist/views/instances/detail/sections/shared.d.cts +3 -4
  217. package/dist/views/instances/detail/sections/shared.d.ts +3 -4
  218. package/dist/views/instances/instance-error-message.d.cts +5 -0
  219. package/dist/views/instances/instance-error-message.d.ts +5 -0
  220. package/dist/views/instances/new/index.cjs +1 -1
  221. package/dist/views/instances/new/index.cjs.map +1 -1
  222. package/dist/views/instances/new/index.js +78 -77
  223. package/dist/views/instances/new/index.js.map +1 -1
  224. package/dist/views/login/index.cjs +1 -1
  225. package/dist/views/login/index.js +1 -1
  226. package/dist/views/search/index.cjs +1 -1
  227. package/dist/views/search/index.cjs.map +1 -1
  228. package/dist/views/search/index.js +2 -3
  229. package/dist/views/sent/index.cjs +1 -1
  230. package/dist/views/sent/index.cjs.map +1 -1
  231. package/dist/views/sent/index.js +2 -3
  232. package/dist/views/settings/index.js +1 -1
  233. package/dist/views/settings/notifications/index.js +1 -1
  234. package/dist/views/templates/categories/index.cjs +1 -1
  235. package/dist/views/templates/categories/index.js +1 -1
  236. package/dist/views/templates/compose/index.cjs +1 -1
  237. package/dist/views/templates/compose/index.js +1 -1
  238. package/dist/views/templates/designer/approver-resolver-model.d.cts +211 -0
  239. package/dist/views/templates/designer/approver-resolver-model.d.ts +211 -0
  240. package/dist/views/templates/designer/dry-run-assignee-label.d.cts +2 -0
  241. package/dist/views/templates/designer/dry-run-assignee-label.d.ts +2 -0
  242. package/dist/views/templates/designer/dry-run-sample-data.d.cts +6 -0
  243. package/dist/views/templates/designer/dry-run-sample-data.d.ts +6 -0
  244. package/dist/views/templates/designer/dynamic-form-resolver-options.d.cts +25 -0
  245. package/dist/views/templates/designer/dynamic-form-resolver-options.d.ts +25 -0
  246. package/dist/views/templates/designer/index.cjs +1 -1
  247. package/dist/views/templates/designer/index.js +1 -1
  248. package/dist/views/templates/designer/node-actor-resolver-options.d.cts +38 -0
  249. package/dist/views/templates/designer/node-actor-resolver-options.d.ts +38 -0
  250. package/dist/views/templates/index.cjs +1 -1
  251. package/dist/views/templates/index.cjs.map +1 -1
  252. package/dist/views/templates/index.js +50 -51
  253. package/dist/views/templates/index.js.map +1 -1
  254. package/dist/views/templates/versions/index.cjs +1 -1
  255. package/dist/views/templates/versions/index.cjs.map +1 -1
  256. package/dist/views/templates/versions/index.js +7 -8
  257. package/dist/views/templates/versions/index.js.map +1 -1
  258. package/package.json +3 -3
  259. package/dist/chunks/FormBuilderView-BVKY1j_0.js.map +0 -1
  260. package/dist/chunks/FormBuilderView-SrGltzFT.cjs +0 -3
  261. package/dist/chunks/FormBuilderView-SrGltzFT.cjs.map +0 -1
  262. package/dist/chunks/FormRendererView-BsTwZkqU.js.map +0 -1
  263. package/dist/chunks/FormRendererView-GpsE03np.cjs +0 -4
  264. package/dist/chunks/FormRendererView-GpsE03np.cjs.map +0 -1
  265. package/dist/chunks/admin-pickers-BRHk3qKq.cjs +0 -2
  266. package/dist/chunks/admin-pickers-BRHk3qKq.cjs.map +0 -1
  267. package/dist/chunks/admin-pickers-Djq3h-UR.js.map +0 -1
  268. package/dist/chunks/approver-filled-form-Dm3Iw7iw.cjs.map +0 -1
  269. package/dist/chunks/approver-filled-form-ZEwpmsHJ.js.map +0 -1
  270. package/dist/chunks/compose-B1GlrZW9.js.map +0 -1
  271. package/dist/chunks/compose-DZk-SfHT.cjs +0 -2
  272. package/dist/chunks/compose-DZk-SfHT.cjs.map +0 -1
  273. package/dist/chunks/designer-BCLrjb4H.js.map +0 -1
  274. package/dist/chunks/designer-BYYxEN9L.cjs +0 -65
  275. package/dist/chunks/designer-BYYxEN9L.cjs.map +0 -1
  276. package/dist/chunks/detail-4F39ggBn.js.map +0 -1
  277. package/dist/chunks/detail-BkMtA_0K.cjs +0 -2
  278. package/dist/chunks/detail-BkMtA_0K.cjs.map +0 -1
  279. package/dist/chunks/orgs-BeeDDWL1.cjs +0 -2
  280. package/dist/chunks/task-node-label-BF6UllxP.cjs +0 -2
  281. package/dist/chunks/task-node-label-BF6UllxP.cjs.map +0 -1
  282. package/dist/chunks/task-node-label-CWZgOBj0.js +0 -9
  283. package/dist/chunks/task-node-label-CWZgOBj0.js.map +0 -1
@@ -1,2 +1,2 @@
1
- "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../../chunks/format-date-time-D-cx5M8z.cjs"),n=require("../../../chunks/bpm-form-field-Bc6k4ZEO.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/react/ContentHeader");o=e.t(o,1);let s=require("@mezzanine-ui/icons"),c=require("@rytass/bpm-core-client/template");var l={display:`grid`,gap:`var(--mzn-spacing-gap-base)`},u={alignItems:`center`,display:`grid`,gap:`var(--mzn-spacing-gap-base)`,gridTemplateColumns:`minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto`},d={alignItems:`center`,display:`grid`,gap:`var(--mzn-spacing-gap-base)`,gridTemplateColumns:`minmax(0, 1fr) minmax(0, 2fr) auto`},f=[{id:`POST`,name:`POST`},{id:`PUT`,name:`PUT`},{id:`PATCH`,name:`PATCH`}],p=[{id:`string`,name:`文字`},{id:`number`,name:`數字`},{id:`boolean`,name:`是/否`},{id:`stringArray`,name:`文字清單`},{id:`json`,name:`JSON`}],m={CREATED:`建立`,DISABLED:`停用`,ENABLED:`啟用`,SECRET_ROTATED:`輪替金鑰`,TEST_SENT:`測試送出`,UPDATED:`更新`},h={deprecated:!1,description:``,endpointId:null,headers:[],key:``,label:``,method:`POST`,mode:`create`,originalUrl:``,parameters:[],replaceHeaders:!0,signingSecret:``,timeoutMs:``,url:``,version:`1`};function g(){let[e,u]=(0,r.useState)(null),[d,f]=(0,r.useState)([]),[p,m]=(0,r.useState)(!0),[g,S]=(0,r.useState)(null),[w,T]=(0,r.useState)(null),[E,D]=(0,r.useState)(null),[O,k]=(0,r.useState)(!1),[A,j]=(0,r.useState)(null),[M,N]=(0,r.useState)(``),[P,F]=(0,r.useState)(!1),[I,L]=(0,r.useState)(null),R=(0,r.useCallback)(async()=>{m(!0);try{let e=await(0,c.readWorkflowWebhookEndpointManagement)();u(e),f(e.enabled?await(0,c.listWorkflowWebhookManagedEndpoints)():[]),S(null)}catch(e){S(C(e))}finally{m(!1)}},[]);(0,r.useEffect)(()=>{R()},[R]);let z=(0,r.useCallback)(async e=>{S(null),T(null);try{return T(await e()),await R(),!0}catch(e){return S(C(e)),!1}},[R]),B=(0,r.useMemo)(()=>d.map(e=>({endpoint:e,key:e.id})),[d]),V=(0,r.useMemo)(()=>[{key:`label`,render:({endpoint:e})=>(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.label}),(0,a.jsxs)(i.Typography,{color:`text-neutral`,component:`span`,variant:`caption`,children:[e.key,`@`,e.version,` · 參數`,` `,e.parameters.length,` 個`]})]}),title:`端點`,width:240},{key:`url`,render:({endpoint:e})=>(0,a.jsxs)(i.Typography,{component:`span`,variant:`body`,children:[e.method,` `,e.url]}),title:`URL`,width:320},{key:`status`,render:({endpoint:e})=>e.active?e.deprecated?(0,a.jsx)(i.Badge,{size:`sub`,text:`不建議使用`,variant:`dot-warning`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`啟用中`,variant:`dot-success`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`已停用`,variant:`dot-inactive`}),title:`狀態`,width:120},{key:`credentials`,render:({endpoint:e})=>(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.hasSigningSecret?`已設定簽章金鑰`:`未簽章`}),(0,a.jsx)(i.Typography,{color:`text-neutral`,component:`span`,variant:`caption`,children:e.headerNames.length?`Header:${e.headerNames.join(`、`)}`:`沒有自訂 header`})]}),title:`憑證`,width:200},{key:`updatedAt`,render:({endpoint:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:t.t(e.updatedAt)}),title:`更新時間`,width:180}],[]),H=(0,r.useMemo)(()=>({render:({endpoint:e})=>[{name:`編輯`,onClick:()=>D(y(e,`edit`))},{name:`建立新版本`,onClick:()=>D(y(e,`version`))},{name:`測試送出`,onClick:()=>{z(async()=>b(e,await(0,c.testWorkflowWebhookEndpoint)(e.id)))}},{name:`輪替金鑰`,onClick:()=>{N(``),F(!1),j(e)}},{name:e.active?`停用`:`啟用`,onClick:()=>{z(async()=>(await(0,c.setWorkflowWebhookEndpointActive)(e.id,!e.active),`已${e.active?`停用`:`啟用`}「${e.label}」。`))}},{name:`異動紀錄`,onClick:()=>{(0,c.listWorkflowWebhookEndpointAudits)(e.id).then(t=>L({endpoint:e,records:t})).catch(e=>S(C(e)))}}],variant:`base-secondary`,width:180}),[z]);async function U(){if(!E)return;k(!0);let e=await z(async()=>{let e=E.parameters.map(e=>({description:e.description.trim()||null,key:e.key.trim(),label:e.label.trim(),required:e.required,type:e.type})),t=E.headers.filter(e=>e.name.trim()).map(e=>({name:e.name.trim(),value:e.value})),n=E.timeoutMs.trim()?Number(E.timeoutMs):null;return E.mode===`edit`&&E.endpointId?(await(0,c.updateWorkflowWebhookEndpoint)({deprecated:E.deprecated,description:E.description,headers:E.replaceHeaders||x(E)?t:null,id:E.endpointId,label:E.label,method:E.method,parameters:e,timeoutMs:n,url:E.url}),`已更新「${E.label}」。`):(await(0,c.createWorkflowWebhookEndpoint)({deprecated:E.deprecated,description:E.description,headers:t,key:E.key,label:E.label,method:E.method,parameters:e,signingSecret:E.signingSecret||null,timeoutMs:n,url:E.url,version:Number(E.version)}),`已建立「${E.label}」v${E.version},設計器現在可以選用。`)});k(!1),e&&D(null)}async function W(){if(!A)return;let e=A;await z(async()=>(await(0,c.rotateWorkflowWebhookEndpointSecret)(e.id,P?null:M),P?`已移除「${e.label}」的簽章金鑰,之後的請求不再簽章。`:`已輪替「${e.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`))&&(j(null),N(``))}let G=!!e?.enabled;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.PageHeader,{children:(0,a.jsx)(o.default,{description:`維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。`,title:`Webhook 端點`,children:(0,a.jsx)(i.Button,{disabled:!G,icon:s.PlusIcon,iconType:`leading`,onClick:()=>D(h),variant:`base-primary`,children:`新增端點`})})}),(0,a.jsx)(i.SectionGroup,{children:(0,a.jsx)(i.Section,{children:(0,a.jsxs)(`div`,{style:l,children:[g?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:g}):null,w?(0,a.jsx)(i.Typography,{color:`text-success`,variant:`body`,children:w}):null,e&&!G?(0,a.jsx)(i.Typography,{color:`text-warning`,variant:`body`,children:`此伺服器未啟用後台維護的 Webhook 端點:需要設定 workflowWebhookTargetSources 含 DATABASE、URL 白名單與加密金鑰。程式註冊的端點不受影響。`}):null,G?(0,a.jsxs)(i.Typography,{color:`text-neutral`,variant:`caption`,children:[`允許的 URL:`,e?.allowedUrlPatterns.join(`、`)]}):null,(0,a.jsx)(i.Table,{actions:H,columns:V,dataSource:B,fullWidth:!0,loading:p})]})})}),E?(0,a.jsx)(v,{draft:E,onCancel:()=>D(null),onChange:D,onConfirm:()=>void U(),saving:O}):null,(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!P&&!M},confirmText:P?`移除金鑰`:`輪替金鑰`,modalType:`standard`,onCancel:()=>j(null),onClose:()=>j(null),onConfirm:()=>void W(),open:!!A,showModalFooter:!0,showModalHeader:!0,supportingText:`新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。`,title:`輪替簽章金鑰:${A?.label??``}`,children:(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(n.t,{label:`移除金鑰`,name:`removeSigningSecret`,children:(0,a.jsx)(i.Toggle,{checked:P,onChange:e=>F(e.target.checked)})}),P?null:(0,a.jsx)(n.t,{label:`新金鑰`,name:`nextSigningSecret`,required:!0,children:(0,a.jsx)(i.Input,{onChange:e=>N(e.target.value),value:M,inputProps:{autoComplete:`new-password`},variant:`password`})})]})}),(0,a.jsx)(i.Modal,{confirmText:`關閉`,modalType:`standard`,onClose:()=>L(null),onConfirm:()=>L(null),open:!!I,showModalFooter:!0,showModalHeader:!0,size:`wide`,supportingText:`只記錄誰在何時變更了哪些欄位,不記錄任何值。`,title:`異動紀錄:${I?.endpoint.label??``}`,children:(0,a.jsx)(i.Table,{columns:_,dataSource:(I?.records??[]).map(e=>({audit:e,key:e.id})),fullWidth:!0})})]})}var _=[{key:`createdAt`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:t.t(e.createdAt)}),title:`時間`,width:180},{key:`action`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:m[e.action]}),title:`動作`,width:120},{key:`changedFields`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.changedFields.join(`、`)||`—`}),title:`欄位`,width:280},{key:`actor`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.actorMemberId??`系統`}),title:`操作者`,width:160}];function v({draft:e,onCancel:t,onChange:r,onConfirm:o,saving:c}){let m=e.mode===`edit`,h=x(e),g=e.replaceHeaders||h,_=t=>r({...e,...t}),v=(t,n)=>_({parameters:e.parameters.map((e,r)=>r===t?{...e,...n}:e)}),y=(t,n)=>_({headers:e.headers.map((e,r)=>r===t?{...e,...n}:e)}),b=e=>t=>_({[e]:t.target.value});return(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmText:m?`儲存`:`建立`,loading:c,modalType:`standard`,onCancel:t,onClose:t,onConfirm:o,open:!0,showModalFooter:!0,showModalHeader:!0,size:`wide`,supportingText:m?`參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。`:e.mode===`version`?`新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。`:`URL 需符合伺服器設定的白名單。`,title:m?`編輯端點:${e.label}`:e.mode===`version`?`建立新版本:${e.key}`:`新增 Webhook 端點`,children:(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(n.t,{label:`Key`,name:`endpointKey`,required:!0,children:(0,a.jsx)(i.Input,{...e.mode===`create`?{}:{readonly:!0},onChange:b(`key`),placeholder:`例如 crm.lead-created`,value:e.key,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(n.t,{label:`版本`,name:`endpointVersion`,required:!0,children:(0,a.jsx)(i.Input,{...m?{readonly:!0}:{},inputProps:{autoComplete:`off`,inputMode:`numeric`},onChange:b(`version`),value:e.version,variant:`base`})}),(0,a.jsx)(n.t,{label:`名稱`,name:`endpointLabel`,required:!0,children:(0,a.jsx)(i.Input,{onChange:b(`label`),placeholder:`例如 CRM 建立名單`,value:e.label,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(n.t,{label:`說明`,name:`endpointDescription`,children:(0,a.jsx)(i.Textarea,{onChange:b(`description`),rows:2,value:e.description})}),(0,a.jsx)(n.t,{label:`URL`,name:`endpointUrl`,required:!0,children:(0,a.jsx)(i.Input,{onChange:b(`url`),placeholder:`https://`,value:e.url,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(n.t,{label:`Method`,name:`endpointMethod`,required:!0,children:(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>_({method:e?.id??`POST`}),options:[...f],value:f.find(t=>t.id===e.method)??null})}),(0,a.jsx)(n.t,{hintText:`留空使用預設 10 秒,上限 30000 毫秒。`,label:`逾時(毫秒)`,name:`endpointTimeout`,children:(0,a.jsx)(i.Input,{inputProps:{autoComplete:`off`,inputMode:`numeric`},onChange:b(`timeoutMs`),value:e.timeoutMs,variant:`base`})}),(0,a.jsx)(n.t,{label:`不建議使用`,name:`endpointDeprecated`,children:(0,a.jsx)(i.Toggle,{checked:e.deprecated,onChange:e=>_({deprecated:e.target.checked})})}),m?null:(0,a.jsx)(n.t,{hintText:`選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。`,label:`簽章金鑰`,name:`endpointSigningSecret`,children:(0,a.jsx)(i.Input,{onChange:b(`signingSecret`),placeholder:`選填,儲存後不再顯示`,value:e.signingSecret,inputProps:{autoComplete:`new-password`},variant:`password`})}),(0,a.jsx)(i.Typography,{variant:`label-primary-highlight`,children:`Headers`}),m?(0,a.jsx)(n.t,{hintText:h?`URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。`:`現有 header 的值不會顯示;開啟後以下列內容取代全部 header。`,label:`取代 headers`,name:`endpointReplaceHeaders`,children:(0,a.jsx)(i.Toggle,{checked:g,disabled:h,onChange:e=>_({replaceHeaders:e.target.checked})})}):null,g?e.headers.map((t,n)=>(0,a.jsxs)(`div`,{style:d,children:[(0,a.jsx)(i.Input,{onChange:e=>y(n,{name:e.target.value}),placeholder:`名稱,例如 Authorization`,inputProps:{autoComplete:`off`},value:t.name,variant:`base`}),(0,a.jsx)(i.Input,{onChange:e=>y(n,{value:e.target.value}),placeholder:`值`,value:t.value,inputProps:{autoComplete:`new-password`},variant:`password`}),(0,a.jsx)(i.Button,{icon:s.TrashIcon,iconType:`icon-only`,onClick:()=>_({headers:e.headers.filter((e,t)=>t!==n)}),variant:`destructive-text-link`,children:`移除 header`})]},n)):null,g?(0,a.jsx)(`div`,{children:(0,a.jsx)(i.Button,{icon:s.PlusIcon,iconType:`leading`,onClick:()=>_({headers:[...e.headers,{name:``,value:``}]}),variant:`base-dashed`,children:`新增 header`})}):null,(0,a.jsx)(i.Typography,{variant:`label-primary-highlight`,children:`參數`}),e.parameters.map((t,n)=>(0,a.jsxs)(`div`,{style:u,children:[(0,a.jsx)(i.Input,{...m?{readonly:!0}:{},onChange:e=>v(n,{key:e.target.value}),placeholder:`參數鍵`,inputProps:{autoComplete:`off`},value:t.key,variant:`base`}),(0,a.jsx)(i.Input,{onChange:e=>v(n,{label:e.target.value}),placeholder:`顯示名稱`,inputProps:{autoComplete:`off`},value:t.label,variant:`base`}),(0,a.jsx)(i.Select,{clearable:!1,disabled:m,onChange:e=>v(n,{type:S(e?.id??null)}),options:[...p],value:p.find(e=>e.id===t.type)??null}),(0,a.jsx)(i.Toggle,{checked:t.required,disabled:m,label:`必填`,onChange:e=>v(n,{required:e.target.checked})}),(0,a.jsx)(i.Button,{disabled:m,icon:s.TrashIcon,iconType:`icon-only`,onClick:()=>_({parameters:e.parameters.filter((e,t)=>t!==n)}),variant:`destructive-text-link`,children:`移除參數`})]},n)),m?null:(0,a.jsx)(`div`,{children:(0,a.jsx)(i.Button,{icon:s.PlusIcon,iconType:`leading`,onClick:()=>_({parameters:[...e.parameters,{description:``,key:``,label:``,required:!1,type:`string`}]}),variant:`base-dashed`,children:`新增參數`})})]})})}function y(e,t){return{deprecated:e.deprecated,description:e.description??``,endpointId:t===`edit`?e.id:null,headers:[],key:e.key,label:e.label,method:e.method,mode:t,originalUrl:e.url,parameters:e.parameters.map(e=>({description:e.description??``,key:e.key,label:e.label,required:e.required,type:e.type})),replaceHeaders:t===`version`,signingSecret:``,timeoutMs:e.timeoutMs?String(e.timeoutMs):``,url:e.url,version:String(t===`version`?e.version+1:e.version)}}function b(e,t){if(t.ok)return`測試送出成功:「${e.label}」回應 HTTP ${t.status??``}。`;throw Error(`測試送出失敗:「${e.label}」${t.status?`回應 HTTP ${t.status}`:``}(${t.errorCode??`未知錯誤`})${t.errorDetail?`:${t.errorDetail}`:``}`)}function x(e){if(e.mode!==`edit`)return!1;let t=e=>{try{return new URL(e.trim()).origin}catch{return e.trim()}};return t(e.url)!==t(e.originalUrl)}function S(e){return p.some(t=>t.id===e)?e:`string`}function C(e){if(!(e instanceof Error))return`發生未知錯誤`;let t=e.message;return t.includes(`WORKFLOW_WEBHOOK_URL_NOT_ALLOWED`)?`URL 不在伺服器允許的白名單內。`:t.includes(`WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT`)?`這個 Key 已由程式註冊的端點使用,請換一個。`:t.includes(`WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED`)?`參數契約不能修改,請改用「建立新版本」。`:t.includes(`WORKFLOW_WEBHOOK_TEST_RATE_LIMITED`)?`測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。`:t}exports.AdminWebhookEndpointsView=g;
1
+ "use client";Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("../../../chunks/rolldown-runtime-BocRIvOZ.cjs"),t=require("../../../chunks/bpm-form-field-Bc6k4ZEO.cjs"),n=require("../../../chunks/format-date-time-D-cx5M8z.cjs");let r=require("react"),i=require("@mezzanine-ui/react"),a=require("react/jsx-runtime"),o=require("@mezzanine-ui/react/ContentHeader");o=e.t(o,1);let s=require("@mezzanine-ui/icons"),c=require("@rytass/bpm-core-client/template");var l={display:`grid`,gap:`var(--mzn-spacing-gap-base)`},u={alignItems:`center`,display:`grid`,gap:`var(--mzn-spacing-gap-base)`,gridTemplateColumns:`minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto`},d={alignItems:`center`,display:`grid`,gap:`var(--mzn-spacing-gap-base)`,gridTemplateColumns:`minmax(0, 1fr) minmax(0, 2fr) auto`},f=[{id:`POST`,name:`POST`},{id:`PUT`,name:`PUT`},{id:`PATCH`,name:`PATCH`}],p=[{id:`string`,name:`文字`},{id:`number`,name:`數字`},{id:`boolean`,name:`是/否`},{id:`stringArray`,name:`文字清單`},{id:`json`,name:`JSON`}],m={CREATED:`建立`,DISABLED:`停用`,ENABLED:`啟用`,SECRET_ROTATED:`輪替金鑰`,TEST_SENT:`測試送出`,UPDATED:`更新`},h={deprecated:!1,description:``,endpointId:null,headers:[],key:``,label:``,method:`POST`,mode:`create`,originalUrl:``,parameters:[],replaceHeaders:!0,signingSecret:``,timeoutMs:``,url:``,version:`1`};function g(){let[e,u]=(0,r.useState)(null),[d,f]=(0,r.useState)([]),[p,m]=(0,r.useState)(!0),[g,S]=(0,r.useState)(null),[w,T]=(0,r.useState)(null),[E,D]=(0,r.useState)(null),[O,k]=(0,r.useState)(!1),[A,j]=(0,r.useState)(null),[M,N]=(0,r.useState)(``),[P,F]=(0,r.useState)(!1),[I,L]=(0,r.useState)(null),R=(0,r.useCallback)(async()=>{m(!0);try{let e=await(0,c.readWorkflowWebhookEndpointManagement)();u(e),f(e.enabled?await(0,c.listWorkflowWebhookManagedEndpoints)():[]),S(null)}catch(e){S(C(e))}finally{m(!1)}},[]);(0,r.useEffect)(()=>{R()},[R]);let z=(0,r.useCallback)(async e=>{S(null),T(null);try{return T(await e()),await R(),!0}catch(e){return S(C(e)),!1}},[R]),B=(0,r.useMemo)(()=>d.map(e=>({endpoint:e,key:e.id})),[d]),V=(0,r.useMemo)(()=>[{key:`label`,render:({endpoint:e})=>(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.label}),(0,a.jsxs)(i.Typography,{color:`text-neutral`,component:`span`,variant:`caption`,children:[e.key,`@`,e.version,` · 參數`,` `,e.parameters.length,` 個`]})]}),title:`端點`,width:240},{key:`url`,render:({endpoint:e})=>(0,a.jsxs)(i.Typography,{component:`span`,variant:`body`,children:[e.method,` `,e.url]}),title:`URL`,width:320},{key:`status`,render:({endpoint:e})=>e.active?e.deprecated?(0,a.jsx)(i.Badge,{size:`sub`,text:`不建議使用`,variant:`dot-warning`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`啟用中`,variant:`dot-success`}):(0,a.jsx)(i.Badge,{size:`sub`,text:`已停用`,variant:`dot-inactive`}),title:`狀態`,width:120},{key:`credentials`,render:({endpoint:e})=>(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.hasSigningSecret?`已設定簽章金鑰`:`未簽章`}),(0,a.jsx)(i.Typography,{color:`text-neutral`,component:`span`,variant:`caption`,children:e.headerNames.length?`Header:${e.headerNames.join(`、`)}`:`沒有自訂 header`})]}),title:`憑證`,width:200},{key:`updatedAt`,render:({endpoint:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:n.t(e.updatedAt)}),title:`更新時間`,width:180}],[]),H=(0,r.useMemo)(()=>({render:({endpoint:e})=>[{name:`編輯`,onClick:()=>D(y(e,`edit`))},{name:`建立新版本`,onClick:()=>D(y(e,`version`))},{name:`測試送出`,onClick:()=>{z(async()=>b(e,await(0,c.testWorkflowWebhookEndpoint)(e.id)))}},{name:`輪替金鑰`,onClick:()=>{N(``),F(!1),j(e)}},{name:e.active?`停用`:`啟用`,onClick:()=>{z(async()=>(await(0,c.setWorkflowWebhookEndpointActive)(e.id,!e.active),`已${e.active?`停用`:`啟用`}「${e.label}」。`))}},{name:`異動紀錄`,onClick:()=>{(0,c.listWorkflowWebhookEndpointAudits)(e.id).then(t=>L({endpoint:e,records:t})).catch(e=>S(C(e)))}}],variant:`base-secondary`,width:180}),[z]);async function U(){if(!E)return;k(!0);let e=await z(async()=>{let e=E.parameters.map(e=>({description:e.description.trim()||null,key:e.key.trim(),label:e.label.trim(),required:e.required,type:e.type})),t=E.headers.filter(e=>e.name.trim()).map(e=>({name:e.name.trim(),value:e.value})),n=E.timeoutMs.trim()?Number(E.timeoutMs):null;return E.mode===`edit`&&E.endpointId?(await(0,c.updateWorkflowWebhookEndpoint)({deprecated:E.deprecated,description:E.description,headers:E.replaceHeaders||x(E)?t:null,id:E.endpointId,label:E.label,method:E.method,parameters:e,timeoutMs:n,url:E.url}),`已更新「${E.label}」。`):(await(0,c.createWorkflowWebhookEndpoint)({deprecated:E.deprecated,description:E.description,headers:t,key:E.key,label:E.label,method:E.method,parameters:e,signingSecret:E.signingSecret||null,timeoutMs:n,url:E.url,version:Number(E.version)}),`已建立「${E.label}」v${E.version},設計器現在可以選用。`)});k(!1),e&&D(null)}async function W(){if(!A)return;let e=A;await z(async()=>(await(0,c.rotateWorkflowWebhookEndpointSecret)(e.id,P?null:M),P?`已移除「${e.label}」的簽章金鑰,之後的請求不再簽章。`:`已輪替「${e.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`))&&(j(null),N(``))}let G=!!e?.enabled;return(0,a.jsxs)(a.Fragment,{children:[(0,a.jsx)(i.PageHeader,{children:(0,a.jsx)(o.default,{description:`維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。`,title:`Webhook 端點`,children:(0,a.jsx)(i.Button,{disabled:!G,icon:s.PlusIcon,iconType:`leading`,onClick:()=>D(h),variant:`base-primary`,children:`新增端點`})})}),(0,a.jsx)(i.SectionGroup,{children:(0,a.jsx)(i.Section,{children:(0,a.jsxs)(`div`,{style:l,children:[g?(0,a.jsx)(i.Typography,{color:`text-error`,variant:`body`,children:g}):null,w?(0,a.jsx)(i.Typography,{color:`text-success`,variant:`body`,children:w}):null,e&&!G?(0,a.jsx)(i.Typography,{color:`text-warning`,variant:`body`,children:`此伺服器未啟用後台維護的 Webhook 端點:需要設定 workflowWebhookTargetSources 含 DATABASE、URL 白名單與加密金鑰。程式註冊的端點不受影響。`}):null,G?(0,a.jsxs)(i.Typography,{color:`text-neutral`,variant:`caption`,children:[`允許的 URL:`,e?.allowedUrlPatterns.join(`、`)]}):null,(0,a.jsx)(i.Table,{actions:H,columns:V,dataSource:B,fullWidth:!0,loading:p})]})})}),E?(0,a.jsx)(v,{draft:E,onCancel:()=>D(null),onChange:D,onConfirm:()=>void U(),saving:O}):null,(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmButtonProps:{disabled:!P&&!M},confirmText:P?`移除金鑰`:`輪替金鑰`,modalType:`standard`,onCancel:()=>j(null),onClose:()=>j(null),onConfirm:()=>void W(),open:!!A,showModalFooter:!0,showModalHeader:!0,supportingText:`新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。`,title:`輪替簽章金鑰:${A?.label??``}`,children:(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(t.t,{label:`移除金鑰`,name:`removeSigningSecret`,children:(0,a.jsx)(i.Toggle,{checked:P,onChange:e=>F(e.target.checked)})}),P?null:(0,a.jsx)(t.t,{label:`新金鑰`,name:`nextSigningSecret`,required:!0,children:(0,a.jsx)(i.Input,{onChange:e=>N(e.target.value),value:M,inputProps:{autoComplete:`new-password`},variant:`password`})})]})}),(0,a.jsx)(i.Modal,{confirmText:`關閉`,modalType:`standard`,onClose:()=>L(null),onConfirm:()=>L(null),open:!!I,showModalFooter:!0,showModalHeader:!0,size:`wide`,supportingText:`只記錄誰在何時變更了哪些欄位,不記錄任何值。`,title:`異動紀錄:${I?.endpoint.label??``}`,children:(0,a.jsx)(i.Table,{columns:_,dataSource:(I?.records??[]).map(e=>({audit:e,key:e.id})),fullWidth:!0})})]})}var _=[{key:`createdAt`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:n.t(e.createdAt)}),title:`時間`,width:180},{key:`action`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:m[e.action]}),title:`動作`,width:120},{key:`changedFields`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.changedFields.join(`、`)||`—`}),title:`欄位`,width:280},{key:`actor`,render:({audit:e})=>(0,a.jsx)(i.Typography,{component:`span`,variant:`body`,children:e.actorMemberId??`系統`}),title:`操作者`,width:160}];function v({draft:e,onCancel:n,onChange:r,onConfirm:o,saving:c}){let m=e.mode===`edit`,h=x(e),g=e.replaceHeaders||h,_=t=>r({...e,...t}),v=(t,n)=>_({parameters:e.parameters.map((e,r)=>r===t?{...e,...n}:e)}),y=(t,n)=>_({headers:e.headers.map((e,r)=>r===t?{...e,...n}:e)}),b=e=>t=>_({[e]:t.target.value});return(0,a.jsx)(i.Modal,{cancelText:`取消`,confirmText:m?`儲存`:`建立`,loading:c,modalType:`standard`,onCancel:n,onClose:n,onConfirm:o,open:!0,showModalFooter:!0,showModalHeader:!0,size:`wide`,supportingText:m?`參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。`:e.mode===`version`?`新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。`:`URL 需符合伺服器設定的白名單。`,title:m?`編輯端點:${e.label}`:e.mode===`version`?`建立新版本:${e.key}`:`新增 Webhook 端點`,children:(0,a.jsxs)(`div`,{style:l,children:[(0,a.jsx)(t.t,{label:`Key`,name:`endpointKey`,required:!0,children:(0,a.jsx)(i.Input,{...e.mode===`create`?{}:{readonly:!0},onChange:b(`key`),placeholder:`例如 crm.lead-created`,value:e.key,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(t.t,{label:`版本`,name:`endpointVersion`,required:!0,children:(0,a.jsx)(i.Input,{...m?{readonly:!0}:{},inputProps:{autoComplete:`off`,inputMode:`numeric`},onChange:b(`version`),value:e.version,variant:`base`})}),(0,a.jsx)(t.t,{label:`名稱`,name:`endpointLabel`,required:!0,children:(0,a.jsx)(i.Input,{onChange:b(`label`),placeholder:`例如 CRM 建立名單`,value:e.label,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(t.t,{label:`說明`,name:`endpointDescription`,children:(0,a.jsx)(i.Textarea,{onChange:b(`description`),rows:2,value:e.description})}),(0,a.jsx)(t.t,{label:`URL`,name:`endpointUrl`,required:!0,children:(0,a.jsx)(i.Input,{onChange:b(`url`),placeholder:`https://`,value:e.url,inputProps:{autoComplete:`off`},variant:`base`})}),(0,a.jsx)(t.t,{label:`Method`,name:`endpointMethod`,required:!0,children:(0,a.jsx)(i.Select,{clearable:!1,onChange:e=>_({method:e?.id??`POST`}),options:[...f],value:f.find(t=>t.id===e.method)??null})}),(0,a.jsx)(t.t,{hintText:`留空使用預設 10 秒,上限 30000 毫秒。`,label:`逾時(毫秒)`,name:`endpointTimeout`,children:(0,a.jsx)(i.Input,{inputProps:{autoComplete:`off`,inputMode:`numeric`},onChange:b(`timeoutMs`),value:e.timeoutMs,variant:`base`})}),(0,a.jsx)(t.t,{label:`不建議使用`,name:`endpointDeprecated`,children:(0,a.jsx)(i.Toggle,{checked:e.deprecated,onChange:e=>_({deprecated:e.target.checked})})}),m?null:(0,a.jsx)(t.t,{hintText:`選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。`,label:`簽章金鑰`,name:`endpointSigningSecret`,children:(0,a.jsx)(i.Input,{onChange:b(`signingSecret`),placeholder:`選填,儲存後不再顯示`,value:e.signingSecret,inputProps:{autoComplete:`new-password`},variant:`password`})}),(0,a.jsx)(i.Typography,{variant:`label-primary-highlight`,children:`Headers`}),m?(0,a.jsx)(t.t,{hintText:h?`URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。`:`現有 header 的值不會顯示;開啟後以下列內容取代全部 header。`,label:`取代 headers`,name:`endpointReplaceHeaders`,children:(0,a.jsx)(i.Toggle,{checked:g,disabled:h,onChange:e=>_({replaceHeaders:e.target.checked})})}):null,g?e.headers.map((t,n)=>(0,a.jsxs)(`div`,{style:d,children:[(0,a.jsx)(i.Input,{onChange:e=>y(n,{name:e.target.value}),placeholder:`名稱,例如 Authorization`,inputProps:{autoComplete:`off`},value:t.name,variant:`base`}),(0,a.jsx)(i.Input,{onChange:e=>y(n,{value:e.target.value}),placeholder:`值`,value:t.value,inputProps:{autoComplete:`new-password`},variant:`password`}),(0,a.jsx)(i.Button,{icon:s.TrashIcon,iconType:`icon-only`,onClick:()=>_({headers:e.headers.filter((e,t)=>t!==n)}),variant:`destructive-text-link`,children:`移除 header`})]},n)):null,g?(0,a.jsx)(`div`,{children:(0,a.jsx)(i.Button,{icon:s.PlusIcon,iconType:`leading`,onClick:()=>_({headers:[...e.headers,{name:``,value:``}]}),variant:`base-dashed`,children:`新增 header`})}):null,(0,a.jsx)(i.Typography,{variant:`label-primary-highlight`,children:`參數`}),e.parameters.map((t,n)=>(0,a.jsxs)(`div`,{style:u,children:[(0,a.jsx)(i.Input,{...m?{readonly:!0}:{},onChange:e=>v(n,{key:e.target.value}),placeholder:`參數鍵`,inputProps:{autoComplete:`off`},value:t.key,variant:`base`}),(0,a.jsx)(i.Input,{onChange:e=>v(n,{label:e.target.value}),placeholder:`顯示名稱`,inputProps:{autoComplete:`off`},value:t.label,variant:`base`}),(0,a.jsx)(i.Select,{clearable:!1,disabled:m,onChange:e=>v(n,{type:S(e?.id??null)}),options:[...p],value:p.find(e=>e.id===t.type)??null}),(0,a.jsx)(i.Toggle,{checked:t.required,disabled:m,label:`必填`,onChange:e=>v(n,{required:e.target.checked})}),(0,a.jsx)(i.Button,{disabled:m,icon:s.TrashIcon,iconType:`icon-only`,onClick:()=>_({parameters:e.parameters.filter((e,t)=>t!==n)}),variant:`destructive-text-link`,children:`移除參數`})]},n)),m?null:(0,a.jsx)(`div`,{children:(0,a.jsx)(i.Button,{icon:s.PlusIcon,iconType:`leading`,onClick:()=>_({parameters:[...e.parameters,{description:``,key:``,label:``,required:!1,type:`string`}]}),variant:`base-dashed`,children:`新增參數`})})]})})}function y(e,t){return{deprecated:e.deprecated,description:e.description??``,endpointId:t===`edit`?e.id:null,headers:[],key:e.key,label:e.label,method:e.method,mode:t,originalUrl:e.url,parameters:e.parameters.map(e=>({description:e.description??``,key:e.key,label:e.label,required:e.required,type:e.type})),replaceHeaders:t===`version`,signingSecret:``,timeoutMs:e.timeoutMs?String(e.timeoutMs):``,url:e.url,version:String(t===`version`?e.version+1:e.version)}}function b(e,t){if(t.ok)return`測試送出成功:「${e.label}」回應 HTTP ${t.status??``}。`;throw Error(`測試送出失敗:「${e.label}」${t.status?`回應 HTTP ${t.status}`:``}(${t.errorCode??`未知錯誤`})${t.errorDetail?`:${t.errorDetail}`:``}`)}function x(e){if(e.mode!==`edit`)return!1;let t=e=>{try{return new URL(e.trim()).origin}catch{return e.trim()}};return t(e.url)!==t(e.originalUrl)}function S(e){return p.some(t=>t.id===e)?e:`string`}function C(e){if(!(e instanceof Error))return`發生未知錯誤`;let t=e.message;return t.includes(`WORKFLOW_WEBHOOK_URL_NOT_ALLOWED`)?`URL 不在伺服器允許的白名單內。`:t.includes(`WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT`)?`這個 Key 已由程式註冊的端點使用,請換一個。`:t.includes(`WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED`)?`參數契約不能修改,請改用「建立新版本」。`:t.includes(`WORKFLOW_WEBHOOK_TEST_RATE_LIMITED`)?`測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。`:t}exports.AdminWebhookEndpointsView=g;
2
2
  //# sourceMappingURL=index.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.cjs","names":["useState","useCallback","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","useMemo","Typography","Badge","formatDateTime","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","listWorkflowWebhookEndpointAudits","updateWorkflowWebhookEndpoint","createWorkflowWebhookEndpoint","rotateWorkflowWebhookEndpointSecret","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Table","Modal","BPMFormField","Toggle","Input","Textarea","Select","TrashIcon","require_rolldown_runtime","require_format_date_time","require_bpm_form_field","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","nextManagement","requestError","readErrorMessage","run","work","rows","endpoint","columns","actions","readEditDraft","readTestNotice","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","isOriginChanged","handleRotate","enabled","EndpointDraftModal","event","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","option","readParameterType","mode","result","origin","url","id","message"],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.cjs","names":["useState","useCallback","readWorkflowWebhookEndpointManagement","listWorkflowWebhookManagedEndpoints","useMemo","Typography","Badge","formatDateTime","testWorkflowWebhookEndpoint","setWorkflowWebhookEndpointActive","listWorkflowWebhookEndpointAudits","updateWorkflowWebhookEndpoint","createWorkflowWebhookEndpoint","rotateWorkflowWebhookEndpointSecret","_Fragment","PageHeader","ContentHeader","Button","PlusIcon","SectionGroup","Section","Table","Modal","BPMFormField","Toggle","Input","Textarea","Select","TrashIcon","require_rolldown_runtime","require_bpm_form_field","require_format_date_time","react","_mezzanine_ui_react","react_jsx_runtime","_mezzanine_ui_react_ContentHeader","_mezzanine_ui_icons","_rytass_bpm_core_client_template","STACK_STYLE","ROW_STYLE","HEADER_ROW_STYLE","METHOD_OPTIONS","PARAMETER_TYPE_OPTIONS","AUDIT_ACTION_LABELS","EMPTY_DRAFT","AdminWebhookEndpointsView","management","setManagement","endpoints","setEndpoints","loading","setLoading","error","setError","notice","setNotice","draft","setDraft","saving","setSaving","rotating","setRotating","nextSecret","setNextSecret","removeSecret","setRemoveSecret","audits","setAudits","refresh","nextManagement","requestError","readErrorMessage","run","work","rows","endpoint","columns","actions","readEditDraft","readTestNotice","handleSaveDraft","saved","parameters","parameter","headers","header","timeoutMs","isOriginChanged","handleRotate","enabled","EndpointDraftModal","event","AUDIT_COLUMNS","audit","editing","originChanged","replaceHeaders","update","onChange","patch","updateParameter","current","index","updateHeader","text","field","onCancel","option","readParameterType","mode","result","origin","url","id","message"],"sources":["../../../../src/views/admin/webhook-endpoints/AdminWebhookEndpointsView.tsx"],"sourcesContent":["'use client';\n\nimport {\n ChangeEvent,\n CSSProperties,\n ReactElement,\n useCallback,\n useEffect,\n useMemo,\n useState,\n} from 'react';\nimport {\n Badge,\n Button,\n Input,\n Modal,\n PageHeader,\n Section,\n SectionGroup,\n Select,\n Table,\n Textarea,\n Toggle,\n Typography,\n} from '@mezzanine-ui/react';\nimport ContentHeader from '@mezzanine-ui/react/ContentHeader';\nimport { PlusIcon, TrashIcon } from '@mezzanine-ui/icons';\nimport type { TableActions, TableColumn } from '@mezzanine-ui/core/table';\nimport { NotifyWebhookParameterType } from '@rytass/bpm-core-shared/workflow';\nimport {\n WorkflowWebhookEndpointAuditRecord,\n WorkflowWebhookEndpointManagementRecord,\n WorkflowWebhookEndpointTestResultRecord,\n WorkflowWebhookManagedEndpointRecord,\n createWorkflowWebhookEndpoint,\n listWorkflowWebhookEndpointAudits,\n listWorkflowWebhookManagedEndpoints,\n readWorkflowWebhookEndpointManagement,\n rotateWorkflowWebhookEndpointSecret,\n setWorkflowWebhookEndpointActive,\n testWorkflowWebhookEndpoint,\n updateWorkflowWebhookEndpoint,\n} from '@rytass/bpm-core-client/template';\nimport { BPMFormField } from '../../../components/bpm-form-field';\nimport { formatDateTime } from '../../../lib/format-date-time';\n\ntype SelectOption = Readonly<{ id: string; name: string }>;\n\ntype EndpointRow = Readonly<\n Record<string, unknown> & {\n endpoint: WorkflowWebhookManagedEndpointRecord;\n key: string;\n }\n>;\n\ntype AuditRow = Readonly<\n Record<string, unknown> & {\n audit: WorkflowWebhookEndpointAuditRecord;\n key: string;\n }\n>;\n\ntype ParameterDraft = Readonly<{\n description: string;\n key: string;\n label: string;\n required: boolean;\n type: NotifyWebhookParameterType;\n}>;\n\ntype HeaderDraft = Readonly<{ name: string; value: string }>;\n\n/**\n * `mode` decides what can change: a new endpoint (or a new version of one)\n * sets everything; editing keeps the parameter contract and only replaces\n * headers when asked to.\n */\ntype EndpointDraft = Readonly<{\n deprecated: boolean;\n description: string;\n endpointId: string | null;\n headers: readonly HeaderDraft[];\n key: string;\n label: string;\n method: string;\n mode: 'create' | 'edit' | 'version';\n /** The stored URL when editing, to spot a move to another host. */\n originalUrl: string;\n parameters: readonly ParameterDraft[];\n replaceHeaders: boolean;\n signingSecret: string;\n timeoutMs: string;\n url: string;\n version: string;\n}>;\n\nconst STACK_STYLE: CSSProperties = {\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n};\n\nconst ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 1fr) minmax(0, 1fr) auto auto',\n};\n\nconst HEADER_ROW_STYLE: CSSProperties = {\n alignItems: 'center',\n display: 'grid',\n gap: 'var(--mzn-spacing-gap-base)',\n gridTemplateColumns: 'minmax(0, 1fr) minmax(0, 2fr) auto',\n};\n\nconst METHOD_OPTIONS: readonly SelectOption[] = [\n { id: 'POST', name: 'POST' },\n { id: 'PUT', name: 'PUT' },\n { id: 'PATCH', name: 'PATCH' },\n];\n\nconst PARAMETER_TYPE_OPTIONS: readonly SelectOption[] = [\n { id: 'string', name: '文字' },\n { id: 'number', name: '數字' },\n { id: 'boolean', name: '是/否' },\n { id: 'stringArray', name: '文字清單' },\n { id: 'json', name: 'JSON' },\n];\n\nconst AUDIT_ACTION_LABELS: Readonly<\n Record<WorkflowWebhookEndpointAuditRecord['action'], string>\n> = {\n CREATED: '建立',\n DISABLED: '停用',\n ENABLED: '啟用',\n SECRET_ROTATED: '輪替金鑰',\n TEST_SENT: '測試送出',\n UPDATED: '更新',\n};\n\nconst EMPTY_DRAFT: EndpointDraft = {\n deprecated: false,\n description: '',\n endpointId: null,\n headers: [],\n key: '',\n label: '',\n method: 'POST',\n mode: 'create',\n originalUrl: '',\n parameters: [],\n replaceHeaders: true,\n signingSecret: '',\n timeoutMs: '',\n url: '',\n version: '1',\n};\n\n/**\n * Back-office management of database webhook endpoints (ADR 18 §3.13):\n * create, edit, disable, rotate the signing secret, test-send and read the\n * change history. Header values and secrets are entered here and never shown\n * again. Administrator-only on the server.\n */\nexport function AdminWebhookEndpointsView(): ReactElement {\n const [management, setManagement] =\n useState<WorkflowWebhookEndpointManagementRecord | null>(null);\n const [endpoints, setEndpoints] = useState<\n readonly WorkflowWebhookManagedEndpointRecord[]\n >([]);\n const [loading, setLoading] = useState(true);\n const [error, setError] = useState<string | null>(null);\n const [notice, setNotice] = useState<string | null>(null);\n const [draft, setDraft] = useState<EndpointDraft | null>(null);\n const [saving, setSaving] = useState(false);\n const [rotating, setRotating] =\n useState<WorkflowWebhookManagedEndpointRecord | null>(null);\n const [nextSecret, setNextSecret] = useState('');\n const [removeSecret, setRemoveSecret] = useState(false);\n const [audits, setAudits] = useState<{\n readonly endpoint: WorkflowWebhookManagedEndpointRecord;\n readonly records: readonly WorkflowWebhookEndpointAuditRecord[];\n } | null>(null);\n\n const refresh = useCallback(async (): Promise<void> => {\n setLoading(true);\n\n try {\n const nextManagement = await readWorkflowWebhookEndpointManagement();\n\n setManagement(nextManagement);\n setEndpoints(\n nextManagement.enabled\n ? await listWorkflowWebhookManagedEndpoints()\n : [],\n );\n setError(null);\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n } finally {\n setLoading(false);\n }\n }, []);\n\n useEffect((): void => {\n void refresh();\n }, [refresh]);\n\n const run = useCallback(\n async (work: () => Promise<string | null>): Promise<boolean> => {\n setError(null);\n setNotice(null);\n\n try {\n setNotice(await work());\n await refresh();\n\n return true;\n } catch (requestError: unknown) {\n setError(readErrorMessage(requestError));\n\n return false;\n }\n },\n [refresh],\n );\n\n const rows = useMemo(\n (): EndpointRow[] =>\n endpoints.map((endpoint) => ({ endpoint, key: endpoint.id })),\n [endpoints],\n );\n\n const columns = useMemo(\n (): TableColumn<EndpointRow>[] => [\n {\n key: 'label',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.label}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.key}@{endpoint.version} · 參數{' '}\n {endpoint.parameters.length} 個\n </Typography>\n </div>\n ),\n title: '端點',\n width: 240,\n },\n {\n key: 'url',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {endpoint.method} {endpoint.url}\n </Typography>\n ),\n title: 'URL',\n width: 320,\n },\n {\n key: 'status',\n render: ({ endpoint }: EndpointRow): ReactElement =>\n !endpoint.active ? (\n <Badge size=\"sub\" text=\"已停用\" variant=\"dot-inactive\" />\n ) : endpoint.deprecated ? (\n <Badge size=\"sub\" text=\"不建議使用\" variant=\"dot-warning\" />\n ) : (\n <Badge size=\"sub\" text=\"啟用中\" variant=\"dot-success\" />\n ),\n title: '狀態',\n width: 120,\n },\n {\n key: 'credentials',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <div style={STACK_STYLE}>\n <Typography component=\"span\" variant=\"body\">\n {endpoint.hasSigningSecret ? '已設定簽章金鑰' : '未簽章'}\n </Typography>\n <Typography color=\"text-neutral\" component=\"span\" variant=\"caption\">\n {endpoint.headerNames.length\n ? `Header:${endpoint.headerNames.join('、')}`\n : '沒有自訂 header'}\n </Typography>\n </div>\n ),\n title: '憑證',\n width: 200,\n },\n {\n key: 'updatedAt',\n render: ({ endpoint }: EndpointRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(endpoint.updatedAt)}\n </Typography>\n ),\n title: '更新時間',\n width: 180,\n },\n ],\n [],\n );\n\n const actions = useMemo(\n (): TableActions<EndpointRow> => ({\n render: ({\n endpoint,\n }): ReturnType<TableActions<EndpointRow>['render']> => [\n {\n name: '編輯',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'edit')),\n },\n {\n name: '建立新版本',\n onClick: (): void => setDraft(readEditDraft(endpoint, 'version')),\n },\n {\n name: '測試送出',\n onClick: (): void => {\n void run(async () =>\n readTestNotice(\n endpoint,\n await testWorkflowWebhookEndpoint(endpoint.id),\n ),\n );\n },\n },\n {\n name: '輪替金鑰',\n onClick: (): void => {\n setNextSecret('');\n setRemoveSecret(false);\n setRotating(endpoint);\n },\n },\n {\n name: endpoint.active ? '停用' : '啟用',\n onClick: (): void => {\n void run(async () => {\n await setWorkflowWebhookEndpointActive(\n endpoint.id,\n !endpoint.active,\n );\n\n return `已${endpoint.active ? '停用' : '啟用'}「${endpoint.label}」。`;\n });\n },\n },\n {\n name: '異動紀錄',\n onClick: (): void => {\n void listWorkflowWebhookEndpointAudits(endpoint.id)\n .then((records): void => setAudits({ endpoint, records }))\n .catch((requestError: unknown): void =>\n setError(readErrorMessage(requestError)),\n );\n },\n },\n ],\n variant: 'base-secondary',\n width: 180,\n }),\n [run],\n );\n\n async function handleSaveDraft(): Promise<void> {\n if (!draft) {\n return;\n }\n\n setSaving(true);\n\n const saved = await run(async () => {\n const parameters = draft.parameters.map((parameter) => ({\n description: parameter.description.trim() || null,\n key: parameter.key.trim(),\n label: parameter.label.trim(),\n required: parameter.required,\n type: parameter.type,\n }));\n const headers = draft.headers\n .filter((header) => header.name.trim())\n .map((header) => ({ name: header.name.trim(), value: header.value }));\n const timeoutMs = draft.timeoutMs.trim() ? Number(draft.timeoutMs) : null;\n\n if (draft.mode === 'edit' && draft.endpointId) {\n await updateWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers:\n draft.replaceHeaders || isOriginChanged(draft) ? headers : null,\n id: draft.endpointId,\n label: draft.label,\n method: draft.method,\n parameters,\n timeoutMs,\n url: draft.url,\n });\n\n return `已更新「${draft.label}」。`;\n }\n\n await createWorkflowWebhookEndpoint({\n deprecated: draft.deprecated,\n description: draft.description,\n headers,\n key: draft.key,\n label: draft.label,\n method: draft.method,\n parameters,\n signingSecret: draft.signingSecret || null,\n timeoutMs,\n url: draft.url,\n version: Number(draft.version),\n });\n\n return `已建立「${draft.label}」v${draft.version},設計器現在可以選用。`;\n });\n\n setSaving(false);\n\n if (saved) {\n setDraft(null);\n }\n }\n\n async function handleRotate(): Promise<void> {\n if (!rotating) {\n return;\n }\n\n const endpoint = rotating;\n const done = await run(async () => {\n await rotateWorkflowWebhookEndpointSecret(\n endpoint.id,\n removeSecret ? null : nextSecret,\n );\n\n return removeSecret\n ? `已移除「${endpoint.label}」的簽章金鑰,之後的請求不再簽章。`\n : `已輪替「${endpoint.label}」的簽章金鑰,接收端需改用新金鑰驗簽。`;\n });\n\n if (done) {\n setRotating(null);\n setNextSecret('');\n }\n }\n\n const enabled = Boolean(management?.enabled);\n\n return (\n <>\n <PageHeader>\n <ContentHeader\n description=\"維護知會節點可呼叫的外部系統端點。Header 值與簽章金鑰加密保存,儲存後不會再顯示。\"\n title=\"Webhook 端點\"\n >\n <Button\n disabled={!enabled}\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void => setDraft(EMPTY_DRAFT)}\n variant=\"base-primary\"\n >\n 新增端點\n </Button>\n </ContentHeader>\n </PageHeader>\n\n <SectionGroup>\n <Section>\n <div style={STACK_STYLE}>\n {error ? (\n <Typography color=\"text-error\" variant=\"body\">\n {error}\n </Typography>\n ) : null}\n {notice ? (\n <Typography color=\"text-success\" variant=\"body\">\n {notice}\n </Typography>\n ) : null}\n {management && !enabled ? (\n <Typography color=\"text-warning\" variant=\"body\">\n 此伺服器未啟用後台維護的 Webhook 端點:需要設定\n workflowWebhookTargetSources 含 DATABASE、URL\n 白名單與加密金鑰。程式註冊的端點不受影響。\n </Typography>\n ) : null}\n {enabled ? (\n <Typography color=\"text-neutral\" variant=\"caption\">\n 允許的 URL:{management?.allowedUrlPatterns.join('、')}\n </Typography>\n ) : null}\n <Table\n actions={actions}\n columns={columns}\n dataSource={rows}\n fullWidth\n loading={loading}\n />\n </div>\n </Section>\n </SectionGroup>\n\n {draft ? (\n <EndpointDraftModal\n draft={draft}\n onCancel={(): void => setDraft(null)}\n onChange={setDraft}\n onConfirm={(): void => void handleSaveDraft()}\n saving={saving}\n />\n ) : null}\n\n <Modal\n cancelText=\"取消\"\n confirmButtonProps={{ disabled: !removeSecret && !nextSecret }}\n confirmText={removeSecret ? '移除金鑰' : '輪替金鑰'}\n modalType=\"standard\"\n onCancel={(): void => setRotating(null)}\n onClose={(): void => setRotating(null)}\n onConfirm={(): void => void handleRotate()}\n open={Boolean(rotating)}\n showModalFooter\n showModalHeader\n supportingText=\"新金鑰會加密保存,不會再顯示;請同時更新接收端的驗簽金鑰。\"\n title={`輪替簽章金鑰:${rotating?.label ?? ''}`}\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"移除金鑰\" name=\"removeSigningSecret\">\n <Toggle\n checked={removeSecret}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setRemoveSecret(event.target.checked)\n }\n />\n </BPMFormField>\n {removeSecret ? null : (\n <BPMFormField label=\"新金鑰\" name=\"nextSigningSecret\" required>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n setNextSecret(event.target.value)\n }\n value={nextSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n </div>\n </Modal>\n\n <Modal\n confirmText=\"關閉\"\n modalType=\"standard\"\n onClose={(): void => setAudits(null)}\n onConfirm={(): void => setAudits(null)}\n open={Boolean(audits)}\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText=\"只記錄誰在何時變更了哪些欄位,不記錄任何值。\"\n title={`異動紀錄:${audits?.endpoint.label ?? ''}`}\n >\n <Table\n columns={AUDIT_COLUMNS}\n dataSource={(audits?.records ?? []).map((audit): AuditRow => ({\n audit,\n key: audit.id,\n }))}\n fullWidth\n />\n </Modal>\n </>\n );\n}\n\nconst AUDIT_COLUMNS: TableColumn<AuditRow>[] = [\n {\n key: 'createdAt',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {formatDateTime(audit.createdAt)}\n </Typography>\n ),\n title: '時間',\n width: 180,\n },\n {\n key: 'action',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {AUDIT_ACTION_LABELS[audit.action]}\n </Typography>\n ),\n title: '動作',\n width: 120,\n },\n {\n key: 'changedFields',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.changedFields.join('、') || '—'}\n </Typography>\n ),\n title: '欄位',\n width: 280,\n },\n {\n key: 'actor',\n render: ({ audit }: AuditRow): ReactElement => (\n <Typography component=\"span\" variant=\"body\">\n {audit.actorMemberId ?? '系統'}\n </Typography>\n ),\n title: '操作者',\n width: 160,\n },\n];\n\nfunction EndpointDraftModal({\n draft,\n onCancel,\n onChange,\n onConfirm,\n saving,\n}: {\n readonly draft: EndpointDraft;\n readonly onCancel: () => void;\n readonly onChange: (draft: EndpointDraft) => void;\n readonly onConfirm: () => void;\n readonly saving: boolean;\n}): ReactElement {\n const editing = draft.mode === 'edit';\n // Stored header values must not follow the URL to another host, so a new\n // host always means entering the headers again.\n const originChanged = isOriginChanged(draft);\n const replaceHeaders = draft.replaceHeaders || originChanged;\n const update = (patch: Partial<EndpointDraft>): void =>\n onChange({ ...draft, ...patch });\n const updateParameter = (\n index: number,\n patch: Partial<ParameterDraft>,\n ): void =>\n update({\n parameters: draft.parameters.map((parameter, current) =>\n current === index ? { ...parameter, ...patch } : parameter,\n ),\n });\n const updateHeader = (index: number, patch: Partial<HeaderDraft>): void =>\n update({\n headers: draft.headers.map((header, current) =>\n current === index ? { ...header, ...patch } : header,\n ),\n });\n const text =\n (field: keyof EndpointDraft) =>\n (event: ChangeEvent<HTMLInputElement | HTMLTextAreaElement>): void =>\n update({ [field]: event.target.value });\n\n return (\n <Modal\n cancelText=\"取消\"\n confirmText={editing ? '儲存' : '建立'}\n loading={saving}\n modalType=\"standard\"\n onCancel={onCancel}\n onClose={onCancel}\n onConfirm={onConfirm}\n open\n showModalFooter\n showModalHeader\n size=\"wide\"\n supportingText={\n editing\n ? '參數的鍵、型別與必填是這個版本的契約,無法修改;需要變更請建立新版本。'\n : draft.mode === 'version'\n ? '新版本可調整參數;既有模板仍使用舊版本,直到設計者改選。'\n : 'URL 需符合伺服器設定的白名單。'\n }\n title={\n editing\n ? `編輯端點:${draft.label}`\n : draft.mode === 'version'\n ? `建立新版本:${draft.key}`\n : '新增 Webhook 端點'\n }\n >\n <div style={STACK_STYLE}>\n <BPMFormField label=\"Key\" name=\"endpointKey\" required>\n <Input\n {...(draft.mode === 'create' ? {} : { readonly: true as const })}\n onChange={text('key')}\n placeholder=\"例如 crm.lead-created\"\n value={draft.key}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"版本\" name=\"endpointVersion\" required>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('version')}\n value={draft.version}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"名稱\" name=\"endpointLabel\" required>\n <Input\n onChange={text('label')}\n placeholder=\"例如 CRM 建立名單\"\n value={draft.label}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"說明\" name=\"endpointDescription\">\n <Textarea\n onChange={text('description')}\n rows={2}\n value={draft.description}\n />\n </BPMFormField>\n <BPMFormField label=\"URL\" name=\"endpointUrl\" required>\n <Input\n onChange={text('url')}\n placeholder=\"https://\"\n value={draft.url}\n inputProps={{ autoComplete: 'off' }}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"Method\" name=\"endpointMethod\" required>\n <Select\n clearable={false}\n onChange={(option): void =>\n update({ method: option?.id ?? 'POST' })\n }\n options={[...METHOD_OPTIONS]}\n value={\n METHOD_OPTIONS.find((option) => option.id === draft.method) ??\n null\n }\n />\n </BPMFormField>\n <BPMFormField\n hintText=\"留空使用預設 10 秒,上限 30000 毫秒。\"\n label=\"逾時(毫秒)\"\n name=\"endpointTimeout\"\n >\n <Input\n inputProps={{ autoComplete: 'off', inputMode: 'numeric' }}\n onChange={text('timeoutMs')}\n value={draft.timeoutMs}\n variant=\"base\"\n />\n </BPMFormField>\n <BPMFormField label=\"不建議使用\" name=\"endpointDeprecated\">\n <Toggle\n checked={draft.deprecated}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ deprecated: event.target.checked })\n }\n />\n </BPMFormField>\n {editing ? null : (\n <BPMFormField\n hintText=\"選填;設定後 BPM 以 HMAC-SHA256 簽章,儲存後不會再顯示。\"\n label=\"簽章金鑰\"\n name=\"endpointSigningSecret\"\n >\n <Input\n onChange={text('signingSecret')}\n placeholder=\"選填,儲存後不再顯示\"\n value={draft.signingSecret}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n </BPMFormField>\n )}\n\n <Typography variant=\"label-primary-highlight\">Headers</Typography>\n {editing ? (\n <BPMFormField\n hintText={\n originChanged\n ? 'URL 已改到其他主機,必須重新輸入 header(留空代表不帶任何 header)。'\n : '現有 header 的值不會顯示;開啟後以下列內容取代全部 header。'\n }\n label=\"取代 headers\"\n name=\"endpointReplaceHeaders\"\n >\n <Toggle\n checked={replaceHeaders}\n disabled={originChanged}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n update({ replaceHeaders: event.target.checked })\n }\n />\n </BPMFormField>\n ) : null}\n {replaceHeaders\n ? draft.headers.map((header, index): ReactElement => (\n <div key={index} style={HEADER_ROW_STYLE}>\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { name: event.target.value })\n }\n placeholder=\"名稱,例如 Authorization\"\n inputProps={{ autoComplete: 'off' }}\n value={header.name}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateHeader(index, { value: event.target.value })\n }\n placeholder=\"值\"\n value={header.value}\n inputProps={{ autoComplete: 'new-password' }}\n variant=\"password\"\n />\n <Button\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n headers: draft.headers.filter(\n (_header, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除 header\n </Button>\n </div>\n ))\n : null}\n {replaceHeaders ? (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({ headers: [...draft.headers, { name: '', value: '' }] })\n }\n variant=\"base-dashed\"\n >\n 新增 header\n </Button>\n </div>\n ) : null}\n\n <Typography variant=\"label-primary-highlight\">參數</Typography>\n {draft.parameters.map((parameter, index): ReactElement => (\n <div key={index} style={ROW_STYLE}>\n <Input\n {...(editing ? { readonly: true as const } : {})}\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { key: event.target.value })\n }\n placeholder=\"參數鍵\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.key}\n variant=\"base\"\n />\n <Input\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { label: event.target.value })\n }\n placeholder=\"顯示名稱\"\n inputProps={{ autoComplete: 'off' }}\n value={parameter.label}\n variant=\"base\"\n />\n <Select\n clearable={false}\n disabled={editing}\n onChange={(option): void =>\n updateParameter(index, {\n type: readParameterType(option?.id ?? null),\n })\n }\n options={[...PARAMETER_TYPE_OPTIONS]}\n value={\n PARAMETER_TYPE_OPTIONS.find(\n (option) => option.id === parameter.type,\n ) ?? null\n }\n />\n <Toggle\n checked={parameter.required}\n disabled={editing}\n label=\"必填\"\n onChange={(event: ChangeEvent<HTMLInputElement>): void =>\n updateParameter(index, { required: event.target.checked })\n }\n />\n <Button\n disabled={editing}\n icon={TrashIcon}\n iconType=\"icon-only\"\n onClick={(): void =>\n update({\n parameters: draft.parameters.filter(\n (_parameter, current) => current !== index,\n ),\n })\n }\n variant=\"destructive-text-link\"\n >\n 移除參數\n </Button>\n </div>\n ))}\n {editing ? null : (\n <div>\n <Button\n icon={PlusIcon}\n iconType=\"leading\"\n onClick={(): void =>\n update({\n parameters: [\n ...draft.parameters,\n {\n description: '',\n key: '',\n label: '',\n required: false,\n type: 'string',\n },\n ],\n })\n }\n variant=\"base-dashed\"\n >\n 新增參數\n </Button>\n </div>\n )}\n </div>\n </Modal>\n );\n}\n\nfunction readEditDraft(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n mode: 'edit' | 'version',\n): EndpointDraft {\n return {\n deprecated: endpoint.deprecated,\n description: endpoint.description ?? '',\n endpointId: mode === 'edit' ? endpoint.id : null,\n headers: [],\n key: endpoint.key,\n label: endpoint.label,\n method: endpoint.method,\n mode,\n originalUrl: endpoint.url,\n parameters: endpoint.parameters.map((parameter) => ({\n description: parameter.description ?? '',\n key: parameter.key,\n label: parameter.label,\n required: parameter.required,\n type: parameter.type,\n })),\n // A new version starts without credentials: they are not readable.\n replaceHeaders: mode === 'version',\n signingSecret: '',\n timeoutMs: endpoint.timeoutMs ? String(endpoint.timeoutMs) : '',\n url: endpoint.url,\n version: String(\n mode === 'version' ? endpoint.version + 1 : endpoint.version,\n ),\n };\n}\n\nfunction readTestNotice(\n endpoint: WorkflowWebhookManagedEndpointRecord,\n result: WorkflowWebhookEndpointTestResultRecord,\n): string {\n if (result.ok) {\n return `測試送出成功:「${endpoint.label}」回應 HTTP ${result.status ?? ''}。`;\n }\n\n throw new Error(\n `測試送出失敗:「${endpoint.label}」${result.status ? `回應 HTTP ${result.status}` : ''}(${result.errorCode ?? '未知錯誤'})${result.errorDetail ? `:${result.errorDetail}` : ''}`,\n );\n}\n\nfunction isOriginChanged(draft: EndpointDraft): boolean {\n if (draft.mode !== 'edit') {\n return false;\n }\n\n const origin = (url: string): string => {\n try {\n return new URL(url.trim()).origin;\n } catch {\n return url.trim();\n }\n };\n\n return origin(draft.url) !== origin(draft.originalUrl);\n}\n\nfunction readParameterType(id: string | null): NotifyWebhookParameterType {\n return PARAMETER_TYPE_OPTIONS.some((option) => option.id === id)\n ? (id as NotifyWebhookParameterType)\n : 'string';\n}\n\nfunction readErrorMessage(error: unknown): string {\n if (!(error instanceof Error)) {\n return '發生未知錯誤';\n }\n\n const message = error.message;\n\n if (message.includes('WORKFLOW_WEBHOOK_URL_NOT_ALLOWED')) {\n return 'URL 不在伺服器允許的白名單內。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_KEY_CONFLICT')) {\n return '這個 Key 已由程式註冊的端點使用,請換一個。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_ENDPOINT_CONTRACT_CHANGED')) {\n return '參數契約不能修改,請改用「建立新版本」。';\n }\n\n if (message.includes('WORKFLOW_WEBHOOK_TEST_RATE_LIMITED')) {\n return '測試送出太頻繁,請稍後再試(每 10 秒一次、10 分鐘最多 5 次)。';\n }\n\n return message;\n}\n"],"mappings":"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"}