@acorex/modules 21.0.0-next.39 → 21.0.0-next.41

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 (389) hide show
  1. package/fesm2022/{acorex-modules-ai-management-acorex-modules-ai-management-CU2FvMTx.mjs → acorex-modules-ai-management-acorex-modules-ai-management-D7_4LOGV.mjs} +3725 -956
  2. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-D7_4LOGV.mjs.map +1 -0
  3. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-column.component-D0ruV6aJ.mjs +44 -0
  4. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-column.component-D0ruV6aJ.mjs.map +1 -0
  5. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C7TQMwX4.mjs +257 -0
  6. package/fesm2022/acorex-modules-ai-management-agent-registry-tool-configurator-widget-edit.component-C7TQMwX4.mjs.map +1 -0
  7. package/fesm2022/{acorex-modules-ai-management-agent.entity-CUO9Jczk.mjs → acorex-modules-ai-management-agent.entity-DwPIKib2.mjs} +101 -104
  8. package/fesm2022/acorex-modules-ai-management-agent.entity-DwPIKib2.mjs.map +1 -0
  9. package/fesm2022/{acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-daTGJ1Rd.mjs → acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-D2GJ5qD1.mjs} +63 -43
  10. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-D2GJ5qD1.mjs.map +1 -0
  11. package/fesm2022/{acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-Cmprtps-.mjs → acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-BozVAuLO.mjs} +8 -55
  12. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-BozVAuLO.mjs.map +1 -0
  13. package/fesm2022/{acorex-modules-ai-management-assist.entity-C1nM_x4Z.mjs → acorex-modules-ai-management-assist.entity-CuToMDS_.mjs} +10 -11
  14. package/fesm2022/acorex-modules-ai-management-assist.entity-CuToMDS_.mjs.map +1 -0
  15. package/fesm2022/acorex-modules-ai-management-index-DaGJVOFw.mjs +2 -0
  16. package/fesm2022/{acorex-modules-ai-management-index-CjTjfydP.mjs.map → acorex-modules-ai-management-index-DaGJVOFw.mjs.map} +1 -1
  17. package/fesm2022/{acorex-modules-ai-management-model.entity-CPHxj8h7.mjs → acorex-modules-ai-management-model.entity-vUNlioDw.mjs} +20 -17
  18. package/fesm2022/acorex-modules-ai-management-model.entity-vUNlioDw.mjs.map +1 -0
  19. package/fesm2022/{acorex-modules-ai-management-open-ai-endpoint.entity-a6MjMiXF.mjs → acorex-modules-ai-management-open-ai-endpoint.entity-BpxRR5ir.mjs} +28 -9
  20. package/fesm2022/acorex-modules-ai-management-open-ai-endpoint.entity-BpxRR5ir.mjs.map +1 -0
  21. package/fesm2022/acorex-modules-ai-management.mjs +1 -1
  22. package/fesm2022/acorex-modules-application-management.mjs +1 -1
  23. package/fesm2022/acorex-modules-application-management.mjs.map +1 -1
  24. package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-DniyhnPK.mjs → acorex-modules-assessment-management-acorex-modules-assessment-management-CMS2WJDu.mjs} +26 -26
  25. package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-DniyhnPK.mjs.map → acorex-modules-assessment-management-acorex-modules-assessment-management-CMS2WJDu.mjs.map} +1 -1
  26. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-BggEmLhz.mjs → acorex-modules-assessment-management-assessment-case.entity-C-Q4hu8o.mjs} +2 -2
  27. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-BggEmLhz.mjs.map → acorex-modules-assessment-management-assessment-case.entity-C-Q4hu8o.mjs.map} +1 -1
  28. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-CWR1QZv1.mjs → acorex-modules-assessment-management-assessment-session.entity-CQI_FpUd.mjs} +2 -2
  29. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-CWR1QZv1.mjs.map → acorex-modules-assessment-management-assessment-session.entity-CQI_FpUd.mjs.map} +1 -1
  30. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-qajn_XDh.mjs → acorex-modules-assessment-management-fill-assessment-session.command-Bpvco5iD.mjs} +2 -2
  31. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-qajn_XDh.mjs.map → acorex-modules-assessment-management-fill-assessment-session.command-Bpvco5iD.mjs.map} +1 -1
  32. package/fesm2022/{acorex-modules-assessment-management-index-B2l5Se1l.mjs → acorex-modules-assessment-management-index-_fPuBQeK.mjs} +4 -4
  33. package/fesm2022/{acorex-modules-assessment-management-index-B2l5Se1l.mjs.map → acorex-modules-assessment-management-index-_fPuBQeK.mjs.map} +1 -1
  34. package/fesm2022/{acorex-modules-assessment-management-preview-question.command-BCS477_k.mjs → acorex-modules-assessment-management-preview-question.command-drR6nq76.mjs} +2 -2
  35. package/fesm2022/{acorex-modules-assessment-management-preview-question.command-BCS477_k.mjs.map → acorex-modules-assessment-management-preview-question.command-drR6nq76.mjs.map} +1 -1
  36. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-C8lyuqE-.mjs → acorex-modules-assessment-management-preview-questionnaire.command-CY8tZWdG.mjs} +2 -2
  37. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-C8lyuqE-.mjs.map → acorex-modules-assessment-management-preview-questionnaire.command-CY8tZWdG.mjs.map} +1 -1
  38. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DtowOBLy.mjs → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DV9irFZ0.mjs} +2 -2
  39. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DtowOBLy.mjs.map → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DV9irFZ0.mjs.map} +1 -1
  40. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-Br7XcU_u.mjs → acorex-modules-assessment-management-question-bank-item.entity-DO4bTKKo.mjs} +2 -2
  41. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-Br7XcU_u.mjs.map → acorex-modules-assessment-management-question-bank-item.entity-DO4bTKKo.mjs.map} +1 -1
  42. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-DNUf5RD3.mjs → acorex-modules-assessment-management-questionnaire-calculation.entity-B-N0v4zs.mjs} +2 -2
  43. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-DNUf5RD3.mjs.map → acorex-modules-assessment-management-questionnaire-calculation.entity-B-N0v4zs.mjs.map} +1 -1
  44. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-BdBKHvHP.mjs → acorex-modules-assessment-management-questionnaire-viewer-popup.component-Cc-o6qmY.mjs} +2 -2
  45. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-BdBKHvHP.mjs.map → acorex-modules-assessment-management-questionnaire-viewer-popup.component-Cc-o6qmY.mjs.map} +1 -1
  46. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-B5aP_P4z.mjs → acorex-modules-assessment-management-questionnaire.entity-CJWNlaJs.mjs} +3 -3
  47. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-B5aP_P4z.mjs.map → acorex-modules-assessment-management-questionnaire.entity-CJWNlaJs.mjs.map} +1 -1
  48. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-C3Qt5fmY.mjs → acorex-modules-assessment-management-save-questionnaire-questions.command-C3gOkZa5.mjs} +2 -2
  49. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-C3Qt5fmY.mjs.map → acorex-modules-assessment-management-save-questionnaire-questions.command-C3gOkZa5.mjs.map} +1 -1
  50. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-C9VS-Tp3.mjs → acorex-modules-assessment-management-view-session-answers.command-AvTbWvGE.mjs} +2 -2
  51. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-C9VS-Tp3.mjs.map → acorex-modules-assessment-management-view-session-answers.command-AvTbWvGE.mjs.map} +1 -1
  52. package/fesm2022/acorex-modules-assessment-management.mjs +1 -1
  53. package/fesm2022/{acorex-modules-asset-management-acorex-modules-asset-management-F7Ok5dhs.mjs → acorex-modules-asset-management-acorex-modules-asset-management-DrIhRaZ6.mjs} +321 -146
  54. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-DrIhRaZ6.mjs.map +1 -0
  55. package/fesm2022/acorex-modules-asset-management-asset-rental-history.entity-95NBXoex.mjs +302 -0
  56. package/fesm2022/acorex-modules-asset-management-asset-rental-history.entity-95NBXoex.mjs.map +1 -0
  57. package/fesm2022/acorex-modules-asset-management-asset-state-history.entity-C-z103la.mjs +258 -0
  58. package/fesm2022/acorex-modules-asset-management-asset-state-history.entity-C-z103la.mjs.map +1 -0
  59. package/fesm2022/acorex-modules-asset-management-asset-status.rules-B7KwWQEe.mjs +98 -0
  60. package/fesm2022/acorex-modules-asset-management-asset-status.rules-B7KwWQEe.mjs.map +1 -0
  61. package/fesm2022/{acorex-modules-asset-management-asset-system-history.entity-D1HZG9wO.mjs → acorex-modules-asset-management-asset-system-assignment.entity-HqZtfJpe.mjs} +77 -48
  62. package/fesm2022/acorex-modules-asset-management-asset-system-assignment.entity-HqZtfJpe.mjs.map +1 -0
  63. package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-DDh5RK5M.mjs → acorex-modules-asset-management-asset-system-type.entity-fvrbyjXb.mjs} +15 -5
  64. package/fesm2022/acorex-modules-asset-management-asset-system-type.entity-fvrbyjXb.mjs.map +1 -0
  65. package/fesm2022/{acorex-modules-asset-management-assetSystem.entity-CJCVALaz.mjs → acorex-modules-asset-management-asset-system.entity-DVAaXNWx.mjs} +51 -29
  66. package/fesm2022/acorex-modules-asset-management-asset-system.entity-DVAaXNWx.mjs.map +1 -0
  67. package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-em7lQ1eu.mjs → acorex-modules-asset-management-asset-type-section-component.entity-n-bxBcGz.mjs} +2 -2
  68. package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-em7lQ1eu.mjs.map → acorex-modules-asset-management-asset-type-section-component.entity-n-bxBcGz.mjs.map} +1 -1
  69. package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-BtcNy6Ra.mjs → acorex-modules-asset-management-asset-type-section.entity-BF7N699p.mjs} +2 -2
  70. package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-BtcNy6Ra.mjs.map → acorex-modules-asset-management-asset-type-section.entity-BF7N699p.mjs.map} +1 -1
  71. package/fesm2022/{acorex-modules-asset-management-asset-type.entity-DWhrFVFI.mjs → acorex-modules-asset-management-asset-type.entity-Dt61Rs4F.mjs} +28 -18
  72. package/fesm2022/acorex-modules-asset-management-asset-type.entity-Dt61Rs4F.mjs.map +1 -0
  73. package/fesm2022/{acorex-modules-asset-management-asset.entity-BEjXfkPD.mjs → acorex-modules-asset-management-asset.entity-BzlsaEwC.mjs} +231 -204
  74. package/fesm2022/acorex-modules-asset-management-asset.entity-BzlsaEwC.mjs.map +1 -0
  75. package/fesm2022/acorex-modules-asset-management-assetLifecycle-state.provider-DZ5r2zx7.mjs +192 -0
  76. package/fesm2022/acorex-modules-asset-management-assetLifecycle-state.provider-DZ5r2zx7.mjs.map +1 -0
  77. package/fesm2022/acorex-modules-asset-management-status.provider-C41t4e2U.mjs +363 -0
  78. package/fesm2022/acorex-modules-asset-management-status.provider-C41t4e2U.mjs.map +1 -0
  79. package/fesm2022/acorex-modules-asset-management.mjs +1 -1
  80. package/fesm2022/acorex-modules-business-core.mjs +17 -11
  81. package/fesm2022/acorex-modules-business-core.mjs.map +1 -1
  82. package/fesm2022/acorex-modules-common.mjs +161 -84
  83. package/fesm2022/acorex-modules-common.mjs.map +1 -1
  84. package/fesm2022/acorex-modules-conversation.mjs +4860 -4887
  85. package/fesm2022/acorex-modules-conversation.mjs.map +1 -1
  86. package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-DLndkp6w.mjs +8470 -0
  87. package/fesm2022/acorex-modules-dashboard-management-acorex-modules-dashboard-management-DLndkp6w.mjs.map +1 -0
  88. package/fesm2022/acorex-modules-dashboard-management-index-c8QzHHtG.mjs +127 -0
  89. package/fesm2022/acorex-modules-dashboard-management-index-c8QzHHtG.mjs.map +1 -0
  90. package/fesm2022/acorex-modules-dashboard-management.mjs +1 -8100
  91. package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
  92. package/fesm2022/acorex-modules-document-management.mjs +144 -27
  93. package/fesm2022/acorex-modules-document-management.mjs.map +1 -1
  94. package/fesm2022/acorex-modules-financial-core.mjs.map +1 -1
  95. package/fesm2022/acorex-modules-form-template-management.mjs +1 -1
  96. package/fesm2022/acorex-modules-form-template-management.mjs.map +1 -1
  97. package/fesm2022/{acorex-modules-health-core-allergy-type.entity-CS8a-AUb.mjs → acorex-modules-health-core-allergy-type.entity-BvJmDMcr.mjs} +3 -3
  98. package/fesm2022/acorex-modules-health-core-allergy-type.entity-BvJmDMcr.mjs.map +1 -0
  99. package/fesm2022/{acorex-modules-health-core-blood-type.entity-ZgFOuvG4.mjs → acorex-modules-health-core-blood-type.entity-Vpw9y9J5.mjs} +3 -3
  100. package/fesm2022/acorex-modules-health-core-blood-type.entity-Vpw9y9J5.mjs.map +1 -0
  101. package/fesm2022/{acorex-modules-health-core-body-part.entity-JGLwrFE2.mjs → acorex-modules-health-core-body-part.entity-Cz2NEAqm.mjs} +3 -3
  102. package/fesm2022/acorex-modules-health-core-body-part.entity-Cz2NEAqm.mjs.map +1 -0
  103. package/fesm2022/{acorex-modules-health-core-chronic-condition-type.entity-DrxEPQj1.mjs → acorex-modules-health-core-chronic-condition-type.entity-CKWVW0Rg.mjs} +3 -3
  104. package/fesm2022/acorex-modules-health-core-chronic-condition-type.entity-CKWVW0Rg.mjs.map +1 -0
  105. package/fesm2022/{acorex-modules-health-core-disability-status.entity-UaAQFFMC.mjs → acorex-modules-health-core-disability-status.entity-C7NwwT0i.mjs} +3 -3
  106. package/fesm2022/acorex-modules-health-core-disability-status.entity-C7NwwT0i.mjs.map +1 -0
  107. package/fesm2022/{acorex-modules-health-core-injury-type.entity-DcIn0rxz.mjs → acorex-modules-health-core-injury-type.entity-bfzL6j8C.mjs} +3 -3
  108. package/fesm2022/acorex-modules-health-core-injury-type.entity-bfzL6j8C.mjs.map +1 -0
  109. package/fesm2022/{acorex-modules-health-core-vaccination-type.entity-zYd6KLRC.mjs → acorex-modules-health-core-vaccination-type.entity-CqymQfWK.mjs} +3 -3
  110. package/fesm2022/acorex-modules-health-core-vaccination-type.entity-CqymQfWK.mjs.map +1 -0
  111. package/fesm2022/acorex-modules-health-core.mjs +7 -7
  112. package/fesm2022/acorex-modules-health-core.mjs.map +1 -1
  113. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-Bgsi3FHG.mjs +1924 -0
  114. package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-Bgsi3FHG.mjs.map +1 -0
  115. package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-BRUrGVh1.mjs → acorex-modules-human-capital-management-approve-leave-request.command-CxpTmb-1.mjs} +2 -2
  116. package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-BRUrGVh1.mjs.map → acorex-modules-human-capital-management-approve-leave-request.command-CxpTmb-1.mjs.map} +1 -1
  117. package/fesm2022/acorex-modules-human-capital-management-assign-position-assignment.command-jLGe49dJ.mjs +90 -0
  118. package/fesm2022/acorex-modules-human-capital-management-assign-position-assignment.command-jLGe49dJ.mjs.map +1 -0
  119. package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-B16M3F8s.mjs → acorex-modules-human-capital-management-cancel-leave-request.command-ChNGu90e.mjs} +2 -2
  120. package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-B16M3F8s.mjs.map → acorex-modules-human-capital-management-cancel-leave-request.command-ChNGu90e.mjs.map} +1 -1
  121. package/fesm2022/{acorex-modules-human-capital-management-employee.entity-BmF6_P6d.mjs → acorex-modules-human-capital-management-employee.entity-4k7F7_ON.mjs} +37 -16
  122. package/fesm2022/acorex-modules-human-capital-management-employee.entity-4k7F7_ON.mjs.map +1 -0
  123. package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-7ZGZYxGM.mjs → acorex-modules-human-capital-management-employment-type.entity-Jo2fB9R3.mjs} +5 -5
  124. package/fesm2022/acorex-modules-human-capital-management-employment-type.entity-Jo2fB9R3.mjs.map +1 -0
  125. package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-B3Rk84bJ.mjs → acorex-modules-human-capital-management-leave-request.entity-DhLUXnJu.mjs} +71 -21
  126. package/fesm2022/acorex-modules-human-capital-management-leave-request.entity-DhLUXnJu.mjs.map +1 -0
  127. package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-OKu8_PP1.mjs → acorex-modules-human-capital-management-leave-type.entity-C-lN2bb0.mjs} +5 -6
  128. package/fesm2022/acorex-modules-human-capital-management-leave-type.entity-C-lN2bb0.mjs.map +1 -0
  129. package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-D_C459kx.mjs → acorex-modules-human-capital-management-position-assignment.entity-BD1jN4Mx.mjs} +81 -7
  130. package/fesm2022/acorex-modules-human-capital-management-position-assignment.entity-BD1jN4Mx.mjs.map +1 -0
  131. package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-C0_moDp9.mjs → acorex-modules-human-capital-management-reject-leave-request.command-D0G6UrqI.mjs} +2 -2
  132. package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-C0_moDp9.mjs.map → acorex-modules-human-capital-management-reject-leave-request.command-D0G6UrqI.mjs.map} +1 -1
  133. package/fesm2022/acorex-modules-human-capital-management-revoke-position-assignment.command-CYzqQXja.mjs +97 -0
  134. package/fesm2022/acorex-modules-human-capital-management-revoke-position-assignment.command-CYzqQXja.mjs.map +1 -0
  135. package/fesm2022/acorex-modules-human-capital-management.mjs +1 -1629
  136. package/fesm2022/acorex-modules-human-capital-management.mjs.map +1 -1
  137. package/fesm2022/{acorex-modules-learning-management-certificate-definition.entity-27VKYxw1.mjs → acorex-modules-learning-management-certificate-definition.entity-C_r1Djcx.mjs} +4 -4
  138. package/fesm2022/acorex-modules-learning-management-certificate-definition.entity-C_r1Djcx.mjs.map +1 -0
  139. package/fesm2022/{acorex-modules-learning-management-certificate-type.entity-CBM6N-PD.mjs → acorex-modules-learning-management-certificate-type.entity-DAJNtUya.mjs} +42 -20
  140. package/fesm2022/acorex-modules-learning-management-certificate-type.entity-DAJNtUya.mjs.map +1 -0
  141. package/fesm2022/{acorex-modules-learning-management-certificate.entity-BRBJQYji.mjs → acorex-modules-learning-management-certificate.entity-CSD_CX4V.mjs} +5 -5
  142. package/fesm2022/acorex-modules-learning-management-certificate.entity-CSD_CX4V.mjs.map +1 -0
  143. package/fesm2022/{acorex-modules-learning-management-course-type.entity-B1c6PDLq.mjs → acorex-modules-learning-management-course-type.entity-DmjeLMxV.mjs} +39 -17
  144. package/fesm2022/acorex-modules-learning-management-course-type.entity-DmjeLMxV.mjs.map +1 -0
  145. package/fesm2022/{acorex-modules-learning-management-course.entity-BN8XHAPz.mjs → acorex-modules-learning-management-course.entity-DUUgeikJ.mjs} +3 -3
  146. package/fesm2022/acorex-modules-learning-management-course.entity-DUUgeikJ.mjs.map +1 -0
  147. package/fesm2022/{acorex-modules-learning-management-learning-path.entity-8QlM3R4B.mjs → acorex-modules-learning-management-learning-path.entity-Zo--bDto.mjs} +39 -17
  148. package/fesm2022/acorex-modules-learning-management-learning-path.entity-Zo--bDto.mjs.map +1 -0
  149. package/fesm2022/{acorex-modules-learning-management-skill-level.entity-DXOWslpB.mjs → acorex-modules-learning-management-skill-level.entity-XVCTHW3O.mjs} +10 -10
  150. package/fesm2022/acorex-modules-learning-management-skill-level.entity-XVCTHW3O.mjs.map +1 -0
  151. package/fesm2022/{acorex-modules-learning-management-skill.entity-DrLts807.mjs → acorex-modules-learning-management-skill.entity-VXkLbaD4.mjs} +35 -13
  152. package/fesm2022/acorex-modules-learning-management-skill.entity-VXkLbaD4.mjs.map +1 -0
  153. package/fesm2022/{acorex-modules-learning-management-training-definition.entity-NQqJ5avw.mjs → acorex-modules-learning-management-training-definition.entity-BbVZ9_go.mjs} +3 -3
  154. package/fesm2022/acorex-modules-learning-management-training-definition.entity-BbVZ9_go.mjs.map +1 -0
  155. package/fesm2022/{acorex-modules-learning-management-training-type.entity-CoyDCeen.mjs → acorex-modules-learning-management-training-type.entity-C1otrA63.mjs} +36 -14
  156. package/fesm2022/acorex-modules-learning-management-training-type.entity-C1otrA63.mjs.map +1 -0
  157. package/fesm2022/{acorex-modules-learning-management-training.entity-BCGn0T3H.mjs → acorex-modules-learning-management-training.entity-C4KDv1uh.mjs} +3 -3
  158. package/fesm2022/acorex-modules-learning-management-training.entity-C4KDv1uh.mjs.map +1 -0
  159. package/fesm2022/acorex-modules-learning-management.mjs +716 -19
  160. package/fesm2022/acorex-modules-learning-management.mjs.map +1 -1
  161. package/fesm2022/{acorex-modules-maintenance-management-acorex-modules-maintenance-management-DtODwbIN.mjs → acorex-modules-maintenance-management-acorex-modules-maintenance-management-B5wf4zMI.mjs} +611 -393
  162. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-B5wf4zMI.mjs.map +1 -0
  163. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-BtczD4wu.mjs → acorex-modules-maintenance-management-failure-effect.entity-Cv5KnboB.mjs} +2 -2
  164. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-BtczD4wu.mjs.map → acorex-modules-maintenance-management-failure-effect.entity-Cv5KnboB.mjs.map} +1 -1
  165. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-CDUdEH-e.mjs → acorex-modules-maintenance-management-failure-mode-asset-type.entity-BBL3-hfv.mjs} +2 -2
  166. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-CDUdEH-e.mjs.map → acorex-modules-maintenance-management-failure-mode-asset-type.entity-BBL3-hfv.mjs.map} +1 -1
  167. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-re5UvGp7.mjs → acorex-modules-maintenance-management-failure-mode-mechanism.entity-nxOdHZxu.mjs} +2 -2
  168. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-re5UvGp7.mjs.map → acorex-modules-maintenance-management-failure-mode-mechanism.entity-nxOdHZxu.mjs.map} +1 -1
  169. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-nbFz4LAe.mjs → acorex-modules-maintenance-management-failure-mode-solution.entity-ApD80Scc.mjs} +2 -2
  170. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-nbFz4LAe.mjs.map → acorex-modules-maintenance-management-failure-mode-solution.entity-ApD80Scc.mjs.map} +1 -1
  171. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-CW2NlX59.mjs → acorex-modules-maintenance-management-failure-register-cause.entity-CibfwJLG.mjs} +2 -2
  172. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-CW2NlX59.mjs.map → acorex-modules-maintenance-management-failure-register-cause.entity-CibfwJLG.mjs.map} +1 -1
  173. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-Bi5XgfoL.mjs → acorex-modules-maintenance-management-failure-register-effect.entity-DpoqULBf.mjs} +2 -2
  174. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-Bi5XgfoL.mjs.map → acorex-modules-maintenance-management-failure-register-effect.entity-DpoqULBf.mjs.map} +1 -1
  175. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-DcW6sK01.mjs → acorex-modules-maintenance-management-failure-register-mechanism.entity-0-J2Hkmn.mjs} +2 -2
  176. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-DcW6sK01.mjs.map → acorex-modules-maintenance-management-failure-register-mechanism.entity-0-J2Hkmn.mjs.map} +1 -1
  177. package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-CUxVZo0w.mjs → acorex-modules-maintenance-management-failure-register.entity-C4Az4Rr9.mjs} +24 -54
  178. package/fesm2022/acorex-modules-maintenance-management-failure-register.entity-C4Az4Rr9.mjs.map +1 -0
  179. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-B7LBO-UA.mjs → acorex-modules-maintenance-management-failure-severity.entity-BZo6UUun.mjs} +2 -2
  180. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-B7LBO-UA.mjs.map → acorex-modules-maintenance-management-failure-severity.entity-BZo6UUun.mjs.map} +1 -1
  181. package/fesm2022/{acorex-modules-maintenance-management-maintenance-template.entity-D6ATa-HR.mjs → acorex-modules-maintenance-management-maintenance-template.entity-DxYY0hpG.mjs} +33 -82
  182. package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-DxYY0hpG.mjs.map +1 -0
  183. package/fesm2022/acorex-modules-maintenance-management-work-order-list-command-DTKNtyBF.mjs +54 -0
  184. package/fesm2022/acorex-modules-maintenance-management-work-order-list-command-DTKNtyBF.mjs.map +1 -0
  185. package/fesm2022/acorex-modules-maintenance-management.mjs +1 -1
  186. package/fesm2022/acorex-modules-measurement-core.mjs.map +1 -1
  187. package/fesm2022/{acorex-modules-notification-management-notification-page.component-DDhCqJtg.mjs → acorex-modules-notification-management-notification-page.component-D0we6H1f.mjs} +5 -5
  188. package/fesm2022/{acorex-modules-notification-management-notification-page.component-DDhCqJtg.mjs.map → acorex-modules-notification-management-notification-page.component-D0we6H1f.mjs.map} +1 -1
  189. package/fesm2022/acorex-modules-notification-management.mjs +25 -17
  190. package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
  191. package/fesm2022/acorex-modules-organization-management-JOB_DEFINITION_SKILLS_PAGE_COMPONENT_KEY-BYfbGGOE.mjs +8 -0
  192. package/fesm2022/acorex-modules-organization-management-JOB_DEFINITION_SKILLS_PAGE_COMPONENT_KEY-BYfbGGOE.mjs.map +1 -0
  193. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-Bu8fRj_5.mjs +951 -0
  194. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-Bu8fRj_5.mjs.map +1 -0
  195. package/fesm2022/acorex-modules-organization-management-add-position-to-business-unit.command-Qej_boIY.mjs +109 -0
  196. package/fesm2022/acorex-modules-organization-management-add-position-to-business-unit.command-Qej_boIY.mjs.map +1 -0
  197. package/fesm2022/{acorex-modules-organization-management-business-unit.entity-WiTemBLu.mjs → acorex-modules-organization-management-business-unit.entity-BfQ_7JAq.mjs} +21 -8
  198. package/fesm2022/acorex-modules-organization-management-business-unit.entity-BfQ_7JAq.mjs.map +1 -0
  199. package/fesm2022/{acorex-modules-organization-management-chart.entity-D6Y7kZfM.mjs → acorex-modules-organization-management-chart.entity-CNQGGfHV.mjs} +6 -6
  200. package/fesm2022/acorex-modules-organization-management-chart.entity-CNQGGfHV.mjs.map +1 -0
  201. package/fesm2022/{acorex-modules-organization-management-company.entity-wpNiu8g3.mjs → acorex-modules-organization-management-company.entity-D_nTKLzu.mjs} +4 -4
  202. package/fesm2022/acorex-modules-organization-management-company.entity-D_nTKLzu.mjs.map +1 -0
  203. package/fesm2022/{acorex-modules-organization-management-entity.provider-B0XbUW1I.mjs → acorex-modules-organization-management-entity.provider-B4uYixLQ.mjs} +16 -14
  204. package/fesm2022/acorex-modules-organization-management-entity.provider-B4uYixLQ.mjs.map +1 -0
  205. package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-D7t_nNNk.mjs → acorex-modules-organization-management-feature-definition.provider-COjc6knz.mjs} +2 -2
  206. package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-D7t_nNNk.mjs.map → acorex-modules-organization-management-feature-definition.provider-COjc6knz.mjs.map} +1 -1
  207. package/fesm2022/acorex-modules-organization-management-job-definition-matrix-page.utils-DD3jLujN.mjs +61 -0
  208. package/fesm2022/acorex-modules-organization-management-job-definition-matrix-page.utils-DD3jLujN.mjs.map +1 -0
  209. package/fesm2022/acorex-modules-organization-management-job-definition-pages-component.provider-gDpII9TZ.mjs +28 -0
  210. package/fesm2022/acorex-modules-organization-management-job-definition-pages-component.provider-gDpII9TZ.mjs.map +1 -0
  211. package/fesm2022/acorex-modules-organization-management-job-definition-responsibilities-page.component-CjXV4wrM.mjs +223 -0
  212. package/fesm2022/acorex-modules-organization-management-job-definition-responsibilities-page.component-CjXV4wrM.mjs.map +1 -0
  213. package/fesm2022/acorex-modules-organization-management-job-definition-skills-page.component-2XBgMms-.mjs +219 -0
  214. package/fesm2022/acorex-modules-organization-management-job-definition-skills-page.component-2XBgMms-.mjs.map +1 -0
  215. package/fesm2022/{acorex-modules-organization-management-job-definition.entity-Cb6zEf65.mjs → acorex-modules-organization-management-job-definition.entity-f0JnkdjP.mjs} +21 -154
  216. package/fesm2022/acorex-modules-organization-management-job-definition.entity-f0JnkdjP.mjs.map +1 -0
  217. package/fesm2022/{acorex-modules-organization-management-job-level.datasource-RDGmLrqD.mjs → acorex-modules-organization-management-job-level.datasource-ByHluGvc.mjs} +7 -7
  218. package/fesm2022/acorex-modules-organization-management-job-level.datasource-ByHluGvc.mjs.map +1 -0
  219. package/fesm2022/{acorex-modules-organization-management-job-level.entity-oedF18Xm.mjs → acorex-modules-organization-management-job-level.entity-BJJJQxCp.mjs} +4 -7
  220. package/fesm2022/acorex-modules-organization-management-job-level.entity-BJJJQxCp.mjs.map +1 -0
  221. package/fesm2022/{acorex-modules-organization-management-menu.provider-DAKmAxld.mjs → acorex-modules-organization-management-menu.provider-Dd_Z58sY.mjs} +2 -3
  222. package/fesm2022/{acorex-modules-organization-management-menu.provider-DAKmAxld.mjs.map → acorex-modules-organization-management-menu.provider-Dd_Z58sY.mjs.map} +1 -1
  223. package/fesm2022/acorex-modules-organization-management-org-chart.page-fudrNddI.mjs +1740 -0
  224. package/fesm2022/acorex-modules-organization-management-org-chart.page-fudrNddI.mjs.map +1 -0
  225. package/fesm2022/acorex-modules-organization-management-organization-code-identifier-rules.provider-pocBJezL.mjs +37 -0
  226. package/fesm2022/acorex-modules-organization-management-organization-code-identifier-rules.provider-pocBJezL.mjs.map +1 -0
  227. package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-Be8mvS_Z.mjs → acorex-modules-organization-management-permission-definition.provider-CoB_RGSa.mjs} +2 -3
  228. package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-Be8mvS_Z.mjs.map → acorex-modules-organization-management-permission-definition.provider-CoB_RGSa.mjs.map} +1 -1
  229. package/fesm2022/{acorex-modules-organization-management-position.entity-BveMCKMd.mjs → acorex-modules-organization-management-position.entity-T1DY1fZn.mjs} +8 -9
  230. package/fesm2022/acorex-modules-organization-management-position.entity-T1DY1fZn.mjs.map +1 -0
  231. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-ivufxxLL.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CIPzMi3d.mjs} +4 -3
  232. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CIPzMi3d.mjs.map +1 -0
  233. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DptdG1Nt.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DzdTNVP6.mjs} +2 -2
  234. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DptdG1Nt.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DzdTNVP6.mjs.map} +1 -1
  235. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-qO33kvo_.mjs → acorex-modules-organization-management-responsibilities-matrix.component-C850Dz47.mjs} +5 -5
  236. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-qO33kvo_.mjs.map → acorex-modules-organization-management-responsibilities-matrix.component-C850Dz47.mjs.map} +1 -1
  237. package/fesm2022/{acorex-modules-organization-management-responsibility-level.entity-zOjyjm5H.mjs → acorex-modules-organization-management-responsibility-level.entity-CVxWva5x.mjs} +2 -4
  238. package/fesm2022/acorex-modules-organization-management-responsibility-level.entity-CVxWva5x.mjs.map +1 -0
  239. package/fesm2022/{acorex-modules-organization-management-responsibility.entity-jWEiPi5-.mjs → acorex-modules-organization-management-responsibility.entity-BmDZhqNl.mjs} +5 -7
  240. package/fesm2022/acorex-modules-organization-management-responsibility.entity-BmDZhqNl.mjs.map +1 -0
  241. package/fesm2022/{acorex-modules-organization-management-settings.provider-D3ged-4h.mjs → acorex-modules-organization-management-settings.provider-wwGKyBrV.mjs} +18 -18
  242. package/fesm2022/acorex-modules-organization-management-settings.provider-wwGKyBrV.mjs.map +1 -0
  243. package/fesm2022/acorex-modules-organization-management-team-business-unit.entity-BmXLb4RI.mjs +300 -0
  244. package/fesm2022/acorex-modules-organization-management-team-business-unit.entity-BmXLb4RI.mjs.map +1 -0
  245. package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-D9TZoACE.mjs → acorex-modules-organization-management-team-member-role.entity-C4DGSm2r.mjs} +7 -5
  246. package/fesm2022/acorex-modules-organization-management-team-member-role.entity-C4DGSm2r.mjs.map +1 -0
  247. package/fesm2022/{acorex-modules-organization-management-team-member.entity-Bz4o7c3d.mjs → acorex-modules-organization-management-team-member.entity-CvVHEzIU.mjs} +6 -17
  248. package/fesm2022/acorex-modules-organization-management-team-member.entity-CvVHEzIU.mjs.map +1 -0
  249. package/fesm2022/{acorex-modules-organization-management-team.entity-uVffZPeg.mjs → acorex-modules-organization-management-team.entity-urjULfNp.mjs} +18 -13
  250. package/fesm2022/acorex-modules-organization-management-team.entity-urjULfNp.mjs.map +1 -0
  251. package/fesm2022/acorex-modules-organization-management.mjs +1 -1
  252. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-Dl-3IE-C.mjs → acorex-modules-platform-management-acorex-modules-platform-management-CZMqG3Eq.mjs} +10 -2
  253. package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-Dl-3IE-C.mjs.map → acorex-modules-platform-management-acorex-modules-platform-management-CZMqG3Eq.mjs.map} +1 -1
  254. package/fesm2022/acorex-modules-platform-management-list-registered-data-sources.query-DdDvT0uh.mjs +81 -0
  255. package/fesm2022/acorex-modules-platform-management-list-registered-data-sources.query-DdDvT0uh.mjs.map +1 -0
  256. package/fesm2022/{acorex-modules-platform-management-menu-list.component-Brwqsawl.mjs → acorex-modules-platform-management-menu-list.component-BRA7Q50z.mjs} +2 -2
  257. package/fesm2022/{acorex-modules-platform-management-menu-list.component-Brwqsawl.mjs.map → acorex-modules-platform-management-menu-list.component-BRA7Q50z.mjs.map} +1 -1
  258. package/fesm2022/acorex-modules-platform-management.mjs +1 -1
  259. package/fesm2022/{acorex-modules-product-catalog-product.entity-aVWXuhlQ.mjs → acorex-modules-product-catalog-product.entity-BbB7GAg7.mjs} +3 -2
  260. package/fesm2022/acorex-modules-product-catalog-product.entity-BbB7GAg7.mjs.map +1 -0
  261. package/fesm2022/acorex-modules-product-catalog.mjs +1 -1
  262. package/fesm2022/acorex-modules-report-management.mjs +2 -2
  263. package/fesm2022/acorex-modules-report-management.mjs.map +1 -1
  264. package/fesm2022/acorex-modules-security-management.mjs +531 -188
  265. package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
  266. package/fesm2022/acorex-modules-supplier-management.mjs +1 -0
  267. package/fesm2022/acorex-modules-supplier-management.mjs.map +1 -1
  268. package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-it-Lf0L_.mjs +6066 -0
  269. package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-it-Lf0L_.mjs.map +1 -0
  270. package/fesm2022/{acorex-modules-task-management-task-board.page-DA2563QE.mjs → acorex-modules-task-management-task-board.page-DF4XWz_0.mjs} +260 -87
  271. package/fesm2022/acorex-modules-task-management-task-board.page-DF4XWz_0.mjs.map +1 -0
  272. package/fesm2022/acorex-modules-task-management.mjs +1 -5820
  273. package/fesm2022/acorex-modules-task-management.mjs.map +1 -1
  274. package/fesm2022/acorex-modules-tenant-management.mjs +6 -15
  275. package/fesm2022/acorex-modules-tenant-management.mjs.map +1 -1
  276. package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs → acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-Dj6LkQeZ.mjs} +5 -5
  277. package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs.map → acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-Dj6LkQeZ.mjs.map} +1 -1
  278. package/fesm2022/{acorex-modules-workflow-management-index-C9Qc07oK.mjs → acorex-modules-workflow-management-index-CHySddpP.mjs} +2 -64
  279. package/fesm2022/acorex-modules-workflow-management-index-CHySddpP.mjs.map +1 -0
  280. package/fesm2022/{acorex-modules-workflow-management-index-DMnJRDbq.mjs → acorex-modules-workflow-management-index-Eh5DDK-V.mjs} +5 -4
  281. package/fesm2022/acorex-modules-workflow-management-index-Eh5DDK-V.mjs.map +1 -0
  282. package/fesm2022/{acorex-modules-workflow-management-index-D8fjNgQJ.mjs → acorex-modules-workflow-management-index-V4OesZTq.mjs} +6 -6
  283. package/fesm2022/{acorex-modules-workflow-management-index-D8fjNgQJ.mjs.map → acorex-modules-workflow-management-index-V4OesZTq.mjs.map} +1 -1
  284. package/fesm2022/{acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs → acorex-modules-workflow-management-workflow-definition.entity-CjQQpjdB.mjs} +1 -16
  285. package/fesm2022/{acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs.map → acorex-modules-workflow-management-workflow-definition.entity-CjQQpjdB.mjs.map} +1 -1
  286. package/fesm2022/{acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs → acorex-modules-workflow-management-workflow-instance.entity-B_V3uMSI.mjs} +30 -20
  287. package/fesm2022/acorex-modules-workflow-management-workflow-instance.entity-B_V3uMSI.mjs.map +1 -0
  288. package/fesm2022/{acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs → acorex-modules-workflow-management-workflow-task-popover.component-l37iXJIY.mjs} +19 -15
  289. package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-l37iXJIY.mjs.map +1 -0
  290. package/fesm2022/acorex-modules-workflow-management.mjs +269 -2392
  291. package/fesm2022/acorex-modules-workflow-management.mjs.map +1 -1
  292. package/organization-management/README.md +4 -0
  293. package/package.json +2 -2
  294. package/types/acorex-modules-ai-management.d.ts +563 -59
  295. package/types/acorex-modules-asset-management.d.ts +142 -31
  296. package/types/acorex-modules-business-core.d.ts +8 -11
  297. package/types/acorex-modules-common.d.ts +42 -7
  298. package/types/acorex-modules-conversation.d.ts +1 -0
  299. package/types/acorex-modules-dashboard-management.d.ts +146 -81
  300. package/types/acorex-modules-document-management.d.ts +24 -4
  301. package/types/acorex-modules-financial-core.d.ts +26 -19
  302. package/types/acorex-modules-form-template-management.d.ts +3 -3
  303. package/types/acorex-modules-health-core.d.ts +23 -29
  304. package/types/acorex-modules-human-capital-management.d.ts +23 -3
  305. package/types/acorex-modules-learning-management.d.ts +242 -105
  306. package/types/acorex-modules-maintenance-management.d.ts +13 -14
  307. package/types/acorex-modules-measurement-core.d.ts +95 -33
  308. package/types/acorex-modules-organization-management.d.ts +235 -17
  309. package/types/acorex-modules-reservation-management.d.ts +6 -5
  310. package/types/acorex-modules-security-management.d.ts +32 -7
  311. package/types/acorex-modules-task-management.d.ts +45 -6
  312. package/types/acorex-modules-workflow-management.d.ts +68 -549
  313. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-CU2FvMTx.mjs.map +0 -1
  314. package/fesm2022/acorex-modules-ai-management-agent.entity-CUO9Jczk.mjs.map +0 -1
  315. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-daTGJ1Rd.mjs.map +0 -1
  316. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-Cmprtps-.mjs.map +0 -1
  317. package/fesm2022/acorex-modules-ai-management-assist.entity-C1nM_x4Z.mjs.map +0 -1
  318. package/fesm2022/acorex-modules-ai-management-index-CjTjfydP.mjs +0 -2
  319. package/fesm2022/acorex-modules-ai-management-model.entity-CPHxj8h7.mjs.map +0 -1
  320. package/fesm2022/acorex-modules-ai-management-open-ai-endpoint.entity-a6MjMiXF.mjs.map +0 -1
  321. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-F7Ok5dhs.mjs.map +0 -1
  322. package/fesm2022/acorex-modules-asset-management-asset-system-history.entity-D1HZG9wO.mjs.map +0 -1
  323. package/fesm2022/acorex-modules-asset-management-asset-system-type.entity-DDh5RK5M.mjs.map +0 -1
  324. package/fesm2022/acorex-modules-asset-management-asset-type.entity-DWhrFVFI.mjs.map +0 -1
  325. package/fesm2022/acorex-modules-asset-management-asset.entity-BEjXfkPD.mjs.map +0 -1
  326. package/fesm2022/acorex-modules-asset-management-assetSystem.entity-CJCVALaz.mjs.map +0 -1
  327. package/fesm2022/acorex-modules-health-core-allergy-type.entity-CS8a-AUb.mjs.map +0 -1
  328. package/fesm2022/acorex-modules-health-core-blood-type.entity-ZgFOuvG4.mjs.map +0 -1
  329. package/fesm2022/acorex-modules-health-core-body-part.entity-JGLwrFE2.mjs.map +0 -1
  330. package/fesm2022/acorex-modules-health-core-chronic-condition-type.entity-DrxEPQj1.mjs.map +0 -1
  331. package/fesm2022/acorex-modules-health-core-disability-status.entity-UaAQFFMC.mjs.map +0 -1
  332. package/fesm2022/acorex-modules-health-core-injury-type.entity-DcIn0rxz.mjs.map +0 -1
  333. package/fesm2022/acorex-modules-health-core-vaccination-type.entity-zYd6KLRC.mjs.map +0 -1
  334. package/fesm2022/acorex-modules-human-capital-management-employee.entity-BmF6_P6d.mjs.map +0 -1
  335. package/fesm2022/acorex-modules-human-capital-management-employment-type.entity-7ZGZYxGM.mjs.map +0 -1
  336. package/fesm2022/acorex-modules-human-capital-management-leave-request.entity-B3Rk84bJ.mjs.map +0 -1
  337. package/fesm2022/acorex-modules-human-capital-management-leave-type.entity-OKu8_PP1.mjs.map +0 -1
  338. package/fesm2022/acorex-modules-human-capital-management-position-assignment.entity-D_C459kx.mjs.map +0 -1
  339. package/fesm2022/acorex-modules-learning-management-certificate-definition.entity-27VKYxw1.mjs.map +0 -1
  340. package/fesm2022/acorex-modules-learning-management-certificate-type.entity-CBM6N-PD.mjs.map +0 -1
  341. package/fesm2022/acorex-modules-learning-management-certificate.entity-BRBJQYji.mjs.map +0 -1
  342. package/fesm2022/acorex-modules-learning-management-course-type.entity-B1c6PDLq.mjs.map +0 -1
  343. package/fesm2022/acorex-modules-learning-management-course.entity-BN8XHAPz.mjs.map +0 -1
  344. package/fesm2022/acorex-modules-learning-management-learning-path.entity-8QlM3R4B.mjs.map +0 -1
  345. package/fesm2022/acorex-modules-learning-management-skill-level.entity-DXOWslpB.mjs.map +0 -1
  346. package/fesm2022/acorex-modules-learning-management-skill-matrix-widget-edit.component-CaeZ9P_I.mjs +0 -162
  347. package/fesm2022/acorex-modules-learning-management-skill-matrix-widget-edit.component-CaeZ9P_I.mjs.map +0 -1
  348. package/fesm2022/acorex-modules-learning-management-skill-matrix-widget-view.component-1oWMtdrN.mjs +0 -70
  349. package/fesm2022/acorex-modules-learning-management-skill-matrix-widget-view.component-1oWMtdrN.mjs.map +0 -1
  350. package/fesm2022/acorex-modules-learning-management-skill-matrix.component-_cFwIN-z.mjs +0 -468
  351. package/fesm2022/acorex-modules-learning-management-skill-matrix.component-_cFwIN-z.mjs.map +0 -1
  352. package/fesm2022/acorex-modules-learning-management-skill.entity-DrLts807.mjs.map +0 -1
  353. package/fesm2022/acorex-modules-learning-management-training-definition.entity-NQqJ5avw.mjs.map +0 -1
  354. package/fesm2022/acorex-modules-learning-management-training-type.entity-CoyDCeen.mjs.map +0 -1
  355. package/fesm2022/acorex-modules-learning-management-training.entity-BCGn0T3H.mjs.map +0 -1
  356. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-DtODwbIN.mjs.map +0 -1
  357. package/fesm2022/acorex-modules-maintenance-management-failure-register.entity-CUxVZo0w.mjs.map +0 -1
  358. package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-D6ATa-HR.mjs.map +0 -1
  359. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-BrVNMCi_.mjs +0 -356
  360. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-BrVNMCi_.mjs.map +0 -1
  361. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-CO8jMwVJ.mjs +0 -181
  362. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-CO8jMwVJ.mjs.map +0 -1
  363. package/fesm2022/acorex-modules-organization-management-business-unit.entity-WiTemBLu.mjs.map +0 -1
  364. package/fesm2022/acorex-modules-organization-management-chart.entity-D6Y7kZfM.mjs.map +0 -1
  365. package/fesm2022/acorex-modules-organization-management-company.entity-wpNiu8g3.mjs.map +0 -1
  366. package/fesm2022/acorex-modules-organization-management-entity.provider-B0XbUW1I.mjs.map +0 -1
  367. package/fesm2022/acorex-modules-organization-management-job-definition.entity-Cb6zEf65.mjs.map +0 -1
  368. package/fesm2022/acorex-modules-organization-management-job-level.datasource-RDGmLrqD.mjs.map +0 -1
  369. package/fesm2022/acorex-modules-organization-management-job-level.entity-oedF18Xm.mjs.map +0 -1
  370. package/fesm2022/acorex-modules-organization-management-org-chart.page-mHV0AWGZ.mjs +0 -1081
  371. package/fesm2022/acorex-modules-organization-management-org-chart.page-mHV0AWGZ.mjs.map +0 -1
  372. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs +0 -56
  373. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs.map +0 -1
  374. package/fesm2022/acorex-modules-organization-management-position.entity-BveMCKMd.mjs.map +0 -1
  375. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-ivufxxLL.mjs.map +0 -1
  376. package/fesm2022/acorex-modules-organization-management-responsibility-level.entity-zOjyjm5H.mjs.map +0 -1
  377. package/fesm2022/acorex-modules-organization-management-responsibility.entity-jWEiPi5-.mjs.map +0 -1
  378. package/fesm2022/acorex-modules-organization-management-settings.provider-D3ged-4h.mjs.map +0 -1
  379. package/fesm2022/acorex-modules-organization-management-team-member-role.entity-D9TZoACE.mjs.map +0 -1
  380. package/fesm2022/acorex-modules-organization-management-team-member.entity-Bz4o7c3d.mjs.map +0 -1
  381. package/fesm2022/acorex-modules-organization-management-team.entity-uVffZPeg.mjs.map +0 -1
  382. package/fesm2022/acorex-modules-organization-management-widget-definition.provider-D4yjuqwx.mjs +0 -48
  383. package/fesm2022/acorex-modules-organization-management-widget-definition.provider-D4yjuqwx.mjs.map +0 -1
  384. package/fesm2022/acorex-modules-product-catalog-product.entity-aVWXuhlQ.mjs.map +0 -1
  385. package/fesm2022/acorex-modules-task-management-task-board.page-DA2563QE.mjs.map +0 -1
  386. package/fesm2022/acorex-modules-workflow-management-index-C9Qc07oK.mjs.map +0 -1
  387. package/fesm2022/acorex-modules-workflow-management-index-DMnJRDbq.mjs.map +0 -1
  388. package/fesm2022/acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs.map +0 -1
  389. package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs.map +0 -1
@@ -1,49 +1,26 @@
1
1
  import * as i0 from '@angular/core';
2
- import { Injectable, inject, NgModule, InjectionToken, Inject, makeEnvironmentProviders, Injector, runInInjectionContext, output, ViewEncapsulation, ChangeDetectionStrategy, Component, DestroyRef, signal, computed, effect, viewChild } from '@angular/core';
2
+ import { Injectable, inject, NgModule, InjectionToken, Inject, makeEnvironmentProviders, Injector, runInInjectionContext } from '@angular/core';
3
3
  import { AXPCommonMenuKeys, AXPWidgetsList } from '@acorex/modules/common';
4
- import { AXPSessionService, AXPAuthGuard, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex/platform/auth';
5
- import { AXPEntityService, AXPEntityFormBuilderService, AXPEntityDefinitionRegistryService, entityDetailsCrudActions, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
4
+ import { AXPSessionService, AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex/platform/auth';
5
+ import { AXPEntityService, AXPEntityFormBuilderService, AXPEntityDefinitionRegistryService, entityDetailsCrudActions, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
6
6
  import { firstValueFrom } from 'rxjs';
7
7
  import { AXMCalendarManagementModule } from '@acorex/modules/calendar-management';
8
8
  import { AXPEntityCommandScope, AXPStatusProvider, AXPSystemStatusType, systemStatusToDefinition, AXPSystemStatuses, AXP_STATUS_PROVIDERS, AXP_MENU_PROVIDER } from '@acorex/platform/common';
9
9
  import { AXPSystemActionType, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, provideLazyProvider } from '@acorex/platform/core';
10
- import { AXP_PAGE_COMPONENT_PROVIDER, AXPPropertyViewerComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutToolbarComponent, AXPThemeLayoutStartSideComponent } from '@acorex/platform/layout/components';
10
+ import { AXP_PAGE_COMPONENT_PROVIDER } from '@acorex/platform/layout/components';
11
11
  import { AXPDomainModule } from '@acorex/platform/domain';
12
- import { AXPWidgetGroupEnum, AXP_WIDGETS_EDITOR_CATEGORY, AXPWidgetSerializationHelper, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER, mapAXPPropertyToWidgetProperty } from '@acorex/platform/layout/widget-core';
12
+ import { AXPWidgetGroupEnum, AXP_WIDGETS_EDITOR_CATEGORY, AXPWidgetSerializationHelper, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
13
13
  import { AXPBarChartWidget, AXPHeatmapChartWidget, AXPDonutChartWidget, AXPLineChartWidget, AXPGaugeChartWidget, AXPFunnelChartWidget, AXPKpiDetailsWidget, AXPKpiProgressWidget, AXPKpiSegmentedWidget, AXPKpiStatCardWidget } from '@acorex/modules/dashboard-management';
14
- import * as i5$1 from '@acorex/core/translation';
15
- import { createMultiLanguageString, AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
16
14
  import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY } from '@acorex/platform/layout/widgets';
17
15
  import { provideCommandSetups } from '@acorex/platform/runtime';
18
- import { AXPWorkflowManager, AXPWorkflowDefinitionService, AXP_WORKFLOW_PROVIDER, AXP_ACTIVITY_CATEGORY_PROVIDER, AXP_ACTIVITY_PROVIDER, AXP_WORKFLOW_CATEGORY_PROVIDER, AXPActivityDefinitionService } from '@acorex/platform/workflow';
19
- import { ROUTES, ActivatedRoute, Router } from '@angular/router';
16
+ import { AXPWorkflowManager, AXPWorkflowDefinitionService, AXP_WORKFLOW_PROVIDER, AXP_ACTIVITY_CATEGORY_PROVIDER, AXP_ACTIVITY_PROVIDER, AXP_WORKFLOW_CATEGORY_PROVIDER } from '@acorex/platform/workflow';
20
17
  import { AXDialogService } from '@acorex/components/dialog';
18
+ import { AXTranslationService } from '@acorex/core/translation';
21
19
  import { AXPopupService } from '@acorex/components/popup';
22
20
  import { AXPDialogRendererComponent, AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
23
21
  import { cloneDeep } from 'lodash-es';
24
22
  import { AXToastService } from '@acorex/components/toast';
25
23
  import { AXPWorkflowTaskProvider, AXP_WORKFLOW_TASK_PROVIDER } from '@acorex/modules/task-management';
26
- import * as i2 from '@acorex/components/button';
27
- import { AXButtonModule } from '@acorex/components/button';
28
- import * as i2$1 from '@acorex/components/button-group';
29
- import { AXButtonGroupModule } from '@acorex/components/button-group';
30
- import * as i3 from '@acorex/components/decorators';
31
- import { AXDecoratorModule } from '@acorex/components/decorators';
32
- import * as i5 from '@acorex/components/search-box';
33
- import { AXSearchBoxModule } from '@acorex/components/search-box';
34
- import { AXSelectBoxModule } from '@acorex/components/select-box';
35
- import * as i6 from '@acorex/components/switch';
36
- import { AXSwitchModule } from '@acorex/components/switch';
37
- import { AXTabsModule } from '@acorex/components/tabs';
38
- import * as i4 from '@acorex/components/text-box';
39
- import { AXTextBoxModule } from '@acorex/components/text-box';
40
- import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
41
- import * as i7 from '@angular/common';
42
- import { CommonModule } from '@angular/common';
43
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
44
- import { FormsModule } from '@angular/forms';
45
- import * as i1 from '@acorex/components/tree-view-legacy';
46
- import { AXTreeViewLegacyModule } from '@acorex/components/tree-view-legacy';
47
24
 
48
25
  const config = {
49
26
  i18n: 'workflow-management',
@@ -179,9 +156,9 @@ class AXMWorkflowManagementModuleEntityProvider {
179
156
  if (moduleName === RootConfig.module.name) {
180
157
  switch (entityName) {
181
158
  case RootConfig.entities.workflowDefinition.name:
182
- return (await import('./acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs')).factory();
159
+ return (await import('./acorex-modules-workflow-management-workflow-definition.entity-CjQQpjdB.mjs')).factory();
183
160
  case RootConfig.entities.workflowInstance.name:
184
- return (await import('./acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs')).factory();
161
+ return (await import('./acorex-modules-workflow-management-workflow-instance.entity-B_V3uMSI.mjs')).factory();
185
162
  case RootConfig.entities.activityDefinition.name:
186
163
  return (await import('./acorex-modules-workflow-management-activity-definition.entity-B3DkgDQb.mjs')).factory();
187
164
  case RootConfig.entities.automation.name:
@@ -206,7 +183,6 @@ const AXPWorkflowManagementMenuKeys = {
206
183
  Workflow: 'workflow-management:workflow',
207
184
  WorkflowDefinitions: 'workflow-management:workflow-definitions',
208
185
  WorkflowInstances: 'workflow-management:workflow-instances',
209
- WorkflowStudio: 'workflow-management:workflow-studio',
210
186
  Activities: 'workflow-management:activities',
211
187
  };
212
188
 
@@ -221,7 +197,6 @@ class AXMMenuProvider {
221
197
  return;
222
198
  }
223
199
  const module = RootConfig.module;
224
- const appName = this.sessionService.application?.name ?? module.name;
225
200
  const workflowsMenu = context.find(AXPCommonMenuKeys.Workflows);
226
201
  if (!workflowsMenu.exists) {
227
202
  context.find(AXPCommonMenuKeys.Administration).addItems([
@@ -256,16 +231,6 @@ class AXMMenuProvider {
256
231
  features: [module.name],
257
232
  },
258
233
  },
259
- {
260
- name: AXPWorkflowManagementMenuKeys.WorkflowStudio,
261
- text: '@workflow-management:workflow-studio.menus.workflow-studio.title',
262
- path: `/${appName}/workflow-management/studio`,
263
- priority: 3,
264
- icon: 'fa-light fa-wrench',
265
- policy: {
266
- features: [module.name],
267
- },
268
- },
269
234
  ]);
270
235
  }
271
236
  }
@@ -277,8 +242,57 @@ class AXMMenuProvider {
277
242
  const AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY = {
278
243
  name: 'workflow',
279
244
  order: 3,
280
- title: createMultiLanguageString('Workflow', 'گردش کار'),
245
+ title: '@workflow-management:dashboard-widgets.widget-picker-category.workflow',
246
+ };
247
+
248
+ const SUB = '@workflow-management:dashboard-widgets.widget-picker-sub-categories';
249
+ //#region ---- Workflow dashboard widget picker sub-categories ----
250
+ const AXP_WORKFLOW_DASHBOARD_SUB_KPI = {
251
+ name: 'workflow-kpi',
252
+ order: 1,
253
+ title: `${SUB}.kpi`,
254
+ };
255
+ const AXP_WORKFLOW_DASHBOARD_SUB_THROUGHPUT = {
256
+ name: 'workflow-throughput',
257
+ order: 2,
258
+ title: `${SUB}.throughput`,
259
+ };
260
+ const AXP_WORKFLOW_DASHBOARD_SUB_FAILURES = {
261
+ name: 'workflow-failures',
262
+ order: 3,
263
+ title: `${SUB}.failures`,
264
+ };
265
+ const AXP_WORKFLOW_DASHBOARD_SUB_ERRORS = {
266
+ name: 'workflow-errors',
267
+ order: 4,
268
+ title: `${SUB}.errors`,
269
+ };
270
+ const AXP_WORKFLOW_DASHBOARD_SUB_SLA = {
271
+ name: 'workflow-sla',
272
+ order: 5,
273
+ title: `${SUB}.sla`,
274
+ };
275
+ const AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD = {
276
+ name: 'workflow-workload',
277
+ order: 6,
278
+ title: `${SUB}.workload`,
279
+ };
280
+ const AXP_WORKFLOW_DASHBOARD_SUB_TASKS = {
281
+ name: 'workflow-tasks',
282
+ order: 7,
283
+ title: `${SUB}.tasks`,
284
+ };
285
+ const AXP_WORKFLOW_DASHBOARD_SUB_SYSTEM_HEALTH = {
286
+ name: 'workflow-system-health',
287
+ order: 8,
288
+ title: `${SUB}.system-health`,
289
+ };
290
+ const AXP_WORKFLOW_DASHBOARD_SUB_USER = {
291
+ name: 'workflow-user',
292
+ order: 9,
293
+ title: `${SUB}.user`,
281
294
  };
295
+ //#endregion
282
296
 
283
297
  const AXMWorkflowErrorsBarChartAXPExtendedWidget = {
284
298
  parentName: AXPBarChartWidget.name,
@@ -289,6 +303,7 @@ const AXMWorkflowErrorsBarChartAXPExtendedWidget = {
289
303
  description: '@workflow-management:dashboard-widgets.workflow-errors-bar.widget-description',
290
304
  groups: [AXPWidgetGroupEnum.DashboardWidget],
291
305
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
306
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_ERRORS,
292
307
  options: {
293
308
  title: '@workflow-management:dashboard-widgets.workflow-errors-bar.chart-title',
294
309
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-errors-bar.x-axis-label',
@@ -320,6 +335,7 @@ const AXMWorkflowErrorsHeatmapAXPExtendedWidget = {
320
335
  description: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.widget-description',
321
336
  groups: [AXPWidgetGroupEnum.DashboardWidget],
322
337
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
338
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_ERRORS,
323
339
  options: {
324
340
  showXAxis: true,
325
341
  showYAxis: true,
@@ -348,6 +364,7 @@ const AXMWorkflowFailedProcessesByTypeDonutChartAXPExtendedWidget = {
348
364
  description: '@workflow-management:dashboard-widgets.workflow-failed-processes-by-type-donut.widget-description',
349
365
  groups: [AXPWidgetGroupEnum.DashboardWidget],
350
366
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
367
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_FAILURES,
351
368
  options: {
352
369
  title: '@workflow-management:dashboard-widgets.workflow-failed-processes-by-type-donut.chart-title',
353
370
  dataSource: RootConfig.dataSources.dashboardChart.failedProcessesByType,
@@ -364,6 +381,7 @@ const AXMWorkflowFailedProcessesSummaryBarChartAXPExtendedWidget = {
364
381
  description: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.widget-description',
365
382
  groups: [AXPWidgetGroupEnum.DashboardWidget],
366
383
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
384
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_FAILURES,
367
385
  options: {
368
386
  title: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.chart-title',
369
387
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.x-axis-label',
@@ -382,6 +400,7 @@ const AXMWorkflowFailedProcessesTrendLineChartAXPExtendedWidget = {
382
400
  description: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.widget-description',
383
401
  groups: [AXPWidgetGroupEnum.DashboardWidget],
384
402
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
403
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_FAILURES,
385
404
  options: {
386
405
  title: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.chart-title',
387
406
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.x-axis-label',
@@ -402,6 +421,7 @@ const AXMWorkflowStuckProcessesBarChartAXPExtendedWidget = {
402
421
  description: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.widget-description',
403
422
  groups: [AXPWidgetGroupEnum.DashboardWidget],
404
423
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
424
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_FAILURES,
405
425
  options: {
406
426
  title: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.chart-title',
407
427
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.x-axis-label',
@@ -420,6 +440,7 @@ const AXMWorkflowGaugeChartAXPExtendedWidget = {
420
440
  description: '@workflow-management:dashboard-widgets.workflow-gauge-chart.widget-description',
421
441
  groups: [AXPWidgetGroupEnum.DashboardWidget],
422
442
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
443
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_SLA,
423
444
  options: {
424
445
  title: '@workflow-management:dashboard-widgets.workflow-gauge-chart.chart-title',
425
446
  label: '@workflow-management:dashboard-widgets.workflow-gauge-chart.gauge-label',
@@ -456,6 +477,7 @@ const AXMWorkflowSlaRiskPredictionBarChartAXPExtendedWidget = {
456
477
  description: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.widget-description',
457
478
  groups: [AXPWidgetGroupEnum.DashboardWidget],
458
479
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
480
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_SLA,
459
481
  options: {
460
482
  title: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.chart-title',
461
483
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.x-axis-label',
@@ -474,6 +496,7 @@ const AXMWorkflowSlaTrendLineChartAXPExtendedWidget = {
474
496
  description: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.widget-description',
475
497
  groups: [AXPWidgetGroupEnum.DashboardWidget],
476
498
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
499
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_SLA,
477
500
  options: {
478
501
  title: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.chart-title',
479
502
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.x-axis-label',
@@ -494,6 +517,7 @@ const AXMWorkflowSlaViolationsBarChartAXPExtendedWidget = {
494
517
  description: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.widget-description',
495
518
  groups: [AXPWidgetGroupEnum.DashboardWidget],
496
519
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
520
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_SLA,
497
521
  options: {
498
522
  title: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.chart-title',
499
523
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.x-axis-label',
@@ -512,6 +536,7 @@ const AXMWorkflowSystemHealthBarChartAXPExtendedWidget = {
512
536
  description: '@workflow-management:dashboard-widgets.workflow-system-health-bar.widget-description',
513
537
  groups: [AXPWidgetGroupEnum.DashboardWidget],
514
538
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
539
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_SYSTEM_HEALTH,
515
540
  options: {
516
541
  title: '@workflow-management:dashboard-widgets.workflow-system-health-bar.chart-title',
517
542
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-system-health-bar.x-axis-label',
@@ -530,6 +555,7 @@ const AXMWorkflowOverdueTasksBarChartAXPExtendedWidget = {
530
555
  description: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.widget-description',
531
556
  groups: [AXPWidgetGroupEnum.DashboardWidget],
532
557
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
558
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_TASKS,
533
559
  options: {
534
560
  title: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.chart-title',
535
561
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.x-axis-label',
@@ -548,6 +574,7 @@ const AXMWorkflowPendingTasksByAgeBarChartAXPExtendedWidget = {
548
574
  description: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.widget-description',
549
575
  groups: [AXPWidgetGroupEnum.DashboardWidget],
550
576
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
577
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_TASKS,
551
578
  options: {
552
579
  title: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.chart-title',
553
580
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.x-axis-label',
@@ -566,6 +593,7 @@ const AXMWorkflowLineChartAXPExtendedWidget = {
566
593
  description: '@workflow-management:dashboard-widgets.workflow-line-chart.widget-description',
567
594
  groups: [AXPWidgetGroupEnum.DashboardWidget],
568
595
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
596
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_THROUGHPUT,
569
597
  options: {
570
598
  title: '@workflow-management:dashboard-widgets.workflow-line-chart.chart-title',
571
599
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-line-chart.x-axis-label',
@@ -594,6 +622,7 @@ const AXMWorkflowInstanceConversionFunnelAXPExtendedWidget = {
594
622
  description: '@workflow-management:dashboard-widgets.workflow-instance-conversion-funnel.widget-description',
595
623
  groups: [AXPWidgetGroupEnum.DashboardWidget],
596
624
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
625
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_THROUGHPUT,
597
626
  options: {
598
627
  showLabels: true,
599
628
  showTooltip: true,
@@ -618,6 +647,7 @@ const AXMWorkflowThroughputDailyLineChartAXPExtendedWidget = {
618
647
  description: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.widget-description',
619
648
  groups: [AXPWidgetGroupEnum.DashboardWidget],
620
649
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
650
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_THROUGHPUT,
621
651
  options: {
622
652
  title: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.chart-title',
623
653
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.x-axis-label',
@@ -638,6 +668,7 @@ const AXMWorkflowThroughputWeeklyLineChartAXPExtendedWidget = {
638
668
  description: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.widget-description',
639
669
  groups: [AXPWidgetGroupEnum.DashboardWidget],
640
670
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
671
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_THROUGHPUT,
641
672
  options: {
642
673
  title: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.chart-title',
643
674
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.x-axis-label',
@@ -658,6 +689,7 @@ const AXMWorkflowBottleneckBarChartAXPExtendedWidget = {
658
689
  description: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.widget-description',
659
690
  groups: [AXPWidgetGroupEnum.DashboardWidget],
660
691
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
692
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
661
693
  options: {
662
694
  title: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.chart-title',
663
695
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.x-axis-label',
@@ -676,6 +708,7 @@ const AXMWorkflowDonutChartAXPExtendedWidget = {
676
708
  description: '@workflow-management:dashboard-widgets.workflow-donut-chart.widget-description',
677
709
  groups: [AXPWidgetGroupEnum.DashboardWidget],
678
710
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
711
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
679
712
  options: {
680
713
  title: '@workflow-management:dashboard-widgets.workflow-donut-chart.chart-title',
681
714
  dataSource: RootConfig.dataSources.dashboardChart.workloadByProcess,
@@ -692,6 +725,7 @@ const AXMWorkflowOverloadedUsersBarChartAXPExtendedWidget = {
692
725
  description: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.widget-description',
693
726
  groups: [AXPWidgetGroupEnum.DashboardWidget],
694
727
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
728
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
695
729
  options: {
696
730
  title: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.chart-title',
697
731
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.x-axis-label',
@@ -710,6 +744,7 @@ const AXMWorkflowWorkloadPerUserActiveBarChartAXPExtendedWidget = {
710
744
  description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.widget-description',
711
745
  groups: [AXPWidgetGroupEnum.DashboardWidget],
712
746
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
747
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
713
748
  options: {
714
749
  title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.chart-title',
715
750
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.x-axis-label',
@@ -728,6 +763,7 @@ const AXMWorkflowWorkloadPerUserAvgAgeBarChartAXPExtendedWidget = {
728
763
  description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.widget-description',
729
764
  groups: [AXPWidgetGroupEnum.DashboardWidget],
730
765
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
766
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
731
767
  options: {
732
768
  title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.chart-title',
733
769
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.x-axis-label',
@@ -746,6 +782,7 @@ const AXMWorkflowWorkloadPerUserOverdueBarChartAXPExtendedWidget = {
746
782
  description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.widget-description',
747
783
  groups: [AXPWidgetGroupEnum.DashboardWidget],
748
784
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
785
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_WORKLOAD,
749
786
  options: {
750
787
  title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.chart-title',
751
788
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.x-axis-label',
@@ -764,6 +801,7 @@ const AXMWorkflowKpiDetailsAXPExtendedWidget = {
764
801
  description: '@workflow-management:dashboard-widgets.workflow-kpi-details.widget-description',
765
802
  groups: [AXPWidgetGroupEnum.DashboardWidget],
766
803
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
804
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_KPI,
767
805
  options: {
768
806
  title: '@workflow-management:dashboard-widgets.workflow-kpi-details.options-title',
769
807
  subtitle: '@workflow-management:dashboard-widgets.workflow-kpi-details.options-subtitle',
@@ -782,6 +820,7 @@ const AXMWorkflowKpiProgressAXPExtendedWidget = {
782
820
  description: '@workflow-management:dashboard-widgets.workflow-kpi-progress.widget-description',
783
821
  groups: [AXPWidgetGroupEnum.DashboardWidget],
784
822
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
823
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_KPI,
785
824
  options: {
786
825
  subtitle: '@workflow-management:dashboard-widgets.workflow-kpi-progress.options-subtitle',
787
826
  valueSuffix: '%',
@@ -800,6 +839,7 @@ const AXMWorkflowKpiSegmentedAXPExtendedWidget = {
800
839
  description: '@workflow-management:dashboard-widgets.workflow-kpi-segmented.widget-description',
801
840
  groups: [AXPWidgetGroupEnum.DashboardWidget],
802
841
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
842
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_KPI,
803
843
  options: {
804
844
  title: '@workflow-management:dashboard-widgets.workflow-kpi-segmented.options-title',
805
845
  dataSource: RootConfig.dataSources.dashboardKpi.taskStatusBreakdown,
@@ -816,6 +856,7 @@ const AXMWorkflowKpiStatCardAXPExtendedWidget = {
816
856
  description: '@workflow-management:dashboard-widgets.workflow-kpi-stat-card.widget-description',
817
857
  groups: [AXPWidgetGroupEnum.DashboardWidget],
818
858
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
859
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_KPI,
819
860
  options: {
820
861
  dataSource: RootConfig.dataSources.dashboardKpi.kpiStatCard,
821
862
  },
@@ -831,6 +872,7 @@ const AXMWorkflowBarChartAXPExtendedWidget = {
831
872
  description: '@workflow-management:dashboard-widgets.workflow-bar-chart.widget-description',
832
873
  groups: [AXPWidgetGroupEnum.DashboardWidget],
833
874
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
875
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_USER,
834
876
  options: {
835
877
  title: '@workflow-management:dashboard-widgets.workflow-bar-chart.chart-title',
836
878
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-bar-chart.x-axis-label',
@@ -849,6 +891,7 @@ const AXMWorkflowTasksNearDeadlineBarChartAXPExtendedWidget = {
849
891
  description: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.widget-description',
850
892
  groups: [AXPWidgetGroupEnum.DashboardWidget],
851
893
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
894
+ subCategory: AXP_WORKFLOW_DASHBOARD_SUB_USER,
852
895
  options: {
853
896
  title: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.chart-title',
854
897
  xAxisLabel: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.x-axis-label',
@@ -944,10 +987,10 @@ const AXMActivityCommandConfiguratorWidget = {
944
987
  ],
945
988
  components: {
946
989
  edit: {
947
- component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
990
+ component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-Dj6LkQeZ.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
948
991
  },
949
992
  designer: {
950
- component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
993
+ component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-Dj6LkQeZ.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
951
994
  },
952
995
  column: {
953
996
  component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-column.component-CDo0QVFy.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetColumnComponent),
@@ -1285,6 +1328,77 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
1285
1328
  type: Injectable
1286
1329
  }] });
1287
1330
 
1331
+ //#region ---- Imports ----
1332
+ //#endregion
1333
+ /**
1334
+ * Cartable task activity (frontend): suspends workflow with candidate users only.
1335
+ * Assignee is set when a candidate claims the task on the task board (bookmark update).
1336
+ *
1337
+ * Activity Type: workflow-activity:cartable
1338
+ */
1339
+ class CartableTaskActivity {
1340
+ //#region ---- AXPCommand Implementation ----
1341
+ async execute(input) {
1342
+ console.log('[CartableTaskActivity] input', input.context?.['input'] ?? 'no input');
1343
+ try {
1344
+ if (!input.title && !input.description) {
1345
+ console.warn('[CartableTaskActivity] No title or description provided');
1346
+ }
1347
+ const availableOutcomes = [];
1348
+ const rawActions = input.actions;
1349
+ if (rawActions) {
1350
+ try {
1351
+ const actions = typeof rawActions === 'string' ? JSON.parse(rawActions) : rawActions;
1352
+ const prefix = actions?.prefix ?? [];
1353
+ const suffix = actions?.suffix ?? [];
1354
+ for (const item of [...prefix, ...suffix]) {
1355
+ const name = item?.command?.name ?? item?.name;
1356
+ if (name && typeof name === 'string')
1357
+ availableOutcomes.push(name);
1358
+ }
1359
+ }
1360
+ catch {
1361
+ // ignore parse error
1362
+ }
1363
+ }
1364
+ if (availableOutcomes.length === 0) {
1365
+ availableOutcomes.push('cancel', 'submit');
1366
+ }
1367
+ return {
1368
+ success: true,
1369
+ data: {
1370
+ result: input.context || {},
1371
+ action: 'pending',
1372
+ },
1373
+ metadata: {
1374
+ outcome: 'pending',
1375
+ },
1376
+ };
1377
+ }
1378
+ catch (error) {
1379
+ console.error(`[CartableTaskActivity] Failed to execute:`, error);
1380
+ return {
1381
+ success: false,
1382
+ message: {
1383
+ text: error instanceof Error ? error.message : 'Failed to execute cartable task',
1384
+ },
1385
+ data: {
1386
+ result: {},
1387
+ action: 'cancel',
1388
+ },
1389
+ metadata: {
1390
+ outcome: 'cancel',
1391
+ },
1392
+ };
1393
+ }
1394
+ }
1395
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CartableTaskActivity, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
1396
+ static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CartableTaskActivity }); }
1397
+ }
1398
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: CartableTaskActivity, decorators: [{
1399
+ type: Injectable
1400
+ }] });
1401
+
1288
1402
  //#endregion
1289
1403
  /**
1290
1404
  * ShowToast Activity (Frontend)
@@ -1879,6 +1993,7 @@ var index = /*#__PURE__*/Object.freeze({
1879
1993
  __proto__: null,
1880
1994
  AXMWorkflowActivitiesDefinitionProvider: AXMWorkflowActivitiesDefinitionProvider,
1881
1995
  AXPCreateEntityActivity: AXPCreateEntityActivity,
1996
+ CartableTaskActivity: CartableTaskActivity,
1882
1997
  CollectSignatureActivity: CollectSignatureActivity,
1883
1998
  CreateEntityFormActivity: CreateEntityFormActivity,
1884
1999
  HumanTaskActivity: HumanTaskActivity,
@@ -2428,6 +2543,29 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2428
2543
  }
2429
2544
  //#endregion
2430
2545
  //#region ---- Task Retrieval ----
2546
+ /**
2547
+ * Bookmark types shown on the workflow task board.
2548
+ */
2549
+ isTaskBoardBookmarkPayload(payload) {
2550
+ const t = payload.activityType;
2551
+ return t === 'workflow-activity:human-task' || t === 'workflow-activity:cartable';
2552
+ }
2553
+ /**
2554
+ * Pooled task: must be claimed before submit/cancel (cartable, or human-task with candidates only).
2555
+ */
2556
+ isPooledClaimablePayload(payload) {
2557
+ const assigned = this.normalizeUserIdList(payload.assignedUserIds);
2558
+ const candidates = this.normalizeUserIdList(payload.candidateUserIds);
2559
+ if (payload.activityType === 'workflow-activity:cartable') {
2560
+ return assigned.length === 0 && candidates.length > 0;
2561
+ }
2562
+ return payload.activityType === 'workflow-activity:human-task' && assigned.length === 0 && candidates.length > 0;
2563
+ }
2564
+ normalizeUserIdList(value) {
2565
+ if (!value || value.length === 0)
2566
+ return [];
2567
+ return value.map((id) => String(id)).filter((s) => s.length > 0);
2568
+ }
2431
2569
  /**
2432
2570
  * Get tasks from suspended workflow instances.
2433
2571
  *
@@ -2491,8 +2629,7 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2491
2629
  // Get payload from entity (payload object or parse payloadJson)
2492
2630
  let payload;
2493
2631
  try {
2494
- const raw = bookmark.payload ??
2495
- (bookmark.payloadJson ? JSON.parse(bookmark.payloadJson) : null);
2632
+ const raw = bookmark.payload ?? (bookmark.payloadJson ? JSON.parse(bookmark.payloadJson) : null);
2496
2633
  payload =
2497
2634
  typeof raw === 'object' && raw !== null
2498
2635
  ? raw
@@ -2501,8 +2638,8 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2501
2638
  catch {
2502
2639
  continue;
2503
2640
  }
2504
- // Only process bookmarks for workflow-activity:human-task (cartable tasks only; forms/popups excluded)
2505
- if (payload.activityType !== 'workflow-activity:human-task') {
2641
+ // Task board: human-task and cartable (pooled); exclude other suspended UI bookmarks
2642
+ if (!this.isTaskBoardBookmarkPayload(payload)) {
2506
2643
  continue;
2507
2644
  }
2508
2645
  // Check assignment filter if provided
@@ -2511,7 +2648,8 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2511
2648
  const candidateIds = payload.candidateUserIds || [];
2512
2649
  const allUserIds = [...assignedIds, ...candidateIds];
2513
2650
  // TODO: Also check candidateRoleIds by resolving role members
2514
- const matchesAssignee = allUserIds.some((id) => options.assigneeIds.includes(id));
2651
+ const filterIds = options.assigneeIds.map((id) => String(id));
2652
+ const matchesAssignee = allUserIds.some((id) => filterIds.includes(String(id)));
2515
2653
  if (!matchesAssignee) {
2516
2654
  continue;
2517
2655
  }
@@ -2547,11 +2685,13 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2547
2685
  mapBookmarkToTask(instance, bookmark, payload) {
2548
2686
  // Extract dates
2549
2687
  const dueDate = payload.dueDate
2550
- ? (typeof payload.dueDate === 'string' ? new Date(payload.dueDate) : payload.dueDate)
2551
- : (instance.createdAt ? new Date(instance.createdAt) : new Date());
2552
- const startDate = instance.createdAt
2553
- ? new Date(instance.createdAt)
2554
- : dueDate;
2688
+ ? typeof payload.dueDate === 'string'
2689
+ ? new Date(payload.dueDate)
2690
+ : payload.dueDate
2691
+ : instance.createdAt
2692
+ ? new Date(instance.createdAt)
2693
+ : new Date();
2694
+ const startDate = instance.createdAt ? new Date(instance.createdAt) : dueDate;
2555
2695
  // If startDate and endDate are the same, set endDate to one day after startDate
2556
2696
  let endDate = dueDate;
2557
2697
  if (startDate.getTime() === dueDate.getTime()) {
@@ -2645,9 +2785,28 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2645
2785
  const instanceId = taskData?.instanceId ?? command.options?.['instanceId'] ?? '';
2646
2786
  const bookmarkId = taskData?.bookmarkId ?? command.options?.['bookmarkId'] ?? '';
2647
2787
  const taskToken = taskData?.taskToken ?? command.options?.['taskToken'] ?? '';
2648
- const activityId = taskData?.activityId ?? command.options?.['activityId'] ?? '';
2788
+ const activityId = taskData?.activityId ?? command.options?.['activityId'] ?? command.options?.['stepId'] ?? '';
2649
2789
  const outcome = command.options?.['outcome'] ?? 'Done';
2650
2790
  const userInput = command.options?.['userInput'] ?? {};
2791
+ if (command.name === 'WorkflowManagement.WorkflowInstance:ClaimTask') {
2792
+ if (!instanceId || !bookmarkId || !activityId) {
2793
+ return {
2794
+ success: false,
2795
+ message: {
2796
+ text: 'Missing required parameters: instanceId, bookmarkId, activityId',
2797
+ },
2798
+ };
2799
+ }
2800
+ const claimResult = await this.workflowManager.claimTask(instanceId, bookmarkId, activityId);
2801
+ return {
2802
+ success: claimResult.success,
2803
+ message: claimResult.error
2804
+ ? {
2805
+ text: claimResult.error,
2806
+ }
2807
+ : undefined,
2808
+ };
2809
+ }
2651
2810
  // Handle workflow resume commands
2652
2811
  if (command.name === 'WorkflowManagement.WorkflowInstance:Resume' || command.name === 'resume-workflow') {
2653
2812
  if (!instanceId || !taskToken || !activityId) {
@@ -2695,12 +2854,27 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2695
2854
  const payload = taskData?.payload;
2696
2855
  if (!payload)
2697
2856
  return actions;
2857
+ if (this.isPooledClaimablePayload(payload)) {
2858
+ actions.push({
2859
+ name: 'claim',
2860
+ title: this.translationService.translateSync('@workflow-management:tasks.actions.claim.title'),
2861
+ icon: 'fa-light fa-hand',
2862
+ color: 'primary',
2863
+ priority: 'primary',
2864
+ command: {
2865
+ name: 'WorkflowManagement.WorkflowInstance:ClaimTask',
2866
+ options: {
2867
+ instanceId: taskData.instanceId,
2868
+ bookmarkId: taskData.bookmarkId,
2869
+ activityId: taskData.activityId,
2870
+ },
2871
+ },
2872
+ });
2873
+ return actions;
2874
+ }
2698
2875
  // Extract actions from payload
2699
2876
  if (payload.actions) {
2700
- const allActions = [
2701
- ...(payload.actions.prefix || []),
2702
- ...(payload.actions.suffix || []),
2703
- ];
2877
+ const allActions = [...(payload.actions.prefix || []), ...(payload.actions.suffix || [])];
2704
2878
  for (const action of allActions) {
2705
2879
  const actionName = action.command?.name || action.name || 'unknown';
2706
2880
  actions.push({
@@ -2780,7 +2954,7 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2780
2954
  //#endregion
2781
2955
  //#region ---- Component ----
2782
2956
  getComponent() {
2783
- return () => import('./acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs').then((m) => m.AXMWorkflowTaskPopoverComponent);
2957
+ return () => import('./acorex-modules-workflow-management-workflow-task-popover.component-l37iXJIY.mjs').then((m) => m.AXMWorkflowTaskPopoverComponent);
2784
2958
  }
2785
2959
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPGenericWorkflowTaskProvider, deps: [{ token: AXP_GENERIC_WORKFLOW_TASK_PROVIDER_CONFIG }], target: i0.ɵɵFactoryTarget.Injectable }); }
2786
2960
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPGenericWorkflowTaskProvider }); }
@@ -2803,9 +2977,15 @@ function provideTaskWorkflow() {
2803
2977
  const multiLanguageResolver = injector.get(AXTranslationService);
2804
2978
  const categories = await workflowDefinitionService.getCategories();
2805
2979
  const providers = [];
2980
+ const seenDefinitionNames = new Set();
2806
2981
  for (const category of categories) {
2807
2982
  const workflows = await workflowDefinitionService.getWorkflowsByCategoryId(category.id);
2808
2983
  for (const workflow of workflows) {
2984
+ const key = workflow.name;
2985
+ if (!key || seenDefinitionNames.has(key)) {
2986
+ continue;
2987
+ }
2988
+ seenDefinitionNames.add(key);
2809
2989
  const provider = runInInjectionContext(injector, () => new AXPGenericWorkflowTaskProvider({
2810
2990
  name: workflow.name,
2811
2991
  title: multiLanguageResolver.resolve(workflow.title) ?? workflow.name,
@@ -2815,7 +2995,13 @@ function provideTaskWorkflow() {
2815
2995
  providers.push(provider);
2816
2996
  }
2817
2997
  }
2818
- console.log('providers', providers);
2998
+ if (providers.length === 0) {
2999
+ providers.push(runInInjectionContext(injector, () => new AXPGenericWorkflowTaskProvider({
3000
+ name: 'workflow-tasks-all',
3001
+ title: 'Workflow tasks',
3002
+ icon: 'fa-light fa-inbox',
3003
+ })));
3004
+ }
2819
3005
  return providers;
2820
3006
  })();
2821
3007
  },
@@ -2824,26 +3010,6 @@ function provideTaskWorkflow() {
2824
3010
  ]);
2825
3011
  }
2826
3012
 
2827
- function routesFactory() {
2828
- const config = inject(AXP_ENTITY_CONFIG_TOKEN);
2829
- const routes = [
2830
- {
2831
- path: ':app/workflow-management/studio',
2832
- loadComponent: () => {
2833
- return config.viewers.root();
2834
- },
2835
- canActivate: [AXPAuthGuard],
2836
- data: { reuse: true },
2837
- children: [
2838
- {
2839
- path: '',
2840
- loadComponent: () => Promise.resolve().then(function () { return workflowStudio_component; }).then((c) => c.WorkflowStudioComponent),
2841
- },
2842
- ],
2843
- },
2844
- ];
2845
- return routes;
2846
- }
2847
3013
  class AXMWorkflowManagementModule {
2848
3014
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMWorkflowManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
2849
3015
  static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXMWorkflowManagementModule, imports: [AXMCalendarManagementModule,
@@ -2853,23 +3019,14 @@ class AXMWorkflowManagementModule {
2853
3019
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMWorkflowManagementModule, providers: [
2854
3020
  { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXMWorkflowManagementWidgetsProvider, multi: true },
2855
3021
  { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXMWorkflowDashboardWidgetsProvider, multi: true },
2856
- {
2857
- provide: ROUTES,
2858
- multi: true,
2859
- useFactory: routesFactory,
2860
- },
2861
3022
  provideCommandSetups([
2862
3023
  {
2863
3024
  key: 'WorkflowManagement.WorkflowDefinition:ExecuteWithInput',
2864
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
3025
+ command: () => import('./acorex-modules-workflow-management-index-CHySddpP.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
2865
3026
  },
2866
3027
  {
2867
3028
  key: 'WorkflowManagement.WorkflowDefinition:Execute',
2868
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowCommand),
2869
- },
2870
- {
2871
- key: 'WorkflowManagement.WorkflowDefinition:EditInStudio',
2872
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.EditInStudioCommand),
3029
+ command: () => import('./acorex-modules-workflow-management-index-CHySddpP.mjs').then((c) => c.ExecuteWorkflowCommand),
2873
3030
  },
2874
3031
  {
2875
3032
  key: 'WorkflowManagement.WorkflowDefinition:Activities:Save',
@@ -2899,6 +3056,10 @@ class AXMWorkflowManagementModule {
2899
3056
  key: 'workflow-activity:human-task',
2900
3057
  command: () => Promise.resolve().then(function () { return index; }).then((c) => c.HumanTaskActivity),
2901
3058
  },
3059
+ {
3060
+ key: 'workflow-activity:cartable',
3061
+ command: () => Promise.resolve().then(function () { return index; }).then((c) => c.CartableTaskActivity),
3062
+ },
2902
3063
  {
2903
3064
  key: 'workflow-activity:collect-signature',
2904
3065
  command: () => Promise.resolve().then(function () { return index; }).then((c) => c.CollectSignatureActivity),
@@ -2911,8 +3072,8 @@ class AXMWorkflowManagementModule {
2911
3072
  useClass: AXMWorkflowManagementModuleEntityProvider,
2912
3073
  multi: true,
2913
3074
  },
2914
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-DMnJRDbq.mjs').then((m) => m.AXMWorkflowInstanceActivityInstancesPageComponentProvider)),
2915
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-D8fjNgQJ.mjs').then((m) => m.AXMWorkflowDefinitionActivitiesPageComponentProvider)),
3075
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-Eh5DDK-V.mjs').then((m) => m.AXMWorkflowInstanceActivityInstancesPageComponentProvider)),
3076
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-V4OesZTq.mjs').then((m) => m.AXMWorkflowDefinitionActivitiesPageComponentProvider)),
2916
3077
  // Automation condition builder: default automation.rules(refType, refId); modules override for their refTypes
2917
3078
  {
2918
3079
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
@@ -2963,17 +3124,12 @@ class AXMWorkflowManagementModule {
2963
3124
  useClass: AXMWorkflowCategoryProvider,
2964
3125
  multi: true,
2965
3126
  },
2966
- // Workflow Definition Metadata Provider
2967
- {
2968
- provide: AXP_WORKFLOW_PROVIDER,
2969
- useClass: AXMWorkflowDefinitionProvider,
2970
- multi: true,
2971
- },
2972
3127
  // Provide activity classes for dependency injection (only frontend activities)
2973
3128
  ShowConfirmPopupActivity,
2974
3129
  ShowLayoutPopupActivity,
2975
3130
  CreateEntityFormActivity,
2976
3131
  HumanTaskActivity,
3132
+ CartableTaskActivity,
2977
3133
  ShowToastActivity,
2978
3134
  CollectSignatureActivity,
2979
3135
  // Generic Workflow Task Provider (all workflows – no definitionId filter).
@@ -3016,23 +3172,14 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3016
3172
  providers: [
3017
3173
  { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXMWorkflowManagementWidgetsProvider, multi: true },
3018
3174
  { provide: AXP_WIDGET_DEFINITION_PROVIDER, useClass: AXMWorkflowDashboardWidgetsProvider, multi: true },
3019
- {
3020
- provide: ROUTES,
3021
- multi: true,
3022
- useFactory: routesFactory,
3023
- },
3024
3175
  provideCommandSetups([
3025
3176
  {
3026
3177
  key: 'WorkflowManagement.WorkflowDefinition:ExecuteWithInput',
3027
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
3178
+ command: () => import('./acorex-modules-workflow-management-index-CHySddpP.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
3028
3179
  },
3029
3180
  {
3030
3181
  key: 'WorkflowManagement.WorkflowDefinition:Execute',
3031
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowCommand),
3032
- },
3033
- {
3034
- key: 'WorkflowManagement.WorkflowDefinition:EditInStudio',
3035
- command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.EditInStudioCommand),
3182
+ command: () => import('./acorex-modules-workflow-management-index-CHySddpP.mjs').then((c) => c.ExecuteWorkflowCommand),
3036
3183
  },
3037
3184
  {
3038
3185
  key: 'WorkflowManagement.WorkflowDefinition:Activities:Save',
@@ -3062,6 +3209,10 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3062
3209
  key: 'workflow-activity:human-task',
3063
3210
  command: () => Promise.resolve().then(function () { return index; }).then((c) => c.HumanTaskActivity),
3064
3211
  },
3212
+ {
3213
+ key: 'workflow-activity:cartable',
3214
+ command: () => Promise.resolve().then(function () { return index; }).then((c) => c.CartableTaskActivity),
3215
+ },
3065
3216
  {
3066
3217
  key: 'workflow-activity:collect-signature',
3067
3218
  command: () => Promise.resolve().then(function () { return index; }).then((c) => c.CollectSignatureActivity),
@@ -3074,8 +3225,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3074
3225
  useClass: AXMWorkflowManagementModuleEntityProvider,
3075
3226
  multi: true,
3076
3227
  },
3077
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-DMnJRDbq.mjs').then((m) => m.AXMWorkflowInstanceActivityInstancesPageComponentProvider)),
3078
- provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-D8fjNgQJ.mjs').then((m) => m.AXMWorkflowDefinitionActivitiesPageComponentProvider)),
3228
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-Eh5DDK-V.mjs').then((m) => m.AXMWorkflowInstanceActivityInstancesPageComponentProvider)),
3229
+ provideLazyProvider(AXP_PAGE_COMPONENT_PROVIDER, () => import('./acorex-modules-workflow-management-index-V4OesZTq.mjs').then((m) => m.AXMWorkflowDefinitionActivitiesPageComponentProvider)),
3079
3230
  // Automation condition builder: default automation.rules(refType, refId); modules override for their refTypes
3080
3231
  {
3081
3232
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
@@ -3126,17 +3277,12 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3126
3277
  useClass: AXMWorkflowCategoryProvider,
3127
3278
  multi: true,
3128
3279
  },
3129
- // Workflow Definition Metadata Provider
3130
- {
3131
- provide: AXP_WORKFLOW_PROVIDER,
3132
- useClass: AXMWorkflowDefinitionProvider,
3133
- multi: true,
3134
- },
3135
3280
  // Provide activity classes for dependency injection (only frontend activities)
3136
3281
  ShowConfirmPopupActivity,
3137
3282
  ShowLayoutPopupActivity,
3138
3283
  CreateEntityFormActivity,
3139
3284
  HumanTaskActivity,
3285
+ CartableTaskActivity,
3140
3286
  ShowToastActivity,
3141
3287
  CollectSignatureActivity,
3142
3288
  // Generic Workflow Task Provider (all workflows – no definitionId filter).
@@ -3172,2278 +3318,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
3172
3318
  // Entity exports - services and modules removed, handled by middleware
3173
3319
  // Exporting entity types for use in feature components
3174
3320
 
3175
- //#region ---- Imports ----
3176
- //#endregion
3177
- class AXMActivityCategoriesTreeComponent {
3178
- constructor() {
3179
- //#region ---- Services & Dependencies ----
3180
- this.activityDefinitionService = inject(AXPActivityDefinitionService);
3181
- this.multiLanguageResolver = inject(AXTranslationService);
3182
- //#endregion
3183
- //#region ---- Output Events ----
3184
- this.categoryClick = output();
3185
- this.activityClick = output();
3186
- /** Emitted when user starts dragging an activity (so parent can set draggedActivity for canvas drop). */
3187
- this.activityDragStart = output();
3188
- //#endregion
3189
- //#region ---- Lazy Tree Data (same pattern as report-categories-tree) ----
3190
- this.provideLazyTreeView = async (selectedItemId) => {
3191
- if (selectedItemId !== undefined && selectedItemId !== null) {
3192
- const parentId = String(selectedItemId);
3193
- if (parentId.startsWith('activity_')) {
3194
- return [];
3195
- }
3196
- const categories = await this.activityDefinitionService.getCategories(parentId);
3197
- const categoryItems = categories.map((item) => ({
3198
- id: item.id,
3199
- title: this.multiLanguageResolver.resolve(item.title) || item.id,
3200
- hasChild: (item.childrenCount ?? 0) > 0 || (item.itemsCount ?? 0) > 0,
3201
- item,
3202
- type: 'category',
3203
- expanded: false,
3204
- }));
3205
- const activities = await this.activityDefinitionService.getActivitiesByCategoryId(parentId);
3206
- const definitionItems = activities.map((item) => ({
3207
- id: `activity_${item.type ?? item.name}`,
3208
- title: this.multiLanguageResolver.resolve(item.title) || item.name || item.type || '',
3209
- hasChild: false,
3210
- item,
3211
- type: 'definition',
3212
- expanded: false,
3213
- }));
3214
- return [...categoryItems, ...definitionItems];
3215
- }
3216
- const categories = await this.activityDefinitionService.getCategories();
3217
- return categories.map((item) => ({
3218
- id: item.id,
3219
- title: this.multiLanguageResolver.resolve(item.title) || item.id,
3220
- hasChild: (item.childrenCount ?? 0) > 0 || (item.itemsCount ?? 0) > 0,
3221
- item,
3222
- type: 'category',
3223
- expanded: false,
3224
- }));
3225
- };
3226
- }
3227
- //#endregion
3228
- //#region ---- Event Handlers ----
3229
- handleNodeClick(event) {
3230
- const node = event.data;
3231
- if (node.type === 'category' && node.item) {
3232
- this.categoryClick.emit(node.item);
3233
- }
3234
- else if (node.type === 'definition' && node.item) {
3235
- this.activityClick.emit(node.item);
3236
- }
3237
- }
3238
- onActivityDragStart(event, item) {
3239
- if (item.type !== 'definition' || !item.item)
3240
- return;
3241
- event.stopPropagation();
3242
- if (event.dataTransfer) {
3243
- event.dataTransfer.effectAllowed = 'copy';
3244
- event.dataTransfer.setData('text/plain', item.item.type);
3245
- }
3246
- this.activityDragStart.emit({ event, activity: item.item });
3247
- }
3248
- /**
3249
- * Normalize FontAwesome icon for display: prepend 'fa-light ' when missing style prefix.
3250
- */
3251
- getActivityIconClass(icon) {
3252
- if (!icon?.trim())
3253
- return 'fa-light fa-puzzle-piece';
3254
- const trimmed = icon.trim();
3255
- const hasStylePrefix = /^(fa-light|fas|far|fal|fa-solid|fa-regular|fa-brands|fa-duotone)(\s|$)/i.test(trimmed);
3256
- return hasStylePrefix ? trimmed : `fa-light ${trimmed}`;
3257
- }
3258
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMActivityCategoriesTreeComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
3259
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXMActivityCategoriesTreeComponent, isStandalone: true, selector: "axp-activity-categories-tree", outputs: { categoryClick: "categoryClick", activityClick: "activityClick", activityDragStart: "activityDragStart" }, host: { classAttribute: "axp-activity-categories-tree" }, ngImport: i0, template: "<ax-tree-view-legacy\n [showCheckbox]=\"false\"\n [itemTemplate]=\"itemTemplate\"\n [textField]=\"'title'\"\n [hasChildField]=\"'hasChild'\"\n [valueField]=\"'id'\"\n [expandedField]=\"'expanded'\"\n [items]=\"provideLazyTreeView\"\n (onNodeClick)=\"handleNodeClick($event)\"\n>\n</ax-tree-view-legacy>\n\n<ng-template #itemTemplate let-item>\n @if (item.type === 'category') {\n <span class=\"__tree-item __category\">\n <i class=\"fas fa-folder ax-text-warning __icon\"></i>\n <span class=\"__title\">{{ item.title }}</span>\n </span>\n } @else {\n <span\n class=\"__tree-item __activity\"\n draggable=\"true\"\n (dragstart)=\"onActivityDragStart($event, item)\"\n >\n <i class=\"__icon ax-text-primary\" [class]=\"getActivityIconClass(item.item?.icon)\"></i>\n <span class=\"__title\">{{ item.title }}</span>\n </span>\n }\n</ng-template>\n", styles: [".axp-activity-categories-tree{height:100%;width:100%}.axp-activity-categories-tree .__tree-item{display:flex;align-items:center;gap:.5rem}.axp-activity-categories-tree .__tree-item .__icon{flex-shrink:0}.axp-activity-categories-tree .__tree-item .__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.axp-activity-categories-tree .__activity{cursor:grab}.axp-activity-categories-tree .__activity:active{cursor:grabbing}\n"], dependencies: [{ kind: "ngmodule", type: AXDecoratorModule }, { kind: "ngmodule", type: AXTreeViewLegacyModule }, { kind: "component", type: i1.AXTreeViewLegacyComponent, selector: "ax-tree-view-legacy", inputs: ["items", "showCheckbox", "hasCheckboxField", "selectionMode", "selectionBehavior", "selectionScope", "focusNodeEnabled", "valueField", "textField", "visibleField", "disableField", "hasChildField", "selectedField", "expandedField", "tooltipField", "childrenField", "activeField", "indeterminateField", "parentField", "iconField", "toggleIcons", "look", "showEmptyNodeMassage", "itemTemplate", "emptyTemplate", "expandOn"], outputs: ["onSelectionChanged", "onItemSelectedChanged", "onNodeClick", "onCollapsedChanged", "onNodedbClick"] }, { kind: "ngmodule", type: AXTranslationModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
3260
- }
3261
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMActivityCategoriesTreeComponent, decorators: [{
3262
- type: Component,
3263
- args: [{ selector: 'axp-activity-categories-tree', standalone: true, imports: [AXDecoratorModule, AXTreeViewLegacyModule, AXTranslationModule], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: { class: 'axp-activity-categories-tree' }, template: "<ax-tree-view-legacy\n [showCheckbox]=\"false\"\n [itemTemplate]=\"itemTemplate\"\n [textField]=\"'title'\"\n [hasChildField]=\"'hasChild'\"\n [valueField]=\"'id'\"\n [expandedField]=\"'expanded'\"\n [items]=\"provideLazyTreeView\"\n (onNodeClick)=\"handleNodeClick($event)\"\n>\n</ax-tree-view-legacy>\n\n<ng-template #itemTemplate let-item>\n @if (item.type === 'category') {\n <span class=\"__tree-item __category\">\n <i class=\"fas fa-folder ax-text-warning __icon\"></i>\n <span class=\"__title\">{{ item.title }}</span>\n </span>\n } @else {\n <span\n class=\"__tree-item __activity\"\n draggable=\"true\"\n (dragstart)=\"onActivityDragStart($event, item)\"\n >\n <i class=\"__icon ax-text-primary\" [class]=\"getActivityIconClass(item.item?.icon)\"></i>\n <span class=\"__title\">{{ item.title }}</span>\n </span>\n }\n</ng-template>\n", styles: [".axp-activity-categories-tree{height:100%;width:100%}.axp-activity-categories-tree .__tree-item{display:flex;align-items:center;gap:.5rem}.axp-activity-categories-tree .__tree-item .__icon{flex-shrink:0}.axp-activity-categories-tree .__tree-item .__title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.axp-activity-categories-tree .__activity{cursor:grab}.axp-activity-categories-tree .__activity:active{cursor:grabbing}\n"] }]
3264
- }], propDecorators: { categoryClick: [{ type: i0.Output, args: ["categoryClick"] }], activityClick: [{ type: i0.Output, args: ["activityClick"] }], activityDragStart: [{ type: i0.Output, args: ["activityDragStart"] }] } });
3265
-
3266
- class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3267
- constructor() {
3268
- super(...arguments);
3269
- //#region ---- Services & Dependencies ----
3270
- this.workflowManager = inject(AXPWorkflowManager);
3271
- this.activityDefinitionService = inject(AXPActivityDefinitionService);
3272
- this.entityService = inject(AXPEntityService);
3273
- this.translationService = inject(AXTranslationService);
3274
- this.activatedRoute = inject(ActivatedRoute);
3275
- this.router = inject(Router);
3276
- this.workflowDefinitionService = inject(AXPWorkflowDefinitionService);
3277
- this.layoutBuilder = inject(AXPLayoutBuilderService);
3278
- this.destroyRef = inject(DestroyRef);
3279
- //#endregion
3280
- //#region ---- State ----
3281
- this.activeTab = signal('json', ...(ngDevMode ? [{ debugName: "activeTab" }] : /* istanbul ignore next */ []));
3282
- this.selectedCategory = signal(null, ...(ngDevMode ? [{ debugName: "selectedCategory" }] : /* istanbul ignore next */ []));
3283
- this.selectedActivity = signal(null, ...(ngDevMode ? [{ debugName: "selectedActivity" }] : /* istanbul ignore next */ []));
3284
- this.workflowJson = signal(this.getEmptyWorkflow(), ...(ngDevMode ? [{ debugName: "workflowJson" }] : /* istanbul ignore next */ []));
3285
- this.visualNodes = signal([], ...(ngDevMode ? [{ debugName: "visualNodes" }] : /* istanbul ignore next */ []));
3286
- this.selectedNode = signal(null, ...(ngDevMode ? [{ debugName: "selectedNode" }] : /* istanbul ignore next */ []));
3287
- this.isExecuting = signal(false, ...(ngDevMode ? [{ debugName: "isExecuting" }] : /* istanbul ignore next */ []));
3288
- this.executionLogs = signal([], ...(ngDevMode ? [{ debugName: "executionLogs" }] : /* istanbul ignore next */ []));
3289
- // Execution Dialog State
3290
- this.showExecutionDialog = signal(false, ...(ngDevMode ? [{ debugName: "showExecutionDialog" }] : /* istanbul ignore next */ []));
3291
- this.workflowInstanceState = signal(null, ...(ngDevMode ? [{ debugName: "workflowInstanceState" }] : /* istanbul ignore next */ []));
3292
- // UI State
3293
- this.showPropertiesPanel = signal(true, ...(ngDevMode ? [{ debugName: "showPropertiesPanel" }] : /* istanbul ignore next */ []));
3294
- /** When true, workflow changes can trigger auto-save (e.g. apply to JSON); actual persist is up to the host. */
3295
- this.autoSaveEnabled = signal(false, ...(ngDevMode ? [{ debugName: "autoSaveEnabled" }] : /* istanbul ignore next */ []));
3296
- /** Activity definition for the selected node (loaded when selection changes). */
3297
- this.activityDefinitionForSelected = signal(null, ...(ngDevMode ? [{ debugName: "activityDefinitionForSelected" }] : /* istanbul ignore next */ []));
3298
- /** Cache key for property viewer tabs so we keep stable refs and avoid re-render/focus loss on value change. */
3299
- this.lastPropertyViewerStructKey = null;
3300
- /** Cached tabs; updated only when selected node identity or def structure changes. */
3301
- this.cachedPropertyViewerTabs = signal([], ...(ngDevMode ? [{ debugName: "cachedPropertyViewerTabs" }] : /* istanbul ignore next */ []));
3302
- /** Tabs for the property viewer (platform widget-based rendering). Stable refs to prevent focus loss. */
3303
- this.propertyViewerTabs = computed(() => this.cachedPropertyViewerTabs(), ...(ngDevMode ? [{ debugName: "propertyViewerTabs" }] : /* istanbul ignore next */ []));
3304
- this.updatePropertyViewerTabsEffect = effect(() => {
3305
- const def = this.activityDefinitionForSelected();
3306
- const node = this.selectedNode();
3307
- if (!node) {
3308
- this.lastPropertyViewerStructKey = null;
3309
- this.cachedPropertyViewerTabs.set([]);
3310
- return;
3311
- }
3312
- const structKey = `${node.id}:${node.type}:${def?.inputs?.length ?? 0}`;
3313
- if (this.lastPropertyViewerStructKey === structKey)
3314
- return;
3315
- this.lastPropertyViewerStructKey = structKey;
3316
- this.cachedPropertyViewerTabs.set(this.buildPropertyViewerTabs(def, node));
3317
- }, ...(ngDevMode ? [{ debugName: "updatePropertyViewerTabsEffect" }] : /* istanbul ignore next */ []));
3318
- this.propertyViewerRef = viewChild(AXPPropertyViewerComponent, ...(ngDevMode ? [{ debugName: "propertyViewerRef" }] : /* istanbul ignore next */ []));
3319
- this.loadActivityDefinitionForSelectedEffect = effect(() => {
3320
- const node = this.selectedNode();
3321
- if (!node) {
3322
- this.activityDefinitionForSelected.set(null);
3323
- return;
3324
- }
3325
- this.activityDefinitionService.getActivityByName(node.type).then((def) => {
3326
- this.activityDefinitionForSelected.set(def ?? null);
3327
- });
3328
- }, ...(ngDevMode ? [{ debugName: "loadActivityDefinitionForSelectedEffect" }] : /* istanbul ignore next */ []));
3329
- this.initPropertyViewerContextEffect = effect(() => {
3330
- const viewer = this.propertyViewerRef();
3331
- const node = this.selectedNode();
3332
- const tabs = this.propertyViewerTabs();
3333
- if (viewer && node && tabs.length > 0) {
3334
- viewer.initializeContext({ ...node, properties: { ...node.properties } });
3335
- }
3336
- }, ...(ngDevMode ? [{ debugName: "initPropertyViewerContextEffect" }] : /* istanbul ignore next */ []));
3337
- // Workflow Settings
3338
- this.workflowSettings = signal({
3339
- definitionId: '',
3340
- name: '',
3341
- description: '',
3342
- inputs: [],
3343
- outputs: [],
3344
- variables: [],
3345
- outcomes: ['Done'],
3346
- usableAsActivity: false,
3347
- autoUpdateConsumingWorkflows: false,
3348
- version: 1,
3349
- isLatest: true,
3350
- isPublished: false,
3351
- toolVersion: '1.0.0',
3352
- providerName: 'WorkflowStudio',
3353
- }, ...(ngDevMode ? [{ debugName: "workflowSettings" }] : /* istanbul ignore next */ []));
3354
- /** Data source for variable type select (settings modal). */
3355
- this.variableTypeOptions = [
3356
- { value: 'string', label: 'String' },
3357
- { value: 'number', label: 'Number' },
3358
- { value: 'boolean', label: 'Boolean' },
3359
- { value: 'object', label: 'Object' },
3360
- { value: 'array', label: 'Array' },
3361
- ];
3362
- // Canvas state
3363
- this.canvasOffset = { x: 0, y: 0 };
3364
- this.isDraggingCanvas = false;
3365
- this.dragStartPos = { x: 0, y: 0 };
3366
- this.draggedActivity = null;
3367
- this.draggedNode = null;
3368
- this.nodeDragOffset = { x: 0, y: 0 };
3369
- this.connectionSource = null;
3370
- /** Canvas area element for zoom/center/auto-layout. */
3371
- this.canvasAreaRef = viewChild('canvasAreaRef', ...(ngDevMode ? [{ debugName: "canvasAreaRef" }] : /* istanbul ignore next */ []));
3372
- /**
3373
- * دسترسی به Object برای استفاده در template
3374
- */
3375
- this.Object = Object;
3376
- /**
3377
- * دسترسی به typeof برای استفاده در template
3378
- */
3379
- this.typeof = (value) => typeof value;
3380
- /**
3381
- * دسترسی به JSON برای استفاده در template
3382
- */
3383
- this.JSON = JSON;
3384
- }
3385
- async ngOnInit() {
3386
- // Page layout initialization
3387
- await super.ngOnInit();
3388
- // Load workflow from query parameter if provided
3389
- await this.loadWorkflowFromRoute();
3390
- }
3391
- /**
3392
- * Load workflow from route query parameter
3393
- */
3394
- async loadWorkflowFromRoute() {
3395
- // Read from snapshot (for initial load)
3396
- const workflowName = this.activatedRoute.snapshot.queryParams['workflow'];
3397
- if (!workflowName) {
3398
- return;
3399
- }
3400
- await this.loadWorkflowByName(workflowName);
3401
- // Subscribe to query param changes (like drive component)
3402
- this.activatedRoute.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (params) => {
3403
- const newWorkflowName = params['workflow'];
3404
- if (newWorkflowName && newWorkflowName !== workflowName) {
3405
- await this.loadWorkflowByName(newWorkflowName);
3406
- }
3407
- });
3408
- }
3409
- /**
3410
- * Update a single workflow setting field (for signal-based form binding).
3411
- */
3412
- updateWorkflowSetting(key, value) {
3413
- this.workflowSettings.update((s) => ({ ...s, [key]: value }));
3414
- }
3415
- /**
3416
- * Handle JSON editor input (textarea value -> workflowJson signal).
3417
- */
3418
- onWorkflowJsonInput(ev) {
3419
- const value = ev.target.value;
3420
- this.workflowJson.set(value);
3421
- }
3422
- //#region ---- Workflow definition display (multi-language) ----
3423
- /**
3424
- * Resolves workflow definition title for studio UI strings (settings, graph root label).
3425
- */
3426
- resolveWorkflowDefinitionTitle(workflowDef) {
3427
- const raw = workflowDef.title;
3428
- if (raw == null || raw === '') {
3429
- return workflowDef.name || 'Root';
3430
- }
3431
- return typeof raw === 'string'
3432
- ? raw
3433
- : (this.translationService.resolve(raw) ?? workflowDef.name ?? 'Root');
3434
- }
3435
- /**
3436
- * Resolves workflow definition description for studio settings (current locale string).
3437
- */
3438
- resolveWorkflowDefinitionDescription(workflowDef) {
3439
- const raw = workflowDef.description;
3440
- if (raw == null || raw === '') {
3441
- return '';
3442
- }
3443
- return typeof raw === 'string' ? raw : (this.translationService.resolve(raw) ?? '');
3444
- }
3445
- //#endregion
3446
- /**
3447
- * Load workflow by name
3448
- */
3449
- async loadWorkflowByName(workflowName) {
3450
- try {
3451
- this.addLog('info', `Loading workflow: ${workflowName}...`);
3452
- // Try to get workflow from entity service first
3453
- const workflowEntityService = this.entityService
3454
- .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3455
- .data();
3456
- const result = await workflowEntityService.query({
3457
- skip: 0,
3458
- take: 1,
3459
- filter: {
3460
- logic: 'and',
3461
- filters: [
3462
- {
3463
- field: 'name',
3464
- operator: { type: 'equal' },
3465
- value: workflowName,
3466
- },
3467
- ],
3468
- },
3469
- });
3470
- let workflowDef = null;
3471
- if (result.items && result.items.length > 0) {
3472
- workflowDef = result.items[0];
3473
- }
3474
- else {
3475
- // Try workflow definition service
3476
- workflowDef = await this.workflowDefinitionService.getWorkflowByName(workflowName);
3477
- }
3478
- if (!workflowDef) {
3479
- this.addLog('warning', `Workflow '${workflowName}' not found`);
3480
- return;
3481
- }
3482
- // Convert workflow definition to studio JSON format
3483
- const studioJson = this.convertWorkflowDefinitionToStudioJson(workflowDef);
3484
- this.workflowJson.set(JSON.stringify(studioJson, null, 2));
3485
- // Update workflow settings
3486
- this.workflowSettings.set({
3487
- definitionId: workflowDef.id || workflowDef.definitionId || workflowDef.name,
3488
- name: workflowDef.name || '',
3489
- description: this.resolveWorkflowDefinitionDescription(workflowDef),
3490
- inputs: (workflowDef.inputs || []).map((input) => this.mapDefinitionInputToWorkflowInput(input)),
3491
- outputs: (workflowDef.outputs || []).map((output) => this.mapDefinitionOutputToWorkflowOutput(output)),
3492
- variables: workflowDef.variables || [],
3493
- outcomes: workflowDef.outcomes || ['Done'],
3494
- usableAsActivity: workflowDef.extensions?.elsa?.options?.usableAsActivity || false,
3495
- autoUpdateConsumingWorkflows: workflowDef.extensions?.elsa?.options?.autoUpdateConsumingWorkflows || false,
3496
- version: workflowDef.version || 1,
3497
- isLatest: workflowDef.isLatest !== undefined ? workflowDef.isLatest : true,
3498
- isPublished: workflowDef.statusId === AXPSystemStatusType.Published,
3499
- toolVersion: workflowDef.toolVersion || '1.0.0',
3500
- providerName: workflowDef.providerName || 'ACoreX',
3501
- });
3502
- this.addLog('success', `Workflow '${workflowName}' loaded successfully`);
3503
- // If visual tab is active, convert to visual
3504
- if (this.activeTab() === 'visual') {
3505
- this.jsonToVisual();
3506
- }
3507
- }
3508
- catch (error) {
3509
- this.addLog('error', `Failed to load workflow: ${error.message}`);
3510
- console.error('[WorkflowStudio] Error loading workflow:', error);
3511
- }
3512
- }
3513
- /**
3514
- * Convert workflow definition to studio JSON format
3515
- */
3516
- convertWorkflowDefinitionToStudioJson(workflowDef) {
3517
- // Convert graph format to root activity format
3518
- const graph = workflowDef.graph;
3519
- if (!graph) {
3520
- return this.getEmptyWorkflow();
3521
- }
3522
- // Build root activity structure
3523
- const rootActivity = {
3524
- id: graph.startActivityId || 'root',
3525
- type: 'workflow-activity:sequence',
3526
- name: this.resolveWorkflowDefinitionTitle(workflowDef),
3527
- children: [],
3528
- };
3529
- // Convert activities to children
3530
- const activities = graph.activities || [];
3531
- const connections = graph.connections || [];
3532
- // Build activity map
3533
- const activityMap = new Map();
3534
- activities.forEach((activity) => {
3535
- activityMap.set(activity.id, {
3536
- id: activity.id,
3537
- type: activity.name || activity.type,
3538
- name: activity.customProperties?.nodeId || activity.id,
3539
- properties: activity.inputs || {},
3540
- children: [],
3541
- });
3542
- });
3543
- // Build connections tree
3544
- const startActivity = activityMap.get(graph.startActivityId);
3545
- if (startActivity) {
3546
- rootActivity.children.push(startActivity);
3547
- // Follow connections to build tree
3548
- const processed = new Set();
3549
- const processActivity = (activityId) => {
3550
- if (processed.has(activityId)) {
3551
- return;
3552
- }
3553
- processed.add(activityId);
3554
- const activity = activityMap.get(activityId);
3555
- if (!activity) {
3556
- return;
3557
- }
3558
- // Find outgoing connections
3559
- const outgoingConnections = connections.filter((conn) => conn.source.activtyName === activityId);
3560
- outgoingConnections.forEach((conn) => {
3561
- const targetActivity = activityMap.get(conn.target.activtyName);
3562
- if (targetActivity && !processed.has(targetActivity.id)) {
3563
- activity.children.push(targetActivity);
3564
- processActivity(targetActivity.id);
3565
- }
3566
- });
3567
- };
3568
- processActivity(graph.startActivityId);
3569
- }
3570
- return {
3571
- id: workflowDef.id || workflowDef.name || 'workflow',
3572
- name: workflowDef.name || '',
3573
- description: this.resolveWorkflowDefinitionDescription(workflowDef),
3574
- version: workflowDef.version || 1,
3575
- root: rootActivity,
3576
- };
3577
- }
3578
- //#endregion
3579
- //#region ---- Page Layout Overrides ----
3580
- async getPageTitle() {
3581
- return await this.translationService.translateAsync('@workflow-management:workflow-studio.menus.workflow-studio.title');
3582
- }
3583
- async getPageDescription() {
3584
- return await this.translationService.translateAsync('@workflow-management:workflow-studio.menus.workflow-studio.description');
3585
- }
3586
- async getPrimaryMenuItems() {
3587
- return [
3588
- {
3589
- name: 'execute-workflow',
3590
- title: '@workflow-management:workflow-studio.actions.execute-workflow.title',
3591
- icon: 'fa-light fa-play',
3592
- color: 'success',
3593
- disabled: this.isExecuting(),
3594
- command: { name: 'execute-workflow' },
3595
- },
3596
- {
3597
- name: 'workflow-settings',
3598
- title: '@workflow-management:workflow-studio.actions.settings.title',
3599
- icon: 'fa-light fa-cog',
3600
- color: 'default',
3601
- command: { name: 'workflow-settings' },
3602
- },
3603
- {
3604
- name: 'export-workflow',
3605
- title: '@workflow-management:workflow-studio.actions.export.title',
3606
- icon: 'fa-light fa-download',
3607
- color: 'default',
3608
- command: { name: 'export-workflow' },
3609
- },
3610
- ];
3611
- }
3612
- async getSecondaryMenuItems() {
3613
- return [
3614
- {
3615
- name: 'format-json',
3616
- title: '@workflow-management:workflow-studio.actions.format-json.title',
3617
- icon: 'fa-light fa-code',
3618
- color: 'default',
3619
- command: { name: 'format-json' },
3620
- },
3621
- {
3622
- name: 'clear-canvas',
3623
- title: '@workflow-management:workflow-studio.actions.clear-canvas.title',
3624
- icon: 'fa-light fa-trash',
3625
- color: 'danger',
3626
- visible: this.activeTab() === 'visual',
3627
- command: { name: 'clear-canvas' },
3628
- },
3629
- ];
3630
- }
3631
- async execute(command) {
3632
- switch (command.name) {
3633
- case 'execute-workflow':
3634
- this.openExecutionDialog();
3635
- break;
3636
- case 'workflow-settings':
3637
- this.openWorkflowSettings();
3638
- break;
3639
- case 'export-workflow':
3640
- this.downloadWorkflowDefinition();
3641
- break;
3642
- case 'format-json':
3643
- this.formatJson();
3644
- break;
3645
- case 'clear-canvas':
3646
- this.clearCanvas();
3647
- break;
3648
- }
3649
- }
3650
- //#endregion
3651
- //#region ---- Category & Activity Loading ----
3652
- /**
3653
- * Handle category selection from tree
3654
- */
3655
- onCategoryClick(category) {
3656
- this.selectedCategory.set(category);
3657
- this.selectedActivity.set(null);
3658
- }
3659
- /**
3660
- * Handle activity selection from tree
3661
- */
3662
- onActivityClick(activity) {
3663
- this.selectedActivity.set(activity);
3664
- this.addLog('info', `Activity selected: ${activity.name}`);
3665
- }
3666
- /**
3667
- * Handle drag start from activity tree – set draggedActivity so canvas drop can add the node.
3668
- */
3669
- onActivityDragStartFromTree(payload) {
3670
- this.draggedActivity = this.convertActivityDefinitionToInfo(payload.activity);
3671
- if (payload.event.dataTransfer) {
3672
- payload.event.dataTransfer.effectAllowed = 'copy';
3673
- payload.event.dataTransfer.setData('text/plain', payload.activity.type);
3674
- }
3675
- }
3676
- /**
3677
- * Convert AXPActivityDefinition to ActivityInfo
3678
- */
3679
- mapDefinitionInputToWorkflowInput(input) {
3680
- const titleRaw = input.title ?? input.name;
3681
- const titleStr = typeof titleRaw === 'string' ? titleRaw : (this.translationService.resolve(titleRaw) ?? String(input.name));
3682
- const descRaw = input.description;
3683
- const descStr = descRaw == null ? undefined : typeof descRaw === 'string' ? descRaw : this.translationService.resolve(descRaw);
3684
- if (input.dataType != null && input.interface != null) {
3685
- return {
3686
- name: input.name,
3687
- title: titleStr,
3688
- description: descStr,
3689
- schema: {
3690
- dataType: input.dataType,
3691
- interface: input.interface,
3692
- },
3693
- validations: input.validations,
3694
- };
3695
- }
3696
- if (input.schema) {
3697
- return {
3698
- name: input.name,
3699
- title: titleStr,
3700
- description: descStr,
3701
- schema: input.schema,
3702
- validations: input.validations,
3703
- };
3704
- }
3705
- return {
3706
- name: input.name,
3707
- title: input.name,
3708
- description: descStr,
3709
- schema: { dataType: input.typeName || 'string', defaultValue: input.defaultValue },
3710
- validations: input.isRequired ? [{ rule: 'required' }] : undefined,
3711
- };
3712
- }
3713
- mapDefinitionOutputToWorkflowOutput(output) {
3714
- const titleRaw = output.title ?? output.name;
3715
- const titleStr = typeof titleRaw === 'string' ? titleRaw : (this.translationService.resolve(titleRaw) ?? String(output.name));
3716
- const descStr = output.description == null
3717
- ? undefined
3718
- : typeof output.description === 'string'
3719
- ? output.description
3720
- : this.translationService.resolve(output.description);
3721
- if (output.dataType != null && output.interface != null) {
3722
- return {
3723
- name: output.name,
3724
- title: titleStr,
3725
- description: descStr,
3726
- schema: { dataType: output.dataType, interface: output.interface },
3727
- path: output.path,
3728
- metadata: output.metadata,
3729
- };
3730
- }
3731
- if (output.schema) {
3732
- return {
3733
- name: output.name,
3734
- title: titleStr,
3735
- description: descStr,
3736
- schema: output.schema,
3737
- path: output.path,
3738
- metadata: output.metadata,
3739
- };
3740
- }
3741
- return {
3742
- name: output.name,
3743
- title: titleStr,
3744
- description: descStr,
3745
- schema: { dataType: output.typeName || 'string' },
3746
- };
3747
- }
3748
- convertActivityDefinitionToInfo(activity) {
3749
- const properties = (activity.inputs || []).map((input) => ({
3750
- name: input.name,
3751
- type: this.getPropertyTypeFromDataType(input.dataType),
3752
- required: !!input.validations?.some((v) => v.rule === 'required'),
3753
- description: this.translationService.resolve(input.description) ?? undefined,
3754
- defaultValue: undefined,
3755
- }));
3756
- const defaultProperties = {};
3757
- properties.forEach((prop) => {
3758
- if (prop.defaultValue !== undefined) {
3759
- defaultProperties[prop.name] = prop.defaultValue;
3760
- }
3761
- });
3762
- return {
3763
- type: activity.type,
3764
- name: activity.name,
3765
- description: this.translationService.resolve(activity.description) || '',
3766
- icon: this.normalizeActivityIcon(activity.icon),
3767
- properties,
3768
- defaultProperties,
3769
- };
3770
- }
3771
- /**
3772
- * Normalize FontAwesome icon: if missing style prefix (e.g. fa-light, fas), prepend 'fa-light ' so short values like 'fa-shield-alt' render.
3773
- */
3774
- normalizeActivityIcon(icon) {
3775
- if (!icon?.trim())
3776
- return 'fa-light fa-circle';
3777
- const trimmed = icon.trim();
3778
- const hasStylePrefix = /^(fa-light|fas|far|fal|fa-solid|fa-regular|fa-brands|fa-duotone)(\s|$)/i.test(trimmed);
3779
- return hasStylePrefix ? trimmed : `fa-light ${trimmed}`;
3780
- }
3781
- /**
3782
- * Map {@link AXPProperty.dataType} to visual editor property type.
3783
- */
3784
- getPropertyTypeFromDataType(dataType) {
3785
- if (dataType === 'array')
3786
- return 'array';
3787
- if (dataType === 'object')
3788
- return 'object';
3789
- if (dataType === 'boolean')
3790
- return 'boolean';
3791
- if (dataType === 'number' || dataType === 'integer')
3792
- return 'number';
3793
- if (dataType === 'blob')
3794
- return 'any';
3795
- return 'string';
3796
- }
3797
- /**
3798
- * Get category color
3799
- */
3800
- getCategoryColor(categoryId) {
3801
- const colorMap = {
3802
- 'workflow-markers': '#10B981',
3803
- 'control-flow': '#3B82F6',
3804
- 'user-interaction': '#8B5CF6',
3805
- data: '#10B981',
3806
- navigation: '#F59E0B',
3807
- events: '#EF4444',
3808
- http: '#06B6D4',
3809
- };
3810
- return colorMap[categoryId] || '#64748B';
3811
- }
3812
- /**
3813
- * Get empty workflow JSON
3814
- */
3815
- getEmptyWorkflow() {
3816
- return JSON.stringify({
3817
- id: 'new-workflow',
3818
- name: '',
3819
- description: '',
3820
- version: 1,
3821
- root: {
3822
- id: 'root',
3823
- type: 'workflow-activity:sequence',
3824
- name: 'Root',
3825
- children: [],
3826
- },
3827
- }, null, 2);
3828
- }
3829
- //#endregion
3830
- /**
3831
- * Sync visualizer with JSON changes
3832
- */
3833
- syncVisualizerWithJson() {
3834
- try {
3835
- if (this.activeTab() === 'visual') {
3836
- this.jsonToVisual();
3837
- }
3838
- }
3839
- catch (err) {
3840
- console.error('[WorkflowStudio] Error syncing visualizer:', err);
3841
- }
3842
- }
3843
- //#region ---- Workflow Execution ----
3844
- /**
3845
- * Open execution dialog
3846
- */
3847
- openExecutionDialog() {
3848
- this.showExecutionDialog.set(true);
3849
- this.workflowInstanceState.set(null);
3850
- }
3851
- /**
3852
- * Close execution dialog
3853
- */
3854
- closeExecutionDialog() {
3855
- this.showExecutionDialog.set(false);
3856
- this.workflowInstanceState.set(null);
3857
- }
3858
- /**
3859
- * Start workflow execution
3860
- */
3861
- async startWorkflowExecution() {
3862
- await this.runWorkflow();
3863
- }
3864
- /**
3865
- * اجرای workflow
3866
- */
3867
- async runWorkflow() {
3868
- this.isExecuting.set(true);
3869
- this.executionLogs.set([]);
3870
- this.workflowInstanceState.set({
3871
- status: 'running',
3872
- startTime: new Date(),
3873
- currentState: null,
3874
- });
3875
- this.addLog('info', 'شروع اجرای Workflow...');
3876
- try {
3877
- // Parse JSON
3878
- const workflowDef = JSON.parse(this.workflowJson());
3879
- const logMessage = await this.translationService.translateAsync('@workflow-management:test-pages.messages.info.json-parsed');
3880
- this.addLog('success', logMessage, workflowDef);
3881
- // Save workflow definition to entity service first
3882
- const workflowId = workflowDef.id || `workflow-${Date.now()}`;
3883
- const definitionToSave = this.exportWorkflowDefinition();
3884
- if (!definitionToSave) {
3885
- throw new Error('Failed to export workflow definition');
3886
- }
3887
- // Save or update workflow definition
3888
- try {
3889
- const existing = await this.entityService
3890
- .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3891
- .data()
3892
- .byKey(workflowId);
3893
- if (existing) {
3894
- await this.entityService
3895
- .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3896
- .data()
3897
- .update(workflowId, definitionToSave);
3898
- }
3899
- else {
3900
- await this.entityService
3901
- .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3902
- .data()
3903
- .create({ ...definitionToSave, id: workflowId });
3904
- }
3905
- const saveMessage = await this.translationService.translateAsync('@workflow-management:test-pages.messages.success.workflow-saved');
3906
- this.addLog('success', saveMessage);
3907
- }
3908
- catch (saveError) {
3909
- // Continue execution even if save fails
3910
- const saveErrorMessage = await this.translationService.translateAsync('@workflow-management:test-pages.messages.warning.save-failed');
3911
- this.addLog('warning', `${saveErrorMessage}: ${saveError.message}`);
3912
- }
3913
- // اجرای workflow
3914
- const executingMessage = await this.translationService.translateAsync('@workflow-management:test-pages.messages.info.executing');
3915
- this.addLog('info', executingMessage);
3916
- // Start workflow execution using the workflow name
3917
- const workflowName = definitionToSave.name || workflowId;
3918
- let result = await this.workflowManager.start(workflowName, {});
3919
- this.addLog('info', `Workflow started. Instance ID: ${result.instanceId}`, result);
3920
- if (!result.instanceId) {
3921
- this.addLog('error', '❌ Workflow با خطا مواجه شد', result);
3922
- return;
3923
- }
3924
- // Handle workflow execution loop - execute all frontend tasks
3925
- let currentResult = result;
3926
- let taskCount = 0;
3927
- while (currentResult.nextTask) {
3928
- taskCount++;
3929
- const task = currentResult.nextTask;
3930
- this.addLog('info', `📋 Task ${taskCount}: ${task.activityType} (${task.activityName || task.activityId})`, task);
3931
- try {
3932
- // Execute frontend task
3933
- this.addLog('info', `⚡ Executing task: ${task.activityType}...`);
3934
- // const { output, outcome } = await this.workflowManager.execute(task);
3935
- // this.addLog('success', `✅ Task executed. Outcome: ${outcome}`, { output, outcome });
3936
- // Complete task and get next
3937
- this.addLog('info', `🔄 Completing task and getting next...`);
3938
- // currentResult = await this.workflowManager.complete(
3939
- // currentResult.instanceId!,
3940
- // task,
3941
- // outcome,
3942
- // output
3943
- // );
3944
- if (!currentResult.instanceId) {
3945
- this.addLog('error', '❌ Task completion failed', currentResult);
3946
- break;
3947
- }
3948
- if (currentResult.nextTask) {
3949
- this.addLog('info', `➡️ Next task available: ${currentResult.nextTask.activityType}`);
3950
- }
3951
- else {
3952
- this.addLog('success', '✅ No more tasks. Workflow completed!');
3953
- }
3954
- }
3955
- catch (error) {
3956
- this.addLog('error', `❌ Error executing task: ${error.message}`, error);
3957
- currentResult = {
3958
- ...currentResult,
3959
- success: false,
3960
- error: error.message || 'Task execution failed',
3961
- };
3962
- break;
3963
- }
3964
- }
3965
- // نتیجه
3966
- this.workflowInstanceState.set({
3967
- status: 'finished',
3968
- finalResult: currentResult,
3969
- startTime: this.workflowInstanceState().startTime || new Date(),
3970
- endTime: new Date(),
3971
- result: currentResult,
3972
- currentState: currentResult.state?.output?.['taskStatus'] || currentResult.state?.output?.['currentState'],
3973
- });
3974
- if (currentResult.success) {
3975
- this.addLog('success', `✅ Workflow با موفقیت اجرا شد! (${taskCount} task(s) executed)`, currentResult);
3976
- }
3977
- else {
3978
- this.addLog('error', '❌ Workflow با خطا مواجه شد: ' + (currentResult.error || 'Unknown error'), currentResult);
3979
- }
3980
- }
3981
- catch (error) {
3982
- this.addLog('error', '❌ خطا در اجرای Workflow: ' + error.message, error);
3983
- this.workflowInstanceState.set({
3984
- status: 'error',
3985
- error: error.message,
3986
- startTime: this.workflowInstanceState().startTime,
3987
- });
3988
- }
3989
- finally {
3990
- this.isExecuting.set(false);
3991
- }
3992
- }
3993
- /**
3994
- * اضافه کردن لاگ
3995
- */
3996
- addLog(level, message, data) {
3997
- const logs = this.executionLogs();
3998
- logs.push({
3999
- timestamp: new Date(),
4000
- level,
4001
- message,
4002
- data,
4003
- });
4004
- this.executionLogs.set([...logs]);
4005
- }
4006
- /**
4007
- * کپی کردن نمونه activity
4008
- */
4009
- copyActivityTemplate(activity) {
4010
- const template = {
4011
- id: `${activity.type.toLowerCase()}-${Date.now()}`,
4012
- type: activity.type,
4013
- name: activity.name,
4014
- properties: {},
4015
- };
4016
- // کپی در کلیپ‌بورد
4017
- navigator.clipboard.writeText(JSON.stringify(template, null, 2));
4018
- this.addLog('success', `✂️ Template برای ${activity.name} کپی شد!`);
4019
- }
4020
- /**
4021
- * فرمت کردن JSON
4022
- */
4023
- formatJson() {
4024
- try {
4025
- const parsed = JSON.parse(this.workflowJson());
4026
- this.workflowJson.set(JSON.stringify(parsed, null, 2));
4027
- this.addLog('success', '✨ JSON فرمت شد');
4028
- }
4029
- catch (error) {
4030
- this.addLog('error', '❌ خطا در فرمت: ' + error.message);
4031
- }
4032
- }
4033
- /**
4034
- * Open workflow settings dialog built with Layout Builder (platform widgets / Acorex).
4035
- */
4036
- openWorkflowSettings() {
4037
- this.syncWorkflowSettingsFromJson();
4038
- const settings = this.workflowSettings();
4039
- const dialogContext = {
4040
- name: settings.name,
4041
- definitionId: settings.definitionId,
4042
- description: settings.description ?? '',
4043
- inputsJson: JSON.stringify(settings.inputs, null, 2),
4044
- outputsJson: JSON.stringify(settings.outputs, null, 2),
4045
- variablesJson: JSON.stringify(settings.variables, null, 2),
4046
- outcomesJson: Array.isArray(settings.outcomes) ? settings.outcomes.join(', ') : 'Done',
4047
- version: settings.version,
4048
- isLatest: settings.isLatest,
4049
- isPublished: settings.isPublished,
4050
- usableAsActivity: settings.usableAsActivity,
4051
- autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows,
4052
- toolVersion: settings.toolVersion ?? '1.0.0',
4053
- providerName: settings.providerName ?? 'WorkflowStudio',
4054
- };
4055
- this.layoutBuilder
4056
- .create()
4057
- .dialog((dialog) => {
4058
- dialog
4059
- .setTitle('@workflow-management:workflow-studio.settings.title')
4060
- .setSize('lg')
4061
- .setCloseButton(true)
4062
- .setContext(dialogContext)
4063
- .content((flex) => {
4064
- flex
4065
- .setDirection('column')
4066
- .setGap('12px')
4067
- .fieldset((general) => {
4068
- general
4069
- .setTitle('@workflow-management:workflow-studio.settings.tabs.general')
4070
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.name.title', (field) => {
4071
- field.path('name');
4072
- field.textBox({
4073
- placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.name.placeholder',
4074
- });
4075
- })
4076
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.title', (field) => {
4077
- field.path('definitionId');
4078
- field.textBox({
4079
- placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.placeholder',
4080
- });
4081
- })
4082
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.description.title', (field) => {
4083
- field.path('description');
4084
- field.largeTextBox({
4085
- placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.description.placeholder',
4086
- rows: 4,
4087
- });
4088
- });
4089
- })
4090
- .fieldset((inputs) => {
4091
- inputs
4092
- .setTitle('@workflow-management:workflow-studio.settings.tabs.inputs')
4093
- .formField('@workflow-management:workflow-studio.settings.sections.inputs.fields.inputs-json', (field) => {
4094
- field.path('inputsJson');
4095
- field.largeTextBox({ rows: 12 });
4096
- });
4097
- })
4098
- .fieldset((outputs) => {
4099
- outputs
4100
- .setTitle('@workflow-management:workflow-studio.settings.tabs.outputs')
4101
- .formField('@workflow-management:workflow-studio.settings.sections.outputs.fields.outputs-json', (field) => {
4102
- field.path('outputsJson');
4103
- field.largeTextBox({ rows: 12 });
4104
- });
4105
- })
4106
- .fieldset((variables) => {
4107
- variables
4108
- .setTitle('@workflow-management:workflow-studio.settings.tabs.variables')
4109
- .formField('@workflow-management:workflow-studio.settings.sections.variables.fields.variables-json', (field) => {
4110
- field.path('variablesJson');
4111
- field.largeTextBox({ rows: 12 });
4112
- });
4113
- })
4114
- .fieldset((advanced) => {
4115
- advanced
4116
- .setTitle('@workflow-management:workflow-studio.settings.tabs.advanced')
4117
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.version', (field) => {
4118
- field.path('version');
4119
- field.numberBox({ min: 1 });
4120
- })
4121
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-latest', (field) => {
4122
- field.path('isLatest');
4123
- field.toggleSwitch();
4124
- })
4125
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-published', (field) => {
4126
- field.path('isPublished');
4127
- field.toggleSwitch();
4128
- })
4129
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.usable-as-activity', (field) => {
4130
- field.path('usableAsActivity');
4131
- field.toggleSwitch();
4132
- })
4133
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.auto-update-consuming', (field) => {
4134
- field.path('autoUpdateConsumingWorkflows');
4135
- field.toggleSwitch();
4136
- })
4137
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.tool-version', (field) => {
4138
- field.path('toolVersion');
4139
- field.textBox({ placeholder: '1.0.0' });
4140
- })
4141
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.provider-name', (field) => {
4142
- field.path('providerName');
4143
- field.textBox({ placeholder: 'WorkflowStudio' });
4144
- })
4145
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-label', (field) => {
4146
- field.path('outcomesJson');
4147
- field.textBox({
4148
- placeholder: '@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-placeholder',
4149
- });
4150
- });
4151
- });
4152
- })
4153
- .setActions((actions) => {
4154
- actions
4155
- .cancel('@workflow-management:workflow-studio.settings.actions.cancel')
4156
- .submit('@workflow-management:workflow-studio.settings.actions.save');
4157
- })
4158
- .onAction(async (dialogRef) => {
4159
- const action = dialogRef.action();
4160
- if (action === 'cancel')
4161
- return;
4162
- const ctx = dialogRef.context();
4163
- if (!ctx)
4164
- return;
4165
- let inputs = [];
4166
- let outputs = [];
4167
- let variables = [];
4168
- let outcomes = ['Done'];
4169
- try {
4170
- if (typeof ctx.inputsJson === 'string' && ctx.inputsJson.trim()) {
4171
- inputs = JSON.parse(ctx.inputsJson);
4172
- }
4173
- }
4174
- catch {
4175
- this.addLog('error', 'Invalid inputs JSON');
4176
- }
4177
- try {
4178
- if (typeof ctx.outputsJson === 'string' && ctx.outputsJson.trim()) {
4179
- outputs = JSON.parse(ctx.outputsJson);
4180
- }
4181
- }
4182
- catch {
4183
- this.addLog('error', 'Invalid outputs JSON');
4184
- }
4185
- try {
4186
- if (typeof ctx.variablesJson === 'string' && ctx.variablesJson.trim()) {
4187
- variables = JSON.parse(ctx.variablesJson);
4188
- }
4189
- }
4190
- catch {
4191
- this.addLog('error', 'Invalid variables JSON');
4192
- }
4193
- if (typeof ctx.outcomesJson === 'string' && ctx.outcomesJson.trim()) {
4194
- outcomes = ctx.outcomesJson
4195
- .split(',')
4196
- .map((s) => s.trim())
4197
- .filter(Boolean);
4198
- }
4199
- if (outcomes.length === 0)
4200
- outcomes = ['Done'];
4201
- const newSettings = {
4202
- definitionId: String(ctx.definitionId ?? ''),
4203
- name: String(ctx.name ?? ''),
4204
- description: String(ctx.description ?? ''),
4205
- inputs,
4206
- outputs,
4207
- variables,
4208
- outcomes,
4209
- version: Number(ctx.version) || 1,
4210
- isLatest: Boolean(ctx.isLatest),
4211
- isPublished: Boolean(ctx.isPublished),
4212
- usableAsActivity: Boolean(ctx.usableAsActivity),
4213
- autoUpdateConsumingWorkflows: Boolean(ctx.autoUpdateConsumingWorkflows),
4214
- toolVersion: String(ctx.toolVersion ?? '1.0.0'),
4215
- providerName: String(ctx.providerName ?? 'WorkflowStudio'),
4216
- };
4217
- this.workflowSettings.set(newSettings);
4218
- this.applyWorkflowSettingsToJson();
4219
- });
4220
- })
4221
- .show();
4222
- }
4223
- /**
4224
- * Sync workflowSettings from current workflow JSON (used before opening settings dialog).
4225
- */
4226
- syncWorkflowSettingsFromJson() {
4227
- try {
4228
- const workflow = JSON.parse(this.workflowJson());
4229
- this.workflowSettings.set({
4230
- definitionId: workflow.definitionId || workflow.id || '',
4231
- name: workflow.name || '',
4232
- description: this.resolveWorkflowDefinitionDescription(workflow),
4233
- inputs: (workflow.inputs || []).map((input) => this.mapDefinitionInputToWorkflowInput(input)),
4234
- outputs: (workflow.outputs || []).map((output) => this.mapDefinitionOutputToWorkflowOutput(output)),
4235
- variables: workflow.variables || [],
4236
- outcomes: workflow.outcomes || ['Done'],
4237
- usableAsActivity: workflow.options?.usableAsActivity || false,
4238
- autoUpdateConsumingWorkflows: workflow.options?.autoUpdateConsumingWorkflows || false,
4239
- version: workflow.version || 1,
4240
- isLatest: workflow.isLatest !== undefined ? workflow.isLatest : true,
4241
- isPublished: workflow.isPublished || false,
4242
- toolVersion: workflow.toolVersion || '1.0.0',
4243
- providerName: workflow.providerName || 'WorkflowStudio',
4244
- });
4245
- }
4246
- catch {
4247
- this.workflowSettings.set({
4248
- definitionId: '',
4249
- name: '',
4250
- description: '',
4251
- inputs: [],
4252
- outputs: [],
4253
- variables: [],
4254
- outcomes: ['Done'],
4255
- usableAsActivity: false,
4256
- autoUpdateConsumingWorkflows: false,
4257
- version: 1,
4258
- isLatest: true,
4259
- isPublished: false,
4260
- toolVersion: '1.0.0',
4261
- providerName: 'WorkflowStudio',
4262
- });
4263
- }
4264
- }
4265
- /**
4266
- * Apply current workflowSettings to workflow JSON (used after saving from dialog).
4267
- */
4268
- applyWorkflowSettingsToJson() {
4269
- try {
4270
- const workflow = JSON.parse(this.workflowJson());
4271
- const settings = this.workflowSettings();
4272
- workflow.definitionId = settings.definitionId;
4273
- workflow.name = settings.name;
4274
- workflow.description = settings.description;
4275
- workflow.version = settings.version;
4276
- workflow.isLatest = settings.isLatest;
4277
- workflow.isPublished = settings.isPublished;
4278
- workflow.toolVersion = settings.toolVersion;
4279
- workflow.providerName = settings.providerName;
4280
- workflow.options = {
4281
- usableAsActivity: settings.usableAsActivity,
4282
- autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows,
4283
- };
4284
- workflow.variables = settings.variables.map((v) => ({
4285
- id: v.name,
4286
- name: v.name,
4287
- typeName: v.typeName,
4288
- value: v.value,
4289
- storageDriverType: 'Memory',
4290
- }));
4291
- workflow.inputs = settings.inputs.map((i) => ({
4292
- name: i.name,
4293
- title: i.title,
4294
- description: i.description,
4295
- dataType: i.schema.dataType,
4296
- interface: i.schema.interface ?? { type: 'text-editor', options: {} },
4297
- validations: i.validations,
4298
- }));
4299
- workflow.outputs = settings.outputs.map((o) => ({
4300
- name: o.name,
4301
- title: o.title,
4302
- description: o.description,
4303
- dataType: o.schema.dataType,
4304
- interface: o.schema.interface ?? { type: 'text-editor', options: {} },
4305
- path: o.path,
4306
- metadata: o.metadata,
4307
- }));
4308
- workflow.outcomes = settings.outcomes;
4309
- workflow.customProperties = workflow.customProperties || {};
4310
- workflow.isReadonly = false;
4311
- workflow.isSystem = false;
4312
- this.workflowJson.set(JSON.stringify(workflow, null, 2));
4313
- this.addLog('success', '✅ Workflow settings saved');
4314
- }
4315
- catch (error) {
4316
- this.addLog('error', '❌ Failed to save settings: ' + error?.message);
4317
- }
4318
- }
4319
- /**
4320
- * Export workflow به فرمت Elsa Workflow Definition v3.0.0
4321
- * https://elsaworkflows.io/schemas/workflow-definition/v3.0.0/schema.json
4322
- */
4323
- exportWorkflowDefinition() {
4324
- try {
4325
- const workflow = JSON.parse(this.workflowJson());
4326
- const settings = this.workflowSettings();
4327
- // Create Elsa Workflow Definition v3.0.0 structure
4328
- const definition = {
4329
- // VersionedEntity fields
4330
- id: workflow.id || this.generateId(),
4331
- version: settings.version,
4332
- isLatest: settings.isLatest,
4333
- isPublished: settings.isPublished,
4334
- // Identification fields
4335
- definitionId: settings.definitionId || workflow.id || this.generateId(),
4336
- name: settings.name || workflow.name || 'Untitled Workflow',
4337
- description: settings.description || this.resolveWorkflowDefinitionDescription(workflow),
4338
- toolVersion: settings.toolVersion || '3.0.0',
4339
- // Materialization fields
4340
- providerName: settings.providerName || 'ACoreX',
4341
- materializerContext: {
4342
- materializerName: 'Json',
4343
- // Store the root activity as JSON string
4344
- stringData: JSON.stringify(workflow.root),
4345
- },
4346
- // WorkflowCommon fields
4347
- options: {
4348
- usableAsActivity: settings.usableAsActivity || false,
4349
- autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows || false,
4350
- },
4351
- // Variables array
4352
- variables: settings.variables.map((v) => ({
4353
- id: v.name,
4354
- name: v.name,
4355
- typeName: v.typeName,
4356
- value: v.value,
4357
- storageDriverType: 'Memory',
4358
- })),
4359
- // Inputs array (aligned with {@link AXPProperty})
4360
- inputs: settings.inputs.map((i) => ({
4361
- name: i.name,
4362
- title: i.title,
4363
- description: i.description,
4364
- dataType: i.schema.dataType,
4365
- interface: i.schema.interface ?? { type: 'text-editor', options: {} },
4366
- validations: i.validations || [],
4367
- })),
4368
- // Outputs array (aligned with {@link AXPWorkflowOutputProperty})
4369
- outputs: settings.outputs.map((o) => ({
4370
- name: o.name,
4371
- title: o.title,
4372
- description: o.description,
4373
- dataType: o.schema.dataType,
4374
- interface: o.schema.interface ?? { type: 'text-editor', options: {} },
4375
- path: o.path,
4376
- metadata: o.metadata,
4377
- })),
4378
- // Outcomes array
4379
- outcomes: settings.outcomes || ['Done'],
4380
- // Custom properties
4381
- customProperties: workflow.customProperties || {},
4382
- // Flags
4383
- isReadonly: false,
4384
- isSystem: false,
4385
- // Root activity (direct reference for Elsa compatibility)
4386
- root: workflow.root,
4387
- };
4388
- return definition;
4389
- }
4390
- catch (error) {
4391
- this.addLog('error', '❌ خطا در export: ' + error.message);
4392
- return null;
4393
- }
4394
- }
4395
- /**
4396
- * دانلود WorkflowDefinition به صورت JSON file
4397
- */
4398
- downloadWorkflowDefinition() {
4399
- const definition = this.exportWorkflowDefinition();
4400
- if (!definition)
4401
- return;
4402
- const blob = new Blob([JSON.stringify(definition, null, 2)], { type: 'application/json' });
4403
- const url = URL.createObjectURL(blob);
4404
- const link = document.createElement('a');
4405
- link.href = url;
4406
- link.download = `${definition.definitionId || 'workflow'}-v${definition.version}.json`;
4407
- link.click();
4408
- URL.revokeObjectURL(url);
4409
- this.addLog('success', `📥 Workflow Definition دانلود شد: ${link.download}`);
4410
- }
4411
- generateId() {
4412
- return `wf-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`;
4413
- }
4414
- // ============ Workflow Inputs Management ============
4415
- addWorkflowInput() {
4416
- const settings = this.workflowSettings();
4417
- settings.inputs.push({
4418
- name: `input${settings.inputs.length + 1}`,
4419
- title: `Input ${settings.inputs.length + 1}`,
4420
- description: '',
4421
- schema: {
4422
- dataType: 'string',
4423
- defaultValue: undefined,
4424
- interface: { type: 'text-editor', options: {} },
4425
- },
4426
- validations: undefined,
4427
- });
4428
- this.workflowSettings.set({ ...settings });
4429
- }
4430
- removeWorkflowInput(index) {
4431
- const settings = this.workflowSettings();
4432
- settings.inputs.splice(index, 1);
4433
- this.workflowSettings.set({ ...settings });
4434
- }
4435
- updateWorkflowInput(index, field, value) {
4436
- const settings = this.workflowSettings();
4437
- const input = settings.inputs[index];
4438
- if (field === 'schema') {
4439
- // For nested schema updates
4440
- input[field] = value;
4441
- }
4442
- else if (field.startsWith('schema.')) {
4443
- // For nested schema properties like 'schema.dataType'
4444
- const schemaField = field.replace('schema.', '');
4445
- if (!input.schema) {
4446
- input.schema = { dataType: 'string', interface: { type: 'text-editor', options: {} } };
4447
- }
4448
- input.schema[schemaField] = value;
4449
- }
4450
- else {
4451
- input[field] = value;
4452
- }
4453
- this.workflowSettings.set({ ...settings });
4454
- }
4455
- updateWorkflowInputSchema(index, schemaField, value) {
4456
- const settings = this.workflowSettings();
4457
- const input = settings.inputs[index];
4458
- if (!input.schema) {
4459
- input.schema = { dataType: 'string', interface: { type: 'text-editor', options: {} } };
4460
- }
4461
- input.schema[schemaField] = value;
4462
- this.workflowSettings.set({ ...settings });
4463
- }
4464
- updateWorkflowInputValidation(index, isRequired) {
4465
- const settings = this.workflowSettings();
4466
- const input = settings.inputs[index];
4467
- if (isRequired) {
4468
- if (!input.validations) {
4469
- input.validations = [];
4470
- }
4471
- if (!input.validations.some((v) => v.rule === 'required')) {
4472
- input.validations.push({ rule: 'required' });
4473
- }
4474
- }
4475
- else {
4476
- input.validations = input.validations?.filter((v) => v.rule !== 'required');
4477
- if (input.validations?.length === 0) {
4478
- input.validations = undefined;
4479
- }
4480
- }
4481
- this.workflowSettings.set({ ...settings });
4482
- }
4483
- getInputIsRequired(input) {
4484
- return input.validations?.some((v) => v.rule === 'required') ?? false;
4485
- }
4486
- // ============ Workflow Outputs Management ============
4487
- addWorkflowOutput() {
4488
- const settings = this.workflowSettings();
4489
- settings.outputs.push({
4490
- name: `output${settings.outputs.length + 1}`,
4491
- title: `Output ${settings.outputs.length + 1}`,
4492
- description: '',
4493
- schema: {
4494
- dataType: 'string',
4495
- },
4496
- });
4497
- this.workflowSettings.set({ ...settings });
4498
- }
4499
- removeWorkflowOutput(index) {
4500
- const settings = this.workflowSettings();
4501
- settings.outputs.splice(index, 1);
4502
- this.workflowSettings.set({ ...settings });
4503
- }
4504
- updateWorkflowOutput(index, field, value) {
4505
- const settings = this.workflowSettings();
4506
- const output = settings.outputs[index];
4507
- if (field.startsWith('schema.')) {
4508
- // For nested schema properties like 'schema.dataType'
4509
- const schemaField = field.replace('schema.', '');
4510
- if (!output.schema) {
4511
- output.schema = { dataType: 'string' };
4512
- }
4513
- output.schema[schemaField] = value;
4514
- }
4515
- else {
4516
- output[field] = value;
4517
- }
4518
- this.workflowSettings.set({ ...settings });
4519
- }
4520
- updateWorkflowOutputSchema(index, schemaField, value) {
4521
- const settings = this.workflowSettings();
4522
- const output = settings.outputs[index];
4523
- if (!output.schema) {
4524
- output.schema = { dataType: 'string' };
4525
- }
4526
- output.schema[schemaField] = value;
4527
- this.workflowSettings.set({ ...settings });
4528
- }
4529
- // ============ Workflow Variables Management ============
4530
- addWorkflowVariable() {
4531
- const settings = this.workflowSettings();
4532
- settings.variables.push({
4533
- name: `variable${settings.variables.length + 1}`,
4534
- typeName: 'string',
4535
- value: '',
4536
- description: '',
4537
- });
4538
- this.workflowSettings.set({ ...settings });
4539
- }
4540
- removeWorkflowVariable(index) {
4541
- const settings = this.workflowSettings();
4542
- settings.variables.splice(index, 1);
4543
- this.workflowSettings.set({ ...settings });
4544
- }
4545
- updateWorkflowVariable(index, field, value) {
4546
- const settings = this.workflowSettings();
4547
- settings.variables[index][field] = value;
4548
- this.workflowSettings.set({ ...settings });
4549
- }
4550
- /**
4551
- * به‌روزرسانی outcomes از string
4552
- */
4553
- updateOutcomes(outcomesString) {
4554
- const settings = this.workflowSettings();
4555
- settings.outcomes = outcomesString
4556
- .split(',')
4557
- .map((o) => o.trim())
4558
- .filter((o) => o.length > 0);
4559
- this.workflowSettings.set({ ...settings });
4560
- }
4561
- /**
4562
- * پاک کردن لاگ‌ها
4563
- */
4564
- clearLogs() {
4565
- this.executionLogs.set([]);
4566
- }
4567
- // ============ Visual Designer Methods ============
4568
- /**
4569
- * تغییر تب
4570
- */
4571
- switchTab(tab) {
4572
- if (tab === 'visual' && this.activeTab() === 'json') {
4573
- // تبدیل JSON به Visual
4574
- this.jsonToVisual();
4575
- }
4576
- else if (tab === 'json' && this.activeTab() === 'visual') {
4577
- // تبدیل Visual به JSON
4578
- this.visualToJson();
4579
- }
4580
- this.activeTab.set(tab);
4581
- }
4582
- /**
4583
- * انتخاب Node
4584
- */
4585
- selectNodeById(node) {
4586
- this.selectedNode.set(node);
4587
- }
4588
- /**
4589
- * Delete node from canvas (used from template to avoid event propagation).
4590
- */
4591
- deleteNodeFromCanvas(nodeId) {
4592
- this.deleteNode(nodeId);
4593
- }
4594
- /**
4595
- * حذف Node
4596
- */
4597
- deleteNode(nodeId) {
4598
- const nodes = this.visualNodes().filter((n) => n.id !== nodeId);
4599
- // حذف اتصالات به این نود
4600
- nodes.forEach((n) => {
4601
- n.connections = n.connections.filter((c) => c !== nodeId);
4602
- });
4603
- this.visualNodes.set(nodes);
4604
- if (this.selectedNode()?.id === nodeId) {
4605
- this.selectedNode.set(null);
4606
- }
4607
- this.addLog('info', `🗑️ Node حذف شد`);
4608
- }
4609
- /**
4610
- * اتصال دو Node با outcome مشخص
4611
- */
4612
- connectNodes(fromId, toId, outcome) {
4613
- const nodes = this.visualNodes();
4614
- const fromNodeIndex = nodes.findIndex((n) => n.id === fromId);
4615
- const toNode = nodes.find((n) => n.id === toId);
4616
- if (fromNodeIndex !== -1 && toNode) {
4617
- const fromNode = nodes[fromNodeIndex];
4618
- // Use outcome-based connections if available
4619
- if (outcome && fromNode.outcomes && fromNode.outcomes.length > 1) {
4620
- const outcomeConnections = fromNode.outcomeConnections || [];
4621
- // Check if this outcome already has a connection
4622
- const existingConnection = outcomeConnections.find((c) => c.outcome === outcome);
4623
- if (existingConnection) {
4624
- this.addLog('warning', `⚠️ Outcome "${outcome}" قبلاً متصل شده است`);
4625
- return;
4626
- }
4627
- // Add new outcome connection
4628
- const updatedNodes = [...nodes];
4629
- updatedNodes[fromNodeIndex] = {
4630
- ...fromNode,
4631
- outcomeConnections: [...outcomeConnections, { outcome, targetNodeId: toId }],
4632
- connections: [...fromNode.connections, toId], // Keep for backward compat
4633
- };
4634
- this.visualNodes.set(updatedNodes);
4635
- this.addLog('success', `🔗 ${fromNode.name} [${outcome}] → ${toNode.name}`);
4636
- }
4637
- else {
4638
- // Simple connection (no outcomes)
4639
- if (!fromNode.connections.includes(toId)) {
4640
- const updatedNodes = [...nodes];
4641
- updatedNodes[fromNodeIndex] = {
4642
- ...fromNode,
4643
- connections: [...fromNode.connections, toId],
4644
- };
4645
- this.visualNodes.set(updatedNodes);
4646
- this.addLog('success', `🔗 ${fromNode.name} متصل شد به ${toNode.name}`);
4647
- }
4648
- else {
4649
- this.addLog('warning', '⚠️ این اتصال از قبل وجود دارد');
4650
- }
4651
- }
4652
- }
4653
- else {
4654
- this.addLog('error', '❌ خطا در ایجاد اتصال');
4655
- }
4656
- }
4657
- /**
4658
- * قطع اتصال (با یا بدون outcome)
4659
- */
4660
- disconnectNodes(fromId, toId, outcome) {
4661
- const nodes = this.visualNodes();
4662
- const fromNodeIndex = nodes.findIndex((n) => n.id === fromId);
4663
- if (fromNodeIndex !== -1) {
4664
- const fromNode = nodes[fromNodeIndex];
4665
- const updatedNodes = [...nodes];
4666
- // Remove from outcome connections if specified
4667
- if (outcome && fromNode.outcomeConnections) {
4668
- updatedNodes[fromNodeIndex] = {
4669
- ...fromNode,
4670
- outcomeConnections: fromNode.outcomeConnections.filter((c) => !(c.outcome === outcome && c.targetNodeId === toId)),
4671
- connections: fromNode.connections.filter((c) => c !== toId),
4672
- };
4673
- }
4674
- else {
4675
- // Simple disconnect
4676
- updatedNodes[fromNodeIndex] = {
4677
- ...fromNode,
4678
- connections: fromNode.connections.filter((c) => c !== toId),
4679
- outcomeConnections: fromNode.outcomeConnections?.filter((c) => c.targetNodeId !== toId),
4680
- };
4681
- }
4682
- this.visualNodes.set(updatedNodes);
4683
- this.addLog('info', `✂️ اتصال قطع شد${outcome ? ` [${outcome}]` : ''}`);
4684
- }
4685
- }
4686
- /**
4687
- * تبدیل JSON به Visual
4688
- */
4689
- jsonToVisual() {
4690
- try {
4691
- const workflow = JSON.parse(this.workflowJson());
4692
- const nodes = [];
4693
- let yPos = 100;
4694
- // پردازش root activity
4695
- if (workflow.root) {
4696
- this.processActivityToNode(workflow.root, nodes, 100, yPos);
4697
- }
4698
- this.visualNodes.set(nodes);
4699
- this.addLog('success', '✅ JSON به Visual تبدیل شد');
4700
- }
4701
- catch (error) {
4702
- this.addLog('error', '❌ خطا در تبدیل: ' + error.message);
4703
- }
4704
- }
4705
- /**
4706
- * پردازش Activity به Node (recursive)
4707
- */
4708
- processActivityToNode(activity, nodes, x, y, parentId) {
4709
- const nodeId = activity.id || `${activity.type}-${Date.now()}-${Math.random()}`;
4710
- // Get outcomes for this activity type (use default for now, will be updated async if needed)
4711
- const outcomes = ['Done']; // Default outcome, will be updated when activity info is loaded
4712
- // Get outcomeConnections from activity definition
4713
- const outcomeConnections = activity.outcomeConnections || [];
4714
- // Build simple connections list from outcomeConnections for backward compatibility
4715
- const connections = outcomeConnections.map((conn) => conn.targetNodeId);
4716
- const node = {
4717
- id: nodeId,
4718
- type: activity.type,
4719
- name: activity.name || activity.type,
4720
- icon: this.getIconForActivityType(activity.type),
4721
- properties: activity.properties || {},
4722
- position: { x, y },
4723
- connections: connections,
4724
- outcomeConnections: outcomeConnections,
4725
- outcomes: outcomes,
4726
- };
4727
- nodes.push(node);
4728
- // اگر parent دارد، اتصال برقرار کن (برای Sequence)
4729
- if (parentId && !outcomeConnections.length) {
4730
- const parentNode = nodes.find((n) => n.id === parentId);
4731
- if (parentNode && !parentNode.connections.includes(nodeId)) {
4732
- parentNode.connections.push(nodeId);
4733
- }
4734
- }
4735
- // پردازش children (برای Sequence) - اما فقط اگر outcomeConnections نباشد
4736
- if (activity.children && Array.isArray(activity.children) && !outcomeConnections.length) {
4737
- let childY = y;
4738
- activity.children.forEach((child, index) => {
4739
- childY = y + index * 100;
4740
- this.processActivityToNode(child, nodes, x + 250, childY, nodeId);
4741
- });
4742
- }
4743
- return nodeId;
4744
- }
4745
- /**
4746
- * تبدیل Visual به JSON
4747
- */
4748
- visualToJson() {
4749
- try {
4750
- const nodes = this.visualNodes();
4751
- if (nodes.length === 0) {
4752
- this.addLog('warning', '⚠️ هیچ Node ای وجود ندارد');
4753
- return;
4754
- }
4755
- // پیدا کردن root node (node بدون parent)
4756
- const rootNode = this.findRootNode(nodes);
4757
- if (!rootNode) {
4758
- this.addLog('error', '❌ Root Node پیدا نشد');
4759
- return;
4760
- }
4761
- const workflow = {
4762
- id: 'visual-workflow-' + Date.now(),
4763
- name: 'Visual Workflow',
4764
- version: 1,
4765
- root: this.nodeToActivity(rootNode, nodes),
4766
- };
4767
- this.workflowJson.set(JSON.stringify(workflow, null, 2));
4768
- this.addLog('success', '✅ Visual به JSON تبدیل شد');
4769
- }
4770
- catch (error) {
4771
- this.addLog('error', '❌ خطا در تبدیل: ' + error.message);
4772
- }
4773
- }
4774
- /**
4775
- * پیدا کردن Root Node
4776
- */
4777
- findRootNode(nodes) {
4778
- // Node ای که به آن اشاره نشده
4779
- const connectedIds = new Set();
4780
- nodes.forEach((n) => n.connections.forEach((c) => connectedIds.add(c)));
4781
- const rootNodes = nodes.filter((n) => !connectedIds.has(n.id));
4782
- return rootNodes[0] || nodes[0];
4783
- }
4784
- /**
4785
- * تبدیل Node به Activity (recursive)
4786
- */
4787
- nodeToActivity(node, allNodes) {
4788
- const activity = {
4789
- id: node.id,
4790
- type: node.type,
4791
- name: node.name,
4792
- properties: node.properties,
4793
- };
4794
- // اگر children دارد (connections)
4795
- if (node.connections.length > 0) {
4796
- const children = node.connections
4797
- .map((connId) => allNodes.find((n) => n.id === connId))
4798
- .filter((n) => n !== undefined)
4799
- .map((childNode) => this.nodeToActivity(childNode, allNodes));
4800
- if (children.length > 0) {
4801
- activity.children = children;
4802
- }
4803
- }
4804
- return activity;
4805
- }
4806
- /**
4807
- * دریافت آیکون برای نوع Activity
4808
- */
4809
- getIconForActivityType(type) {
4810
- const iconMap = {
4811
- 'workflow-activity:sequence': 'fa-light fa-list-ol',
4812
- 'workflow-activity:show-confirm-dialog': 'fa-light fa-question-circle',
4813
- 'workflow-activity:show-alert-dialog': 'fa-light fa-circle-info',
4814
- 'workflow-activity:show-toast': 'fa-light fa-bell',
4815
- 'workflow-activity:set-variable': 'fa-light fa-variable',
4816
- 'workflow-activity:navigate': 'fa-light fa-route',
4817
- 'workflow-activity:dispatch-event': 'fa-light fa-paper-plane',
4818
- 'workflow-activity:entity-create': 'fa-light fa-plus',
4819
- 'workflow-activity:entity-read': 'fa-light fa-book-open',
4820
- 'workflow-activity:entity-update': 'fa-light fa-pen',
4821
- 'workflow-activity:entity-delete': 'fa-light fa-trash',
4822
- };
4823
- return iconMap[type] || 'fa-light fa-circle';
4824
- }
4825
- /**
4826
- * به‌روزرسانی property نود
4827
- */
4828
- updateNodeProperty(nodeId, propertyName, value) {
4829
- const nodes = this.visualNodes();
4830
- const nodeIndex = nodes.findIndex((n) => n.id === nodeId);
4831
- if (nodeIndex !== -1) {
4832
- const node = nodes[nodeIndex];
4833
- const updatedNodes = [...nodes];
4834
- if (propertyName === 'name') {
4835
- updatedNodes[nodeIndex] = {
4836
- ...node,
4837
- name: value,
4838
- };
4839
- }
4840
- else {
4841
- const newProperties = {
4842
- ...node.properties,
4843
- [propertyName]: value,
4844
- };
4845
- let newOutcomes = node.outcomes;
4846
- const shouldRecomputeOutcomes = (propertyName === 'expectedStatusCodes' && node.type === 'workflow-activity:http-request') ||
4847
- (propertyName === 'actions' && node.type === 'workflow-activity:human-task');
4848
- if (shouldRecomputeOutcomes) {
4849
- this.findActivityInfo(node.type)
4850
- .then((activityInfo) => {
4851
- if (activityInfo) {
4852
- const computedOutcomes = this.computeOutcomes(activityInfo, newProperties);
4853
- const updatedNodes = this.visualNodes();
4854
- const nodeIdx = updatedNodes.findIndex((n) => n.id === nodeId);
4855
- if (nodeIdx !== -1) {
4856
- updatedNodes[nodeIdx] = {
4857
- ...updatedNodes[nodeIdx],
4858
- outcomes: computedOutcomes,
4859
- };
4860
- this.visualNodes.set([...updatedNodes]);
4861
- this.addLog('info', `🔄 Outcomes updated: [${computedOutcomes.join(', ')}]`);
4862
- }
4863
- }
4864
- })
4865
- .catch(() => { });
4866
- }
4867
- updatedNodes[nodeIndex] = {
4868
- ...node,
4869
- properties: newProperties,
4870
- outcomes: newOutcomes,
4871
- };
4872
- }
4873
- this.visualNodes.set(updatedNodes);
4874
- if (this.selectedNode()?.id === nodeId) {
4875
- this.selectedNode.set(updatedNodes[nodeIndex]);
4876
- }
4877
- }
4878
- }
4879
- /**
4880
- * پیدا کردن activity info بر اساس type
4881
- */
4882
- async findActivityInfo(type) {
4883
- try {
4884
- const activity = await this.activityDefinitionService.getActivityByName(type);
4885
- if (activity) {
4886
- return this.convertActivityDefinitionToInfo(activity);
4887
- }
4888
- }
4889
- catch (error) {
4890
- console.warn(`Failed to find activity info for type: ${type}`, error);
4891
- }
4892
- return null;
4893
- }
4894
- /**
4895
- * پاک کردن همه نودها
4896
- */
4897
- clearCanvas() {
4898
- this.visualNodes.set([]);
4899
- this.selectedNode.set(null);
4900
- this.addLog('info', '🗑️ Canvas پاک شد');
4901
- }
4902
- /**
4903
- * Copy workflow Definition ID to clipboard (Elsa-style workflow info).
4904
- */
4905
- async copyDefinitionIdToClipboard() {
4906
- const id = this.workflowSettings().definitionId || 'new-workflow';
4907
- try {
4908
- if (typeof navigator !== 'undefined' && navigator.clipboard?.writeText) {
4909
- await navigator.clipboard.writeText(id);
4910
- this.addLog('success', 'Definition ID copied to clipboard');
4911
- }
4912
- }
4913
- catch {
4914
- this.addLog('warning', 'Could not copy to clipboard');
4915
- }
4916
- }
4917
- /**
4918
- * Scroll canvas area so content is centered (Elsa-style "Center").
4919
- */
4920
- canvasCenter() {
4921
- const el = this.canvasAreaRef()?.nativeElement;
4922
- if (!el)
4923
- return;
4924
- const nodes = this.visualNodes();
4925
- if (nodes.length === 0)
4926
- return;
4927
- let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
4928
- for (const n of nodes) {
4929
- minX = Math.min(minX, n.position.x);
4930
- minY = Math.min(minY, n.position.y);
4931
- maxX = Math.max(maxX, n.position.x + 150);
4932
- maxY = Math.max(maxY, n.position.y + 120);
4933
- }
4934
- const cx = (minX + maxX) / 2;
4935
- const cy = (minY + maxY) / 2;
4936
- const parent = el.parentElement;
4937
- if (parent && parent.scrollWidth > parent.clientWidth) {
4938
- parent.scrollLeft = Math.max(0, cx - parent.clientWidth / 2);
4939
- }
4940
- if (parent && parent.scrollHeight > parent.clientHeight) {
4941
- parent.scrollTop = Math.max(0, cy - parent.clientHeight / 2);
4942
- }
4943
- }
4944
- /**
4945
- * Scroll canvas so all nodes are in view (Elsa-style "Zoom to fit" – fit by scroll).
4946
- */
4947
- canvasZoomToFit() {
4948
- const el = this.canvasAreaRef()?.nativeElement;
4949
- if (!el)
4950
- return;
4951
- const nodes = this.visualNodes();
4952
- if (nodes.length === 0)
4953
- return;
4954
- let minX = Infinity, minY = Infinity, maxX = -Infinity, maxY = -Infinity;
4955
- for (const n of nodes) {
4956
- minX = Math.min(minX, n.position.x);
4957
- minY = Math.min(minY, n.position.y);
4958
- maxX = Math.max(maxX, n.position.x + 150);
4959
- maxY = Math.max(maxY, n.position.y + 120);
4960
- }
4961
- const parent = el.parentElement;
4962
- if (parent) {
4963
- parent.scrollLeft = Math.max(0, minX - 24);
4964
- parent.scrollTop = Math.max(0, minY - 24);
4965
- }
4966
- }
4967
- /**
4968
- * Auto-arrange nodes in a vertical flow (Elsa-style "Auto layout").
4969
- */
4970
- canvasAutoLayout() {
4971
- const nodes = this.visualNodes();
4972
- if (nodes.length === 0)
4973
- return;
4974
- const root = this.findRootNode(nodes);
4975
- const ordered = [];
4976
- const visited = new Set();
4977
- const add = (n) => {
4978
- if (visited.has(n.id))
4979
- return;
4980
- visited.add(n.id);
4981
- ordered.push(n);
4982
- const targets = (n.outcomeConnections ?? [])
4983
- .map((c) => this.findNodeById(c.targetNodeId))
4984
- .filter(Boolean);
4985
- for (const t of targets)
4986
- add(t);
4987
- const fallback = (n.connections ?? []).map((id) => this.findNodeById(id)).filter(Boolean);
4988
- for (const t of fallback)
4989
- add(t);
4990
- };
4991
- if (root)
4992
- add(root);
4993
- for (const n of nodes)
4994
- if (!visited.has(n.id))
4995
- ordered.push(n);
4996
- const startX = 50;
4997
- const startY = 50;
4998
- const stepY = 120;
4999
- this.visualNodes.update((list) => list.map((node) => {
5000
- const idx = ordered.findIndex((o) => o.id === node.id);
5001
- const y = idx >= 0 ? startY + idx * stepY : node.position.y;
5002
- return { ...node, position: { x: startX, y } };
5003
- }));
5004
- this.addLog('info', 'Layout applied');
5005
- }
5006
- // ============ Drag & Drop Methods ============
5007
- /**
5008
- * شروع drag از activity list
5009
- */
5010
- onActivityDragStart(event, activity) {
5011
- this.draggedActivity = activity;
5012
- if (event.dataTransfer) {
5013
- event.dataTransfer.effectAllowed = 'copy';
5014
- event.dataTransfer.setData('text/plain', activity.type);
5015
- }
5016
- this.addLog('info', `🎯 در حال Drag: ${activity.name}`);
5017
- }
5018
- /**
5019
- * پایان drag از activity list
5020
- */
5021
- onActivityDragEnd(event) {
5022
- this.draggedActivity = null;
5023
- }
5024
- /**
5025
- * drag over روی Canvas
5026
- */
5027
- onCanvasDragOver(event) {
5028
- event.preventDefault();
5029
- if (event.dataTransfer) {
5030
- event.dataTransfer.dropEffect = 'copy';
5031
- }
5032
- }
5033
- /**
5034
- * drag leave از Canvas
5035
- */
5036
- onCanvasDragLeave(event) {
5037
- // می‌توان از این برای visual feedback استفاده کرد
5038
- }
5039
- /**
5040
- * محاسبه outcomes برای یک activity
5041
- */
5042
- computeOutcomes(activityInfo, properties) {
5043
- // For HTTP Request with expected status codes
5044
- if (activityInfo.type === 'workflow-activity:http-request' && properties['expectedStatusCodes']) {
5045
- const codes = Array.isArray(properties['expectedStatusCodes'])
5046
- ? properties['expectedStatusCodes']
5047
- : [properties['expectedStatusCodes']];
5048
- const statusOutcomes = codes.map((code) => code.toString());
5049
- return [...statusOutcomes, 'Done', 'Failed', 'Timeout'];
5050
- }
5051
- // Human Task: outcomes from actions (prefix/suffix) in workflow definition
5052
- if (activityInfo.type === 'workflow-activity:human-task' && properties['actions']) {
5053
- const names = [];
5054
- try {
5055
- const actions = properties['actions'];
5056
- const parsed = typeof actions === 'string' ? JSON.parse(actions) : actions;
5057
- const prefix = parsed?.prefix ?? [];
5058
- const suffix = parsed?.suffix ?? [];
5059
- for (const item of [...prefix, ...suffix]) {
5060
- const name = item?.command?.name ?? item?.name;
5061
- if (name && typeof name === 'string' && !names.includes(name))
5062
- names.push(name);
5063
- }
5064
- }
5065
- catch {
5066
- // ignore parse error
5067
- }
5068
- if (names.length > 0)
5069
- return names;
5070
- }
5071
- // Default: check activity info for outcomes
5072
- const outcomeMap = {
5073
- 'workflow-activity:if': ['Then', 'Else'],
5074
- 'workflow-activity:show-confirm-dialog': ['Confirmed', 'Cancelled'],
5075
- 'workflow-activity:show-alert-dialog': ['Done'],
5076
- 'workflow-activity:show-form': ['Submitted', 'Cancelled'],
5077
- 'workflow-activity:human-task': ['submit', 'cancel'],
5078
- 'workflow-activity:http-request': ['Done', 'Failed', 'Timeout'],
5079
- 'workflow-activity:sequence': ['Done'],
5080
- 'workflow-activity:for-each': ['Done'],
5081
- 'workflow-activity:while': ['Done'],
5082
- 'workflow-activity:set-variable': ['Done'],
5083
- 'workflow-activity:navigate': ['Done'],
5084
- 'workflow-activity:show-toast': ['Done'],
5085
- 'workflow-activity:dispatch-event': ['Done'],
5086
- 'workflow-activity:entity-create': ['Done', 'Failed'],
5087
- 'workflow-activity:entity-read': ['Done', 'NotFound', 'Failed'],
5088
- 'workflow-activity:entity-update': ['Done', 'Failed'],
5089
- 'workflow-activity:entity-delete': ['Done', 'Failed'],
5090
- };
5091
- return outcomeMap[activityInfo.type] || ['Done'];
5092
- }
5093
- /**
5094
- * drop روی Canvas - اضافه کردن activity جدید
5095
- */
5096
- onCanvasDrop(event) {
5097
- event.preventDefault();
5098
- if (!this.draggedActivity) {
5099
- return;
5100
- }
5101
- const canvas = event.currentTarget;
5102
- const rect = canvas.getBoundingClientRect();
5103
- const x = event.clientX - rect.left - 75; // center node
5104
- const y = event.clientY - rect.top - 40;
5105
- const nodes = this.visualNodes();
5106
- const defaultProps = { ...(this.draggedActivity.defaultProperties || {}) };
5107
- const newNode = {
5108
- id: `${this.draggedActivity.type}-${Date.now()}`,
5109
- type: this.draggedActivity.type,
5110
- name: this.draggedActivity.name,
5111
- icon: this.draggedActivity.icon,
5112
- properties: defaultProps,
5113
- position: { x: Math.max(0, x), y: Math.max(0, y) },
5114
- connections: [],
5115
- outcomeConnections: [],
5116
- outcomes: this.computeOutcomes(this.draggedActivity, defaultProps),
5117
- };
5118
- this.visualNodes.set([...nodes, newNode]);
5119
- const outcomesInfo = newNode.outcomes && newNode.outcomes.length > 1
5120
- ? ` with ${newNode.outcomes.length} outcomes [${newNode.outcomes.join(', ')}]`
5121
- : '';
5122
- this.addLog('success', `✅ Activity ${this.draggedActivity.name} اضافه شد${outcomesInfo}`);
5123
- this.draggedActivity = null;
5124
- }
5125
- /**
5126
- * شروع drag نود
5127
- */
5128
- onNodeDragStart(event, node) {
5129
- this.draggedNode = node;
5130
- const target = event.target;
5131
- const rect = target.getBoundingClientRect();
5132
- this.nodeDragOffset = {
5133
- x: event.clientX - rect.left,
5134
- y: event.clientY - rect.top,
5135
- };
5136
- if (event.dataTransfer) {
5137
- event.dataTransfer.effectAllowed = 'move';
5138
- // Make drag image transparent
5139
- const img = new Image();
5140
- img.src = 'data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7';
5141
- event.dataTransfer.setDragImage(img, 0, 0);
5142
- }
5143
- }
5144
- /**
5145
- * در حال drag نود
5146
- */
5147
- onNodeDrag(event, node) {
5148
- if (!this.draggedNode || event.clientX === 0 || event.clientY === 0) {
5149
- return;
5150
- }
5151
- const canvas = document.querySelector('.canvas-area');
5152
- if (!canvas)
5153
- return;
5154
- const rect = canvas.getBoundingClientRect();
5155
- const x = event.clientX - rect.left - this.nodeDragOffset.x;
5156
- const y = event.clientY - rect.top - this.nodeDragOffset.y;
5157
- const nodes = this.visualNodes();
5158
- const nodeIndex = nodes.findIndex((n) => n.id === node.id);
5159
- if (nodeIndex !== -1) {
5160
- nodes[nodeIndex].position = {
5161
- x: Math.max(0, x),
5162
- y: Math.max(0, y),
5163
- };
5164
- this.visualNodes.set([...nodes]);
5165
- }
5166
- }
5167
- /**
5168
- * پایان drag نود
5169
- */
5170
- onNodeDragEnd(event, node) {
5171
- this.draggedNode = null;
5172
- }
5173
- /**
5174
- * کلیک روی کانکتور - برای ایجاد اتصال (برای activities با یک outcome)
5175
- */
5176
- onConnectorClick(event, node, type) {
5177
- event.stopPropagation();
5178
- if (!this.connectionSource) {
5179
- // اولین کلیک - ذخیره source
5180
- if (type === 'out') {
5181
- this.connectionSource = { node, type };
5182
- this.addLog('info', `🔗 منبع اتصال انتخاب شد: ${node.name}`);
5183
- }
5184
- }
5185
- else {
5186
- // دومین کلیک - ایجاد اتصال
5187
- if (type === 'in' && this.connectionSource.node.id !== node.id) {
5188
- this.connectNodes(this.connectionSource.node.id, node.id, this.connectionSource.outcome);
5189
- this.connectionSource = null;
5190
- }
5191
- else {
5192
- this.addLog('warning', '⚠️ اتصال نامعتبر - ابتدا روی connector خروجی و سپس ورودی کلیک کنید');
5193
- this.connectionSource = null;
5194
- }
5195
- }
5196
- }
5197
- /**
5198
- * کلیک روی outcome connector - برای activities با چند outcome
5199
- */
5200
- onOutcomeConnectorClick(event, node, outcome) {
5201
- event.stopPropagation();
5202
- if (!this.connectionSource) {
5203
- // اولین کلیک - ذخیره source با outcome
5204
- this.connectionSource = { node, type: 'out', outcome };
5205
- this.addLog('info', `🔗 منبع اتصال انتخاب شد: ${node.name} [${outcome}]`);
5206
- }
5207
- else {
5208
- this.addLog('warning', '⚠️ لطفاً روی input connector یک نود دیگر کلیک کنید');
5209
- this.connectionSource = null;
5210
- }
5211
- }
5212
- // ============ UI Methods ============
5213
- /**
5214
- * تغییر وضعیت نمایش Properties Panel
5215
- */
5216
- togglePropertiesPanel() {
5217
- this.showPropertiesPanel.set(!this.showPropertiesPanel());
5218
- }
5219
- /**
5220
- * Build property viewer tabs from activity definition (platform widget-based).
5221
- * Used so the properties panel renders via the same widget system as the form builder.
5222
- */
5223
- buildPropertyViewerTabs(def, node) {
5224
- const generalGroup = { name: 'identity', title: 'General', order: 0 };
5225
- const inputGroup = { name: 'input-properties', title: 'Input Properties', order: 1 };
5226
- const outputGroup = { name: 'output', title: 'Output & Variables', order: 2 };
5227
- const identityProps = [
5228
- this.createReadOnlyStringProp('id', 'ID', 'id', generalGroup),
5229
- this.createReadOnlyStringProp('type', 'Type', 'type', generalGroup),
5230
- this.createStringProp('name', 'Name', 'name', generalGroup),
5231
- ];
5232
- const inputProps = (def?.inputs ?? []).map((input, index) => this.activityInputToWidgetProperty(input, inputGroup, index));
5233
- const outputProps = [
5234
- this.createStringProp('outputVariable', 'Output Variable', 'properties.outputVariable', outputGroup),
5235
- ];
5236
- const groups = [
5237
- { name: generalGroup.name, title: generalGroup.title, isCollapsed: false, props: identityProps },
5238
- ...(inputProps.length
5239
- ? [{ name: inputGroup.name, title: inputGroup.title, isCollapsed: false, props: inputProps }]
5240
- : []),
5241
- { name: outputGroup.name, title: outputGroup.title, isCollapsed: false, props: outputProps },
5242
- ];
5243
- return [{ name: 'general', title: 'General', groups }];
5244
- }
5245
- createStringProp(name, title, path, group) {
5246
- return {
5247
- name,
5248
- title,
5249
- group,
5250
- order: 0,
5251
- schema: {
5252
- dataType: 'string',
5253
- interface: {
5254
- path,
5255
- name,
5256
- type: 'text-editor',
5257
- options: {},
5258
- },
5259
- },
5260
- visible: true,
5261
- };
5262
- }
5263
- createReadOnlyStringProp(name, title, path, group) {
5264
- return {
5265
- name,
5266
- title,
5267
- group,
5268
- order: 0,
5269
- schema: {
5270
- dataType: 'string',
5271
- interface: {
5272
- path,
5273
- name,
5274
- type: 'text-editor',
5275
- options: { readonly: true },
5276
- },
5277
- },
5278
- visible: true,
5279
- };
5280
- }
5281
- activityInputToWidgetProperty(input, group, order) {
5282
- return mapAXPPropertyToWidgetProperty(input, {
5283
- group,
5284
- order,
5285
- valuePathPrefix: 'properties',
5286
- resolveTitle: (prop) => typeof prop.title === 'string' ? prop.title : (this.translationService.resolve(prop.title) ?? prop.name),
5287
- resolveDescription: (prop) => prop.description === undefined
5288
- ? undefined
5289
- : typeof prop.description === 'string'
5290
- ? prop.description
5291
- : this.translationService.resolve(prop.description),
5292
- });
5293
- }
5294
- /**
5295
- * Apply property viewer context changes back to the selected node.
5296
- */
5297
- onPropertyViewerChanged(ev) {
5298
- const node = this.selectedNode();
5299
- if (!node || ev.mode !== 'update')
5300
- return;
5301
- const v = ev.values;
5302
- if (v.name !== undefined)
5303
- this.updateNodeProperty(node.id, 'name', v.name);
5304
- if (v.properties && typeof v.properties === 'object') {
5305
- for (const key of Object.keys(v.properties)) {
5306
- this.updateNodeProperty(node.id, key, v.properties[key]);
5307
- }
5308
- }
5309
- }
5310
- // ============ Template Helper Methods ============
5311
- /**
5312
- * پیدا کردن Node با ID
5313
- */
5314
- findNodeById(nodeId) {
5315
- return this.visualNodes().find((n) => n.id === nodeId);
5316
- }
5317
- /**
5318
- * بررسی اینکه آیا properties خالی است یا نه
5319
- */
5320
- hasProperties(properties) {
5321
- return properties && Object.keys(properties).length > 0;
5322
- }
5323
- /**
5324
- * Builds SVG path for a curved connection (quadratic Bezier) so the line is smooth like Elsa/n8n.
5325
- * Control point is offset so the curve bows naturally between source and target.
5326
- */
5327
- getConnectionPath(x1, y1, x2, y2) {
5328
- const midX = (x1 + x2) / 2;
5329
- const midY = (y1 + y2) / 2;
5330
- const dy = y2 - y1;
5331
- const offset = Math.min(80, Math.max(40, Math.abs(dy) * 0.3));
5332
- const cpy = midY - (dy >= 0 ? offset : -offset);
5333
- return `M ${x1} ${y1} Q ${midX} ${cpy} ${x2} ${y2}`;
5334
- }
5335
- /**
5336
- * Approximate midpoint on the curve for label placement (quadratic Bezier t=0.5).
5337
- */
5338
- getConnectionLabelPosition(x1, y1, x2, y2) {
5339
- const midX = (x1 + x2) / 2;
5340
- const midY = (y1 + y2) / 2;
5341
- const dy = y2 - y1;
5342
- const offset = Math.min(80, Math.max(40, Math.abs(dy) * 0.3));
5343
- const cpy = midY - (dy >= 0 ? offset : -offset);
5344
- const t = 0.5;
5345
- const x = (1 - t) * (1 - t) * x1 + 2 * (1 - t) * t * midX + t * t * x2;
5346
- const y = (1 - t) * (1 - t) * y1 + 2 * (1 - t) * t * cpy + t * t * y2;
5347
- return { x, y: y + 12 };
5348
- }
5349
- /**
5350
- * دریافت رنگ بر اساس outcome
5351
- */
5352
- getOutcomeColor(outcome) {
5353
- const colorMap = {
5354
- '200': '#10b981', // Green - Success
5355
- Done: '#10b981', // Green - Success
5356
- Success: '#10b981', // Green - Success
5357
- '404': '#ef4444', // Red - Error
5358
- '500': '#ef4444', // Red - Error
5359
- Failed: '#ef4444', // Red - Error
5360
- Error: '#ef4444', // Red - Error
5361
- Timeout: '#f59e0b', // Orange - Warning
5362
- Cancelled: '#f59e0b', // Orange - Warning
5363
- Then: '#3b82f6', // Blue - Info
5364
- Else: '#64748b', // Gray
5365
- };
5366
- return colorMap[outcome] || '#8b5cf6'; // Purple - Default
5367
- }
5368
- /**
5369
- * Returns marker name for arrowhead def (success, error, warning, info, primary, default).
5370
- */
5371
- getOutcomeColorName(outcome) {
5372
- if (['200', 'Done', 'Success'].includes(outcome)) {
5373
- return 'success';
5374
- }
5375
- if (['404', '500', 'Failed', 'Error'].includes(outcome)) {
5376
- return 'error';
5377
- }
5378
- if (['Timeout', 'Cancelled'].includes(outcome)) {
5379
- return 'warning';
5380
- }
5381
- if (['Then'].includes(outcome)) {
5382
- return 'info';
5383
- }
5384
- if (['Else'].includes(outcome)) {
5385
- return 'default';
5386
- }
5387
- return 'primary'; // purple for custom outcomes
5388
- }
5389
- /**
5390
- * به‌روزرسانی property با parse کردن JSON
5391
- */
5392
- updateNodePropertyJSON(nodeId, propertyName, jsonString) {
5393
- try {
5394
- const value = JSON.parse(jsonString);
5395
- this.updateNodeProperty(nodeId, propertyName, value);
5396
- }
5397
- catch (error) {
5398
- // اگر JSON نامعتبر بود، چیزی نکن
5399
- console.warn('Invalid JSON:', jsonString);
5400
- }
5401
- }
5402
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowStudioComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
5403
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: WorkflowStudioComponent, isStandalone: true, selector: "app-workflow-studio", providers: [
5404
- {
5405
- provide: AXPPageLayoutBase,
5406
- useExisting: WorkflowStudioComponent,
5407
- },
5408
- ], viewQueries: [{ propertyName: "propertyViewerRef", first: true, predicate: AXPPropertyViewerComponent, descendants: true, isSignal: true }, { propertyName: "canvasAreaRef", first: true, predicate: ["canvasAreaRef"], descendants: true, isSignal: true }], usesInheritance: true, ngImport: i0, template: "<axp-page-layout>\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ '@workflow-management:activities.menus.activity-categories.title' | translate | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n [delayTime]=\"300\"\n [placeholder]=\"'@workflow-management:workflow-studio.components.activity-categories-tree.search-placeholder' | translate | async\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content>\n <axp-activity-categories-tree\n (categoryClick)=\"onCategoryClick($event)\"\n (activityClick)=\"onActivityClick($event)\"\n (activityDragStart)=\"onActivityDragStartFromTree($event)\"\n ></axp-activity-categories-tree>\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-toolbar>\n <axp-layout-prefix>\n <!-- JSON / Visual toggle (same pattern as report view mode) -->\n <div class=\"studio-editor-tabs\">\n <ax-button-group class=\"ax-sm\" [selection]=\"'single'\">\n <ax-button-group-item (onClick)=\"switchTab('json')\" text=\"{{ '@workflow-management:workflow-studio.terms.json-editor' | translate | async }}\" [selected]=\"activeTab() === 'json'\">\n <ax-prefix>\n <i class=\"fa-light fa-code\"></i>\n </ax-prefix>\n </ax-button-group-item>\n <ax-button-group-item (onClick)=\"switchTab('visual')\" text=\"{{ '@workflow-management:workflow-studio.terms.visual-designer' | translate | async }}\" [selected]=\"activeTab() === 'visual'\">\n <ax-prefix>\n <i class=\"fa-light fa-diagram-project\"></i>\n </ax-prefix>\n </ax-button-group-item>\n </ax-button-group>\n </div>\n </axp-layout-prefix>\n </axp-page-toolbar>\n\n <axp-page-content>\n <div class=\"workflow-studio\">\n <!-- Main Layout -->\n <div class=\"studio-body\" [class.properties-hidden]=\"!showPropertiesPanel()\">\n\n <!-- Editor -->\n <div class=\"studio-editor\">\n <!-- Tab Content -->\n <div class=\"editor-content\">\n <!-- JSON Tab -->\n @if (activeTab() === 'json') {\n <div class=\"json-tab\">\n <textarea class=\"json-editor\" [value]=\"workflowJson()\"\n (input)=\"onWorkflowJsonInput($event)\"\n [placeholder]=\"'@workflow-management:workflow-studio.components.json-editor.placeholder' | translate | async\"\n spellcheck=\"false\"></textarea>\n </div>\n }\n\n <!-- Visual Tab -->\n @if (activeTab() === 'visual') {\n <div class=\"visual-tab\">\n <!-- Canvas -->\n <div class=\"visual-canvas\">\n <div class=\"canvas-toolbar\">\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.zoom-to-fit.title' | translate | async\" (onClick)=\"canvasZoomToFit()\">\n <ax-prefix><i class=\"fa-light fa-expand\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.center.title' | translate | async\" (onClick)=\"canvasCenter()\">\n <ax-prefix><i class=\"fa-light fa-crosshairs\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.auto-layout.title' | translate | async\" (onClick)=\"canvasAutoLayout()\">\n <ax-prefix><i class=\"fa-light fa-sitemap\"></i></ax-prefix>\n </ax-button>\n <span class=\"toolbar-sep\"></span>\n <label class=\"toolbar-auto-save\">\n <ax-switch [value]=\"autoSaveEnabled()\" (valueChange)=\"autoSaveEnabled.set($event)\"></ax-switch>\n <span>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.auto-save' | translate | async }}</span>\n </label>\n <span class=\"toolbar-sep\"></span>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.clear-canvas.title' | translate | async\" (onClick)=\"clearCanvas()\">\n <ax-prefix><i class=\"fa-light fa-trash\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.convert-to-json.title' | translate | async\" (onClick)=\"visualToJson()\">\n <ax-prefix><i class=\"fa-light fa-code\"></i></ax-prefix>\n </ax-button>\n <span class=\"tool-info\">\n <i class=\"fa-light fa-lightbulb\"></i>\n <strong>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.hint' | translate | async }}</strong>\n </span>\n </div>\n\n <div #canvasAreaRef class=\"canvas-area\" (drop)=\"onCanvasDrop($event)\" (dragover)=\"onCanvasDragOver($event)\"\n (dragleave)=\"onCanvasDragLeave($event)\">\n <!-- SVG for Connections -->\n <svg class=\"connections-layer\">\n <!-- Outcome-based Connections -->\n @for (node of visualNodes(); track node.id) {\n @if (node.outcomeConnections && node.outcomeConnections.length > 0) {\n @for (conn of node.outcomeConnections; track conn.targetNodeId + conn.outcome) {\n @let targetNode = findNodeById(conn.targetNodeId);\n @if (targetNode) {\n <g class=\"outcome-connection-group\">\n <line [attr.x1]=\"node.position.x + 75\" [attr.y1]=\"node.position.y + 80\"\n [attr.x2]=\"targetNode.position.x + 75\" [attr.y2]=\"targetNode.position.y - 50\"\n class=\"connection-line outcome-line\" [attr.stroke]=\"getOutcomeColor(conn.outcome)\"\n stroke-width=\"2.5\"\n [attr.marker-end]=\"'url(#arrowhead-' + getOutcomeColorName(conn.outcome) + ')'\"\n style=\"cursor: pointer\" (dblclick)=\"disconnectNodes(node.id, conn.targetNodeId, conn.outcome)\"\n [attr.title]=\"'Outcome: ' + conn.outcome + ' (Double-click to remove)'\">\n <title>{{ conn.outcome }} \u00E2\u2020\u2019 {{ targetNode.name }}</title>\n </line>\n <text [attr.x]=\"(node.position.x + targetNode.position.x) / 2 + 75\"\n [attr.y]=\"(node.position.y + targetNode.position.y) / 2 + 15\" class=\"connection-label\"\n text-anchor=\"middle\" dominant-baseline=\"middle\" [attr.fill]=\"getOutcomeColor(conn.outcome)\" font-size=\"11\"\n font-weight=\"600\" pointer-events=\"none\">\n {{ conn.outcome }}\n </text>\n </g>\n }\n }\n } @else {\n <!-- Simple Connections (backward compatibility) -->\n @for (targetId of node.connections; track targetId) {\n @let targetNode = findNodeById(targetId);\n @if (targetNode) {\n @let sx = node.position.x + 75;\n @let sy = node.position.y + 40;\n @let tx = targetNode.position.x + 75;\n @let ty = targetNode.position.y - 50;\n @let pathD = getConnectionPath(sx, sy, tx, ty);\n <g class=\"connection-group\">\n <path [attr.d]=\"pathD\" class=\"connection-line connection-hit\" fill=\"none\" stroke=\"transparent\"\n stroke-width=\"16\" pointer-events=\"stroke\" (dblclick)=\"disconnectNodes(node.id, targetId)\">\n </path>\n <path [attr.d]=\"pathD\" class=\"connection-line\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"2\"\n stroke-linecap=\"round\" marker-end=\"url(#arrowhead-default)\" pointer-events=\"none\">\n </path>\n <title>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.connection-remove-hint' | translate | async }}</title>\n </g>\n }\n }\n }\n }\n\n <defs>\n <!-- Arrow markers: larger, rounded tip on line end (refX so tip touches path end) -->\n <marker id=\"arrowhead-default\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#64748b\" />\n </marker>\n <marker id=\"arrowhead-primary\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#8b5cf6\" />\n </marker>\n <marker id=\"arrowhead-success\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#10b981\" />\n </marker>\n <marker id=\"arrowhead-error\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#ef4444\" />\n </marker>\n <marker id=\"arrowhead-warning\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#f59e0b\" />\n </marker>\n <marker id=\"arrowhead-info\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#3b82f6\" />\n </marker>\n </defs>\n </svg>\n\n <!-- Nodes -->\n @for (node of visualNodes(); track node.id) {\n <div class=\"visual-node\" [class.selected]=\"selectedNode()?.id === node.id\"\n [style.left.px]=\"node.position.x\" [style.top.px]=\"node.position.y\" [attr.data-node-id]=\"node.id\"\n draggable=\"true\" (dragstart)=\"onNodeDragStart($event, node)\" (drag)=\"onNodeDrag($event, node)\"\n (dragend)=\"onNodeDragEnd($event, node)\" (click)=\"selectNodeById(node)\">\n <div class=\"node-header\">\n <i [class]=\"node.icon\"></i>\n <span>{{ node.name }}</span>\n <span class=\"node-delete-wrap\" (click)=\"$event.stopPropagation()\">\n <ax-button look=\"blank\" size=\"sm\" class=\"node-delete\" (onClick)=\"deleteNodeFromCanvas(node.id)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </span>\n </div>\n\n <div class=\"node-body\">\n <small>{{ node.type }}</small>\n </div>\n\n <div class=\"node-connectors\">\n <!-- Input Connector -->\n <div class=\"connector connector-in\" title=\"Input\" (click)=\"onConnectorClick($event, node, 'in')\">\n </div>\n\n <!-- Output Connectors - Multiple outcomes support -->\n @if (node.outcomes && node.outcomes.length > 1) {\n <!-- Multiple outcomes: show separate port for each -->\n <div class=\"outcomes-container\">\n @for (outcome of node.outcomes; track outcome; let idx = $index) {\n <div class=\"outcome-connector\" [class.active]=\"\n connectionSource?.node?.id === node.id && connectionSource?.outcome === outcome\n \" [attr.data-outcome]=\"outcome\" [title]=\"'Output: ' + outcome\"\n (click)=\"onOutcomeConnectorClick($event, node, outcome)\">\n <span class=\"outcome-label\">{{ outcome }}</span>\n <div class=\"outcome-dot\"></div>\n </div>\n }\n </div>\n } @else {\n <!-- Single outcome: show simple output connector -->\n <div class=\"connector connector-out\" [class.active]=\"connectionSource?.node?.id === node.id\"\n title=\"Output\" (click)=\"onConnectorClick($event, node, 'out')\"></div>\n }\n </div>\n </div>\n }\n\n <!-- Empty State -->\n @if (visualNodes().length === 0) {\n <div class=\"canvas-empty-state\">\n <i class=\"fa-light fa-diagram-project\"></i>\n <p>{{ '@workflow-management:workflow-studio.components.canvas-empty-state.title' | translate | async }}</p>\n <small>{{ '@workflow-management:workflow-studio.components.canvas-empty-state.description' | translate | async }}</small>\n </div>\n }\n </div>\n </div>\n\n <!-- Workflow Panel (when no node selected, Elsa-style) -->\n @if (!selectedNode() && showPropertiesPanel()) {\n <div class=\"properties-panel workflow-panel\">\n <div class=\"properties-header\">\n <i class=\"fa-light fa-diagram-project\"></i>\n <h4>{{ '@workflow-management:workflow-studio.components.workflow-panel.title' | translate | async }}</h4>\n <div class=\"header-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close-panel' | translate | async\" (onClick)=\"togglePropertiesPanel()\">\n <ax-prefix><i class=\"fa-light fa-angle-right\"></i></ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"properties-body\">\n <section class=\"workflow-panel-section\">\n <h5>{{ '@workflow-management:workflow-studio.components.workflow-panel.metadata' | translate | async }}</h5>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.workflow-panel.name' | translate | async }}</label>\n <ax-text-box class=\"form-input\" [value]=\"workflowSettings().name\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.workflow-panel.description' | translate | async }}</label>\n <ax-text-box class=\"form-input\" [value]=\"workflowSettings().description\" [disabled]=\"true\" />\n </div>\n </section>\n <div class=\"properties-divider\"></div>\n <section class=\"workflow-panel-section\">\n <h5>{{ '@workflow-management:workflow-studio.components.workflow-panel.information' | translate | async }}</h5>\n <div class=\"workflow-info-table\">\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.definition-id' | translate | async }}</span>\n <span class=\"info-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.workflow-panel.copy' | translate | async\" (onClick)=\"copyDefinitionIdToClipboard()\">\n <ax-prefix><i class=\"fa-light fa-copy\"></i></ax-prefix>\n </ax-button>\n </span>\n <span class=\"info-value\">{{ workflowSettings().definitionId || 'new-workflow' }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.version' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().version }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.status' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().isPublished ? ('@workflow-management:workflow-studio.components.workflow-panel.published' | translate | async) : ('@workflow-management:workflow-studio.components.workflow-panel.draft' | translate | async) }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.usable-as-activity' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().usableAsActivity ? ('@general:terms.common.yes-no.yes' | translate | async) : ('@general:terms.common.yes-no.no' | translate | async) }}</span>\n </div>\n </div>\n </section>\n <p class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.workflow-panel.settings-hint' | translate | async }}</p>\n </div>\n </div>\n }\n\n <!-- Properties Panel (when a node is selected) -->\n @if (selectedNode() && showPropertiesPanel()) {\n <div class=\"properties-panel\">\n <div class=\"properties-header\">\n <i class=\"fa-light fa-sliders\"></i>\n <h4>{{ '@workflow-management:workflow-studio.components.properties-panel.title' | translate | async }}</h4>\n <div class=\"header-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close-panel' | translate | async\" (onClick)=\"togglePropertiesPanel()\">\n <ax-prefix><i class=\"fa-light fa-angle-right\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close' | translate | async\" (onClick)=\"selectedNode.set(null)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"properties-body\">\n @if (propertyViewerTabs().length > 0) {\n <div class=\"properties-widget-section\">\n <axp-property-viewer\n #propertyViewerRef\n [tabsInput]=\"propertyViewerTabs()\"\n [mode]=\"'simple'\"\n (onChanged)=\"onPropertyViewerChanged($event)\">\n </axp-property-viewer>\n </div>\n } @else {\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.id' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.id\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.type' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.type\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.name' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.name\"\n (valueChange)=\"updateNodeProperty(selectedNode()!.id, 'name', $event)\" />\n </div>\n <p class=\"no-properties\">\n {{ '@workflow-management:workflow-studio.components.properties-panel.empty-states.no-properties' | translate | async }}\n </p>\n }\n\n <div class=\"properties-divider\"></div>\n\n\n <h5>\u00F0\u0178\u201D\u2014 {{ '@workflow-management:workflow-studio.components.properties-panel.sections.connections' | translate | async }}</h5>\n <small class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.properties-panel.sections.connections-hint' | translate | async }}</small>\n\n <!-- Outcome-based Connections -->\n @if (selectedNode()!.outcomeConnections && selectedNode()!.outcomeConnections!.length > 0) {\n <div class=\"connections-list\">\n @for (conn of selectedNode()!.outcomeConnections!; track conn.targetNodeId + conn.outcome) {\n @let targetNode = findNodeById(conn.targetNodeId);\n @if (targetNode) {\n <div class=\"connection-item outcome-connection\">\n <span class=\"outcome-badge\" [style.background]=\"getOutcomeColor(conn.outcome)\">\n {{ conn.outcome }}\n </span>\n <i class=\"fa-light fa-arrow-right\"></i>\n <span>{{ targetNode.name }}</span>\n <ax-button look=\"blank\" size=\"sm\" class=\"remove-btn\"\n [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.remove-connection' | translate | async\"\n (onClick)=\"disconnectNodes(selectedNode()!.id, conn.targetNodeId, conn.outcome)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n }\n }\n </div>\n } @else if (selectedNode()!.connections.length > 0) {\n <!-- Simple Connections (fallback) -->\n <div class=\"connections-list\">\n @for (targetId of selectedNode()!.connections; track targetId) {\n @let targetNode = findNodeById(targetId);\n @if (targetNode) {\n <div class=\"connection-item\">\n <i class=\"fa-light fa-arrow-right\"></i>\n <span>{{ targetNode.name }}</span>\n <ax-button look=\"blank\" size=\"sm\" class=\"remove-btn\"\n [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.remove-connection' | translate | async\"\n (onClick)=\"disconnectNodes(selectedNode()!.id, targetId)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n }\n }\n </div>\n } @else {\n <p class=\"no-properties\">{{ '@workflow-management:workflow-studio.components.properties-panel.empty-states.no-connections' | translate | async }}</p>\n }\n\n <!-- Available Outcomes Info -->\n @if (selectedNode()!.outcomes && selectedNode()!.outcomes!.length > 1) {\n <div class=\"properties-divider\"></div>\n <h5>\u00F0\u0178\u201C\u00A4 {{ '@workflow-management:workflow-studio.components.properties-panel.sections.available-outcomes' | translate | async }}</h5>\n <small class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.properties-panel.sections.available-outcomes-hint' | translate | async }}</small>\n <div class=\"outcomes-info\">\n @for (outcome of selectedNode()!.outcomes!; track outcome) {\n <span class=\"outcome-tag\" [style.borderColor]=\"getOutcomeColor(outcome)\">\n <span class=\"outcome-dot\" [style.background]=\"getOutcomeColor(outcome)\"></span>\n {{ outcome }}\n </span>\n }\n </div>\n }\n\n <div class=\"properties-divider\"></div>\n\n <h5>\u00F0\u0178\u201C\u009D {{ '@workflow-management:workflow-studio.components.properties-panel.sections.raw-json' | translate | async }}</h5>\n <pre class=\"properties-json\">{{ selectedNode() | json }}</pre>\n </div>\n </div>\n }\n\n <!-- Toggle Button for Properties (when closed) -->\n @if (!showPropertiesPanel()) {\n <ax-button look=\"blank\" class=\"sidebar-toggle-btn right\" (onClick)=\"togglePropertiesPanel()\"\n [title]=\"selectedNode() ? ('@workflow-management:workflow-studio.components.properties-panel.actions.show-panel' | translate | async) : ('@workflow-management:workflow-studio.components.workflow-panel.show-panel' | translate | async)\">\n <ax-prefix><i class=\"fa-light fa-sliders\"></i></ax-prefix>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n\n <!-- Workflow Settings: opened via Layout Builder dialog in openWorkflowSettings() -->\n\n <!-- Workflow Execution Dialog -->\n @if (showExecutionDialog()) {\n <div class=\"execution-dialog-overlay\" (click)=\"closeExecutionDialog()\">\n <div class=\"execution-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Dialog Header -->\n <div class=\"execution-dialog-header\">\n <div class=\"header-content\">\n <i class=\"fa-light fa-play-circle\"></i>\n <div class=\"header-info\">\n <h2>{{ '@workflow-management:test-pages.workflow-studio.actions.execute-workflow.title' | translate |\n async }}</h2>\n <p>{{ '@workflow-management:test-pages.workflow-studio.actions.execute-workflow.description' | translate\n | async }}</p>\n </div>\n </div>\n <ax-button look=\"blank\" size=\"sm\" class=\"close-btn\" [disabled]=\"isExecuting()\" (onClick)=\"closeExecutionDialog()\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n\n <!-- Dialog Body -->\n <div class=\"execution-dialog-body\">\n <!-- Workflow Info Panel (Before Execution) -->\n @if (!workflowInstanceState()) {\n <div class=\"workflow-info-panel\">\n <div class=\"start-section\">\n <div class=\"start-illustration\">\n <i class=\"fa-light fa-rocket\"></i>\n </div>\n <h3>{{ '@workflow-management:test-pages.workflow-studio.messages.info.ready-to-execute' | translate |\n async }}</h3>\n <p>{{ '@workflow-management:test-pages.workflow-studio.messages.info.click-to-start' | translate | async\n }}</p>\n <ax-button\n [text]=\"'@workflow-management:test-pages.workflow-studio.actions.start-execution.title' | translate | async\"\n color=\"success\" size=\"lg\" (onClick)=\"startWorkflowExecution()\">\n </ax-button>\n </div>\n </div>\n }\n\n\n <!-- Custom UI for Registration -->\n @if (false) {\n <div class=\"registration-ui\">\n <div class=\"registration-card\">\n <div class=\"registration-icon\">\n <i class=\"fa-light fa-user-circle\"></i>\n </div>\n <h3>\u00D9\u0081\u00D8\u00B1\u00D8\u00A2\u00DB\u0152\u00D9\u2020\u00D8\u00AF \u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026</h3>\n <p class=\"registration-desc\">\n \u00D8\u00A7\u00DB\u0152\u00D9\u2020 \u00D9\u0081\u00D9\u201E\u00D9\u02C6 \u00D8\u00B4\u00D8\u00A7\u00D9\u2026\u00D9\u201E \u00DA\u2020\u00D9\u2020\u00D8\u00AF \u00D9\u2026\u00D8\u00B1\u00D8\u00AD\u00D9\u201E\u00D9\u2021 \u00D8\u00A7\u00D8\u00B3\u00D8\u00AA \u00DA\u00A9\u00D9\u2021 \u00D8\u00AF\u00D8\u00A7\u00D8\u00AF\u00D9\u2021\u00E2\u20AC\u0152\u00D9\u2021\u00D8\u00A7\u00DB\u0152 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1 \u00D8\u00B1\u00D8\u00A7 \u00D8\u00AC\u00D9\u2026\u00D8\u00B9\u00E2\u20AC\u0152\u00D8\u00A2\u00D9\u02C6\u00D8\u00B1\u00DB\u0152 \u00DA\u00A9\u00D8\u00B1\u00D8\u00AF\u00D9\u2021 \u00D9\u02C6 \u00D8\u00AF\u00D8\u00B1 \u00D9\u2020\u00D9\u2021\u00D8\u00A7\u00DB\u0152\u00D8\u00AA \u00D8\u00AD\u00D8\u00B3\u00D8\u00A7\u00D8\u00A8 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1\u00DB\u0152 \u00D8\u00A7\u00DB\u0152\u00D8\u00AC\u00D8\u00A7\u00D8\u00AF \u00D9\u2026\u00DB\u0152\u00E2\u20AC\u0152\u00DA\u00A9\u00D9\u2020\u00D8\u00AF.\n </p>\n\n @if (workflowInstanceState()?.status === 'running') {\n <div class=\"registration-progress\">\n <div class=\"progress-spinner\">\n <i class=\"fa-light fa-spinner-third fa-spin\"></i>\n </div>\n <p>\u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7\u00DB\u0152 \u00D9\u2026\u00D8\u00B1\u00D8\u00A7\u00D8\u00AD\u00D9\u201E \u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026...</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'finished') {\n <div class=\"registration-success\">\n <i class=\"fa-light fa-check-circle\"></i>\n <h4>\u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026 \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00A7\u00D9\u2020\u00D8\u00AC\u00D8\u00A7\u00D9\u2026 \u00D8\u00B4\u00D8\u00AF!</h4>\n <p>\u00D8\u00AD\u00D8\u00B3\u00D8\u00A7\u00D8\u00A8 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1\u00DB\u0152 \u00D8\u00B4\u00D9\u2026\u00D8\u00A7 \u00D8\u00A7\u00DB\u0152\u00D8\u00AC\u00D8\u00A7\u00D8\u00AF \u00D8\u00B4\u00D8\u00AF \u00D9\u02C6 \u00D8\u00A8\u00D9\u2021 \u00D8\u00B2\u00D9\u02C6\u00D8\u00AF\u00DB\u0152 \u00D8\u00A8\u00D9\u2021 \u00D8\u00AF\u00D8\u00A7\u00D8\u00B4\u00D8\u00A8\u00D9\u02C6\u00D8\u00B1\u00D8\u00AF \u00D9\u2026\u00D9\u2020\u00D8\u00AA\u00D9\u201A\u00D9\u201E \u00D8\u00AE\u00D9\u02C6\u00D8\u00A7\u00D9\u2021\u00DB\u0152\u00D8\u00AF \u00D8\u00B4\u00D8\u00AF.</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Default Execution View -->\n @if (workflowInstanceState()) {\n <div class=\"default-execution-view\">\n <div class=\"execution-status\">\n @if (workflowInstanceState()?.status === 'running') {\n <div class=\"status-running\">\n <i class=\"fa-light fa-spinner-third fa-spin\"></i>\n <h3>\u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7...</h3>\n <p>Workflow \u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00A7\u00D8\u00B3\u00D8\u00AA. \u00D9\u201E\u00D8\u00B7\u00D9\u0081\u00D8\u00A7\u00D9\u2039 \u00D8\u00B5\u00D8\u00A8\u00D8\u00B1 \u00DA\u00A9\u00D9\u2020\u00DB\u0152\u00D8\u00AF.</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'finished') {\n <div class=\"status-finished\">\n <i class=\"fa-light fa-check-circle\"></i>\n <h3>\u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00AA\u00DA\u00A9\u00D9\u2026\u00DB\u0152\u00D9\u201E \u00D8\u00B4\u00D8\u00AF</h3>\n <p>Workflow \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00B4\u00D8\u00AF \u00D9\u02C6 \u00D8\u00AA\u00D9\u2026\u00D8\u00A7\u00D9\u2026 Activities \u00D8\u00A7\u00D9\u2020\u00D8\u00AC\u00D8\u00A7\u00D9\u2026 \u00D8\u00B4\u00D8\u00AF\u00D9\u2020\u00D8\u00AF.</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'error') {\n <div class=\"status-error\">\n <i class=\"fa-light fa-times-circle\"></i>\n <h3>\u00D8\u00AE\u00D8\u00B7\u00D8\u00A7 \u00D8\u00AF\u00D8\u00B1 \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7</h3>\n <p>{{ workflowInstanceState()?.error }}</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Execution Logs Panel -->\n @if (workflowInstanceState() && executionLogs().length > 0) {\n <div class=\"execution-logs-panel\">\n <h3><i class=\"fa-light fa-terminal\"></i> \u00D9\u201E\u00D8\u00A7\u00DA\u00AF\u00E2\u20AC\u0152\u00D9\u2021\u00D8\u00A7\u00DB\u0152 \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7</h3>\n <div class=\"logs-container-compact\">\n @for (log of executionLogs(); track $index) {\n <div class=\"log-item-compact\" [class]=\"'log-' + log.level\">\n <span class=\"log-time\">{{ log.timestamp | date: 'HH:mm:ss' }}</span>\n <span class=\"log-icon\">\n @switch (log.level) {\n @case ('info') {\n <i class=\"fa-light fa-info-circle\"></i>\n }\n @case ('success') {\n <i class=\"fa-light fa-check-circle\"></i>\n }\n @case ('warning') {\n <i class=\"fa-light fa-exclamation-triangle\"></i>\n }\n @case ('error') {\n <i class=\"fa-light fa-times-circle\"></i>\n }\n }\n </span>\n <span class=\"log-message\">{{ log.message }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Dialog Footer -->\n <div class=\"execution-dialog-footer\">\n <div class=\"footer-info\">\n @if (workflowInstanceState()?.startTime) {\n <span class=\"time-info\">\n <i class=\"fa-light fa-clock\"></i>\n \u00D8\u00B4\u00D8\u00B1\u00D9\u02C6\u00D8\u00B9: {{ workflowInstanceState()!.startTime | date: 'HH:mm:ss' }}\n </span>\n }\n @if (workflowInstanceState()?.endTime) {\n <span class=\"time-info\">\n <i class=\"fa-light fa-flag-checkered\"></i>\n \u00D9\u00BE\u00D8\u00A7\u00DB\u0152\u00D8\u00A7\u00D9\u2020: {{ workflowInstanceState()!.endTime | date: 'HH:mm:ss' }}\n </span>\n }\n </div>\n <div class=\"footer-actions\">\n <ax-button\n [text]=\"(workflowInstanceState() ? '@general:actions.close.title' : '@general:actions.cancel.title') | translate | async\"\n color=\"secondary\" size=\"md\" [disabled]=\"isExecuting()\" (onClick)=\"closeExecutionDialog()\">\n </ax-button>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n </axp-page-content>\n</axp-page-layout>\n", styles: [".sidebar-header .toggle-btn{padding:.5rem;margin-left:auto;background:transparent;border:1px solid #e2e8f0;border-radius:6px;color:#64748b;cursor:pointer;transition:all .2s}.sidebar-header .toggle-btn:hover{background:#f8fafc;border-color:#8b5cf6;color:#8b5cf6}.sidebar-header .toggle-btn i{font-size:.875rem}.sidebar-toggle-btn{position:absolute;top:50%;transform:translateY(-50%);z-index:100;padding:1rem .5rem;background:#fff;border:1px solid #e2e8f0;border-radius:8px;color:#8b5cf6;cursor:pointer;box-shadow:0 4px 12px #0000001a;transition:all .3s}.sidebar-toggle-btn:hover{background:#8b5cf6;color:#fff;box-shadow:0 8px 24px #8b5cf64d;transform:translateY(-50%) scale(1.1)}.sidebar-toggle-btn.left{left:0;border-left:none;border-radius:0 8px 8px 0}.sidebar-toggle-btn.right{right:0;border-right:none;border-radius:8px 0 0 8px}.sidebar-toggle-btn i{font-size:1.25rem;display:block}.properties-header .header-actions{display:flex;gap:.5rem;margin-left:auto}.properties-header .header-btn{padding:.375rem .5rem;background:transparent;border:1px solid #e2e8f0;border-radius:4px;color:#64748b;cursor:pointer;transition:all .2s}.properties-header .header-btn:hover{background:#f8fafc;border-color:#8b5cf6;color:#8b5cf6}.properties-header .header-btn i{font-size:.75rem}.connections-list{margin-top:.75rem}.connection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;margin-bottom:.5rem;font-size:.875rem}.connection-item i{color:#8b5cf6}.connection-item span{flex:1;color:#1e293b}.connection-item .remove-btn{padding:.25rem .375rem;background:transparent;border:1px solid #e2e8f0;border-radius:4px;color:#ef4444;cursor:pointer;transition:all .2s}.connection-item .remove-btn:hover{background:#fef2f2;border-color:#ef4444}.connection-item .remove-btn i{font-size:.75rem;color:inherit}.property-editor{margin-top:.75rem}.property-editor .property-row label{display:flex;align-items:center;gap:.5rem;justify-content:space-between}.property-editor .property-row label .property-type-badge{padding:.125rem .375rem;background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;font-size:.625rem;font-weight:400;color:#64748b;text-transform:lowercase;font-family:JetBrains Mono,monospace}.property-editor .property-row select{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;background:#fff;cursor:pointer;transition:all .2s}.property-editor .property-row select:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.property-editor .property-row textarea{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.75rem;font-family:JetBrains Mono,monospace;color:#1e293b;resize:vertical;transition:all .2s}.property-editor .property-row textarea:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.workflow-studio{display:flex;flex-direction:column;height:100vh;background:#f8fafc;overflow:hidden}.studio-editor-tabs ax-button-group-item[selected],.studio-editor-tabs ax-button-group-item.ax-selected{font-weight:600;opacity:1}.workflow-popup .popup-header{text-align:center;margin-bottom:1.5rem;padding-bottom:1rem;border-bottom:2px solid #e2e8f0}.workflow-popup .popup-header h3{margin:0 0 .5rem;color:#1e293b;font-size:1.5rem;font-weight:700}.workflow-popup .popup-header p{margin:0;color:#64748b;font-size:.95rem}.workflow-popup .popup-body{max-height:60vh;overflow-y:auto;padding:0 .5rem}.workflow-popup .popup-body h4{margin:1.5rem 0 .75rem;color:#374151;font-size:1.1rem;font-weight:600;display:flex;align-items:center;gap:.5rem}.workflow-popup .popup-body ul{margin:0;padding-left:1.5rem}.workflow-popup .popup-body ul li{margin-bottom:.5rem;color:#4b5563}.workflow-popup .popup-body ul li strong{color:#1f2937}.workflow-popup .workflow-info{background:#f8fafc;padding:1rem;border-radius:8px;border:1px solid #e2e8f0}.workflow-popup .workflow-variables{background:#fef3c7;padding:1rem;border-radius:8px;border:1px solid #f59e0b}.workflow-popup .workflow-flow{background:#ecfdf5;padding:1rem;border-radius:8px;border:1px solid #10b981}.workflow-popup .workflow-flow .flow-steps{display:flex;flex-direction:column;gap:.75rem}.workflow-popup .workflow-flow .flow-steps .flow-step{display:flex;align-items:center;gap:.75rem;padding:.5rem;background:#fff;border-radius:6px;border:1px solid #d1d5db}.workflow-popup .workflow-flow .flow-steps .flow-step .step-number{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;color:#fff;border-radius:50%;font-size:.8rem;font-weight:600}.workflow-popup .workflow-flow .flow-steps .flow-step .step-text{color:#374151;font-weight:500}.workflow-popup .workflow-json{background:#1f2937;padding:1rem;border-radius:8px;border:1px solid #374151}.workflow-popup .workflow-json .json-preview{background:transparent;color:#e5e7eb;font-family:Monaco,Menlo,Ubuntu Mono,monospace;font-size:.8rem;line-height:1.4;margin:0;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto}.workflow-popup .popup-footer{text-align:center;margin-top:1.5rem;padding-top:1rem;border-top:1px solid #e2e8f0}.workflow-popup .popup-footer .btn{padding:.75rem 1.5rem;background:#3b82f6;color:#fff;border:none;border-radius:6px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:.5rem;transition:background-color .2s}.workflow-popup .popup-footer .btn:hover{background:#2563eb}.workflow-popup .popup-footer .btn i{font-size:.9rem}.view-workflow-link{color:#3b82f6;text-decoration:none;font-size:.85rem;margin-left:.5rem;transition:color .2s}.view-workflow-link:hover{color:#1d4ed8;text-decoration:underline}.studio-header{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;background:#fff;border-bottom:1px solid #e2e8f0;box-shadow:0 1px 3px #0000000d}.studio-header .header-title{display:flex;align-items:center;gap:.75rem}.studio-header .header-title i{font-size:1.75rem;color:#8b5cf6}.studio-header .header-title h1{margin:0;font-size:1.5rem;font-weight:700;color:#1e293b}.studio-header .header-title .badge{padding:.25rem .75rem;background:#8b5cf6;color:#fff;border-radius:12px;font-size:.75rem;font-weight:600}.studio-header .header-actions{display:flex;gap:.75rem;align-items:center}.samples-dropdown{position:relative}.samples-dropdown .samples-menu{position:absolute;top:calc(100% + .5rem);left:0;min-width:320px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 10px 25px #0000001a;z-index:1000;max-height:400px;overflow-y:auto}.samples-dropdown .samples-menu .sample-item{padding:.875rem 1rem;display:flex;align-items:flex-start;gap:.75rem;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:all .2s}.samples-dropdown .samples-menu .sample-item:last-child{border-bottom:none}.samples-dropdown .samples-menu .sample-item:hover{background:#f8fafc;transform:translate(4px)}.samples-dropdown .samples-menu .sample-item i{font-size:1.25rem;margin-top:.125rem;color:#8b5cf6}.samples-dropdown .samples-menu .sample-item .sample-info{display:flex;flex-direction:column;gap:.25rem;flex:1}.samples-dropdown .samples-menu .sample-item .sample-info strong{color:#1e293b;font-size:.875rem;font-weight:600}.samples-dropdown .samples-menu .sample-item .sample-info span{color:#64748b;font-size:.75rem;line-height:1.4}.studio-body{display:grid;grid-template-columns:1fr;gap:0;flex:1;overflow:hidden;transition:grid-template-columns .3s ease}.studio-body.sidebar-hidden,.studio-body.properties-hidden,.studio-body.sidebar-hidden.properties-hidden{grid-template-columns:1fr}.studio-sidebar{background:#fff;border-right:1px solid #e2e8f0;display:flex;flex-direction:column;overflow:hidden}.studio-sidebar .sidebar-header{padding:1rem 1.25rem;border-bottom:1px solid #e2e8f0;display:flex;align-items:center;gap:.5rem}.studio-sidebar .sidebar-header i{font-size:1.25rem;color:#8b5cf6}.studio-sidebar .sidebar-header h3{flex:1;margin:0;font-size:1.125rem;font-weight:600;color:#1e293b}.activities-tree{flex:1;overflow-y:auto;padding:.5rem}.category-section{margin-bottom:.5rem}.category-section .category-header{display:flex;align-items:center;gap:.5rem;padding:.75rem;border-radius:8px;cursor:pointer;transition:all .2s;background:#f8fafc}.category-section .category-header:hover{background:#f1f5f9}.category-section .category-header.active{background:#ede9fe}.category-section .category-header.active>i:first-child{color:#8b5cf6}.category-section .category-header>i:first-child{font-size:.875rem;color:#94a3b8;transition:transform .2s,color .2s}.category-section .category-header>i:nth-child(2){font-size:1.125rem}.category-section .category-header span{flex:1;font-weight:600;font-size:.875rem;color:#334155}.category-section .category-header .count{flex:none;padding:.125rem .5rem;background:#fff;border-radius:10px;font-size:.75rem;font-weight:600;color:#64748b;border:1px solid #e2e8f0}.activities-list{padding:.5rem 0 .5rem 1.5rem;display:flex;flex-direction:column;gap:.5rem;animation:slideDown .3s ease}.activities-list .activities-header{padding:.5rem .75rem;margin-bottom:.5rem}.activities-list .activities-header h4{margin:0;font-size:.875rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.activity-card{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:.875rem;margin-bottom:.75rem;transition:all .2s}.activity-card:hover{border-color:#8b5cf6;box-shadow:0 4px 12px #8b5cf61a;transform:translateY(-1px)}.activity-card .activity-info{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.5rem}.activity-card .activity-info>i{font-size:1.5rem;color:#8b5cf6;margin-top:.125rem}.activity-card .activity-info .activity-details{flex:1;display:flex;flex-direction:column;gap:.25rem}.activity-card .activity-info .activity-details strong{font-size:.875rem;color:#1e293b}.activity-card .activity-info .activity-details small{font-size:.75rem;color:#64748b;line-height:1.4}.activity-card .activity-info .activity-details code{font-size:.75rem;color:#8b5cf6;background:#f3f0ff;padding:.125rem .375rem;border-radius:4px;width:fit-content}.activity-card .copy-btn{float:right;padding:.375rem .75rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;cursor:pointer;transition:all .2s;color:#64748b}.activity-card .copy-btn:hover{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.activity-card .copy-btn i{font-size:.875rem}.activity-card .activity-properties{margin-top:.75rem;padding-top:.75rem;border-top:1px solid #f1f5f9}.activity-card .activity-properties .properties-title{display:block;font-size:.75rem;font-weight:600;color:#64748b;margin-bottom:.5rem}.activity-card .activity-properties .property-item{display:flex;align-items:center;gap:.5rem;padding:.25rem 0;font-size:.75rem}.activity-card .activity-properties .property-item code{color:#1e293b;background:#f8fafc;padding:.125rem .375rem;border-radius:3px}.activity-card .activity-properties .property-item .property-type{color:#64748b;font-style:italic}.activity-card .activity-properties .property-item .required{color:#ef4444;font-weight:700}.studio-editor{display:flex;flex-direction:column;background:#1e293b;overflow:hidden}.studio-editor .editor-header{padding:1rem 1.25rem;background:#0f172a;display:flex;align-items:center;gap:.5rem}.studio-editor .editor-header i{font-size:1.125rem;color:#8b5cf6}.studio-editor .editor-header h3{margin:0;font-size:1rem;font-weight:600;color:#e2e8f0}.studio-editor axp-page-toolbar .editor-tabs{display:flex;gap:.5rem;background:transparent}.studio-editor axp-page-toolbar .editor-tabs .tab-btn{padding:.5rem 1rem;background:transparent;border:1px solid #e2e8f0;border-radius:6px;color:#64748b;font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:.5rem}.studio-editor axp-page-toolbar .editor-tabs .tab-btn i{font-size:.875rem}.studio-editor axp-page-toolbar .editor-tabs .tab-btn:hover{background:#f8fafc;border-color:#cbd5e1;color:#475569}.studio-editor axp-page-toolbar .editor-tabs .tab-btn.active{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.studio-editor .editor-content{flex:1;display:flex;overflow:hidden}.studio-editor .json-tab{flex:1;display:flex;flex-direction:column}.studio-editor .json-editor{flex:1;padding:1.5rem;background:#1e293b;color:#e2e8f0;border:none;outline:none;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.875rem;line-height:1.6;resize:none;overflow:auto}.studio-editor .json-editor::placeholder{color:#475569}.studio-editor .json-editor::-webkit-scrollbar{width:10px;height:10px}.studio-editor .json-editor::-webkit-scrollbar-track{background:#0f172a}.studio-editor .json-editor::-webkit-scrollbar-thumb{background:#475569;border-radius:5px}.studio-editor .json-editor::-webkit-scrollbar-thumb:hover{background:#64748b}.studio-editor .visual-tab{flex:1;display:flex;background:#f8fafc;position:relative}.studio-editor .visual-canvas{flex:1;display:flex;flex-direction:column;overflow:hidden}.studio-editor .visual-canvas .canvas-toolbar{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;background:var(--ax-surface, white);border-bottom:1px solid var(--ax-border, #e2e8f0)}.studio-editor .visual-canvas .canvas-toolbar .tool-btn{padding:.5rem .75rem;background:var(--ax-surface-alt, #f8fafc);border:1px solid var(--ax-border, #e2e8f0);border-radius:6px;color:var(--ax-text-muted, #64748b);cursor:pointer;transition:all .2s}.studio-editor .visual-canvas .canvas-toolbar .tool-btn:hover{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.studio-editor .visual-canvas .canvas-toolbar .tool-btn i{font-size:.875rem}.studio-editor .visual-canvas .canvas-toolbar .toolbar-sep{width:1px;height:1.25rem;background:var(--ax-border, #e2e8f0);flex-shrink:0}.studio-editor .visual-canvas .canvas-toolbar .toolbar-auto-save{display:flex;align-items:center;gap:.5rem;font-size:.8125rem;color:var(--ax-text-muted, #64748b);cursor:default}.studio-editor .visual-canvas .canvas-toolbar .toolbar-auto-save ax-switch{flex-shrink:0}.studio-editor .visual-canvas .canvas-toolbar .tool-info{flex:1;display:flex;align-items:center;gap:.5rem;min-height:1.75rem;font-size:.8125rem;color:var(--ax-text-muted, #64748b);line-height:1.4}.studio-editor .visual-canvas .canvas-toolbar .tool-info strong{font-weight:600}.studio-editor .visual-canvas .canvas-toolbar .tool-info i{font-size:1rem;color:#8b5cf6;flex-shrink:0}.studio-editor .visual-canvas .canvas-area{flex:1;position:relative;background:linear-gradient(90deg,#e5e7eb 1px,transparent 1px),linear-gradient(#e5e7eb 1px,transparent 1px);background-size:20px 20px;overflow:auto;min-height:600px}.studio-editor .visual-canvas .connections-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1}.studio-editor .visual-canvas .connection-line{fill:none;transition:stroke .2s}.studio-editor .visual-canvas .connection-line.connection-hit{stroke:transparent;stroke-width:16;cursor:pointer;pointer-events:stroke}.studio-editor .visual-canvas .connection-line.connection-hit:hover~.outcome-line,.studio-editor .visual-canvas .connection-line.connection-hit:hover~.connection-line:not(.connection-hit){filter:brightness(.9)}.studio-editor .visual-canvas .connection-line:not(.connection-hit){stroke-linecap:round;pointer-events:none}.studio-editor .visual-canvas .connection-line.outcome-line{stroke-width:2.5}.studio-editor .visual-canvas .visual-node{position:absolute;width:150px;background:#fff;border:2px solid #e2e8f0;border-radius:8px;box-shadow:0 2px 8px #0000001a;cursor:move;transition:all .2s;z-index:2}.studio-editor .visual-canvas .visual-node:hover{border-color:#8b5cf6;box-shadow:0 4px 16px #8b5cf633;transform:translateY(-2px)}.studio-editor .visual-canvas .visual-node.selected{border-color:#8b5cf6;border-width:3px;box-shadow:0 0 0 3px #8b5cf633}.studio-editor .visual-canvas .visual-node .node-header{display:flex;align-items:center;gap:.5rem;padding:.75rem;background:linear-gradient(135deg,#8b5cf6,#7c3aed);color:#fff;border-radius:6px 6px 0 0;font-size:.875rem;font-weight:600}.studio-editor .visual-canvas .visual-node .node-header i{font-size:1rem}.studio-editor .visual-canvas .visual-node .node-header span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-editor .visual-canvas .visual-node .node-header .node-delete{padding:.25rem;background:#fff3;border:none;border-radius:4px;color:#fff;cursor:pointer;transition:all .2s}.studio-editor .visual-canvas .visual-node .node-header .node-delete:hover{background:#ef4444cc}.studio-editor .visual-canvas .visual-node .node-header .node-delete i{font-size:.75rem}.studio-editor .visual-canvas .visual-node .node-body{padding:.75rem}.studio-editor .visual-canvas .visual-node .node-body small{display:block;font-size:.75rem;color:#64748b;text-align:center}.studio-editor .visual-canvas .visual-node .node-connectors{position:relative}.studio-editor .visual-canvas .visual-node .node-connectors .connector{position:absolute;width:12px;height:12px;background:#8b5cf6;border:2px solid white;border-radius:50%;cursor:pointer;transition:all .2s;z-index:10}.studio-editor .visual-canvas .visual-node .node-connectors .connector:hover{transform:scale(1.3);box-shadow:0 0 0 3px #8b5cf64d}.studio-editor .visual-canvas .visual-node .node-connectors .connector-in{top:-50px;left:50%;transform:translate(-50%);background:#3b82f6}.studio-editor .visual-canvas .visual-node .node-connectors .connector-out{bottom:-6px;left:50%;transform:translate(-50%);background:#8b5cf6}.studio-editor .visual-canvas .visual-node .node-connectors .connector-out.active{background:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcomes-container{position:absolute;bottom:-60px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;gap:8px;background:#fff;padding:8px;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:120px;z-index:100}.studio-editor .visual-canvas .visual-node .node-connectors .outcomes-container:before{content:\"\";position:absolute;top:-8px;left:50%;transform:translate(-50%);width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid white;filter:drop-shadow(0 -2px 2px rgba(0,0,0,.05))}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;cursor:pointer;transition:all .2s;position:relative}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector:hover{background:#f1f5f9;border-color:#8b5cf6;transform:translate(2px)}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector.active{background:#fef2f2;border-color:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector.active .outcome-dot{background:#ef4444;box-shadow:0 0 0 3px #ef444433}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector .outcome-label{font-size:.75rem;font-weight:600;color:#475569;-webkit-user-select:none;user-select:none;flex:1}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector .outcome-dot{width:10px;height:10px;background:#8b5cf6;border:2px solid white;border-radius:50%;transition:all .2s;flex-shrink:0}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=\"200\"] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Done] .outcome-dot{background:#10b981}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=\"404\"] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Failed] .outcome-dot{background:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Timeout] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Cancelled] .outcome-dot{background:#f59e0b}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Then] .outcome-dot{background:#3b82f6}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Else] .outcome-dot{background:#64748b}.studio-editor .visual-canvas .canvas-empty-state{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;color:#94a3b8;pointer-events:none}.studio-editor .visual-canvas .canvas-empty-state i{font-size:4rem;margin-bottom:1rem;opacity:.5}.studio-editor .visual-canvas .canvas-empty-state p{margin:0 0 .5rem;font-size:1rem;font-weight:500}.studio-editor .visual-canvas .canvas-empty-state small{font-size:.875rem;opacity:.8}.studio-editor .properties-panel{width:280px;background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column}.studio-editor .properties-panel .properties-header{display:flex;align-items:center;gap:.5rem;padding:1rem;border-bottom:1px solid #e2e8f0}.studio-editor .properties-panel .properties-header i{font-size:1.125rem;color:#8b5cf6}.studio-editor .properties-panel .properties-header h4{flex:1;margin:0;font-size:.875rem;font-weight:600;color:#1e293b}.studio-editor .properties-panel .properties-header button{padding:.25rem .5rem;background:transparent;border:none;color:#64748b;cursor:pointer;transition:color .2s}.studio-editor .properties-panel .properties-header button:hover{color:#ef4444}.studio-editor .properties-panel .properties-body{flex:1;padding:1rem;overflow-y:auto}.studio-editor .properties-panel .properties-body .properties-widget-section{min-height:0}.studio-editor .properties-panel .properties-body .workflow-panel-section{margin-bottom:1.5rem}.studio-editor .properties-panel .properties-body .workflow-panel-section h5{margin:0 0 .75rem;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group{margin-bottom:.75rem}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group label{font-size:.75rem}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group input,.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group textarea{font-size:.8125rem}.studio-editor .properties-panel .properties-body .workflow-info-table{display:flex;flex-direction:column;gap:.5rem}.studio-editor .properties-panel .properties-body .workflow-info-row{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem 0;border-bottom:1px solid #f1f5f9}.studio-editor .properties-panel .properties-body .workflow-info-row:last-child{border-bottom:none}.studio-editor .properties-panel .properties-body .info-label{font-size:.8125rem;font-weight:500;color:#64748b;flex-shrink:0}.studio-editor .properties-panel .properties-body .info-value{font-size:.8125rem;color:#1e293b;text-align:right;word-break:break-all}.studio-editor .properties-panel .properties-body .info-actions{display:flex;align-items:center;gap:.5rem}.studio-editor .properties-panel .properties-body .property-row{margin-bottom:1rem}.studio-editor .properties-panel .properties-body .property-row label{display:block;font-size:.75rem;font-weight:600;color:#64748b;margin-bottom:.375rem;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .property-row input{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;transition:all .2s}.studio-editor .properties-panel .properties-body .property-row input:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.studio-editor .properties-panel .properties-body .property-row input:disabled{background:#f8fafc;color:#94a3b8;cursor:not-allowed}.studio-editor .properties-panel .properties-body .properties-divider{height:1px;background:#e2e8f0;margin:1.5rem 0}.studio-editor .properties-panel .properties-body h5{margin:0 0 .5rem;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .properties-hint{display:block;font-size:.75rem;color:#94a3b8;margin-bottom:.75rem}.studio-editor .properties-panel .properties-body .properties-json{margin:.75rem 0 0;padding:.75rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;color:#1e293b;overflow-x:auto}.studio-editor .properties-panel .properties-body .no-properties{margin:.75rem 0 0;padding:1rem;background:#f8fafc;border:1px dashed #cbd5e1;border-radius:6px;text-align:center;font-size:.75rem;color:#94a3b8}.studio-editor .properties-panel .properties-body .connections-list{display:flex;flex-direction:column;gap:.5rem;margin-top:.75rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;font-size:.75rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item.outcome-connection{border-left-width:3px}.studio-editor .properties-panel .properties-body .connections-list .connection-item i{color:#64748b;font-size:.875rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item span{flex:1;color:#1e293b;font-weight:500}.studio-editor .properties-panel .properties-body .connections-list .connection-item .outcome-badge{padding:.25rem .5rem;border-radius:4px;color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn{padding:.25rem;background:transparent;border:none;color:#ef4444;cursor:pointer;border-radius:4px;transition:all .2s}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn:hover{background:#fee2e2}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn i{font-size:.75rem;color:inherit}.studio-editor .properties-panel .properties-body .outcomes-info{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .625rem;background:#fff;border:2px solid;border-radius:6px;font-size:.75rem;font-weight:600;color:#1e293b;transition:all .2s}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag:hover{transform:translateY(-1px);box-shadow:0 2px 8px #0000001a}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag .outcome-dot{width:8px;height:8px;border-radius:50%}.studio-result{display:flex;flex-direction:column;background:#fff;border-left:1px solid #e2e8f0;overflow:hidden}.studio-result .result-header{padding:1rem 1.25rem;border-bottom:1px solid #e2e8f0;display:flex;align-items:center;gap:.5rem}.studio-result .result-header i{font-size:1.125rem;color:#10b981}.studio-result .result-header h3{flex:1;margin:0;font-size:1rem;font-weight:600;color:#1e293b}.studio-result .result-header .clear-btn{padding:.375rem .75rem;background:#fee2e2;color:#dc2626;border:none;border-radius:6px;cursor:pointer;font-size:.75rem;font-weight:500;transition:all .2s}.studio-result .result-header .clear-btn:hover{background:#fecaca}.studio-result .result-header .clear-btn i{font-size:.75rem;color:inherit}.studio-result .result-body{flex:1;overflow-y:auto;padding:1rem}.logs-container{display:flex;flex-direction:column;gap:.5rem}.log-item{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#f8fafc;border-left:3px solid #cbd5e1;border-radius:6px;font-size:.875rem}.log-item.log-info{border-left-color:#3b82f6;background:#eff6ff}.log-item.log-info .log-icon{color:#3b82f6}.log-item.log-success{border-left-color:#10b981;background:#f0fdf4}.log-item.log-success .log-icon{color:#10b981}.log-item.log-warning{border-left-color:#f59e0b;background:#fffbeb}.log-item.log-warning .log-icon{color:#f59e0b}.log-item.log-error{border-left-color:#ef4444;background:#fef2f2}.log-item.log-error .log-icon{color:#ef4444}.log-item .log-time{font-family:JetBrains Mono,monospace;font-size:.75rem;color:#64748b;min-width:80px}.log-item .log-icon{font-size:1rem}.log-item .log-message{flex:1;color:#1e293b}.log-item .log-data-toggle{padding:.25rem .5rem;background:transparent;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .2s}.log-item .log-data-toggle:hover{background:#fff}.log-item .log-data-toggle i{font-size:.75rem;color:#64748b}.log-data{margin:.5rem 0 0;padding:1rem;background:#0f172a;color:#e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;overflow-x:auto}.settings-modal-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999;padding:2rem;animation:fadeIn .2s ease}.settings-modal{background:#fff;border-radius:12px;box-shadow:0 20px 60px #0000004d;width:100%;max-width:900px;max-height:90vh;display:flex;flex-direction:column;animation:slideUp .3s ease}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.settings-modal-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem 2rem;border-bottom:1px solid #e2e8f0}.settings-modal-header .header-title{display:flex;align-items:center;gap:.75rem}.settings-modal-header .header-title i{font-size:1.5rem;color:#8b5cf6}.settings-modal-header .header-title h2{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b}.settings-modal-header .close-btn{padding:.5rem;background:transparent;border:none;color:#64748b;cursor:pointer;border-radius:6px;transition:all .2s}.settings-modal-header .close-btn:hover{background:#f1f5f9;color:#ef4444}.settings-modal-header .close-btn i{font-size:1.25rem}.settings-modal-body{flex:1;display:flex;flex-direction:column;overflow:hidden}.settings-tabs{padding:0 1.5rem}.settings-content{flex:1;overflow-y:auto;padding:2rem}.settings-section h3{margin:0 0 1.5rem;font-size:1rem;font-weight:600;color:#1e293b}.settings-section .section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem}.settings-section .section-header h3{margin:0}.settings-section .section-header .add-btn{display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:#8b5cf6;color:#fff;border:none;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s}.settings-section .section-header .add-btn:hover{background:#7c3aed;transform:translateY(-1px);box-shadow:0 4px 12px #8b5cf64d}.settings-section .section-header .add-btn i{font-size:.875rem}.form-group{margin-bottom:1.25rem}.form-group label{display:block;font-size:.875rem;font-weight:600;color:#475569;margin-bottom:.5rem}.form-group small{display:block;font-size:.75rem;color:#94a3b8;margin-top:.375rem}.form-group.checkbox-group{margin-bottom:0}.form-group.checkbox-group label{display:flex;align-items:center;gap:.5rem;cursor:pointer;margin-bottom:0}.form-group.checkbox-group label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.form-group.checkbox-group label span{font-size:.875rem;font-weight:500}.form-group.flex-1{flex:1}.form-row{display:flex;gap:1rem;align-items:flex-start}.form-input,.form-select,.form-textarea{width:100%;padding:.625rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;transition:all .2s}.form-input:focus,.form-select:focus,.form-textarea:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.form-input::placeholder,.form-select::placeholder,.form-textarea::placeholder{color:#cbd5e1}.form-textarea{resize:vertical;font-family:inherit}.items-list{display:flex;flex-direction:column;gap:1rem}.item-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;transition:all .2s}.item-card:hover{border-color:#cbd5e1;box-shadow:0 2px 8px #0000000d}.item-card .item-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:#f1f5f9;border-bottom:1px solid #e2e8f0}.item-card .item-header .item-number{font-size:.75rem;font-weight:700;color:#8b5cf6;padding:.25rem .5rem;background:#fff;border-radius:4px}.item-card .item-header .remove-btn{padding:.375rem .625rem;background:transparent;border:none;color:#ef4444;cursor:pointer;border-radius:4px;transition:all .2s}.item-card .item-header .remove-btn:hover{background:#fee2e2}.item-card .item-header .remove-btn i{font-size:.875rem}.item-card .item-body{padding:1rem}.advanced-group{margin-bottom:2rem;padding-bottom:2rem;border-bottom:1px solid #e2e8f0}.advanced-group:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.advanced-group h4{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.5px}.outcomes-preview{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}.outcomes-preview .outcome-chip{display:inline-flex;align-items:center;padding:.375rem .75rem;background:#f1f5f9;border:1px solid #cbd5e1;border-radius:6px;font-size:.75rem;font-weight:600;color:#475569}.export-info{margin-top:1rem;padding:1rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.export-info .info-row{display:flex;align-items:center;gap:.75rem;padding:.5rem 0;border-bottom:1px solid #e2e8f0}.export-info .info-row:last-child{border-bottom:none;padding-bottom:0}.export-info .info-row .label{font-size:.75rem;font-weight:600;color:#64748b;min-width:120px}.export-info .info-row code{flex:1;padding:.25rem .5rem;background:#fff;border:1px solid #e2e8f0;border-radius:4px;font-size:.75rem;color:#1e293b;font-family:JetBrains Mono,monospace}.settings-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:1rem;padding:1.5rem 2rem;border-top:1px solid #e2e8f0;background:#f8fafc}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center;color:#94a3b8}.empty-state i{font-size:3rem;margin-bottom:1rem}.empty-state p{margin:0;font-size:.875rem}.final-result{margin-top:1.5rem;padding-top:1.5rem;border-top:2px solid #e2e8f0}.final-result .result-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background:#f8fafc;border-radius:8px;margin-bottom:1rem;cursor:pointer;transition:all .2s}.final-result .result-header:hover{background:#f1f5f9;transform:translate(-2px)}.final-result .result-header h4{display:flex;align-items:center;gap:.5rem;margin:0;font-size:.875rem;font-weight:600;color:#475569;text-transform:uppercase}.final-result .result-header h4 i{font-size:.875rem;transition:transform .2s}.final-result .result-header .toggle-hint{font-size:.75rem;color:#94a3b8}.final-result .result-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem}.final-result .result-card .result-row{display:flex;align-items:center;gap:.75rem;padding:.5rem 0}.final-result .result-card .result-row:not(:last-child){border-bottom:1px solid #e2e8f0}.final-result .result-card .result-row strong{font-size:.875rem;color:#475569;min-width:100px}.final-result .result-card .result-row .badge{padding:.25rem .75rem;border-radius:12px;font-size:.75rem;font-weight:600}.final-result .result-card .result-row .badge.badge-running{background:#dbeafe;color:#1e40af}.final-result .result-card .result-row .badge.badge-finished{background:#d1fae5;color:#065f46}.final-result .result-card .result-row .badge.badge-cancelled{background:#fed7aa;color:#92400e}.final-result .result-card .result-row .badge.badge-faulted{background:#fee2e2;color:#991b1b}.final-result .result-card .result-row pre{margin:.5rem 0 0;padding:.75rem;background:#0f172a;color:#e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;overflow-x:auto;width:100%}.activities-list::-webkit-scrollbar,.result-body::-webkit-scrollbar{width:8px}.activities-list::-webkit-scrollbar-track,.result-body::-webkit-scrollbar-track{background:#f1f5f9}.activities-list::-webkit-scrollbar-thumb,.result-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.activities-list::-webkit-scrollbar-thumb:hover,.result-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.activity-card{cursor:grab}.activity-card:active{cursor:grabbing}.activity-card[draggable=true]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.visual-node[draggable=true]{cursor:move;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.visual-node:active{cursor:grabbing}.canvas-area[data-drag-over=true]{background-color:#8b5cf60d}.connector:hover{transform:scale(1.3);box-shadow:0 0 0 3px #8b5cf64d}.connector-out.active{animation:pulse 1s infinite}@keyframes pulse{0%,to{box-shadow:0 0 0 3px #ef44444d}50%{box-shadow:0 0 0 6px #ef44441a}}@keyframes slideDown{0%{opacity:0;max-height:0}to{opacity:1;max-height:2000px}}.execution-dialog-overlay{position:fixed;inset:0;background:#000000b3;backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:10000;animation:fadeIn .2s ease}.execution-dialog{width:90vw;max-width:1200px;height:90vh;background:#fff;border-radius:16px;box-shadow:0 25px 50px #0000004d;display:flex;flex-direction:column;overflow:hidden;animation:slideUp .3s ease}.execution-dialog-header{padding:1.5rem 2rem;background:linear-gradient(135deg,#8b5cf6,#7c3aed);color:#fff;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.execution-dialog-header .header-content{display:flex;align-items:center;gap:1rem;flex:1}.execution-dialog-header .header-content>i{font-size:2.5rem;opacity:.9}.execution-dialog-header .header-content .header-info h2{margin:0;font-size:1.75rem;font-weight:700}.execution-dialog-header .header-content .header-info p{margin:.25rem 0 0;opacity:.9;font-size:.95rem}.execution-dialog-header .close-btn{background:#fff3;border:none;width:40px;height:40px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;color:#fff;font-size:1.25rem}.execution-dialog-header .close-btn:hover:not(:disabled){background:#ffffff4d;transform:scale(1.05)}.execution-dialog-header .close-btn:disabled{opacity:.5;cursor:not-allowed}.execution-dialog-body{flex:1;overflow-y:auto;padding:2rem;background:#f8fafc}.execution-dialog-footer{padding:1rem 2rem;background:#fff;border-top:1px solid #e2e8f0;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.execution-dialog-footer .footer-info{display:flex;gap:1.5rem}.execution-dialog-footer .footer-info .time-info{display:flex;align-items:center;gap:.5rem;color:#64748b;font-size:.875rem}.execution-dialog-footer .footer-info .time-info i{color:#8b5cf6}.execution-dialog-footer .footer-actions{display:flex;gap:.75rem}.workflow-info-panel{background:#fff;border-radius:12px;padding:2rem;box-shadow:0 4px 6px #0000000d}.workflow-info-panel .info-section{margin-bottom:2rem}.workflow-info-panel .info-section h3{display:flex;align-items:center;gap:.5rem;margin:0 0 1rem;color:#1e293b;font-size:1.25rem}.workflow-info-panel .info-section h3 i{color:#8b5cf6}.workflow-info-panel .info-section .description{color:#475569;line-height:1.7;margin:0}.workflow-info-panel .info-section .features-list{list-style:none;padding:0;margin:0;display:grid;gap:.75rem}.workflow-info-panel .info-section .features-list li{display:flex;align-items:center;gap:.75rem;padding:.75rem;background:#f8fafc;border-radius:8px;color:#334155}.workflow-info-panel .info-section .features-list li i{color:#10b981;font-size:1.125rem}.workflow-info-panel .start-section{text-align:center;padding:2rem;background:linear-gradient(135deg,#f0fdf4,#dcfce7);border-radius:12px;border:2px dashed #10b981}.workflow-info-panel .start-section .start-illustration{margin-bottom:1rem}.workflow-info-panel .start-section .start-illustration i{font-size:4rem;color:#10b981;animation:float 3s ease-in-out infinite}.workflow-info-panel .start-section h3{margin:0 0 .5rem;color:#1e293b;font-size:1.5rem}.workflow-info-panel .start-section p{margin:0 0 1.5rem;color:#64748b}.state-machine-ui .issue-tracker{background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 1px 2px #0000000d}.state-machine-ui .issue-tracker .issue-header-main{padding:1.5rem 2rem 1rem;border-bottom:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:#64748b;margin-bottom:.75rem}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .project-name{color:#3b82f6;font-weight:600}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .separator{color:#94a3b8}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .issue-key{color:#64748b}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title{display:flex;align-items:center;gap:.75rem}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .type-badge{padding:.375rem .75rem;border-radius:4px;font-size:.8125rem;font-weight:600;display:flex;align-items:center;gap:.375rem;background:#eff6ff;color:#3b82f6}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .type-badge i{font-size:1rem}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .issue-main-title{margin:0;font-size:1.5rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-action-bar{padding:.75rem 2rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;display:flex;justify-content:space-between;align-items:center}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left{display:flex;gap:.5rem}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn{padding:.5rem 1rem;border:1px solid #cbd5e1;border-radius:4px;background:#fff;font-weight:500;font-size:.875rem;cursor:pointer;transition:all .2s;color:#334155}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn:hover:not(:disabled){background:#f1f5f9;border-color:#94a3b8}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn:disabled{opacity:.5;cursor:not-allowed}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-primary{background:#3b82f6;color:#fff;border-color:#3b82f6}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-primary:hover:not(:disabled){background:#2563eb}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-success{background:#10b981;color:#fff;border-color:#10b981}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-success:hover:not(:disabled){background:#059669}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-warning{background:#f59e0b;color:#fff;border-color:#f59e0b}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-warning:hover:not(:disabled){background:#d97706}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-right .more-actions-btn{padding:.5rem 1rem;border:1px solid #cbd5e1;border-radius:4px;background:#fff;font-weight:500;font-size:.875rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;color:#334155;transition:all .2s}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-right .more-actions-btn:hover{background:#f1f5f9}.state-machine-ui .issue-tracker .issue-main-content{display:grid;grid-template-columns:320px 1fr;gap:2rem;padding:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section{margin-bottom:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row{display:flex;padding:.625rem 0;border-bottom:1px solid #f1f5f9}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row:last-child{border-bottom:none}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row label{min-width:100px;font-size:.8125rem;color:#64748b;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value i{font-size:1rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .status-badge{padding:.25rem .625rem;border-radius:4px;color:#fff;font-weight:600;font-size:.75rem;text-transform:uppercase}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .view-workflow-link{color:#3b82f6;font-size:.8125rem;text-decoration:none;margin-left:.5rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .view-workflow-link:hover{text-decoration:underline}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .user-avatar{width:24px;height:24px;border-radius:50%;background:#8b5cf6;color:#fff;display:flex;align-items:center;justify-content:center;font-size:.75rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz{background:#f8fafc;border-radius:8px;padding:1.5rem;border:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz h3{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state{display:flex;flex-direction:column;align-items:center;gap:.375rem;opacity:.4;transition:opacity .2s}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.active,.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.completed{opacity:1}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state .state-circle{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:.875rem;box-shadow:0 2px 4px #0000001a}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state .state-name{font-size:.6875rem;color:#64748b;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.active .state-name{color:#1e293b;font-weight:600}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-arrow{color:#cbd5e1;font-size:.75rem;margin:0 .25rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section{margin-bottom:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section h3,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section .description-content,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .description-content{padding:1rem;background:#f8fafc;border-radius:6px;border:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section .description-content p,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .description-content p{margin:0;color:#475569;line-height:1.7;font-size:.875rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline{display:flex;flex-direction:column;gap:1rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item{display:flex;gap:.75rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-avatar{width:32px;height:32px;border-radius:50%;background:#8b5cf6;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.875rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content{flex:1;padding-bottom:1rem;border-bottom:1px solid #f1f5f9}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header{font-size:.875rem;color:#334155;line-height:1.6;margin-bottom:.375rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header strong{color:#1e293b;font-weight:600}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header .activity-action{color:#64748b}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-meta{display:flex;align-items:center;gap:.5rem;font-size:.8125rem;color:#94a3b8}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-meta .activity-label{color:#8b5cf6;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item:last-child .activity-content{border-bottom:none;padding-bottom:0}.registration-ui{display:flex;justify-content:center;align-items:center;min-height:400px}.registration-ui .registration-card{background:#fff;border-radius:12px;padding:3rem;box-shadow:0 4px 6px #0000000d;text-align:center;max-width:500px}.registration-ui .registration-card .registration-icon{margin-bottom:1.5rem}.registration-ui .registration-card .registration-icon i{font-size:5rem;color:#8b5cf6}.registration-ui .registration-card h3{margin:0 0 .75rem;color:#1e293b;font-size:1.75rem;font-weight:700}.registration-ui .registration-card .registration-desc{margin:0 0 2rem;color:#64748b;line-height:1.7}.registration-ui .registration-card .registration-progress{padding:2rem;background:#fef3c7;border-radius:8px}.registration-ui .registration-card .registration-progress .progress-spinner{margin-bottom:1rem}.registration-ui .registration-card .registration-progress .progress-spinner i{font-size:3rem;color:#f59e0b}.registration-ui .registration-card .registration-progress p{margin:0;color:#92400e;font-weight:500}.registration-ui .registration-card .registration-success{padding:2rem;background:#f0fdf4;border-radius:8px}.registration-ui .registration-card .registration-success i{font-size:4rem;color:#10b981;margin-bottom:1rem}.registration-ui .registration-card .registration-success h4{margin:0 0 .5rem;color:#064e3b;font-size:1.5rem;font-weight:700}.registration-ui .registration-card .registration-success p{margin:0;color:#065f46}.default-execution-view{display:flex;justify-content:center;align-items:center;min-height:400px}.default-execution-view .execution-status{text-align:center;padding:3rem;background:#fff;border-radius:12px;box-shadow:0 4px 6px #0000000d;min-width:400px}.default-execution-view .execution-status i{font-size:5rem;margin-bottom:1.5rem}.default-execution-view .execution-status h3{margin:0 0 .75rem;font-size:1.75rem;font-weight:700}.default-execution-view .execution-status p{margin:0;color:#64748b;line-height:1.7}.default-execution-view .execution-status .status-running i{color:#f59e0b}.default-execution-view .execution-status .status-finished i{color:#10b981}.default-execution-view .execution-status .status-error i{color:#ef4444}.execution-logs-panel{margin-top:2rem;background:#fff;border-radius:12px;padding:1.5rem;box-shadow:0 4px 6px #0000000d}.execution-logs-panel h3{display:flex;align-items:center;gap:.5rem;margin:0 0 1rem;color:#1e293b;font-size:1.125rem}.execution-logs-panel h3 i{color:#8b5cf6}.execution-logs-panel .logs-container-compact{max-height:300px;overflow-y:auto;background:#f8fafc;border-radius:8px;padding:.75rem}.execution-logs-panel .logs-container-compact .log-item-compact{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;border-radius:6px;margin-bottom:.5rem;font-size:.875rem}.execution-logs-panel .logs-container-compact .log-item-compact:last-child{margin-bottom:0}.execution-logs-panel .logs-container-compact .log-item-compact .log-time{font-family:Courier New,monospace;color:#64748b;font-size:.8125rem;min-width:70px}.execution-logs-panel .logs-container-compact .log-item-compact .log-icon{display:flex;align-items:center;justify-content:center;width:20px}.execution-logs-panel .logs-container-compact .log-item-compact .log-icon i{font-size:1rem}.execution-logs-panel .logs-container-compact .log-item-compact .log-message{flex:1;color:#334155}.execution-logs-panel .logs-container-compact .log-item-compact.log-info{background:#eff6ff}.execution-logs-panel .logs-container-compact .log-item-compact.log-info .log-icon i{color:#3b82f6}.execution-logs-panel .logs-container-compact .log-item-compact.log-success{background:#f0fdf4}.execution-logs-panel .logs-container-compact .log-item-compact.log-success .log-icon i{color:#10b981}.execution-logs-panel .logs-container-compact .log-item-compact.log-warning{background:#fffbeb}.execution-logs-panel .logs-container-compact .log-item-compact.log-warning .log-icon i{color:#f59e0b}.execution-logs-panel .logs-container-compact .log-item-compact.log-error{background:#fef2f2}.execution-logs-panel .logs-container-compact .log-item-compact.log-error .log-icon i{color:#ef4444}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXButtonGroupModule }, { kind: "component", type: i2$1.AXButtonGroupComponent, selector: "ax-button-group", inputs: ["disabled", "color", "look", "fitParent", "selection"], outputs: ["onBlur", "onFocus", "lookChange", "colorChange", "disabledChange", "onClick", "selectionChange", "selectedButtonChange"] }, { kind: "component", type: i2$1.AXButtonGroupItemComponent, selector: "ax-button-group-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i3.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i3.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i4.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "ngmodule", type: AXSearchBoxModule }, { kind: "component", type: i5.AXSearchBoxComponent, selector: "ax-search-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "value", "state", "name", "id", "look", "class", "delayTime", "type", "autoSearch"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXSwitchModule }, { kind: "component", type: i6.AXSwitchComponent, selector: "ax-switch", inputs: ["disabled", "readonly", "color", "tabIndex", "value", "name", "isLoading"], outputs: ["onBlur", "onFocus", "valueChange", "onValueChanged", "readonlyChange", "disabledChange"] }, { kind: "ngmodule", type: AXTabsModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type: AXPPageLayoutComponent, selector: "axp-page-layout" }, { kind: "component", type: AXPPropertyViewerComponent, selector: "axp-property-viewer", inputs: ["tabsInput", "mode", "bindingExpressionEditorMode"], outputs: ["onChanged"] }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-page-content, axp-page-footer-container, axp-page-footer, axp-page-header, axp-page-header-container, axp-page-toolbar, axp-layout-content, axp-layout-page-content, axp-layout-sections, axp-layout-body, axp-layout-page-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title-bar, axp-layout-title, axp-layout-title-actions, axp-layout-nav-button, axp-layout-description, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutHeaderComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutToolbarComponent, selector: "axp-layout-toolbar" }, { kind: "component", type: AXPThemeLayoutStartSideComponent, selector: "axp-layout-page-start-side, axp-layout-start-side" }, { kind: "component", type: AXMActivityCategoriesTreeComponent, selector: "axp-activity-categories-tree", outputs: ["categoryClick", "activityClick", "activityDragStart"] }, { kind: "pipe", type: i7.AsyncPipe, name: "async" }, { kind: "pipe", type: i7.JsonPipe, name: "json" }, { kind: "pipe", type: i7.DatePipe, name: "date" }, { kind: "pipe", type: i5$1.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
5409
- }
5410
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowStudioComponent, decorators: [{
5411
- type: Component,
5412
- args: [{ selector: 'app-workflow-studio', standalone: true, imports: [
5413
- CommonModule,
5414
- FormsModule,
5415
- AXButtonModule,
5416
- AXButtonGroupModule,
5417
- AXDecoratorModule,
5418
- AXTextBoxModule,
5419
- AXSelectBoxModule,
5420
- AXSearchBoxModule,
5421
- AXSwitchModule,
5422
- AXTabsModule,
5423
- AXTranslationModule,
5424
- AXPPageLayoutComponent,
5425
- AXPPropertyViewerComponent,
5426
- AXPThemeLayoutBlockComponent,
5427
- AXPThemeLayoutHeaderComponent,
5428
- AXPThemeLayoutToolbarComponent,
5429
- AXPThemeLayoutStartSideComponent,
5430
- AXMActivityCategoriesTreeComponent,
5431
- ], providers: [
5432
- {
5433
- provide: AXPPageLayoutBase,
5434
- useExisting: WorkflowStudioComponent,
5435
- },
5436
- ], changeDetection: ChangeDetectionStrategy.OnPush, template: "<axp-page-layout>\n <axp-layout-start-side>\n <axp-layout-header>\n <axp-layout-title>{{ '@workflow-management:activities.menus.activity-categories.title' | translate | async }}</axp-layout-title>\n <axp-layout-toolbar>\n <ax-search-box\n [delayTime]=\"300\"\n [placeholder]=\"'@workflow-management:workflow-studio.components.activity-categories-tree.search-placeholder' | translate | async\"\n >\n <ax-clear-button></ax-clear-button>\n </ax-search-box>\n </axp-layout-toolbar>\n </axp-layout-header>\n <axp-layout-content>\n <axp-activity-categories-tree\n (categoryClick)=\"onCategoryClick($event)\"\n (activityClick)=\"onActivityClick($event)\"\n (activityDragStart)=\"onActivityDragStartFromTree($event)\"\n ></axp-activity-categories-tree>\n </axp-layout-content>\n </axp-layout-start-side>\n\n <axp-page-toolbar>\n <axp-layout-prefix>\n <!-- JSON / Visual toggle (same pattern as report view mode) -->\n <div class=\"studio-editor-tabs\">\n <ax-button-group class=\"ax-sm\" [selection]=\"'single'\">\n <ax-button-group-item (onClick)=\"switchTab('json')\" text=\"{{ '@workflow-management:workflow-studio.terms.json-editor' | translate | async }}\" [selected]=\"activeTab() === 'json'\">\n <ax-prefix>\n <i class=\"fa-light fa-code\"></i>\n </ax-prefix>\n </ax-button-group-item>\n <ax-button-group-item (onClick)=\"switchTab('visual')\" text=\"{{ '@workflow-management:workflow-studio.terms.visual-designer' | translate | async }}\" [selected]=\"activeTab() === 'visual'\">\n <ax-prefix>\n <i class=\"fa-light fa-diagram-project\"></i>\n </ax-prefix>\n </ax-button-group-item>\n </ax-button-group>\n </div>\n </axp-layout-prefix>\n </axp-page-toolbar>\n\n <axp-page-content>\n <div class=\"workflow-studio\">\n <!-- Main Layout -->\n <div class=\"studio-body\" [class.properties-hidden]=\"!showPropertiesPanel()\">\n\n <!-- Editor -->\n <div class=\"studio-editor\">\n <!-- Tab Content -->\n <div class=\"editor-content\">\n <!-- JSON Tab -->\n @if (activeTab() === 'json') {\n <div class=\"json-tab\">\n <textarea class=\"json-editor\" [value]=\"workflowJson()\"\n (input)=\"onWorkflowJsonInput($event)\"\n [placeholder]=\"'@workflow-management:workflow-studio.components.json-editor.placeholder' | translate | async\"\n spellcheck=\"false\"></textarea>\n </div>\n }\n\n <!-- Visual Tab -->\n @if (activeTab() === 'visual') {\n <div class=\"visual-tab\">\n <!-- Canvas -->\n <div class=\"visual-canvas\">\n <div class=\"canvas-toolbar\">\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.zoom-to-fit.title' | translate | async\" (onClick)=\"canvasZoomToFit()\">\n <ax-prefix><i class=\"fa-light fa-expand\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.center.title' | translate | async\" (onClick)=\"canvasCenter()\">\n <ax-prefix><i class=\"fa-light fa-crosshairs\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.auto-layout.title' | translate | async\" (onClick)=\"canvasAutoLayout()\">\n <ax-prefix><i class=\"fa-light fa-sitemap\"></i></ax-prefix>\n </ax-button>\n <span class=\"toolbar-sep\"></span>\n <label class=\"toolbar-auto-save\">\n <ax-switch [value]=\"autoSaveEnabled()\" (valueChange)=\"autoSaveEnabled.set($event)\"></ax-switch>\n <span>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.auto-save' | translate | async }}</span>\n </label>\n <span class=\"toolbar-sep\"></span>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.clear-canvas.title' | translate | async\" (onClick)=\"clearCanvas()\">\n <ax-prefix><i class=\"fa-light fa-trash\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" class=\"ax-sm\" [attr.title]=\"'@workflow-management:workflow-studio.components.canvas-toolbar.convert-to-json.title' | translate | async\" (onClick)=\"visualToJson()\">\n <ax-prefix><i class=\"fa-light fa-code\"></i></ax-prefix>\n </ax-button>\n <span class=\"tool-info\">\n <i class=\"fa-light fa-lightbulb\"></i>\n <strong>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.hint' | translate | async }}</strong>\n </span>\n </div>\n\n <div #canvasAreaRef class=\"canvas-area\" (drop)=\"onCanvasDrop($event)\" (dragover)=\"onCanvasDragOver($event)\"\n (dragleave)=\"onCanvasDragLeave($event)\">\n <!-- SVG for Connections -->\n <svg class=\"connections-layer\">\n <!-- Outcome-based Connections -->\n @for (node of visualNodes(); track node.id) {\n @if (node.outcomeConnections && node.outcomeConnections.length > 0) {\n @for (conn of node.outcomeConnections; track conn.targetNodeId + conn.outcome) {\n @let targetNode = findNodeById(conn.targetNodeId);\n @if (targetNode) {\n <g class=\"outcome-connection-group\">\n <line [attr.x1]=\"node.position.x + 75\" [attr.y1]=\"node.position.y + 80\"\n [attr.x2]=\"targetNode.position.x + 75\" [attr.y2]=\"targetNode.position.y - 50\"\n class=\"connection-line outcome-line\" [attr.stroke]=\"getOutcomeColor(conn.outcome)\"\n stroke-width=\"2.5\"\n [attr.marker-end]=\"'url(#arrowhead-' + getOutcomeColorName(conn.outcome) + ')'\"\n style=\"cursor: pointer\" (dblclick)=\"disconnectNodes(node.id, conn.targetNodeId, conn.outcome)\"\n [attr.title]=\"'Outcome: ' + conn.outcome + ' (Double-click to remove)'\">\n <title>{{ conn.outcome }} \u00E2\u2020\u2019 {{ targetNode.name }}</title>\n </line>\n <text [attr.x]=\"(node.position.x + targetNode.position.x) / 2 + 75\"\n [attr.y]=\"(node.position.y + targetNode.position.y) / 2 + 15\" class=\"connection-label\"\n text-anchor=\"middle\" dominant-baseline=\"middle\" [attr.fill]=\"getOutcomeColor(conn.outcome)\" font-size=\"11\"\n font-weight=\"600\" pointer-events=\"none\">\n {{ conn.outcome }}\n </text>\n </g>\n }\n }\n } @else {\n <!-- Simple Connections (backward compatibility) -->\n @for (targetId of node.connections; track targetId) {\n @let targetNode = findNodeById(targetId);\n @if (targetNode) {\n @let sx = node.position.x + 75;\n @let sy = node.position.y + 40;\n @let tx = targetNode.position.x + 75;\n @let ty = targetNode.position.y - 50;\n @let pathD = getConnectionPath(sx, sy, tx, ty);\n <g class=\"connection-group\">\n <path [attr.d]=\"pathD\" class=\"connection-line connection-hit\" fill=\"none\" stroke=\"transparent\"\n stroke-width=\"16\" pointer-events=\"stroke\" (dblclick)=\"disconnectNodes(node.id, targetId)\">\n </path>\n <path [attr.d]=\"pathD\" class=\"connection-line\" fill=\"none\" stroke=\"#64748b\" stroke-width=\"2\"\n stroke-linecap=\"round\" marker-end=\"url(#arrowhead-default)\" pointer-events=\"none\">\n </path>\n <title>{{ '@workflow-management:workflow-studio.components.canvas-toolbar.connection-remove-hint' | translate | async }}</title>\n </g>\n }\n }\n }\n }\n\n <defs>\n <!-- Arrow markers: larger, rounded tip on line end (refX so tip touches path end) -->\n <marker id=\"arrowhead-default\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#64748b\" />\n </marker>\n <marker id=\"arrowhead-primary\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#8b5cf6\" />\n </marker>\n <marker id=\"arrowhead-success\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#10b981\" />\n </marker>\n <marker id=\"arrowhead-error\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#ef4444\" />\n </marker>\n <marker id=\"arrowhead-warning\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#f59e0b\" />\n </marker>\n <marker id=\"arrowhead-info\" markerWidth=\"12\" markerHeight=\"12\" refX=\"10\" refY=\"4\" orient=\"auto\">\n <polygon points=\"0 0, 12 4, 0 8\" fill=\"#3b82f6\" />\n </marker>\n </defs>\n </svg>\n\n <!-- Nodes -->\n @for (node of visualNodes(); track node.id) {\n <div class=\"visual-node\" [class.selected]=\"selectedNode()?.id === node.id\"\n [style.left.px]=\"node.position.x\" [style.top.px]=\"node.position.y\" [attr.data-node-id]=\"node.id\"\n draggable=\"true\" (dragstart)=\"onNodeDragStart($event, node)\" (drag)=\"onNodeDrag($event, node)\"\n (dragend)=\"onNodeDragEnd($event, node)\" (click)=\"selectNodeById(node)\">\n <div class=\"node-header\">\n <i [class]=\"node.icon\"></i>\n <span>{{ node.name }}</span>\n <span class=\"node-delete-wrap\" (click)=\"$event.stopPropagation()\">\n <ax-button look=\"blank\" size=\"sm\" class=\"node-delete\" (onClick)=\"deleteNodeFromCanvas(node.id)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </span>\n </div>\n\n <div class=\"node-body\">\n <small>{{ node.type }}</small>\n </div>\n\n <div class=\"node-connectors\">\n <!-- Input Connector -->\n <div class=\"connector connector-in\" title=\"Input\" (click)=\"onConnectorClick($event, node, 'in')\">\n </div>\n\n <!-- Output Connectors - Multiple outcomes support -->\n @if (node.outcomes && node.outcomes.length > 1) {\n <!-- Multiple outcomes: show separate port for each -->\n <div class=\"outcomes-container\">\n @for (outcome of node.outcomes; track outcome; let idx = $index) {\n <div class=\"outcome-connector\" [class.active]=\"\n connectionSource?.node?.id === node.id && connectionSource?.outcome === outcome\n \" [attr.data-outcome]=\"outcome\" [title]=\"'Output: ' + outcome\"\n (click)=\"onOutcomeConnectorClick($event, node, outcome)\">\n <span class=\"outcome-label\">{{ outcome }}</span>\n <div class=\"outcome-dot\"></div>\n </div>\n }\n </div>\n } @else {\n <!-- Single outcome: show simple output connector -->\n <div class=\"connector connector-out\" [class.active]=\"connectionSource?.node?.id === node.id\"\n title=\"Output\" (click)=\"onConnectorClick($event, node, 'out')\"></div>\n }\n </div>\n </div>\n }\n\n <!-- Empty State -->\n @if (visualNodes().length === 0) {\n <div class=\"canvas-empty-state\">\n <i class=\"fa-light fa-diagram-project\"></i>\n <p>{{ '@workflow-management:workflow-studio.components.canvas-empty-state.title' | translate | async }}</p>\n <small>{{ '@workflow-management:workflow-studio.components.canvas-empty-state.description' | translate | async }}</small>\n </div>\n }\n </div>\n </div>\n\n <!-- Workflow Panel (when no node selected, Elsa-style) -->\n @if (!selectedNode() && showPropertiesPanel()) {\n <div class=\"properties-panel workflow-panel\">\n <div class=\"properties-header\">\n <i class=\"fa-light fa-diagram-project\"></i>\n <h4>{{ '@workflow-management:workflow-studio.components.workflow-panel.title' | translate | async }}</h4>\n <div class=\"header-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close-panel' | translate | async\" (onClick)=\"togglePropertiesPanel()\">\n <ax-prefix><i class=\"fa-light fa-angle-right\"></i></ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"properties-body\">\n <section class=\"workflow-panel-section\">\n <h5>{{ '@workflow-management:workflow-studio.components.workflow-panel.metadata' | translate | async }}</h5>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.workflow-panel.name' | translate | async }}</label>\n <ax-text-box class=\"form-input\" [value]=\"workflowSettings().name\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.workflow-panel.description' | translate | async }}</label>\n <ax-text-box class=\"form-input\" [value]=\"workflowSettings().description\" [disabled]=\"true\" />\n </div>\n </section>\n <div class=\"properties-divider\"></div>\n <section class=\"workflow-panel-section\">\n <h5>{{ '@workflow-management:workflow-studio.components.workflow-panel.information' | translate | async }}</h5>\n <div class=\"workflow-info-table\">\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.definition-id' | translate | async }}</span>\n <span class=\"info-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.workflow-panel.copy' | translate | async\" (onClick)=\"copyDefinitionIdToClipboard()\">\n <ax-prefix><i class=\"fa-light fa-copy\"></i></ax-prefix>\n </ax-button>\n </span>\n <span class=\"info-value\">{{ workflowSettings().definitionId || 'new-workflow' }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.version' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().version }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.status' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().isPublished ? ('@workflow-management:workflow-studio.components.workflow-panel.published' | translate | async) : ('@workflow-management:workflow-studio.components.workflow-panel.draft' | translate | async) }}</span>\n </div>\n <div class=\"workflow-info-row\">\n <span class=\"info-label\">{{ '@workflow-management:workflow-studio.components.workflow-panel.usable-as-activity' | translate | async }}</span>\n <span class=\"info-value\">{{ workflowSettings().usableAsActivity ? ('@general:terms.common.yes-no.yes' | translate | async) : ('@general:terms.common.yes-no.no' | translate | async) }}</span>\n </div>\n </div>\n </section>\n <p class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.workflow-panel.settings-hint' | translate | async }}</p>\n </div>\n </div>\n }\n\n <!-- Properties Panel (when a node is selected) -->\n @if (selectedNode() && showPropertiesPanel()) {\n <div class=\"properties-panel\">\n <div class=\"properties-header\">\n <i class=\"fa-light fa-sliders\"></i>\n <h4>{{ '@workflow-management:workflow-studio.components.properties-panel.title' | translate | async }}</h4>\n <div class=\"header-actions\">\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close-panel' | translate | async\" (onClick)=\"togglePropertiesPanel()\">\n <ax-prefix><i class=\"fa-light fa-angle-right\"></i></ax-prefix>\n </ax-button>\n <ax-button look=\"blank\" size=\"sm\" [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.close' | translate | async\" (onClick)=\"selectedNode.set(null)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n </div>\n <div class=\"properties-body\">\n @if (propertyViewerTabs().length > 0) {\n <div class=\"properties-widget-section\">\n <axp-property-viewer\n #propertyViewerRef\n [tabsInput]=\"propertyViewerTabs()\"\n [mode]=\"'simple'\"\n (onChanged)=\"onPropertyViewerChanged($event)\">\n </axp-property-viewer>\n </div>\n } @else {\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.id' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.id\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.type' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.type\" [disabled]=\"true\" />\n </div>\n <div class=\"property-row\">\n <label>{{ '@workflow-management:workflow-studio.components.properties-panel.fields.name' | translate | async }}:</label>\n <ax-text-box class=\"form-input\" [value]=\"selectedNode()!.name\"\n (valueChange)=\"updateNodeProperty(selectedNode()!.id, 'name', $event)\" />\n </div>\n <p class=\"no-properties\">\n {{ '@workflow-management:workflow-studio.components.properties-panel.empty-states.no-properties' | translate | async }}\n </p>\n }\n\n <div class=\"properties-divider\"></div>\n\n\n <h5>\u00F0\u0178\u201D\u2014 {{ '@workflow-management:workflow-studio.components.properties-panel.sections.connections' | translate | async }}</h5>\n <small class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.properties-panel.sections.connections-hint' | translate | async }}</small>\n\n <!-- Outcome-based Connections -->\n @if (selectedNode()!.outcomeConnections && selectedNode()!.outcomeConnections!.length > 0) {\n <div class=\"connections-list\">\n @for (conn of selectedNode()!.outcomeConnections!; track conn.targetNodeId + conn.outcome) {\n @let targetNode = findNodeById(conn.targetNodeId);\n @if (targetNode) {\n <div class=\"connection-item outcome-connection\">\n <span class=\"outcome-badge\" [style.background]=\"getOutcomeColor(conn.outcome)\">\n {{ conn.outcome }}\n </span>\n <i class=\"fa-light fa-arrow-right\"></i>\n <span>{{ targetNode.name }}</span>\n <ax-button look=\"blank\" size=\"sm\" class=\"remove-btn\"\n [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.remove-connection' | translate | async\"\n (onClick)=\"disconnectNodes(selectedNode()!.id, conn.targetNodeId, conn.outcome)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n }\n }\n </div>\n } @else if (selectedNode()!.connections.length > 0) {\n <!-- Simple Connections (fallback) -->\n <div class=\"connections-list\">\n @for (targetId of selectedNode()!.connections; track targetId) {\n @let targetNode = findNodeById(targetId);\n @if (targetNode) {\n <div class=\"connection-item\">\n <i class=\"fa-light fa-arrow-right\"></i>\n <span>{{ targetNode.name }}</span>\n <ax-button look=\"blank\" size=\"sm\" class=\"remove-btn\"\n [title]=\"'@workflow-management:workflow-studio.components.properties-panel.actions.remove-connection' | translate | async\"\n (onClick)=\"disconnectNodes(selectedNode()!.id, targetId)\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n }\n }\n </div>\n } @else {\n <p class=\"no-properties\">{{ '@workflow-management:workflow-studio.components.properties-panel.empty-states.no-connections' | translate | async }}</p>\n }\n\n <!-- Available Outcomes Info -->\n @if (selectedNode()!.outcomes && selectedNode()!.outcomes!.length > 1) {\n <div class=\"properties-divider\"></div>\n <h5>\u00F0\u0178\u201C\u00A4 {{ '@workflow-management:workflow-studio.components.properties-panel.sections.available-outcomes' | translate | async }}</h5>\n <small class=\"properties-hint\">{{ '@workflow-management:workflow-studio.components.properties-panel.sections.available-outcomes-hint' | translate | async }}</small>\n <div class=\"outcomes-info\">\n @for (outcome of selectedNode()!.outcomes!; track outcome) {\n <span class=\"outcome-tag\" [style.borderColor]=\"getOutcomeColor(outcome)\">\n <span class=\"outcome-dot\" [style.background]=\"getOutcomeColor(outcome)\"></span>\n {{ outcome }}\n </span>\n }\n </div>\n }\n\n <div class=\"properties-divider\"></div>\n\n <h5>\u00F0\u0178\u201C\u009D {{ '@workflow-management:workflow-studio.components.properties-panel.sections.raw-json' | translate | async }}</h5>\n <pre class=\"properties-json\">{{ selectedNode() | json }}</pre>\n </div>\n </div>\n }\n\n <!-- Toggle Button for Properties (when closed) -->\n @if (!showPropertiesPanel()) {\n <ax-button look=\"blank\" class=\"sidebar-toggle-btn right\" (onClick)=\"togglePropertiesPanel()\"\n [title]=\"selectedNode() ? ('@workflow-management:workflow-studio.components.properties-panel.actions.show-panel' | translate | async) : ('@workflow-management:workflow-studio.components.workflow-panel.show-panel' | translate | async)\">\n <ax-prefix><i class=\"fa-light fa-sliders\"></i></ax-prefix>\n </ax-button>\n }\n </div>\n }\n </div>\n </div>\n\n </div>\n\n <!-- Workflow Settings: opened via Layout Builder dialog in openWorkflowSettings() -->\n\n <!-- Workflow Execution Dialog -->\n @if (showExecutionDialog()) {\n <div class=\"execution-dialog-overlay\" (click)=\"closeExecutionDialog()\">\n <div class=\"execution-dialog\" (click)=\"$event.stopPropagation()\">\n <!-- Dialog Header -->\n <div class=\"execution-dialog-header\">\n <div class=\"header-content\">\n <i class=\"fa-light fa-play-circle\"></i>\n <div class=\"header-info\">\n <h2>{{ '@workflow-management:test-pages.workflow-studio.actions.execute-workflow.title' | translate |\n async }}</h2>\n <p>{{ '@workflow-management:test-pages.workflow-studio.actions.execute-workflow.description' | translate\n | async }}</p>\n </div>\n </div>\n <ax-button look=\"blank\" size=\"sm\" class=\"close-btn\" [disabled]=\"isExecuting()\" (onClick)=\"closeExecutionDialog()\">\n <ax-prefix><i class=\"fa-light fa-times\"></i></ax-prefix>\n </ax-button>\n </div>\n\n <!-- Dialog Body -->\n <div class=\"execution-dialog-body\">\n <!-- Workflow Info Panel (Before Execution) -->\n @if (!workflowInstanceState()) {\n <div class=\"workflow-info-panel\">\n <div class=\"start-section\">\n <div class=\"start-illustration\">\n <i class=\"fa-light fa-rocket\"></i>\n </div>\n <h3>{{ '@workflow-management:test-pages.workflow-studio.messages.info.ready-to-execute' | translate |\n async }}</h3>\n <p>{{ '@workflow-management:test-pages.workflow-studio.messages.info.click-to-start' | translate | async\n }}</p>\n <ax-button\n [text]=\"'@workflow-management:test-pages.workflow-studio.actions.start-execution.title' | translate | async\"\n color=\"success\" size=\"lg\" (onClick)=\"startWorkflowExecution()\">\n </ax-button>\n </div>\n </div>\n }\n\n\n <!-- Custom UI for Registration -->\n @if (false) {\n <div class=\"registration-ui\">\n <div class=\"registration-card\">\n <div class=\"registration-icon\">\n <i class=\"fa-light fa-user-circle\"></i>\n </div>\n <h3>\u00D9\u0081\u00D8\u00B1\u00D8\u00A2\u00DB\u0152\u00D9\u2020\u00D8\u00AF \u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026</h3>\n <p class=\"registration-desc\">\n \u00D8\u00A7\u00DB\u0152\u00D9\u2020 \u00D9\u0081\u00D9\u201E\u00D9\u02C6 \u00D8\u00B4\u00D8\u00A7\u00D9\u2026\u00D9\u201E \u00DA\u2020\u00D9\u2020\u00D8\u00AF \u00D9\u2026\u00D8\u00B1\u00D8\u00AD\u00D9\u201E\u00D9\u2021 \u00D8\u00A7\u00D8\u00B3\u00D8\u00AA \u00DA\u00A9\u00D9\u2021 \u00D8\u00AF\u00D8\u00A7\u00D8\u00AF\u00D9\u2021\u00E2\u20AC\u0152\u00D9\u2021\u00D8\u00A7\u00DB\u0152 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1 \u00D8\u00B1\u00D8\u00A7 \u00D8\u00AC\u00D9\u2026\u00D8\u00B9\u00E2\u20AC\u0152\u00D8\u00A2\u00D9\u02C6\u00D8\u00B1\u00DB\u0152 \u00DA\u00A9\u00D8\u00B1\u00D8\u00AF\u00D9\u2021 \u00D9\u02C6 \u00D8\u00AF\u00D8\u00B1 \u00D9\u2020\u00D9\u2021\u00D8\u00A7\u00DB\u0152\u00D8\u00AA \u00D8\u00AD\u00D8\u00B3\u00D8\u00A7\u00D8\u00A8 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1\u00DB\u0152 \u00D8\u00A7\u00DB\u0152\u00D8\u00AC\u00D8\u00A7\u00D8\u00AF \u00D9\u2026\u00DB\u0152\u00E2\u20AC\u0152\u00DA\u00A9\u00D9\u2020\u00D8\u00AF.\n </p>\n\n @if (workflowInstanceState()?.status === 'running') {\n <div class=\"registration-progress\">\n <div class=\"progress-spinner\">\n <i class=\"fa-light fa-spinner-third fa-spin\"></i>\n </div>\n <p>\u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7\u00DB\u0152 \u00D9\u2026\u00D8\u00B1\u00D8\u00A7\u00D8\u00AD\u00D9\u201E \u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026...</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'finished') {\n <div class=\"registration-success\">\n <i class=\"fa-light fa-check-circle\"></i>\n <h4>\u00D8\u00AB\u00D8\u00A8\u00D8\u00AA\u00E2\u20AC\u0152\u00D9\u2020\u00D8\u00A7\u00D9\u2026 \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00A7\u00D9\u2020\u00D8\u00AC\u00D8\u00A7\u00D9\u2026 \u00D8\u00B4\u00D8\u00AF!</h4>\n <p>\u00D8\u00AD\u00D8\u00B3\u00D8\u00A7\u00D8\u00A8 \u00DA\u00A9\u00D8\u00A7\u00D8\u00B1\u00D8\u00A8\u00D8\u00B1\u00DB\u0152 \u00D8\u00B4\u00D9\u2026\u00D8\u00A7 \u00D8\u00A7\u00DB\u0152\u00D8\u00AC\u00D8\u00A7\u00D8\u00AF \u00D8\u00B4\u00D8\u00AF \u00D9\u02C6 \u00D8\u00A8\u00D9\u2021 \u00D8\u00B2\u00D9\u02C6\u00D8\u00AF\u00DB\u0152 \u00D8\u00A8\u00D9\u2021 \u00D8\u00AF\u00D8\u00A7\u00D8\u00B4\u00D8\u00A8\u00D9\u02C6\u00D8\u00B1\u00D8\u00AF \u00D9\u2026\u00D9\u2020\u00D8\u00AA\u00D9\u201A\u00D9\u201E \u00D8\u00AE\u00D9\u02C6\u00D8\u00A7\u00D9\u2021\u00DB\u0152\u00D8\u00AF \u00D8\u00B4\u00D8\u00AF.</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Default Execution View -->\n @if (workflowInstanceState()) {\n <div class=\"default-execution-view\">\n <div class=\"execution-status\">\n @if (workflowInstanceState()?.status === 'running') {\n <div class=\"status-running\">\n <i class=\"fa-light fa-spinner-third fa-spin\"></i>\n <h3>\u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7...</h3>\n <p>Workflow \u00D8\u00AF\u00D8\u00B1 \u00D8\u00AD\u00D8\u00A7\u00D9\u201E \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00A7\u00D8\u00B3\u00D8\u00AA. \u00D9\u201E\u00D8\u00B7\u00D9\u0081\u00D8\u00A7\u00D9\u2039 \u00D8\u00B5\u00D8\u00A8\u00D8\u00B1 \u00DA\u00A9\u00D9\u2020\u00DB\u0152\u00D8\u00AF.</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'finished') {\n <div class=\"status-finished\">\n <i class=\"fa-light fa-check-circle\"></i>\n <h3>\u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00AA\u00DA\u00A9\u00D9\u2026\u00DB\u0152\u00D9\u201E \u00D8\u00B4\u00D8\u00AF</h3>\n <p>Workflow \u00D8\u00A8\u00D8\u00A7 \u00D9\u2026\u00D9\u02C6\u00D9\u0081\u00D9\u201A\u00DB\u0152\u00D8\u00AA \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7 \u00D8\u00B4\u00D8\u00AF \u00D9\u02C6 \u00D8\u00AA\u00D9\u2026\u00D8\u00A7\u00D9\u2026 Activities \u00D8\u00A7\u00D9\u2020\u00D8\u00AC\u00D8\u00A7\u00D9\u2026 \u00D8\u00B4\u00D8\u00AF\u00D9\u2020\u00D8\u00AF.</p>\n </div>\n }\n\n @if (workflowInstanceState()?.status === 'error') {\n <div class=\"status-error\">\n <i class=\"fa-light fa-times-circle\"></i>\n <h3>\u00D8\u00AE\u00D8\u00B7\u00D8\u00A7 \u00D8\u00AF\u00D8\u00B1 \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7</h3>\n <p>{{ workflowInstanceState()?.error }}</p>\n </div>\n }\n </div>\n </div>\n }\n\n <!-- Execution Logs Panel -->\n @if (workflowInstanceState() && executionLogs().length > 0) {\n <div class=\"execution-logs-panel\">\n <h3><i class=\"fa-light fa-terminal\"></i> \u00D9\u201E\u00D8\u00A7\u00DA\u00AF\u00E2\u20AC\u0152\u00D9\u2021\u00D8\u00A7\u00DB\u0152 \u00D8\u00A7\u00D8\u00AC\u00D8\u00B1\u00D8\u00A7</h3>\n <div class=\"logs-container-compact\">\n @for (log of executionLogs(); track $index) {\n <div class=\"log-item-compact\" [class]=\"'log-' + log.level\">\n <span class=\"log-time\">{{ log.timestamp | date: 'HH:mm:ss' }}</span>\n <span class=\"log-icon\">\n @switch (log.level) {\n @case ('info') {\n <i class=\"fa-light fa-info-circle\"></i>\n }\n @case ('success') {\n <i class=\"fa-light fa-check-circle\"></i>\n }\n @case ('warning') {\n <i class=\"fa-light fa-exclamation-triangle\"></i>\n }\n @case ('error') {\n <i class=\"fa-light fa-times-circle\"></i>\n }\n }\n </span>\n <span class=\"log-message\">{{ log.message }}</span>\n </div>\n }\n </div>\n </div>\n }\n </div>\n\n <!-- Dialog Footer -->\n <div class=\"execution-dialog-footer\">\n <div class=\"footer-info\">\n @if (workflowInstanceState()?.startTime) {\n <span class=\"time-info\">\n <i class=\"fa-light fa-clock\"></i>\n \u00D8\u00B4\u00D8\u00B1\u00D9\u02C6\u00D8\u00B9: {{ workflowInstanceState()!.startTime | date: 'HH:mm:ss' }}\n </span>\n }\n @if (workflowInstanceState()?.endTime) {\n <span class=\"time-info\">\n <i class=\"fa-light fa-flag-checkered\"></i>\n \u00D9\u00BE\u00D8\u00A7\u00DB\u0152\u00D8\u00A7\u00D9\u2020: {{ workflowInstanceState()!.endTime | date: 'HH:mm:ss' }}\n </span>\n }\n </div>\n <div class=\"footer-actions\">\n <ax-button\n [text]=\"(workflowInstanceState() ? '@general:actions.close.title' : '@general:actions.cancel.title') | translate | async\"\n color=\"secondary\" size=\"md\" [disabled]=\"isExecuting()\" (onClick)=\"closeExecutionDialog()\">\n </ax-button>\n </div>\n </div>\n </div>\n </div>\n }\n </div>\n </axp-page-content>\n</axp-page-layout>\n", styles: [".sidebar-header .toggle-btn{padding:.5rem;margin-left:auto;background:transparent;border:1px solid #e2e8f0;border-radius:6px;color:#64748b;cursor:pointer;transition:all .2s}.sidebar-header .toggle-btn:hover{background:#f8fafc;border-color:#8b5cf6;color:#8b5cf6}.sidebar-header .toggle-btn i{font-size:.875rem}.sidebar-toggle-btn{position:absolute;top:50%;transform:translateY(-50%);z-index:100;padding:1rem .5rem;background:#fff;border:1px solid #e2e8f0;border-radius:8px;color:#8b5cf6;cursor:pointer;box-shadow:0 4px 12px #0000001a;transition:all .3s}.sidebar-toggle-btn:hover{background:#8b5cf6;color:#fff;box-shadow:0 8px 24px #8b5cf64d;transform:translateY(-50%) scale(1.1)}.sidebar-toggle-btn.left{left:0;border-left:none;border-radius:0 8px 8px 0}.sidebar-toggle-btn.right{right:0;border-right:none;border-radius:8px 0 0 8px}.sidebar-toggle-btn i{font-size:1.25rem;display:block}.properties-header .header-actions{display:flex;gap:.5rem;margin-left:auto}.properties-header .header-btn{padding:.375rem .5rem;background:transparent;border:1px solid #e2e8f0;border-radius:4px;color:#64748b;cursor:pointer;transition:all .2s}.properties-header .header-btn:hover{background:#f8fafc;border-color:#8b5cf6;color:#8b5cf6}.properties-header .header-btn i{font-size:.75rem}.connections-list{margin-top:.75rem}.connection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;margin-bottom:.5rem;font-size:.875rem}.connection-item i{color:#8b5cf6}.connection-item span{flex:1;color:#1e293b}.connection-item .remove-btn{padding:.25rem .375rem;background:transparent;border:1px solid #e2e8f0;border-radius:4px;color:#ef4444;cursor:pointer;transition:all .2s}.connection-item .remove-btn:hover{background:#fef2f2;border-color:#ef4444}.connection-item .remove-btn i{font-size:.75rem;color:inherit}.property-editor{margin-top:.75rem}.property-editor .property-row label{display:flex;align-items:center;gap:.5rem;justify-content:space-between}.property-editor .property-row label .property-type-badge{padding:.125rem .375rem;background:#f1f5f9;border:1px solid #e2e8f0;border-radius:4px;font-size:.625rem;font-weight:400;color:#64748b;text-transform:lowercase;font-family:JetBrains Mono,monospace}.property-editor .property-row select{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;background:#fff;cursor:pointer;transition:all .2s}.property-editor .property-row select:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.property-editor .property-row textarea{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.75rem;font-family:JetBrains Mono,monospace;color:#1e293b;resize:vertical;transition:all .2s}.property-editor .property-row textarea:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.workflow-studio{display:flex;flex-direction:column;height:100vh;background:#f8fafc;overflow:hidden}.studio-editor-tabs ax-button-group-item[selected],.studio-editor-tabs ax-button-group-item.ax-selected{font-weight:600;opacity:1}.workflow-popup .popup-header{text-align:center;margin-bottom:1.5rem;padding-bottom:1rem;border-bottom:2px solid #e2e8f0}.workflow-popup .popup-header h3{margin:0 0 .5rem;color:#1e293b;font-size:1.5rem;font-weight:700}.workflow-popup .popup-header p{margin:0;color:#64748b;font-size:.95rem}.workflow-popup .popup-body{max-height:60vh;overflow-y:auto;padding:0 .5rem}.workflow-popup .popup-body h4{margin:1.5rem 0 .75rem;color:#374151;font-size:1.1rem;font-weight:600;display:flex;align-items:center;gap:.5rem}.workflow-popup .popup-body ul{margin:0;padding-left:1.5rem}.workflow-popup .popup-body ul li{margin-bottom:.5rem;color:#4b5563}.workflow-popup .popup-body ul li strong{color:#1f2937}.workflow-popup .workflow-info{background:#f8fafc;padding:1rem;border-radius:8px;border:1px solid #e2e8f0}.workflow-popup .workflow-variables{background:#fef3c7;padding:1rem;border-radius:8px;border:1px solid #f59e0b}.workflow-popup .workflow-flow{background:#ecfdf5;padding:1rem;border-radius:8px;border:1px solid #10b981}.workflow-popup .workflow-flow .flow-steps{display:flex;flex-direction:column;gap:.75rem}.workflow-popup .workflow-flow .flow-steps .flow-step{display:flex;align-items:center;gap:.75rem;padding:.5rem;background:#fff;border-radius:6px;border:1px solid #d1d5db}.workflow-popup .workflow-flow .flow-steps .flow-step .step-number{display:flex;align-items:center;justify-content:center;width:24px;height:24px;background:#3b82f6;color:#fff;border-radius:50%;font-size:.8rem;font-weight:600}.workflow-popup .workflow-flow .flow-steps .flow-step .step-text{color:#374151;font-weight:500}.workflow-popup .workflow-json{background:#1f2937;padding:1rem;border-radius:8px;border:1px solid #374151}.workflow-popup .workflow-json .json-preview{background:transparent;color:#e5e7eb;font-family:Monaco,Menlo,Ubuntu Mono,monospace;font-size:.8rem;line-height:1.4;margin:0;white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto}.workflow-popup .popup-footer{text-align:center;margin-top:1.5rem;padding-top:1rem;border-top:1px solid #e2e8f0}.workflow-popup .popup-footer .btn{padding:.75rem 1.5rem;background:#3b82f6;color:#fff;border:none;border-radius:6px;font-weight:600;cursor:pointer;display:inline-flex;align-items:center;gap:.5rem;transition:background-color .2s}.workflow-popup .popup-footer .btn:hover{background:#2563eb}.workflow-popup .popup-footer .btn i{font-size:.9rem}.view-workflow-link{color:#3b82f6;text-decoration:none;font-size:.85rem;margin-left:.5rem;transition:color .2s}.view-workflow-link:hover{color:#1d4ed8;text-decoration:underline}.studio-header{display:flex;justify-content:space-between;align-items:center;padding:1rem 1.5rem;background:#fff;border-bottom:1px solid #e2e8f0;box-shadow:0 1px 3px #0000000d}.studio-header .header-title{display:flex;align-items:center;gap:.75rem}.studio-header .header-title i{font-size:1.75rem;color:#8b5cf6}.studio-header .header-title h1{margin:0;font-size:1.5rem;font-weight:700;color:#1e293b}.studio-header .header-title .badge{padding:.25rem .75rem;background:#8b5cf6;color:#fff;border-radius:12px;font-size:.75rem;font-weight:600}.studio-header .header-actions{display:flex;gap:.75rem;align-items:center}.samples-dropdown{position:relative}.samples-dropdown .samples-menu{position:absolute;top:calc(100% + .5rem);left:0;min-width:320px;background:#fff;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 10px 25px #0000001a;z-index:1000;max-height:400px;overflow-y:auto}.samples-dropdown .samples-menu .sample-item{padding:.875rem 1rem;display:flex;align-items:flex-start;gap:.75rem;cursor:pointer;border-bottom:1px solid #f1f5f9;transition:all .2s}.samples-dropdown .samples-menu .sample-item:last-child{border-bottom:none}.samples-dropdown .samples-menu .sample-item:hover{background:#f8fafc;transform:translate(4px)}.samples-dropdown .samples-menu .sample-item i{font-size:1.25rem;margin-top:.125rem;color:#8b5cf6}.samples-dropdown .samples-menu .sample-item .sample-info{display:flex;flex-direction:column;gap:.25rem;flex:1}.samples-dropdown .samples-menu .sample-item .sample-info strong{color:#1e293b;font-size:.875rem;font-weight:600}.samples-dropdown .samples-menu .sample-item .sample-info span{color:#64748b;font-size:.75rem;line-height:1.4}.studio-body{display:grid;grid-template-columns:1fr;gap:0;flex:1;overflow:hidden;transition:grid-template-columns .3s ease}.studio-body.sidebar-hidden,.studio-body.properties-hidden,.studio-body.sidebar-hidden.properties-hidden{grid-template-columns:1fr}.studio-sidebar{background:#fff;border-right:1px solid #e2e8f0;display:flex;flex-direction:column;overflow:hidden}.studio-sidebar .sidebar-header{padding:1rem 1.25rem;border-bottom:1px solid #e2e8f0;display:flex;align-items:center;gap:.5rem}.studio-sidebar .sidebar-header i{font-size:1.25rem;color:#8b5cf6}.studio-sidebar .sidebar-header h3{flex:1;margin:0;font-size:1.125rem;font-weight:600;color:#1e293b}.activities-tree{flex:1;overflow-y:auto;padding:.5rem}.category-section{margin-bottom:.5rem}.category-section .category-header{display:flex;align-items:center;gap:.5rem;padding:.75rem;border-radius:8px;cursor:pointer;transition:all .2s;background:#f8fafc}.category-section .category-header:hover{background:#f1f5f9}.category-section .category-header.active{background:#ede9fe}.category-section .category-header.active>i:first-child{color:#8b5cf6}.category-section .category-header>i:first-child{font-size:.875rem;color:#94a3b8;transition:transform .2s,color .2s}.category-section .category-header>i:nth-child(2){font-size:1.125rem}.category-section .category-header span{flex:1;font-weight:600;font-size:.875rem;color:#334155}.category-section .category-header .count{flex:none;padding:.125rem .5rem;background:#fff;border-radius:10px;font-size:.75rem;font-weight:600;color:#64748b;border:1px solid #e2e8f0}.activities-list{padding:.5rem 0 .5rem 1.5rem;display:flex;flex-direction:column;gap:.5rem;animation:slideDown .3s ease}.activities-list .activities-header{padding:.5rem .75rem;margin-bottom:.5rem}.activities-list .activities-header h4{margin:0;font-size:.875rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.activity-card{background:#fff;border:1px solid #e2e8f0;border-radius:8px;padding:.875rem;margin-bottom:.75rem;transition:all .2s}.activity-card:hover{border-color:#8b5cf6;box-shadow:0 4px 12px #8b5cf61a;transform:translateY(-1px)}.activity-card .activity-info{display:flex;align-items:flex-start;gap:.75rem;margin-bottom:.5rem}.activity-card .activity-info>i{font-size:1.5rem;color:#8b5cf6;margin-top:.125rem}.activity-card .activity-info .activity-details{flex:1;display:flex;flex-direction:column;gap:.25rem}.activity-card .activity-info .activity-details strong{font-size:.875rem;color:#1e293b}.activity-card .activity-info .activity-details small{font-size:.75rem;color:#64748b;line-height:1.4}.activity-card .activity-info .activity-details code{font-size:.75rem;color:#8b5cf6;background:#f3f0ff;padding:.125rem .375rem;border-radius:4px;width:fit-content}.activity-card .copy-btn{float:right;padding:.375rem .75rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;cursor:pointer;transition:all .2s;color:#64748b}.activity-card .copy-btn:hover{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.activity-card .copy-btn i{font-size:.875rem}.activity-card .activity-properties{margin-top:.75rem;padding-top:.75rem;border-top:1px solid #f1f5f9}.activity-card .activity-properties .properties-title{display:block;font-size:.75rem;font-weight:600;color:#64748b;margin-bottom:.5rem}.activity-card .activity-properties .property-item{display:flex;align-items:center;gap:.5rem;padding:.25rem 0;font-size:.75rem}.activity-card .activity-properties .property-item code{color:#1e293b;background:#f8fafc;padding:.125rem .375rem;border-radius:3px}.activity-card .activity-properties .property-item .property-type{color:#64748b;font-style:italic}.activity-card .activity-properties .property-item .required{color:#ef4444;font-weight:700}.studio-editor{display:flex;flex-direction:column;background:#1e293b;overflow:hidden}.studio-editor .editor-header{padding:1rem 1.25rem;background:#0f172a;display:flex;align-items:center;gap:.5rem}.studio-editor .editor-header i{font-size:1.125rem;color:#8b5cf6}.studio-editor .editor-header h3{margin:0;font-size:1rem;font-weight:600;color:#e2e8f0}.studio-editor axp-page-toolbar .editor-tabs{display:flex;gap:.5rem;background:transparent}.studio-editor axp-page-toolbar .editor-tabs .tab-btn{padding:.5rem 1rem;background:transparent;border:1px solid #e2e8f0;border-radius:6px;color:#64748b;font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s;display:flex;align-items:center;justify-content:center;gap:.5rem}.studio-editor axp-page-toolbar .editor-tabs .tab-btn i{font-size:.875rem}.studio-editor axp-page-toolbar .editor-tabs .tab-btn:hover{background:#f8fafc;border-color:#cbd5e1;color:#475569}.studio-editor axp-page-toolbar .editor-tabs .tab-btn.active{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.studio-editor .editor-content{flex:1;display:flex;overflow:hidden}.studio-editor .json-tab{flex:1;display:flex;flex-direction:column}.studio-editor .json-editor{flex:1;padding:1.5rem;background:#1e293b;color:#e2e8f0;border:none;outline:none;font-family:JetBrains Mono,Fira Code,Consolas,monospace;font-size:.875rem;line-height:1.6;resize:none;overflow:auto}.studio-editor .json-editor::placeholder{color:#475569}.studio-editor .json-editor::-webkit-scrollbar{width:10px;height:10px}.studio-editor .json-editor::-webkit-scrollbar-track{background:#0f172a}.studio-editor .json-editor::-webkit-scrollbar-thumb{background:#475569;border-radius:5px}.studio-editor .json-editor::-webkit-scrollbar-thumb:hover{background:#64748b}.studio-editor .visual-tab{flex:1;display:flex;background:#f8fafc;position:relative}.studio-editor .visual-canvas{flex:1;display:flex;flex-direction:column;overflow:hidden}.studio-editor .visual-canvas .canvas-toolbar{display:flex;align-items:center;gap:.75rem;padding:.75rem 1rem;background:var(--ax-surface, white);border-bottom:1px solid var(--ax-border, #e2e8f0)}.studio-editor .visual-canvas .canvas-toolbar .tool-btn{padding:.5rem .75rem;background:var(--ax-surface-alt, #f8fafc);border:1px solid var(--ax-border, #e2e8f0);border-radius:6px;color:var(--ax-text-muted, #64748b);cursor:pointer;transition:all .2s}.studio-editor .visual-canvas .canvas-toolbar .tool-btn:hover{background:#8b5cf6;border-color:#8b5cf6;color:#fff}.studio-editor .visual-canvas .canvas-toolbar .tool-btn i{font-size:.875rem}.studio-editor .visual-canvas .canvas-toolbar .toolbar-sep{width:1px;height:1.25rem;background:var(--ax-border, #e2e8f0);flex-shrink:0}.studio-editor .visual-canvas .canvas-toolbar .toolbar-auto-save{display:flex;align-items:center;gap:.5rem;font-size:.8125rem;color:var(--ax-text-muted, #64748b);cursor:default}.studio-editor .visual-canvas .canvas-toolbar .toolbar-auto-save ax-switch{flex-shrink:0}.studio-editor .visual-canvas .canvas-toolbar .tool-info{flex:1;display:flex;align-items:center;gap:.5rem;min-height:1.75rem;font-size:.8125rem;color:var(--ax-text-muted, #64748b);line-height:1.4}.studio-editor .visual-canvas .canvas-toolbar .tool-info strong{font-weight:600}.studio-editor .visual-canvas .canvas-toolbar .tool-info i{font-size:1rem;color:#8b5cf6;flex-shrink:0}.studio-editor .visual-canvas .canvas-area{flex:1;position:relative;background:linear-gradient(90deg,#e5e7eb 1px,transparent 1px),linear-gradient(#e5e7eb 1px,transparent 1px);background-size:20px 20px;overflow:auto;min-height:600px}.studio-editor .visual-canvas .connections-layer{position:absolute;top:0;left:0;width:100%;height:100%;pointer-events:none;z-index:1}.studio-editor .visual-canvas .connection-line{fill:none;transition:stroke .2s}.studio-editor .visual-canvas .connection-line.connection-hit{stroke:transparent;stroke-width:16;cursor:pointer;pointer-events:stroke}.studio-editor .visual-canvas .connection-line.connection-hit:hover~.outcome-line,.studio-editor .visual-canvas .connection-line.connection-hit:hover~.connection-line:not(.connection-hit){filter:brightness(.9)}.studio-editor .visual-canvas .connection-line:not(.connection-hit){stroke-linecap:round;pointer-events:none}.studio-editor .visual-canvas .connection-line.outcome-line{stroke-width:2.5}.studio-editor .visual-canvas .visual-node{position:absolute;width:150px;background:#fff;border:2px solid #e2e8f0;border-radius:8px;box-shadow:0 2px 8px #0000001a;cursor:move;transition:all .2s;z-index:2}.studio-editor .visual-canvas .visual-node:hover{border-color:#8b5cf6;box-shadow:0 4px 16px #8b5cf633;transform:translateY(-2px)}.studio-editor .visual-canvas .visual-node.selected{border-color:#8b5cf6;border-width:3px;box-shadow:0 0 0 3px #8b5cf633}.studio-editor .visual-canvas .visual-node .node-header{display:flex;align-items:center;gap:.5rem;padding:.75rem;background:linear-gradient(135deg,#8b5cf6,#7c3aed);color:#fff;border-radius:6px 6px 0 0;font-size:.875rem;font-weight:600}.studio-editor .visual-canvas .visual-node .node-header i{font-size:1rem}.studio-editor .visual-canvas .visual-node .node-header span{flex:1;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.studio-editor .visual-canvas .visual-node .node-header .node-delete{padding:.25rem;background:#fff3;border:none;border-radius:4px;color:#fff;cursor:pointer;transition:all .2s}.studio-editor .visual-canvas .visual-node .node-header .node-delete:hover{background:#ef4444cc}.studio-editor .visual-canvas .visual-node .node-header .node-delete i{font-size:.75rem}.studio-editor .visual-canvas .visual-node .node-body{padding:.75rem}.studio-editor .visual-canvas .visual-node .node-body small{display:block;font-size:.75rem;color:#64748b;text-align:center}.studio-editor .visual-canvas .visual-node .node-connectors{position:relative}.studio-editor .visual-canvas .visual-node .node-connectors .connector{position:absolute;width:12px;height:12px;background:#8b5cf6;border:2px solid white;border-radius:50%;cursor:pointer;transition:all .2s;z-index:10}.studio-editor .visual-canvas .visual-node .node-connectors .connector:hover{transform:scale(1.3);box-shadow:0 0 0 3px #8b5cf64d}.studio-editor .visual-canvas .visual-node .node-connectors .connector-in{top:-50px;left:50%;transform:translate(-50%);background:#3b82f6}.studio-editor .visual-canvas .visual-node .node-connectors .connector-out{bottom:-6px;left:50%;transform:translate(-50%);background:#8b5cf6}.studio-editor .visual-canvas .visual-node .node-connectors .connector-out.active{background:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcomes-container{position:absolute;bottom:-60px;left:50%;transform:translate(-50%);display:flex;flex-direction:column;gap:8px;background:#fff;padding:8px;border:1px solid #e2e8f0;border-radius:8px;box-shadow:0 4px 12px #00000026;min-width:120px;z-index:100}.studio-editor .visual-canvas .visual-node .node-connectors .outcomes-container:before{content:\"\";position:absolute;top:-8px;left:50%;transform:translate(-50%);width:0;height:0;border-left:8px solid transparent;border-right:8px solid transparent;border-bottom:8px solid white;filter:drop-shadow(0 -2px 2px rgba(0,0,0,.05))}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector{display:flex;align-items:center;justify-content:space-between;padding:6px 10px;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;cursor:pointer;transition:all .2s;position:relative}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector:hover{background:#f1f5f9;border-color:#8b5cf6;transform:translate(2px)}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector.active{background:#fef2f2;border-color:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector.active .outcome-dot{background:#ef4444;box-shadow:0 0 0 3px #ef444433}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector .outcome-label{font-size:.75rem;font-weight:600;color:#475569;-webkit-user-select:none;user-select:none;flex:1}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector .outcome-dot{width:10px;height:10px;background:#8b5cf6;border:2px solid white;border-radius:50%;transition:all .2s;flex-shrink:0}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=\"200\"] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Done] .outcome-dot{background:#10b981}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=\"404\"] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Failed] .outcome-dot{background:#ef4444}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Timeout] .outcome-dot,.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Cancelled] .outcome-dot{background:#f59e0b}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Then] .outcome-dot{background:#3b82f6}.studio-editor .visual-canvas .visual-node .node-connectors .outcome-connector[data-outcome=Else] .outcome-dot{background:#64748b}.studio-editor .visual-canvas .canvas-empty-state{position:absolute;top:50%;left:50%;transform:translate(-50%,-50%);text-align:center;color:#94a3b8;pointer-events:none}.studio-editor .visual-canvas .canvas-empty-state i{font-size:4rem;margin-bottom:1rem;opacity:.5}.studio-editor .visual-canvas .canvas-empty-state p{margin:0 0 .5rem;font-size:1rem;font-weight:500}.studio-editor .visual-canvas .canvas-empty-state small{font-size:.875rem;opacity:.8}.studio-editor .properties-panel{width:280px;background:#fff;border-left:1px solid #e2e8f0;display:flex;flex-direction:column}.studio-editor .properties-panel .properties-header{display:flex;align-items:center;gap:.5rem;padding:1rem;border-bottom:1px solid #e2e8f0}.studio-editor .properties-panel .properties-header i{font-size:1.125rem;color:#8b5cf6}.studio-editor .properties-panel .properties-header h4{flex:1;margin:0;font-size:.875rem;font-weight:600;color:#1e293b}.studio-editor .properties-panel .properties-header button{padding:.25rem .5rem;background:transparent;border:none;color:#64748b;cursor:pointer;transition:color .2s}.studio-editor .properties-panel .properties-header button:hover{color:#ef4444}.studio-editor .properties-panel .properties-body{flex:1;padding:1rem;overflow-y:auto}.studio-editor .properties-panel .properties-body .properties-widget-section{min-height:0}.studio-editor .properties-panel .properties-body .workflow-panel-section{margin-bottom:1.5rem}.studio-editor .properties-panel .properties-body .workflow-panel-section h5{margin:0 0 .75rem;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group{margin-bottom:.75rem}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group label{font-size:.75rem}.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group input,.studio-editor .properties-panel .properties-body .workflow-panel-section .form-group textarea{font-size:.8125rem}.studio-editor .properties-panel .properties-body .workflow-info-table{display:flex;flex-direction:column;gap:.5rem}.studio-editor .properties-panel .properties-body .workflow-info-row{display:flex;align-items:center;justify-content:space-between;gap:.75rem;padding:.5rem 0;border-bottom:1px solid #f1f5f9}.studio-editor .properties-panel .properties-body .workflow-info-row:last-child{border-bottom:none}.studio-editor .properties-panel .properties-body .info-label{font-size:.8125rem;font-weight:500;color:#64748b;flex-shrink:0}.studio-editor .properties-panel .properties-body .info-value{font-size:.8125rem;color:#1e293b;text-align:right;word-break:break-all}.studio-editor .properties-panel .properties-body .info-actions{display:flex;align-items:center;gap:.5rem}.studio-editor .properties-panel .properties-body .property-row{margin-bottom:1rem}.studio-editor .properties-panel .properties-body .property-row label{display:block;font-size:.75rem;font-weight:600;color:#64748b;margin-bottom:.375rem;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .property-row input{width:100%;padding:.5rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;transition:all .2s}.studio-editor .properties-panel .properties-body .property-row input:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.studio-editor .properties-panel .properties-body .property-row input:disabled{background:#f8fafc;color:#94a3b8;cursor:not-allowed}.studio-editor .properties-panel .properties-body .properties-divider{height:1px;background:#e2e8f0;margin:1.5rem 0}.studio-editor .properties-panel .properties-body h5{margin:0 0 .5rem;font-size:.75rem;font-weight:600;color:#64748b;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .properties-hint{display:block;font-size:.75rem;color:#94a3b8;margin-bottom:.75rem}.studio-editor .properties-panel .properties-body .properties-json{margin:.75rem 0 0;padding:.75rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;color:#1e293b;overflow-x:auto}.studio-editor .properties-panel .properties-body .no-properties{margin:.75rem 0 0;padding:1rem;background:#f8fafc;border:1px dashed #cbd5e1;border-radius:6px;text-align:center;font-size:.75rem;color:#94a3b8}.studio-editor .properties-panel .properties-body .connections-list{display:flex;flex-direction:column;gap:.5rem;margin-top:.75rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item{display:flex;align-items:center;gap:.5rem;padding:.5rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:6px;font-size:.75rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item.outcome-connection{border-left-width:3px}.studio-editor .properties-panel .properties-body .connections-list .connection-item i{color:#64748b;font-size:.875rem}.studio-editor .properties-panel .properties-body .connections-list .connection-item span{flex:1;color:#1e293b;font-weight:500}.studio-editor .properties-panel .properties-body .connections-list .connection-item .outcome-badge{padding:.25rem .5rem;border-radius:4px;color:#fff;font-size:.65rem;font-weight:700;text-transform:uppercase;letter-spacing:.5px}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn{padding:.25rem;background:transparent;border:none;color:#ef4444;cursor:pointer;border-radius:4px;transition:all .2s}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn:hover{background:#fee2e2}.studio-editor .properties-panel .properties-body .connections-list .connection-item .remove-btn i{font-size:.75rem;color:inherit}.studio-editor .properties-panel .properties-body .outcomes-info{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag{display:inline-flex;align-items:center;gap:.375rem;padding:.375rem .625rem;background:#fff;border:2px solid;border-radius:6px;font-size:.75rem;font-weight:600;color:#1e293b;transition:all .2s}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag:hover{transform:translateY(-1px);box-shadow:0 2px 8px #0000001a}.studio-editor .properties-panel .properties-body .outcomes-info .outcome-tag .outcome-dot{width:8px;height:8px;border-radius:50%}.studio-result{display:flex;flex-direction:column;background:#fff;border-left:1px solid #e2e8f0;overflow:hidden}.studio-result .result-header{padding:1rem 1.25rem;border-bottom:1px solid #e2e8f0;display:flex;align-items:center;gap:.5rem}.studio-result .result-header i{font-size:1.125rem;color:#10b981}.studio-result .result-header h3{flex:1;margin:0;font-size:1rem;font-weight:600;color:#1e293b}.studio-result .result-header .clear-btn{padding:.375rem .75rem;background:#fee2e2;color:#dc2626;border:none;border-radius:6px;cursor:pointer;font-size:.75rem;font-weight:500;transition:all .2s}.studio-result .result-header .clear-btn:hover{background:#fecaca}.studio-result .result-header .clear-btn i{font-size:.75rem;color:inherit}.studio-result .result-body{flex:1;overflow-y:auto;padding:1rem}.logs-container{display:flex;flex-direction:column;gap:.5rem}.log-item{display:flex;align-items:flex-start;gap:.5rem;padding:.75rem;background:#f8fafc;border-left:3px solid #cbd5e1;border-radius:6px;font-size:.875rem}.log-item.log-info{border-left-color:#3b82f6;background:#eff6ff}.log-item.log-info .log-icon{color:#3b82f6}.log-item.log-success{border-left-color:#10b981;background:#f0fdf4}.log-item.log-success .log-icon{color:#10b981}.log-item.log-warning{border-left-color:#f59e0b;background:#fffbeb}.log-item.log-warning .log-icon{color:#f59e0b}.log-item.log-error{border-left-color:#ef4444;background:#fef2f2}.log-item.log-error .log-icon{color:#ef4444}.log-item .log-time{font-family:JetBrains Mono,monospace;font-size:.75rem;color:#64748b;min-width:80px}.log-item .log-icon{font-size:1rem}.log-item .log-message{flex:1;color:#1e293b}.log-item .log-data-toggle{padding:.25rem .5rem;background:transparent;border:1px solid #cbd5e1;border-radius:4px;cursor:pointer;transition:all .2s}.log-item .log-data-toggle:hover{background:#fff}.log-item .log-data-toggle i{font-size:.75rem;color:#64748b}.log-data{margin:.5rem 0 0;padding:1rem;background:#0f172a;color:#e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;overflow-x:auto}.settings-modal-overlay{position:fixed;inset:0;background:#00000080;display:flex;align-items:center;justify-content:center;z-index:9999;padding:2rem;animation:fadeIn .2s ease}.settings-modal{background:#fff;border-radius:12px;box-shadow:0 20px 60px #0000004d;width:100%;max-width:900px;max-height:90vh;display:flex;flex-direction:column;animation:slideUp .3s ease}@keyframes slideUp{0%{transform:translateY(20px);opacity:0}to{transform:translateY(0);opacity:1}}.settings-modal-header{display:flex;align-items:center;justify-content:space-between;padding:1.5rem 2rem;border-bottom:1px solid #e2e8f0}.settings-modal-header .header-title{display:flex;align-items:center;gap:.75rem}.settings-modal-header .header-title i{font-size:1.5rem;color:#8b5cf6}.settings-modal-header .header-title h2{margin:0;font-size:1.25rem;font-weight:700;color:#1e293b}.settings-modal-header .close-btn{padding:.5rem;background:transparent;border:none;color:#64748b;cursor:pointer;border-radius:6px;transition:all .2s}.settings-modal-header .close-btn:hover{background:#f1f5f9;color:#ef4444}.settings-modal-header .close-btn i{font-size:1.25rem}.settings-modal-body{flex:1;display:flex;flex-direction:column;overflow:hidden}.settings-tabs{padding:0 1.5rem}.settings-content{flex:1;overflow-y:auto;padding:2rem}.settings-section h3{margin:0 0 1.5rem;font-size:1rem;font-weight:600;color:#1e293b}.settings-section .section-header{display:flex;align-items:center;justify-content:space-between;margin-bottom:1.5rem}.settings-section .section-header h3{margin:0}.settings-section .section-header .add-btn{display:flex;align-items:center;gap:.5rem;padding:.5rem 1rem;background:#8b5cf6;color:#fff;border:none;border-radius:6px;font-size:.875rem;font-weight:500;cursor:pointer;transition:all .2s}.settings-section .section-header .add-btn:hover{background:#7c3aed;transform:translateY(-1px);box-shadow:0 4px 12px #8b5cf64d}.settings-section .section-header .add-btn i{font-size:.875rem}.form-group{margin-bottom:1.25rem}.form-group label{display:block;font-size:.875rem;font-weight:600;color:#475569;margin-bottom:.5rem}.form-group small{display:block;font-size:.75rem;color:#94a3b8;margin-top:.375rem}.form-group.checkbox-group{margin-bottom:0}.form-group.checkbox-group label{display:flex;align-items:center;gap:.5rem;cursor:pointer;margin-bottom:0}.form-group.checkbox-group label input[type=checkbox]{width:18px;height:18px;cursor:pointer}.form-group.checkbox-group label span{font-size:.875rem;font-weight:500}.form-group.flex-1{flex:1}.form-row{display:flex;gap:1rem;align-items:flex-start}.form-input,.form-select,.form-textarea{width:100%;padding:.625rem;border:1px solid #e2e8f0;border-radius:6px;font-size:.875rem;color:#1e293b;transition:all .2s}.form-input:focus,.form-select:focus,.form-textarea:focus{outline:none;border-color:#8b5cf6;box-shadow:0 0 0 3px #8b5cf61a}.form-input::placeholder,.form-select::placeholder,.form-textarea::placeholder{color:#cbd5e1}.form-textarea{resize:vertical;font-family:inherit}.items-list{display:flex;flex-direction:column;gap:1rem}.item-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;overflow:hidden;transition:all .2s}.item-card:hover{border-color:#cbd5e1;box-shadow:0 2px 8px #0000000d}.item-card .item-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem 1rem;background:#f1f5f9;border-bottom:1px solid #e2e8f0}.item-card .item-header .item-number{font-size:.75rem;font-weight:700;color:#8b5cf6;padding:.25rem .5rem;background:#fff;border-radius:4px}.item-card .item-header .remove-btn{padding:.375rem .625rem;background:transparent;border:none;color:#ef4444;cursor:pointer;border-radius:4px;transition:all .2s}.item-card .item-header .remove-btn:hover{background:#fee2e2}.item-card .item-header .remove-btn i{font-size:.875rem}.item-card .item-body{padding:1rem}.advanced-group{margin-bottom:2rem;padding-bottom:2rem;border-bottom:1px solid #e2e8f0}.advanced-group:last-child{border-bottom:none;margin-bottom:0;padding-bottom:0}.advanced-group h4{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#475569;text-transform:uppercase;letter-spacing:.5px}.outcomes-preview{display:flex;flex-wrap:wrap;gap:.5rem;margin-top:.75rem}.outcomes-preview .outcome-chip{display:inline-flex;align-items:center;padding:.375rem .75rem;background:#f1f5f9;border:1px solid #cbd5e1;border-radius:6px;font-size:.75rem;font-weight:600;color:#475569}.export-info{margin-top:1rem;padding:1rem;background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px}.export-info .info-row{display:flex;align-items:center;gap:.75rem;padding:.5rem 0;border-bottom:1px solid #e2e8f0}.export-info .info-row:last-child{border-bottom:none;padding-bottom:0}.export-info .info-row .label{font-size:.75rem;font-weight:600;color:#64748b;min-width:120px}.export-info .info-row code{flex:1;padding:.25rem .5rem;background:#fff;border:1px solid #e2e8f0;border-radius:4px;font-size:.75rem;color:#1e293b;font-family:JetBrains Mono,monospace}.settings-modal-footer{display:flex;align-items:center;justify-content:flex-end;gap:1rem;padding:1.5rem 2rem;border-top:1px solid #e2e8f0;background:#f8fafc}.empty-state{display:flex;flex-direction:column;align-items:center;justify-content:center;padding:3rem 1rem;text-align:center;color:#94a3b8}.empty-state i{font-size:3rem;margin-bottom:1rem}.empty-state p{margin:0;font-size:.875rem}.final-result{margin-top:1.5rem;padding-top:1.5rem;border-top:2px solid #e2e8f0}.final-result .result-header{display:flex;align-items:center;justify-content:space-between;padding:.75rem;background:#f8fafc;border-radius:8px;margin-bottom:1rem;cursor:pointer;transition:all .2s}.final-result .result-header:hover{background:#f1f5f9;transform:translate(-2px)}.final-result .result-header h4{display:flex;align-items:center;gap:.5rem;margin:0;font-size:.875rem;font-weight:600;color:#475569;text-transform:uppercase}.final-result .result-header h4 i{font-size:.875rem;transition:transform .2s}.final-result .result-header .toggle-hint{font-size:.75rem;color:#94a3b8}.final-result .result-card{background:#f8fafc;border:1px solid #e2e8f0;border-radius:8px;padding:1rem}.final-result .result-card .result-row{display:flex;align-items:center;gap:.75rem;padding:.5rem 0}.final-result .result-card .result-row:not(:last-child){border-bottom:1px solid #e2e8f0}.final-result .result-card .result-row strong{font-size:.875rem;color:#475569;min-width:100px}.final-result .result-card .result-row .badge{padding:.25rem .75rem;border-radius:12px;font-size:.75rem;font-weight:600}.final-result .result-card .result-row .badge.badge-running{background:#dbeafe;color:#1e40af}.final-result .result-card .result-row .badge.badge-finished{background:#d1fae5;color:#065f46}.final-result .result-card .result-row .badge.badge-cancelled{background:#fed7aa;color:#92400e}.final-result .result-card .result-row .badge.badge-faulted{background:#fee2e2;color:#991b1b}.final-result .result-card .result-row pre{margin:.5rem 0 0;padding:.75rem;background:#0f172a;color:#e2e8f0;border-radius:6px;font-family:JetBrains Mono,monospace;font-size:.75rem;line-height:1.6;overflow-x:auto;width:100%}.activities-list::-webkit-scrollbar,.result-body::-webkit-scrollbar{width:8px}.activities-list::-webkit-scrollbar-track,.result-body::-webkit-scrollbar-track{background:#f1f5f9}.activities-list::-webkit-scrollbar-thumb,.result-body::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:4px}.activities-list::-webkit-scrollbar-thumb:hover,.result-body::-webkit-scrollbar-thumb:hover{background:#94a3b8}.activity-card{cursor:grab}.activity-card:active{cursor:grabbing}.activity-card[draggable=true]{-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.visual-node[draggable=true]{cursor:move;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}.visual-node:active{cursor:grabbing}.canvas-area[data-drag-over=true]{background-color:#8b5cf60d}.connector:hover{transform:scale(1.3);box-shadow:0 0 0 3px #8b5cf64d}.connector-out.active{animation:pulse 1s infinite}@keyframes pulse{0%,to{box-shadow:0 0 0 3px #ef44444d}50%{box-shadow:0 0 0 6px #ef44441a}}@keyframes slideDown{0%{opacity:0;max-height:0}to{opacity:1;max-height:2000px}}.execution-dialog-overlay{position:fixed;inset:0;background:#000000b3;backdrop-filter:blur(4px);display:flex;align-items:center;justify-content:center;z-index:10000;animation:fadeIn .2s ease}.execution-dialog{width:90vw;max-width:1200px;height:90vh;background:#fff;border-radius:16px;box-shadow:0 25px 50px #0000004d;display:flex;flex-direction:column;overflow:hidden;animation:slideUp .3s ease}.execution-dialog-header{padding:1.5rem 2rem;background:linear-gradient(135deg,#8b5cf6,#7c3aed);color:#fff;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.execution-dialog-header .header-content{display:flex;align-items:center;gap:1rem;flex:1}.execution-dialog-header .header-content>i{font-size:2.5rem;opacity:.9}.execution-dialog-header .header-content .header-info h2{margin:0;font-size:1.75rem;font-weight:700}.execution-dialog-header .header-content .header-info p{margin:.25rem 0 0;opacity:.9;font-size:.95rem}.execution-dialog-header .close-btn{background:#fff3;border:none;width:40px;height:40px;border-radius:8px;display:flex;align-items:center;justify-content:center;cursor:pointer;transition:all .2s;color:#fff;font-size:1.25rem}.execution-dialog-header .close-btn:hover:not(:disabled){background:#ffffff4d;transform:scale(1.05)}.execution-dialog-header .close-btn:disabled{opacity:.5;cursor:not-allowed}.execution-dialog-body{flex:1;overflow-y:auto;padding:2rem;background:#f8fafc}.execution-dialog-footer{padding:1rem 2rem;background:#fff;border-top:1px solid #e2e8f0;display:flex;justify-content:space-between;align-items:center;flex-shrink:0}.execution-dialog-footer .footer-info{display:flex;gap:1.5rem}.execution-dialog-footer .footer-info .time-info{display:flex;align-items:center;gap:.5rem;color:#64748b;font-size:.875rem}.execution-dialog-footer .footer-info .time-info i{color:#8b5cf6}.execution-dialog-footer .footer-actions{display:flex;gap:.75rem}.workflow-info-panel{background:#fff;border-radius:12px;padding:2rem;box-shadow:0 4px 6px #0000000d}.workflow-info-panel .info-section{margin-bottom:2rem}.workflow-info-panel .info-section h3{display:flex;align-items:center;gap:.5rem;margin:0 0 1rem;color:#1e293b;font-size:1.25rem}.workflow-info-panel .info-section h3 i{color:#8b5cf6}.workflow-info-panel .info-section .description{color:#475569;line-height:1.7;margin:0}.workflow-info-panel .info-section .features-list{list-style:none;padding:0;margin:0;display:grid;gap:.75rem}.workflow-info-panel .info-section .features-list li{display:flex;align-items:center;gap:.75rem;padding:.75rem;background:#f8fafc;border-radius:8px;color:#334155}.workflow-info-panel .info-section .features-list li i{color:#10b981;font-size:1.125rem}.workflow-info-panel .start-section{text-align:center;padding:2rem;background:linear-gradient(135deg,#f0fdf4,#dcfce7);border-radius:12px;border:2px dashed #10b981}.workflow-info-panel .start-section .start-illustration{margin-bottom:1rem}.workflow-info-panel .start-section .start-illustration i{font-size:4rem;color:#10b981;animation:float 3s ease-in-out infinite}.workflow-info-panel .start-section h3{margin:0 0 .5rem;color:#1e293b;font-size:1.5rem}.workflow-info-panel .start-section p{margin:0 0 1.5rem;color:#64748b}.state-machine-ui .issue-tracker{background:#fff;border-radius:8px;overflow:hidden;box-shadow:0 1px 2px #0000000d}.state-machine-ui .issue-tracker .issue-header-main{padding:1.5rem 2rem 1rem;border-bottom:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:#64748b;margin-bottom:.75rem}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .project-name{color:#3b82f6;font-weight:600}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .separator{color:#94a3b8}.state-machine-ui .issue-tracker .issue-header-main .issue-breadcrumb .issue-key{color:#64748b}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title{display:flex;align-items:center;gap:.75rem}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .type-badge{padding:.375rem .75rem;border-radius:4px;font-size:.8125rem;font-weight:600;display:flex;align-items:center;gap:.375rem;background:#eff6ff;color:#3b82f6}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .type-badge i{font-size:1rem}.state-machine-ui .issue-tracker .issue-header-main .issue-type-title .issue-main-title{margin:0;font-size:1.5rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-action-bar{padding:.75rem 2rem;background:#f8fafc;border-bottom:1px solid #e2e8f0;display:flex;justify-content:space-between;align-items:center}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left{display:flex;gap:.5rem}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn{padding:.5rem 1rem;border:1px solid #cbd5e1;border-radius:4px;background:#fff;font-weight:500;font-size:.875rem;cursor:pointer;transition:all .2s;color:#334155}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn:hover:not(:disabled){background:#f1f5f9;border-color:#94a3b8}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn:disabled{opacity:.5;cursor:not-allowed}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-primary{background:#3b82f6;color:#fff;border-color:#3b82f6}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-primary:hover:not(:disabled){background:#2563eb}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-success{background:#10b981;color:#fff;border-color:#10b981}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-success:hover:not(:disabled){background:#059669}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-warning{background:#f59e0b;color:#fff;border-color:#f59e0b}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-left .status-transition-btn.btn-warning:hover:not(:disabled){background:#d97706}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-right .more-actions-btn{padding:.5rem 1rem;border:1px solid #cbd5e1;border-radius:4px;background:#fff;font-weight:500;font-size:.875rem;cursor:pointer;display:flex;align-items:center;gap:.5rem;color:#334155;transition:all .2s}.state-machine-ui .issue-tracker .issue-action-bar .action-bar-right .more-actions-btn:hover{background:#f1f5f9}.state-machine-ui .issue-tracker .issue-main-content{display:grid;grid-template-columns:320px 1fr;gap:2rem;padding:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section{margin-bottom:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row{display:flex;padding:.625rem 0;border-bottom:1px solid #f1f5f9}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row:last-child{border-bottom:none}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row label{min-width:100px;font-size:.8125rem;color:#64748b;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value{display:flex;align-items:center;gap:.5rem;font-size:.875rem;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value i{font-size:1rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .status-badge{padding:.25rem .625rem;border-radius:4px;color:#fff;font-weight:600;font-size:.75rem;text-transform:uppercase}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .view-workflow-link{color:#3b82f6;font-size:.8125rem;text-decoration:none;margin-left:.5rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .view-workflow-link:hover{text-decoration:underline}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .details-section .detail-row .detail-value .user-avatar{width:24px;height:24px;border-radius:50%;background:#8b5cf6;color:#fff;display:flex;align-items:center;justify-content:center;font-size:.75rem}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz{background:#f8fafc;border-radius:8px;padding:1.5rem;border:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz h3{margin:0 0 1rem;font-size:.875rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow{display:flex;align-items:center;gap:.5rem;flex-wrap:wrap}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state{display:flex;flex-direction:column;align-items:center;gap:.375rem;opacity:.4;transition:opacity .2s}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.active,.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.completed{opacity:1}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state .state-circle{width:36px;height:36px;border-radius:50%;display:flex;align-items:center;justify-content:center;color:#fff;font-size:.875rem;box-shadow:0 2px 4px #0000001a}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state .state-name{font-size:.6875rem;color:#64748b;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-state.active .state-name{color:#1e293b;font-weight:600}.state-machine-ui .issue-tracker .issue-main-content .issue-details-panel .state-machine-viz .states-flow .flow-arrow{color:#cbd5e1;font-size:.75rem;margin:0 .25rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section{margin-bottom:2rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section h3,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section h3{margin:0 0 1rem;font-size:1rem;font-weight:600;color:#1e293b}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section .description-content,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .description-content{padding:1rem;background:#f8fafc;border-radius:6px;border:1px solid #e2e8f0}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .description-section .description-content p,.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .description-content p{margin:0;color:#475569;line-height:1.7;font-size:.875rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline{display:flex;flex-direction:column;gap:1rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item{display:flex;gap:.75rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-avatar{width:32px;height:32px;border-radius:50%;background:#8b5cf6;color:#fff;display:flex;align-items:center;justify-content:center;flex-shrink:0;font-size:.875rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content{flex:1;padding-bottom:1rem;border-bottom:1px solid #f1f5f9}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header{font-size:.875rem;color:#334155;line-height:1.6;margin-bottom:.375rem}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header strong{color:#1e293b;font-weight:600}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-header .activity-action{color:#64748b}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-meta{display:flex;align-items:center;gap:.5rem;font-size:.8125rem;color:#94a3b8}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item .activity-content .activity-meta .activity-label{color:#8b5cf6;font-weight:500}.state-machine-ui .issue-tracker .issue-main-content .issue-description-panel .activity-section .activity-timeline .activity-item:last-child .activity-content{border-bottom:none;padding-bottom:0}.registration-ui{display:flex;justify-content:center;align-items:center;min-height:400px}.registration-ui .registration-card{background:#fff;border-radius:12px;padding:3rem;box-shadow:0 4px 6px #0000000d;text-align:center;max-width:500px}.registration-ui .registration-card .registration-icon{margin-bottom:1.5rem}.registration-ui .registration-card .registration-icon i{font-size:5rem;color:#8b5cf6}.registration-ui .registration-card h3{margin:0 0 .75rem;color:#1e293b;font-size:1.75rem;font-weight:700}.registration-ui .registration-card .registration-desc{margin:0 0 2rem;color:#64748b;line-height:1.7}.registration-ui .registration-card .registration-progress{padding:2rem;background:#fef3c7;border-radius:8px}.registration-ui .registration-card .registration-progress .progress-spinner{margin-bottom:1rem}.registration-ui .registration-card .registration-progress .progress-spinner i{font-size:3rem;color:#f59e0b}.registration-ui .registration-card .registration-progress p{margin:0;color:#92400e;font-weight:500}.registration-ui .registration-card .registration-success{padding:2rem;background:#f0fdf4;border-radius:8px}.registration-ui .registration-card .registration-success i{font-size:4rem;color:#10b981;margin-bottom:1rem}.registration-ui .registration-card .registration-success h4{margin:0 0 .5rem;color:#064e3b;font-size:1.5rem;font-weight:700}.registration-ui .registration-card .registration-success p{margin:0;color:#065f46}.default-execution-view{display:flex;justify-content:center;align-items:center;min-height:400px}.default-execution-view .execution-status{text-align:center;padding:3rem;background:#fff;border-radius:12px;box-shadow:0 4px 6px #0000000d;min-width:400px}.default-execution-view .execution-status i{font-size:5rem;margin-bottom:1.5rem}.default-execution-view .execution-status h3{margin:0 0 .75rem;font-size:1.75rem;font-weight:700}.default-execution-view .execution-status p{margin:0;color:#64748b;line-height:1.7}.default-execution-view .execution-status .status-running i{color:#f59e0b}.default-execution-view .execution-status .status-finished i{color:#10b981}.default-execution-view .execution-status .status-error i{color:#ef4444}.execution-logs-panel{margin-top:2rem;background:#fff;border-radius:12px;padding:1.5rem;box-shadow:0 4px 6px #0000000d}.execution-logs-panel h3{display:flex;align-items:center;gap:.5rem;margin:0 0 1rem;color:#1e293b;font-size:1.125rem}.execution-logs-panel h3 i{color:#8b5cf6}.execution-logs-panel .logs-container-compact{max-height:300px;overflow-y:auto;background:#f8fafc;border-radius:8px;padding:.75rem}.execution-logs-panel .logs-container-compact .log-item-compact{display:flex;align-items:center;gap:.75rem;padding:.5rem .75rem;border-radius:6px;margin-bottom:.5rem;font-size:.875rem}.execution-logs-panel .logs-container-compact .log-item-compact:last-child{margin-bottom:0}.execution-logs-panel .logs-container-compact .log-item-compact .log-time{font-family:Courier New,monospace;color:#64748b;font-size:.8125rem;min-width:70px}.execution-logs-panel .logs-container-compact .log-item-compact .log-icon{display:flex;align-items:center;justify-content:center;width:20px}.execution-logs-panel .logs-container-compact .log-item-compact .log-icon i{font-size:1rem}.execution-logs-panel .logs-container-compact .log-item-compact .log-message{flex:1;color:#334155}.execution-logs-panel .logs-container-compact .log-item-compact.log-info{background:#eff6ff}.execution-logs-panel .logs-container-compact .log-item-compact.log-info .log-icon i{color:#3b82f6}.execution-logs-panel .logs-container-compact .log-item-compact.log-success{background:#f0fdf4}.execution-logs-panel .logs-container-compact .log-item-compact.log-success .log-icon i{color:#10b981}.execution-logs-panel .logs-container-compact .log-item-compact.log-warning{background:#fffbeb}.execution-logs-panel .logs-container-compact .log-item-compact.log-warning .log-icon i{color:#f59e0b}.execution-logs-panel .logs-container-compact .log-item-compact.log-error{background:#fef2f2}.execution-logs-panel .logs-container-compact .log-item-compact.log-error .log-icon i{color:#ef4444}@keyframes fadeIn{0%{opacity:0}to{opacity:1}}@keyframes slideUp{0%{opacity:0;transform:translateY(20px)}to{opacity:1;transform:translateY(0)}}@keyframes float{0%,to{transform:translateY(0)}50%{transform:translateY(-10px)}}\n"] }]
5437
- }], propDecorators: { propertyViewerRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPPropertyViewerComponent), { isSignal: true }] }], canvasAreaRef: [{ type: i0.ViewChild, args: ['canvasAreaRef', { isSignal: true }] }] } });
5438
-
5439
- var workflowStudio_component = /*#__PURE__*/Object.freeze({
5440
- __proto__: null,
5441
- WorkflowStudioComponent: WorkflowStudioComponent
5442
- });
5443
-
5444
3321
  /**
5445
3322
  * Generated bundle index. Do not edit.
5446
3323
  */
5447
3324
 
5448
- export { AXCCategoryProvider, AXMActivityCategoriesTreeComponent, AXMMenuProvider, AXMWorkflowActivitiesDefinitionProvider, AXMWorkflowManagementModule, AXMWorkflowManagementModuleEntityProvider, AXPCreateEntityActivity, AXPGenericWorkflowTaskProvider, AXP_GENERIC_WORKFLOW_TASK_PROVIDER_CONFIG, CollectSignatureActivity, CreateEntityFormActivity, HumanTaskActivity, RootConfig, ShowConfirmPopupActivity, ShowLayoutPopupActivity, ShowToastActivity, WorkflowStudioComponent };
3325
+ export { AXCCategoryProvider, AXMMenuProvider, AXMWorkflowActivitiesDefinitionProvider, AXMWorkflowManagementModule, AXMWorkflowManagementModuleEntityProvider, AXPCreateEntityActivity, AXPGenericWorkflowTaskProvider, AXP_GENERIC_WORKFLOW_TASK_PROVIDER_CONFIG, CartableTaskActivity, CollectSignatureActivity, CreateEntityFormActivity, HumanTaskActivity, RootConfig, ShowConfirmPopupActivity, ShowLayoutPopupActivity, ShowToastActivity };
5449
3326
  //# sourceMappingURL=acorex-modules-workflow-management.mjs.map