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

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 (256) hide show
  1. package/fesm2022/{acorex-modules-ai-management-acorex-modules-ai-management-WuqoH4OL.mjs → acorex-modules-ai-management-acorex-modules-ai-management-CU2FvMTx.mjs} +260 -80
  2. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-CU2FvMTx.mjs.map +1 -0
  3. package/fesm2022/{acorex-modules-ai-management-agent.entity-DK9GNMdR.mjs → acorex-modules-ai-management-agent.entity-CUO9Jczk.mjs} +14 -19
  4. package/fesm2022/acorex-modules-ai-management-agent.entity-CUO9Jczk.mjs.map +1 -0
  5. package/fesm2022/{acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-CWXEW9yL.mjs → acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-daTGJ1Rd.mjs} +52 -8
  6. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-daTGJ1Rd.mjs.map +1 -0
  7. package/fesm2022/{acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-CNKwIqUE.mjs → acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-Cmprtps-.mjs} +49 -7
  8. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-Cmprtps-.mjs.map +1 -0
  9. package/fesm2022/{acorex-modules-ai-management-assist.entity-DX2U9sd5.mjs → acorex-modules-ai-management-assist.entity-C1nM_x4Z.mjs} +2 -2
  10. package/fesm2022/{acorex-modules-ai-management-assist.entity-DX2U9sd5.mjs.map → acorex-modules-ai-management-assist.entity-C1nM_x4Z.mjs.map} +1 -1
  11. package/fesm2022/{acorex-modules-ai-management-index-KX3TVRXr.mjs → acorex-modules-ai-management-index-CjTjfydP.mjs} +2 -2
  12. package/fesm2022/{acorex-modules-ai-management-index-KX3TVRXr.mjs.map → acorex-modules-ai-management-index-CjTjfydP.mjs.map} +1 -1
  13. package/fesm2022/{acorex-modules-ai-management-model.entity-BeuDUahR.mjs → acorex-modules-ai-management-model.entity-CPHxj8h7.mjs} +2 -2
  14. package/fesm2022/{acorex-modules-ai-management-model.entity-BeuDUahR.mjs.map → acorex-modules-ai-management-model.entity-CPHxj8h7.mjs.map} +1 -1
  15. package/fesm2022/{acorex-modules-ai-management-open-ai-endpoint.entity-D-9unl6i.mjs → acorex-modules-ai-management-open-ai-endpoint.entity-a6MjMiXF.mjs} +2 -2
  16. package/fesm2022/{acorex-modules-ai-management-open-ai-endpoint.entity-D-9unl6i.mjs.map → acorex-modules-ai-management-open-ai-endpoint.entity-a6MjMiXF.mjs.map} +1 -1
  17. package/fesm2022/acorex-modules-ai-management.mjs +1 -1
  18. package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-BNK6C-Ng.mjs → acorex-modules-assessment-management-acorex-modules-assessment-management-DniyhnPK.mjs} +509 -436
  19. package/fesm2022/acorex-modules-assessment-management-acorex-modules-assessment-management-DniyhnPK.mjs.map +1 -0
  20. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-Ds8pRzvE.mjs → acorex-modules-assessment-management-assessment-case.entity-BggEmLhz.mjs} +2 -2
  21. package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-Ds8pRzvE.mjs.map → acorex-modules-assessment-management-assessment-case.entity-BggEmLhz.mjs.map} +1 -1
  22. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-tq1Q4wkS.mjs → acorex-modules-assessment-management-assessment-session.entity-CWR1QZv1.mjs} +2 -2
  23. package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-tq1Q4wkS.mjs.map → acorex-modules-assessment-management-assessment-session.entity-CWR1QZv1.mjs.map} +1 -1
  24. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-yf0PnWC0.mjs → acorex-modules-assessment-management-fill-assessment-session.command-qajn_XDh.mjs} +2 -2
  25. package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-yf0PnWC0.mjs.map → acorex-modules-assessment-management-fill-assessment-session.command-qajn_XDh.mjs.map} +1 -1
  26. package/fesm2022/{acorex-modules-assessment-management-index-B2SncZAW.mjs → acorex-modules-assessment-management-index-B2l5Se1l.mjs} +25 -26
  27. package/fesm2022/acorex-modules-assessment-management-index-B2l5Se1l.mjs.map +1 -0
  28. package/fesm2022/{acorex-modules-assessment-management-preview-question.command-DPzL8C44.mjs → acorex-modules-assessment-management-preview-question.command-BCS477_k.mjs} +10 -11
  29. package/fesm2022/acorex-modules-assessment-management-preview-question.command-BCS477_k.mjs.map +1 -0
  30. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-BrI5gFtx.mjs → acorex-modules-assessment-management-preview-questionnaire.command-C8lyuqE-.mjs} +2 -2
  31. package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-BrI5gFtx.mjs.map → acorex-modules-assessment-management-preview-questionnaire.command-C8lyuqE-.mjs.map} +1 -1
  32. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-XD5IJpvW.mjs → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DtowOBLy.mjs} +2 -2
  33. package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-XD5IJpvW.mjs.map → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DtowOBLy.mjs.map} +1 -1
  34. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-CZ32sQ9M.mjs → acorex-modules-assessment-management-question-bank-item.entity-Br7XcU_u.mjs} +2 -2
  35. package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-CZ32sQ9M.mjs.map → acorex-modules-assessment-management-question-bank-item.entity-Br7XcU_u.mjs.map} +1 -1
  36. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-C7gf4s1y.mjs → acorex-modules-assessment-management-questionnaire-calculation.entity-DNUf5RD3.mjs} +2 -2
  37. package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-C7gf4s1y.mjs.map → acorex-modules-assessment-management-questionnaire-calculation.entity-DNUf5RD3.mjs.map} +1 -1
  38. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-BZyIlYWg.mjs → acorex-modules-assessment-management-questionnaire-viewer-popup.component-BdBKHvHP.mjs} +3 -3
  39. package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-BZyIlYWg.mjs.map → acorex-modules-assessment-management-questionnaire-viewer-popup.component-BdBKHvHP.mjs.map} +1 -1
  40. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-CmmThk2f.mjs → acorex-modules-assessment-management-questionnaire.entity-B5aP_P4z.mjs} +3 -3
  41. package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-CmmThk2f.mjs.map → acorex-modules-assessment-management-questionnaire.entity-B5aP_P4z.mjs.map} +1 -1
  42. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-GLqvK8wB.mjs → acorex-modules-assessment-management-save-questionnaire-questions.command-C3Qt5fmY.mjs} +2 -2
  43. package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-GLqvK8wB.mjs.map → acorex-modules-assessment-management-save-questionnaire-questions.command-C3Qt5fmY.mjs.map} +1 -1
  44. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-CU1TVonZ.mjs → acorex-modules-assessment-management-view-session-answers.command-C9VS-Tp3.mjs} +2 -2
  45. package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-CU1TVonZ.mjs.map → acorex-modules-assessment-management-view-session-answers.command-C9VS-Tp3.mjs.map} +1 -1
  46. package/fesm2022/acorex-modules-assessment-management.mjs +1 -1
  47. package/fesm2022/{acorex-modules-asset-management-acorex-modules-asset-management-BDs0ZgD5.mjs → acorex-modules-asset-management-acorex-modules-asset-management-F7Ok5dhs.mjs} +519 -81
  48. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-F7Ok5dhs.mjs.map +1 -0
  49. package/fesm2022/{acorex-modules-asset-management-asset-system-history.entity-CSCwWY_F.mjs → acorex-modules-asset-management-asset-system-history.entity-D1HZG9wO.mjs} +2 -2
  50. package/fesm2022/{acorex-modules-asset-management-asset-system-history.entity-CSCwWY_F.mjs.map → acorex-modules-asset-management-asset-system-history.entity-D1HZG9wO.mjs.map} +1 -1
  51. package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-CcefMT8J.mjs → acorex-modules-asset-management-asset-system-type.entity-DDh5RK5M.mjs} +60 -38
  52. package/fesm2022/acorex-modules-asset-management-asset-system-type.entity-DDh5RK5M.mjs.map +1 -0
  53. package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-6Rauu2Z1.mjs → acorex-modules-asset-management-asset-type-section-component.entity-em7lQ1eu.mjs} +2 -2
  54. package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-6Rauu2Z1.mjs.map → acorex-modules-asset-management-asset-type-section-component.entity-em7lQ1eu.mjs.map} +1 -1
  55. package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-r_H1QGwp.mjs → acorex-modules-asset-management-asset-type-section.entity-BtcNy6Ra.mjs} +6 -48
  56. package/fesm2022/acorex-modules-asset-management-asset-type-section.entity-BtcNy6Ra.mjs.map +1 -0
  57. package/fesm2022/{acorex-modules-asset-management-asset-type.entity-cWVqpbHH.mjs → acorex-modules-asset-management-asset-type.entity-DWhrFVFI.mjs} +53 -100
  58. package/fesm2022/acorex-modules-asset-management-asset-type.entity-DWhrFVFI.mjs.map +1 -0
  59. package/fesm2022/{acorex-modules-asset-management-asset.entity-CamZGWTM.mjs → acorex-modules-asset-management-asset.entity-BEjXfkPD.mjs} +66 -56
  60. package/fesm2022/acorex-modules-asset-management-asset.entity-BEjXfkPD.mjs.map +1 -0
  61. package/fesm2022/{acorex-modules-asset-management-assetSystem.entity-Dq2ASslk.mjs → acorex-modules-asset-management-assetSystem.entity-CJCVALaz.mjs} +2 -2
  62. package/fesm2022/{acorex-modules-asset-management-assetSystem.entity-Dq2ASslk.mjs.map → acorex-modules-asset-management-assetSystem.entity-CJCVALaz.mjs.map} +1 -1
  63. package/fesm2022/acorex-modules-asset-management.mjs +1 -1
  64. package/fesm2022/acorex-modules-common.mjs +38 -41
  65. package/fesm2022/acorex-modules-common.mjs.map +1 -1
  66. package/fesm2022/acorex-modules-conversation.mjs +1046 -249
  67. package/fesm2022/acorex-modules-conversation.mjs.map +1 -1
  68. package/fesm2022/acorex-modules-dashboard-management.mjs +1098 -706
  69. package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
  70. package/fesm2022/acorex-modules-data-management.mjs +63 -35
  71. package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
  72. package/fesm2022/acorex-modules-document-management.mjs +101 -57
  73. package/fesm2022/acorex-modules-document-management.mjs.map +1 -1
  74. package/fesm2022/{acorex-modules-human-capital-management-employee.entity-BRpqFRuI.mjs → acorex-modules-human-capital-management-employee.entity-BmF6_P6d.mjs} +48 -21
  75. package/fesm2022/acorex-modules-human-capital-management-employee.entity-BmF6_P6d.mjs.map +1 -0
  76. package/fesm2022/acorex-modules-human-capital-management.mjs +1 -1
  77. package/fesm2022/acorex-modules-location-management.mjs +18 -99
  78. package/fesm2022/acorex-modules-location-management.mjs.map +1 -1
  79. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-DtODwbIN.mjs +7137 -0
  80. package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-DtODwbIN.mjs.map +1 -0
  81. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-DQJJtCqU.mjs → acorex-modules-maintenance-management-failure-effect.entity-BtczD4wu.mjs} +2 -2
  82. package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-DQJJtCqU.mjs.map → acorex-modules-maintenance-management-failure-effect.entity-BtczD4wu.mjs.map} +1 -1
  83. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-gg2fpT2N.mjs → acorex-modules-maintenance-management-failure-mode-asset-type.entity-CDUdEH-e.mjs} +2 -2
  84. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-gg2fpT2N.mjs.map → acorex-modules-maintenance-management-failure-mode-asset-type.entity-CDUdEH-e.mjs.map} +1 -1
  85. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-CHUaAnID.mjs → acorex-modules-maintenance-management-failure-mode-mechanism.entity-re5UvGp7.mjs} +2 -2
  86. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-CHUaAnID.mjs.map → acorex-modules-maintenance-management-failure-mode-mechanism.entity-re5UvGp7.mjs.map} +1 -1
  87. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-B93x1uP_.mjs → acorex-modules-maintenance-management-failure-mode-solution.entity-nbFz4LAe.mjs} +2 -2
  88. package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-B93x1uP_.mjs.map → acorex-modules-maintenance-management-failure-mode-solution.entity-nbFz4LAe.mjs.map} +1 -1
  89. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-McM3l12Q.mjs → acorex-modules-maintenance-management-failure-register-cause.entity-CW2NlX59.mjs} +2 -2
  90. package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-McM3l12Q.mjs.map → acorex-modules-maintenance-management-failure-register-cause.entity-CW2NlX59.mjs.map} +1 -1
  91. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-_jjy1oeg.mjs → acorex-modules-maintenance-management-failure-register-effect.entity-Bi5XgfoL.mjs} +2 -2
  92. package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-_jjy1oeg.mjs.map → acorex-modules-maintenance-management-failure-register-effect.entity-Bi5XgfoL.mjs.map} +1 -1
  93. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-5CmdhowW.mjs → acorex-modules-maintenance-management-failure-register-mechanism.entity-DcW6sK01.mjs} +2 -2
  94. package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-5CmdhowW.mjs.map → acorex-modules-maintenance-management-failure-register-mechanism.entity-DcW6sK01.mjs.map} +1 -1
  95. package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-D_lQrda5.mjs → acorex-modules-maintenance-management-failure-register.entity-CUxVZo0w.mjs} +3 -3
  96. package/fesm2022/acorex-modules-maintenance-management-failure-register.entity-CUxVZo0w.mjs.map +1 -0
  97. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BIZxoVIS.mjs → acorex-modules-maintenance-management-failure-severity.entity-B7LBO-UA.mjs} +2 -2
  98. package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BIZxoVIS.mjs.map → acorex-modules-maintenance-management-failure-severity.entity-B7LBO-UA.mjs.map} +1 -1
  99. package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-D6ATa-HR.mjs +443 -0
  100. package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-D6ATa-HR.mjs.map +1 -0
  101. package/fesm2022/acorex-modules-maintenance-management.mjs +1 -3579
  102. package/fesm2022/acorex-modules-maintenance-management.mjs.map +1 -1
  103. package/fesm2022/acorex-modules-notification-management.mjs +11 -5
  104. package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
  105. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-BrVNMCi_.mjs +356 -0
  106. package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-BrVNMCi_.mjs.map +1 -0
  107. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-CO8jMwVJ.mjs +181 -0
  108. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-CO8jMwVJ.mjs.map +1 -0
  109. package/fesm2022/acorex-modules-organization-management-business-unit.entity-WiTemBLu.mjs +359 -0
  110. package/fesm2022/acorex-modules-organization-management-business-unit.entity-WiTemBLu.mjs.map +1 -0
  111. package/fesm2022/{acorex-modules-organization-management-chart.entity-bRxA8XHZ.mjs → acorex-modules-organization-management-chart.entity-D6Y7kZfM.mjs} +33 -29
  112. package/fesm2022/acorex-modules-organization-management-chart.entity-D6Y7kZfM.mjs.map +1 -0
  113. package/fesm2022/{acorex-modules-organization-management-company.entity-BohMJQNi.mjs → acorex-modules-organization-management-company.entity-wpNiu8g3.mjs} +6 -8
  114. package/fesm2022/acorex-modules-organization-management-company.entity-wpNiu8g3.mjs.map +1 -0
  115. package/fesm2022/acorex-modules-organization-management-data-source-evaluator-scope.provider-BrKtojM9.mjs +48 -0
  116. package/fesm2022/acorex-modules-organization-management-data-source-evaluator-scope.provider-BrKtojM9.mjs.map +1 -0
  117. package/fesm2022/acorex-modules-organization-management-entity.provider-B0XbUW1I.mjs +59 -0
  118. package/fesm2022/acorex-modules-organization-management-entity.provider-B0XbUW1I.mjs.map +1 -0
  119. package/fesm2022/acorex-modules-organization-management-feature-definition.provider-D7t_nNNk.mjs +19 -0
  120. package/fesm2022/acorex-modules-organization-management-feature-definition.provider-D7t_nNNk.mjs.map +1 -0
  121. package/fesm2022/{acorex-modules-organization-management-job-definition.entity-S9Jlmr-o.mjs → acorex-modules-organization-management-job-definition.entity-Cb6zEf65.mjs} +2 -2
  122. package/fesm2022/{acorex-modules-organization-management-job-definition.entity-S9Jlmr-o.mjs.map → acorex-modules-organization-management-job-definition.entity-Cb6zEf65.mjs.map} +1 -1
  123. package/fesm2022/acorex-modules-organization-management-job-level.datasource-RDGmLrqD.mjs +95 -0
  124. package/fesm2022/acorex-modules-organization-management-job-level.datasource-RDGmLrqD.mjs.map +1 -0
  125. package/fesm2022/acorex-modules-organization-management-job-level.entity-oedF18Xm.mjs +274 -0
  126. package/fesm2022/acorex-modules-organization-management-job-level.entity-oedF18Xm.mjs.map +1 -0
  127. package/fesm2022/acorex-modules-organization-management-menu.provider-DAKmAxld.mjs +193 -0
  128. package/fesm2022/acorex-modules-organization-management-menu.provider-DAKmAxld.mjs.map +1 -0
  129. package/fesm2022/acorex-modules-organization-management-org-chart.page-mHV0AWGZ.mjs +1081 -0
  130. package/fesm2022/acorex-modules-organization-management-org-chart.page-mHV0AWGZ.mjs.map +1 -0
  131. package/fesm2022/acorex-modules-organization-management-permission-definition.provider-Be8mvS_Z.mjs +77 -0
  132. package/fesm2022/acorex-modules-organization-management-permission-definition.provider-Be8mvS_Z.mjs.map +1 -0
  133. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs +56 -0
  134. package/fesm2022/acorex-modules-organization-management-permission.keys-DwZNBc12.mjs.map +1 -0
  135. package/fesm2022/{acorex-modules-organization-management-position.entity-DLPufeWz.mjs → acorex-modules-organization-management-position.entity-BveMCKMd.mjs} +108 -106
  136. package/fesm2022/acorex-modules-organization-management-position.entity-BveMCKMd.mjs.map +1 -0
  137. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-mMZywr0X.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-ivufxxLL.mjs} +25 -29
  138. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-ivufxxLL.mjs.map +1 -0
  139. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-CfRBMxLk.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DptdG1Nt.mjs} +2 -2
  140. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-CfRBMxLk.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-DptdG1Nt.mjs.map} +1 -1
  141. package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-B06t1G1E.mjs → acorex-modules-organization-management-responsibilities-matrix.component-qO33kvo_.mjs} +14 -21
  142. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix.component-qO33kvo_.mjs.map +1 -0
  143. package/fesm2022/acorex-modules-organization-management-responsibility-level.entity-zOjyjm5H.mjs +137 -0
  144. package/fesm2022/acorex-modules-organization-management-responsibility-level.entity-zOjyjm5H.mjs.map +1 -0
  145. package/fesm2022/{acorex-modules-organization-management-responsibility.entity-CMmr3wJa.mjs → acorex-modules-organization-management-responsibility.entity-jWEiPi5-.mjs} +2 -2
  146. package/fesm2022/{acorex-modules-organization-management-responsibility.entity-CMmr3wJa.mjs.map → acorex-modules-organization-management-responsibility.entity-jWEiPi5-.mjs.map} +1 -1
  147. package/fesm2022/acorex-modules-organization-management-settings.provider-D3ged-4h.mjs +228 -0
  148. package/fesm2022/acorex-modules-organization-management-settings.provider-D3ged-4h.mjs.map +1 -0
  149. package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-CZ4MibH4.mjs → acorex-modules-organization-management-team-member-role.entity-D9TZoACE.mjs} +68 -8
  150. package/fesm2022/acorex-modules-organization-management-team-member-role.entity-D9TZoACE.mjs.map +1 -0
  151. package/fesm2022/{acorex-modules-organization-management-team-member.entity-8sTjn5Jn.mjs → acorex-modules-organization-management-team-member.entity-Bz4o7c3d.mjs} +2 -2
  152. package/fesm2022/{acorex-modules-organization-management-team-member.entity-8sTjn5Jn.mjs.map → acorex-modules-organization-management-team-member.entity-Bz4o7c3d.mjs.map} +1 -1
  153. package/fesm2022/{acorex-modules-organization-management-team.entity-CGR0UlYl.mjs → acorex-modules-organization-management-team.entity-uVffZPeg.mjs} +100 -37
  154. package/fesm2022/acorex-modules-organization-management-team.entity-uVffZPeg.mjs.map +1 -0
  155. package/fesm2022/acorex-modules-organization-management-widget-definition.provider-D4yjuqwx.mjs +48 -0
  156. package/fesm2022/acorex-modules-organization-management-widget-definition.provider-D4yjuqwx.mjs.map +1 -0
  157. package/fesm2022/acorex-modules-organization-management.mjs +1 -2216
  158. package/fesm2022/acorex-modules-organization-management.mjs.map +1 -1
  159. package/fesm2022/acorex-modules-platform-dev-tools-menu.provider-BFueKnuF.mjs +40 -0
  160. package/fesm2022/acorex-modules-platform-dev-tools-menu.provider-BFueKnuF.mjs.map +1 -0
  161. package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-CGyf-4eq.mjs +33 -0
  162. package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-CGyf-4eq.mjs.map +1 -0
  163. package/fesm2022/acorex-modules-platform-dev-tools.mjs +14 -94
  164. package/fesm2022/acorex-modules-platform-dev-tools.mjs.map +1 -1
  165. package/fesm2022/{acorex-modules-report-management-report-runner-root-page.component-DPSNAAct.mjs → acorex-modules-report-management-report-runner-root-page.component-BjKrHoBg.mjs} +107 -107
  166. package/fesm2022/acorex-modules-report-management-report-runner-root-page.component-BjKrHoBg.mjs.map +1 -0
  167. package/fesm2022/acorex-modules-report-management.mjs +1 -1
  168. package/fesm2022/{acorex-modules-reservation-management-acorex-modules-reservation-management-BMemqW2V.mjs → acorex-modules-reservation-management-acorex-modules-reservation-management-BoUiTlmu.mjs} +65 -76
  169. package/fesm2022/acorex-modules-reservation-management-acorex-modules-reservation-management-BoUiTlmu.mjs.map +1 -0
  170. package/fesm2022/{acorex-modules-reservation-management-reservation-class-status.entity-Bg7d38wV.mjs → acorex-modules-reservation-management-reservation-class-status.entity-D-ZdqKa8.mjs} +2 -2
  171. package/fesm2022/{acorex-modules-reservation-management-reservation-class-status.entity-Bg7d38wV.mjs.map → acorex-modules-reservation-management-reservation-class-status.entity-D-ZdqKa8.mjs.map} +1 -1
  172. package/fesm2022/{acorex-modules-reservation-management-reservation-resource-type.entity-BK-rLEXi.mjs → acorex-modules-reservation-management-reservation-resource-type.entity-zPD-Psml.mjs} +2 -2
  173. package/fesm2022/{acorex-modules-reservation-management-reservation-resource-type.entity-BK-rLEXi.mjs.map → acorex-modules-reservation-management-reservation-resource-type.entity-zPD-Psml.mjs.map} +1 -1
  174. package/fesm2022/{acorex-modules-reservation-management-reservation-status-transition.entity-2ngXhKAV.mjs → acorex-modules-reservation-management-reservation-status-transition.entity-CQ85ZAGF.mjs} +2 -2
  175. package/fesm2022/{acorex-modules-reservation-management-reservation-status-transition.entity-2ngXhKAV.mjs.map → acorex-modules-reservation-management-reservation-status-transition.entity-CQ85ZAGF.mjs.map} +1 -1
  176. package/fesm2022/acorex-modules-reservation-management.mjs +1 -1
  177. package/fesm2022/acorex-modules-security-management.mjs +269 -190
  178. package/fesm2022/acorex-modules-security-management.mjs.map +1 -1
  179. package/fesm2022/{acorex-modules-task-management-task-board.page-C1H_GTqy.mjs → acorex-modules-task-management-task-board.page-DA2563QE.mjs} +15 -10
  180. package/fesm2022/acorex-modules-task-management-task-board.page-DA2563QE.mjs.map +1 -0
  181. package/fesm2022/acorex-modules-task-management.mjs +27 -13
  182. package/fesm2022/acorex-modules-task-management.mjs.map +1 -1
  183. package/fesm2022/acorex-modules-workflow-management-WORKFLOW_DEFINITION_ACTIVITIES_PAGE_COMPONENT_KEY-D6q__Ewd.mjs +5 -0
  184. package/fesm2022/acorex-modules-workflow-management-WORKFLOW_DEFINITION_ACTIVITIES_PAGE_COMPONENT_KEY-D6q__Ewd.mjs.map +1 -0
  185. package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-column.component-C8lgSjfc.mjs → acorex-modules-workflow-management-activity-command-configurator-widget-column.component-CDo0QVFy.mjs} +14 -6
  186. package/fesm2022/acorex-modules-workflow-management-activity-command-configurator-widget-column.component-CDo0QVFy.mjs.map +1 -0
  187. package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BGUPxGXP.mjs → acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs} +31 -16
  188. package/fesm2022/acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs.map +1 -0
  189. package/fesm2022/{acorex-modules-workflow-management-activity-definition.entity-Bvs1OfE_.mjs → acorex-modules-workflow-management-activity-definition.entity-B3DkgDQb.mjs} +10 -12
  190. package/fesm2022/acorex-modules-workflow-management-activity-definition.entity-B3DkgDQb.mjs.map +1 -0
  191. package/fesm2022/{acorex-modules-workflow-management-index-DWIDQsWq.mjs → acorex-modules-workflow-management-index-C9Qc07oK.mjs} +125 -3
  192. package/fesm2022/acorex-modules-workflow-management-index-C9Qc07oK.mjs.map +1 -0
  193. package/fesm2022/acorex-modules-workflow-management-index-D8fjNgQJ.mjs +726 -0
  194. package/fesm2022/acorex-modules-workflow-management-index-D8fjNgQJ.mjs.map +1 -0
  195. package/fesm2022/acorex-modules-workflow-management-index-DMnJRDbq.mjs +294 -0
  196. package/fesm2022/acorex-modules-workflow-management-index-DMnJRDbq.mjs.map +1 -0
  197. package/fesm2022/acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs +56 -0
  198. package/fesm2022/acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs.map +1 -0
  199. package/fesm2022/{acorex-modules-workflow-management-workflow-definition.entity-aJou58ED.mjs → acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs} +101 -140
  200. package/fesm2022/acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs.map +1 -0
  201. package/fesm2022/{acorex-modules-workflow-management-workflow-instance.entity-Cq7LE7u5.mjs → acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs} +10 -1
  202. package/fesm2022/acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs.map +1 -0
  203. package/fesm2022/{acorex-modules-workflow-management-workflow-task-popover.component-CIakASVR.mjs → acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs} +11 -7
  204. package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs.map +1 -0
  205. package/fesm2022/acorex-modules-workflow-management.mjs +746 -402
  206. package/fesm2022/acorex-modules-workflow-management.mjs.map +1 -1
  207. package/organization-management/README.md +1 -1
  208. package/package.json +2 -2
  209. package/types/acorex-modules-ai-management.d.ts +64 -16
  210. package/types/acorex-modules-asset-management.d.ts +115 -58
  211. package/types/acorex-modules-common.d.ts +2 -4
  212. package/types/acorex-modules-dashboard-management.d.ts +226 -109
  213. package/types/acorex-modules-data-management.d.ts +2 -2
  214. package/types/acorex-modules-document-management.d.ts +1 -2
  215. package/types/acorex-modules-human-capital-management.d.ts +6 -0
  216. package/types/acorex-modules-maintenance-management.d.ts +561 -41
  217. package/types/acorex-modules-notification-management.d.ts +7 -3
  218. package/types/acorex-modules-organization-management.d.ts +52 -107
  219. package/types/acorex-modules-security-management.d.ts +15 -1
  220. package/types/acorex-modules-task-management.d.ts +8 -13
  221. package/types/acorex-modules-workflow-management.d.ts +67 -13
  222. package/fesm2022/acorex-modules-ai-management-acorex-modules-ai-management-WuqoH4OL.mjs.map +0 -1
  223. package/fesm2022/acorex-modules-ai-management-agent.entity-DK9GNMdR.mjs.map +0 -1
  224. package/fesm2022/acorex-modules-ai-management-ai-delegated-agent-transcript-popup.component-CWXEW9yL.mjs.map +0 -1
  225. package/fesm2022/acorex-modules-ai-management-assist-delegated-agent-configurator-widget-edit.component-CNKwIqUE.mjs.map +0 -1
  226. package/fesm2022/acorex-modules-assessment-management-acorex-modules-assessment-management-BNK6C-Ng.mjs.map +0 -1
  227. package/fesm2022/acorex-modules-assessment-management-index-B2SncZAW.mjs.map +0 -1
  228. package/fesm2022/acorex-modules-assessment-management-preview-question.command-DPzL8C44.mjs.map +0 -1
  229. package/fesm2022/acorex-modules-asset-management-acorex-modules-asset-management-BDs0ZgD5.mjs.map +0 -1
  230. package/fesm2022/acorex-modules-asset-management-asset-system-type.entity-CcefMT8J.mjs.map +0 -1
  231. package/fesm2022/acorex-modules-asset-management-asset-type-section.entity-r_H1QGwp.mjs.map +0 -1
  232. package/fesm2022/acorex-modules-asset-management-asset-type.entity-cWVqpbHH.mjs.map +0 -1
  233. package/fesm2022/acorex-modules-asset-management-asset.entity-CamZGWTM.mjs.map +0 -1
  234. package/fesm2022/acorex-modules-human-capital-management-employee.entity-BRpqFRuI.mjs.map +0 -1
  235. package/fesm2022/acorex-modules-maintenance-management-failure-register.entity-D_lQrda5.mjs.map +0 -1
  236. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-C-EKX6Oy.mjs +0 -91
  237. package/fesm2022/acorex-modules-organization-management-business-unit-type.entity-C-EKX6Oy.mjs.map +0 -1
  238. package/fesm2022/acorex-modules-organization-management-chart.entity-bRxA8XHZ.mjs.map +0 -1
  239. package/fesm2022/acorex-modules-organization-management-company.entity-BohMJQNi.mjs.map +0 -1
  240. package/fesm2022/acorex-modules-organization-management-org-chart.page-eRTHzLDQ.mjs +0 -784
  241. package/fesm2022/acorex-modules-organization-management-org-chart.page-eRTHzLDQ.mjs.map +0 -1
  242. package/fesm2022/acorex-modules-organization-management-position.entity-DLPufeWz.mjs.map +0 -1
  243. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-mMZywr0X.mjs.map +0 -1
  244. package/fesm2022/acorex-modules-organization-management-responsibilities-matrix.component-B06t1G1E.mjs.map +0 -1
  245. package/fesm2022/acorex-modules-organization-management-team-member-role.entity-CZ4MibH4.mjs.map +0 -1
  246. package/fesm2022/acorex-modules-organization-management-team.entity-CGR0UlYl.mjs.map +0 -1
  247. package/fesm2022/acorex-modules-report-management-report-runner-root-page.component-DPSNAAct.mjs.map +0 -1
  248. package/fesm2022/acorex-modules-reservation-management-acorex-modules-reservation-management-BMemqW2V.mjs.map +0 -1
  249. package/fesm2022/acorex-modules-task-management-task-board.page-C1H_GTqy.mjs.map +0 -1
  250. package/fesm2022/acorex-modules-workflow-management-activity-command-configurator-widget-column.component-C8lgSjfc.mjs.map +0 -1
  251. package/fesm2022/acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BGUPxGXP.mjs.map +0 -1
  252. package/fesm2022/acorex-modules-workflow-management-activity-definition.entity-Bvs1OfE_.mjs.map +0 -1
  253. package/fesm2022/acorex-modules-workflow-management-index-DWIDQsWq.mjs.map +0 -1
  254. package/fesm2022/acorex-modules-workflow-management-workflow-definition.entity-aJou58ED.mjs.map +0 -1
  255. package/fesm2022/acorex-modules-workflow-management-workflow-instance.entity-Cq7LE7u5.mjs.map +0 -1
  256. package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-CIakASVR.mjs.map +0 -1
@@ -5,43 +5,43 @@ import { AXPSessionService, AXPAuthGuard, AXP_PERMISSION_DEFINITION_PROVIDER } f
5
5
  import { AXPEntityService, AXPEntityFormBuilderService, AXPEntityDefinitionRegistryService, entityDetailsCrudActions, AXP_ENTITY_ACTION_PLUGIN, AXP_ENTITY_CONFIG_TOKEN, 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
- import { AXPEntityCommandScope, AXPSystemStatuses, AXP_MENU_PROVIDER } from '@acorex/platform/common';
9
- import { createMultiLanguageString, AXPSystemActionType, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXP_MODULE_MANIFEST_PROVIDER, AXPMultiLanguageStringResolverService } from '@acorex/platform/core';
8
+ import { AXPEntityCommandScope, AXPStatusProvider, AXPSystemStatusType, systemStatusToDefinition, AXPSystemStatuses, AXP_STATUS_PROVIDERS, AXP_MENU_PROVIDER } from '@acorex/platform/common';
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
11
  import { AXPDomainModule } from '@acorex/platform/domain';
11
- import { AXPWidgetGroupEnum, AXP_WIDGETS_EDITOR_CATEGORY, AXPWidgetSerializationHelper, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex/platform/layout/widget-core';
12
- import { AXPBarChartWidget, AXPDonutChartWidget, AXPLineChartWidget, AXPGaugeChartWidget } from '@acorex/modules/dashboard-management';
12
+ import { AXPWidgetGroupEnum, AXP_WIDGETS_EDITOR_CATEGORY, AXPWidgetSerializationHelper, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER, mapAXPPropertyToWidgetProperty } from '@acorex/platform/layout/widget-core';
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';
13
16
  import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY } from '@acorex/platform/layout/widgets';
14
17
  import { provideCommandSetups } from '@acorex/platform/runtime';
15
18
  import { AXPWorkflowManager, AXPWorkflowDefinitionService, AXP_WORKFLOW_PROVIDER, AXP_ACTIVITY_CATEGORY_PROVIDER, AXP_ACTIVITY_PROVIDER, AXP_WORKFLOW_CATEGORY_PROVIDER, AXPActivityDefinitionService } from '@acorex/platform/workflow';
16
19
  import { ROUTES, ActivatedRoute, Router } from '@angular/router';
17
20
  import { AXDialogService } from '@acorex/components/dialog';
18
- import * as i8 from '@acorex/core/translation';
19
- import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
20
21
  import { AXPopupService } from '@acorex/components/popup';
21
22
  import { AXPDialogRendererComponent, AXPLayoutBuilderService } from '@acorex/platform/layout/builder';
22
23
  import { cloneDeep } from 'lodash-es';
23
24
  import { AXToastService } from '@acorex/components/toast';
24
25
  import { AXPWorkflowTaskProvider, AXP_WORKFLOW_TASK_PROVIDER } from '@acorex/modules/task-management';
25
- import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
26
- import * as i7 from '@angular/common';
27
- import { CommonModule } from '@angular/common';
28
- import { FormsModule } from '@angular/forms';
29
26
  import * as i2 from '@acorex/components/button';
30
27
  import { AXButtonModule } from '@acorex/components/button';
31
28
  import * as i2$1 from '@acorex/components/button-group';
32
29
  import { AXButtonGroupModule } from '@acorex/components/button-group';
33
30
  import * as i3 from '@acorex/components/decorators';
34
31
  import { AXDecoratorModule } from '@acorex/components/decorators';
35
- import * as i4 from '@acorex/components/text-box';
36
- import { AXTextBoxModule } from '@acorex/components/text-box';
37
- import { AXSelectBoxModule } from '@acorex/components/select-box';
38
32
  import * as i5 from '@acorex/components/search-box';
39
33
  import { AXSearchBoxModule } from '@acorex/components/search-box';
34
+ import { AXSelectBoxModule } from '@acorex/components/select-box';
40
35
  import * as i6 from '@acorex/components/switch';
41
36
  import { AXSwitchModule } from '@acorex/components/switch';
42
37
  import { AXTabsModule } from '@acorex/components/tabs';
38
+ import * as i4 from '@acorex/components/text-box';
39
+ import { AXTextBoxModule } from '@acorex/components/text-box';
43
40
  import { AXPPageLayoutBaseComponent, AXPPageLayoutComponent, AXPPageLayoutBase } from '@acorex/platform/layout/views';
44
- import { AXPPropertyViewerComponent, AXPThemeLayoutBlockComponent, AXPThemeLayoutHeaderComponent, AXPThemeLayoutToolbarComponent, AXPThemeLayoutStartSideComponent } from '@acorex/platform/layout/components';
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
45
  import * as i1 from '@acorex/components/tree-view-legacy';
46
46
  import { AXTreeViewLegacyModule } from '@acorex/components/tree-view-legacy';
47
47
 
@@ -49,6 +49,8 @@ const config = {
49
49
  i18n: 'workflow-management',
50
50
  module: 'WorkflowManagement',
51
51
  };
52
+ /** Builds extended dashboard widget type ids: `{module}:Widget:Dashboard:{Segment}`. */
53
+ const workflowDashboardWidgetId = (segment) => `${config.module}:Widget:Dashboard:${segment}`;
52
54
  const RootConfig = {
53
55
  config,
54
56
  module: {
@@ -114,12 +116,54 @@ const RootConfig = {
114
116
  tasksNearDeadline: `${config.module}:DataSource:TasksNearDeadline`,
115
117
  bottleneckActivities: `${config.module}:DataSource:BottleneckActivities`,
116
118
  errorsByCategory: `${config.module}:DataSource:ErrorsByCategory`,
119
+ /** Workflow instance funnel: counts per stage (created -> completed). */
120
+ instanceConversionFunnel: `${config.module}:DataSource:InstanceConversionFunnel`,
121
+ /** Heatmap: errors by activity/stage and weekday (or day bucket). */
122
+ errorsByActivityDayHeatmap: `${config.module}:DataSource:ErrorsByActivityDayHeatmap`,
117
123
  workloadPerUserActive: `${config.module}:DataSource:WorkloadPerUserActive`,
118
124
  workloadPerUserOverdue: `${config.module}:DataSource:WorkloadPerUserOverdue`,
119
125
  workloadPerUserAvgAgeHours: `${config.module}:DataSource:WorkloadPerUserAvgAgeHours`,
120
126
  workloadOverloadedUsers: `${config.module}:DataSource:WorkloadOverloadedUsers`,
121
127
  slaRiskPrediction: `${config.module}:DataSource:SlaRiskPrediction`,
122
128
  },
129
+ dashboardKpi: {
130
+ slaComplianceSnapshot: `${config.module}:DataSource:SlaComplianceSnapshot`,
131
+ taskStatusBreakdown: `${config.module}:DataSource:TaskStatusBreakdown`,
132
+ throughputOverview: `${config.module}:DataSource:ThroughputOverview`,
133
+ kpiStatCard: `${config.module}:DataSource:KpiStatCard`,
134
+ },
135
+ },
136
+ /** Extended dashboard widget type ids; used by workflow dashboard widget configs. */
137
+ widgets: {
138
+ barChart: workflowDashboardWidgetId('BarChart'),
139
+ tasksNearDeadlineBar: workflowDashboardWidgetId('TasksNearDeadlineBar'),
140
+ pendingTasksByAgeBar: workflowDashboardWidgetId('PendingTasksByAgeBar'),
141
+ overdueTasksBar: workflowDashboardWidgetId('OverdueTasksBar'),
142
+ bottleneckBar: workflowDashboardWidgetId('BottleneckBar'),
143
+ workloadPerUserOverdueBar: workflowDashboardWidgetId('WorkloadPerUserOverdueBar'),
144
+ stuckProcessesBar: workflowDashboardWidgetId('StuckProcessesBar'),
145
+ slaRiskPredictionBar: workflowDashboardWidgetId('SlaRiskPredictionBar'),
146
+ failedProcessesByTypeDonut: workflowDashboardWidgetId('FailedProcessesByTypeDonut'),
147
+ failedProcessesTrendLine: workflowDashboardWidgetId('FailedProcessesTrendLine'),
148
+ throughputDailyLine: workflowDashboardWidgetId('ThroughputDailyLine'),
149
+ throughputWeeklyLine: workflowDashboardWidgetId('ThroughputWeeklyLine'),
150
+ failedProcessesSummaryBar: workflowDashboardWidgetId('FailedProcessesSummaryBar'),
151
+ workloadPerUserActiveBar: workflowDashboardWidgetId('WorkloadPerUserActiveBar'),
152
+ workloadPerUserAvgAgeBar: workflowDashboardWidgetId('WorkloadPerUserAvgAgeBar'),
153
+ overloadedUsersBar: workflowDashboardWidgetId('OverloadedUsersBar'),
154
+ donutChart: workflowDashboardWidgetId('DonutChart'),
155
+ slaViolationsBar: workflowDashboardWidgetId('SlaViolationsBar'),
156
+ gaugeChart: workflowDashboardWidgetId('GaugeChart'),
157
+ lineChart: workflowDashboardWidgetId('LineChart'),
158
+ slaTrendLine: workflowDashboardWidgetId('SlaTrendLine'),
159
+ errorsBar: workflowDashboardWidgetId('ErrorsBar'),
160
+ instanceConversionFunnel: workflowDashboardWidgetId('InstanceConversionFunnel'),
161
+ errorsHeatmap: workflowDashboardWidgetId('ErrorsHeatmap'),
162
+ systemHealthBar: workflowDashboardWidgetId('SystemHealthBar'),
163
+ kpiDetails: workflowDashboardWidgetId('KpiDetails'),
164
+ kpiProgress: workflowDashboardWidgetId('KpiProgress'),
165
+ kpiSegmented: workflowDashboardWidgetId('KpiSegmented'),
166
+ kpiStatCard: workflowDashboardWidgetId('KpiStatCard'),
123
167
  },
124
168
  };
125
169
 
@@ -135,11 +179,11 @@ class AXMWorkflowManagementModuleEntityProvider {
135
179
  if (moduleName === RootConfig.module.name) {
136
180
  switch (entityName) {
137
181
  case RootConfig.entities.workflowDefinition.name:
138
- return (await import('./acorex-modules-workflow-management-workflow-definition.entity-aJou58ED.mjs')).factory();
182
+ return (await import('./acorex-modules-workflow-management-workflow-definition.entity-DqPVpcSv.mjs')).factory();
139
183
  case RootConfig.entities.workflowInstance.name:
140
- return (await import('./acorex-modules-workflow-management-workflow-instance.entity-Cq7LE7u5.mjs')).factory();
184
+ return (await import('./acorex-modules-workflow-management-workflow-instance.entity-sfsoT0is.mjs')).factory();
141
185
  case RootConfig.entities.activityDefinition.name:
142
- return (await import('./acorex-modules-workflow-management-activity-definition.entity-Bvs1OfE_.mjs')).factory();
186
+ return (await import('./acorex-modules-workflow-management-activity-definition.entity-B3DkgDQb.mjs')).factory();
143
187
  case RootConfig.entities.automation.name:
144
188
  return (await import('./acorex-modules-workflow-management-automation.entity-BigK8yE2.mjs')).factory();
145
189
  }
@@ -164,7 +208,6 @@ const AXPWorkflowManagementMenuKeys = {
164
208
  WorkflowInstances: 'workflow-management:workflow-instances',
165
209
  WorkflowStudio: 'workflow-management:workflow-studio',
166
210
  Activities: 'workflow-management:activities',
167
- ActivityDefinitions: 'workflow-management:activity-definitions',
168
211
  };
169
212
 
170
213
  class AXMMenuProvider {
@@ -223,16 +266,6 @@ class AXMMenuProvider {
223
266
  features: [module.name],
224
267
  },
225
268
  },
226
- {
227
- name: AXPWorkflowManagementMenuKeys.ActivityDefinitions,
228
- text: '@workflow-management:activities.menus.activity.title',
229
- path: this.entityService.createPath(module.name, RootConfig.entities.activityDefinition.name),
230
- priority: 4,
231
- icon: RootConfig.entities.activityDefinition.icon,
232
- policy: {
233
- features: [module.name],
234
- },
235
- },
236
269
  ]);
237
270
  }
238
271
  }
@@ -251,29 +284,72 @@ const AXMWorkflowErrorsBarChartAXPExtendedWidget = {
251
284
  parentName: AXPBarChartWidget.name,
252
285
  widget: {
253
286
  ...AXPBarChartWidget,
254
- name: 'workflow-errors-bar',
255
- title: createMultiLanguageString('Workflow Error Categorization', 'دسته‌بندی خطاهای گردش کار'),
287
+ name: RootConfig.widgets.errorsBar,
288
+ title: '@workflow-management:dashboard-widgets.workflow-errors-bar.widget-title',
289
+ description: '@workflow-management:dashboard-widgets.workflow-errors-bar.widget-description',
256
290
  groups: [AXPWidgetGroupEnum.DashboardWidget],
257
291
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
258
292
  options: {
259
- title: createMultiLanguageString('Errors by type and code', 'خطاها بر اساس نوع و کد'),
260
- xAxisLabel: createMultiLanguageString('Error category', 'دسته خطا'),
261
- yAxisLabel: createMultiLanguageString('Occurrences', 'تکرار'),
293
+ title: '@workflow-management:dashboard-widgets.workflow-errors-bar.chart-title',
294
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-errors-bar.x-axis-label',
295
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-errors-bar.y-axis-label',
262
296
  dataSource: RootConfig.dataSources.dashboardChart.errorsByCategory,
263
297
  },
264
298
  },
265
299
  };
266
300
 
301
+ /**
302
+ * Real-world use case:
303
+ * Heatmap of workflow errors by activity/stage (Y) and day bucket (X).
304
+ *
305
+ * Typical interpretation:
306
+ * - X: weekday ("Mon".."Sun") or recent days ("D-6".. "Today")
307
+ * - Y: activity name / step name (e.g. "Approval", "Validation", "Notify")
308
+ * - value: error count
309
+ * - label: optional preformatted tooltip value (e.g. "12 errors")
310
+ *
311
+ * DataSource contract (items):
312
+ * - `{ x: string|number, y: string|number, value: number, label?: string }[]`
313
+ */
314
+ const AXMWorkflowErrorsHeatmapAXPExtendedWidget = {
315
+ parentName: AXPHeatmapChartWidget.name,
316
+ widget: {
317
+ ...AXPHeatmapChartWidget,
318
+ name: RootConfig.widgets.errorsHeatmap,
319
+ title: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.widget-title',
320
+ description: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.widget-description',
321
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
322
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
323
+ options: {
324
+ showXAxis: true,
325
+ showYAxis: true,
326
+ showTooltip: true,
327
+ // xAxisLabel: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.x-axis-label',
328
+ // yAxisLabel: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.y-axis-label',
329
+ cellPadding: 0.08,
330
+ borderRadius: 3,
331
+ animationEasing: 'cubic-out',
332
+ animationDuration: 800,
333
+ dataSource: RootConfig.dataSources.dashboardChart.errorsByActivityDayHeatmap,
334
+ messages: {
335
+ noData: '@workflow-management:dashboard-widgets.common.no-data',
336
+ noDataHelp: '@workflow-management:dashboard-widgets.workflow-errors-heatmap.no-data-help',
337
+ },
338
+ },
339
+ },
340
+ };
341
+
267
342
  const AXMWorkflowFailedProcessesByTypeDonutChartAXPExtendedWidget = {
268
343
  parentName: AXPDonutChartWidget.name,
269
344
  widget: {
270
345
  ...AXPDonutChartWidget,
271
- name: 'workflow-failed-processes-by-type-donut',
272
- title: createMultiLanguageString('Workflow Failed Processes by Type', 'فرایندهای ناموفق بر اساس نوع'),
346
+ name: RootConfig.widgets.failedProcessesByTypeDonut,
347
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-by-type-donut.widget-title',
348
+ description: '@workflow-management:dashboard-widgets.workflow-failed-processes-by-type-donut.widget-description',
273
349
  groups: [AXPWidgetGroupEnum.DashboardWidget],
274
350
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
275
351
  options: {
276
- title: createMultiLanguageString('Affected Process Types', 'انواع فرایند تحت تأثیر'),
352
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-by-type-donut.chart-title',
277
353
  dataSource: RootConfig.dataSources.dashboardChart.failedProcessesByType,
278
354
  },
279
355
  },
@@ -283,14 +359,15 @@ const AXMWorkflowFailedProcessesSummaryBarChartAXPExtendedWidget = {
283
359
  parentName: AXPBarChartWidget.name,
284
360
  widget: {
285
361
  ...AXPBarChartWidget,
286
- name: 'workflow-failed-processes-summary-bar',
287
- title: createMultiLanguageString('Workflow Failed Processes Summary', 'خلاصه فرایندهای ناموفق گردش کار'),
362
+ name: RootConfig.widgets.failedProcessesSummaryBar,
363
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.widget-title',
364
+ description: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.widget-description',
288
365
  groups: [AXPWidgetGroupEnum.DashboardWidget],
289
366
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
290
367
  options: {
291
- title: createMultiLanguageString('Total vs Recent Failures', 'کل در مقابل شکست‌های اخیر'),
292
- xAxisLabel: createMultiLanguageString('Scope', 'محدوده'),
293
- yAxisLabel: createMultiLanguageString('Instances', 'نمونه‌ها'),
368
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.chart-title',
369
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.x-axis-label',
370
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-summary-bar.y-axis-label',
294
371
  dataSource: RootConfig.dataSources.dashboardChart.failedProcessesSummary,
295
372
  },
296
373
  },
@@ -300,14 +377,15 @@ const AXMWorkflowFailedProcessesTrendLineChartAXPExtendedWidget = {
300
377
  parentName: AXPLineChartWidget.name,
301
378
  widget: {
302
379
  ...AXPLineChartWidget,
303
- name: 'workflow-failed-processes-trend-line',
304
- title: createMultiLanguageString('Workflow Failed Instances Trend', 'روند نمونه‌های ناموفق گردش کار'),
380
+ name: RootConfig.widgets.failedProcessesTrendLine,
381
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.widget-title',
382
+ description: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.widget-description',
305
383
  groups: [AXPWidgetGroupEnum.DashboardWidget],
306
384
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
307
385
  options: {
308
- title: createMultiLanguageString('Failed Instances by Week', 'نمونه‌های ناموفق بر اساس هفته'),
309
- xAxisLabel: createMultiLanguageString('Week', 'هفته'),
310
- yAxisLabel: createMultiLanguageString('Failures', 'شکست‌ها'),
386
+ title: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.chart-title',
387
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.x-axis-label',
388
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-failed-processes-trend-line.y-axis-label',
311
389
  fillArea: false,
312
390
  yAxisStartsAtZero: true,
313
391
  dataSource: RootConfig.dataSources.dashboardChart.failedProcessFailureTrend,
@@ -319,14 +397,15 @@ const AXMWorkflowStuckProcessesBarChartAXPExtendedWidget = {
319
397
  parentName: AXPBarChartWidget.name,
320
398
  widget: {
321
399
  ...AXPBarChartWidget,
322
- name: 'workflow-stuck-processes-bar',
323
- title: createMultiLanguageString('Workflow Stuck Processes', 'فرایندهای گیرکرده گردش کار'),
400
+ name: RootConfig.widgets.stuckProcessesBar,
401
+ title: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.widget-title',
402
+ description: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.widget-description',
324
403
  groups: [AXPWidgetGroupEnum.DashboardWidget],
325
404
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
326
405
  options: {
327
- title: createMultiLanguageString('Idle Time by Instance (hours)', 'زمان بیکاری بر اساس نمونه (ساعت)'),
328
- xAxisLabel: createMultiLanguageString('Instance', 'نمونه'),
329
- yAxisLabel: createMultiLanguageString('Hours without progress', 'ساعت بدون پیشرفت'),
406
+ title: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.chart-title',
407
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.x-axis-label',
408
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-stuck-processes-bar.y-axis-label',
330
409
  dataSource: RootConfig.dataSources.dashboardChart.stuckProcesses,
331
410
  },
332
411
  },
@@ -336,13 +415,14 @@ const AXMWorkflowGaugeChartAXPExtendedWidget = {
336
415
  parentName: AXPGaugeChartWidget.name,
337
416
  widget: {
338
417
  ...AXPGaugeChartWidget,
339
- name: 'workflow-gauge-chart',
340
- title: createMultiLanguageString('Workflow SLA Compliance', 'انطباق SLA گردش کار'),
418
+ name: RootConfig.widgets.gaugeChart,
419
+ title: '@workflow-management:dashboard-widgets.workflow-gauge-chart.widget-title',
420
+ description: '@workflow-management:dashboard-widgets.workflow-gauge-chart.widget-description',
341
421
  groups: [AXPWidgetGroupEnum.DashboardWidget],
342
422
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
343
423
  options: {
344
- title: createMultiLanguageString('SLA Compliance', 'انطباق SLA'),
345
- label: createMultiLanguageString('Resolved In SLA (%)', 'حل‌شده در SLA (٪)'),
424
+ title: '@workflow-management:dashboard-widgets.workflow-gauge-chart.chart-title',
425
+ label: '@workflow-management:dashboard-widgets.workflow-gauge-chart.gauge-label',
346
426
  dataSource: RootConfig.dataSources.dashboardChart.slaCompliance,
347
427
  minValue: 0,
348
428
  maxValue: 100,
@@ -350,10 +430,18 @@ const AXMWorkflowGaugeChartAXPExtendedWidget = {
350
430
  {
351
431
  value: 30,
352
432
  color: 'rgba(var(--ax-sys-color-danger-500))',
353
- label: 'Low',
433
+ label: '@workflow-management:dashboard-widgets.workflow-gauge-chart.threshold-low',
434
+ },
435
+ {
436
+ value: 70,
437
+ color: 'rgba(var(--ax-sys-color-warning-500))',
438
+ label: '@workflow-management:dashboard-widgets.workflow-gauge-chart.threshold-medium',
439
+ },
440
+ {
441
+ value: 100,
442
+ color: 'rgba(var(--ax-sys-color-success-500))',
443
+ label: '@workflow-management:dashboard-widgets.workflow-gauge-chart.threshold-high',
354
444
  },
355
- { value: 70, color: 'rgba(var(--ax-sys-color-warning-500))', label: 'Medium' },
356
- { value: 100, color: 'rgba(var(--ax-sys-color-success-500))', label: 'High' },
357
445
  ],
358
446
  },
359
447
  },
@@ -363,14 +451,15 @@ const AXMWorkflowSlaRiskPredictionBarChartAXPExtendedWidget = {
363
451
  parentName: AXPBarChartWidget.name,
364
452
  widget: {
365
453
  ...AXPBarChartWidget,
366
- name: 'workflow-sla-risk-prediction-bar',
367
- title: createMultiLanguageString('Workflow SLA Risk Prediction', 'پیش‌بینی ریسک SLA گردش کار'),
454
+ name: RootConfig.widgets.slaRiskPredictionBar,
455
+ title: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.widget-title',
456
+ description: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.widget-description',
368
457
  groups: [AXPWidgetGroupEnum.DashboardWidget],
369
458
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
370
459
  options: {
371
- title: createMultiLanguageString('Likely breach risk score (0–100)', 'امتیاز ریسک نقض محتمل (۰–۱۰۰)'),
372
- xAxisLabel: createMultiLanguageString('Item', 'مورد'),
373
- yAxisLabel: createMultiLanguageString('Risk score', 'امتیاز ریسک'),
460
+ title: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.chart-title',
461
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.x-axis-label',
462
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-risk-prediction-bar.y-axis-label',
374
463
  dataSource: RootConfig.dataSources.dashboardChart.slaRiskPrediction,
375
464
  },
376
465
  },
@@ -380,14 +469,15 @@ const AXMWorkflowSlaTrendLineChartAXPExtendedWidget = {
380
469
  parentName: AXPLineChartWidget.name,
381
470
  widget: {
382
471
  ...AXPLineChartWidget,
383
- name: 'workflow-sla-trend-line',
384
- title: createMultiLanguageString('Workflow SLA Compliance Trend', 'روند انطباق SLA گردش کار'),
472
+ name: RootConfig.widgets.slaTrendLine,
473
+ title: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.widget-title',
474
+ description: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.widget-description',
385
475
  groups: [AXPWidgetGroupEnum.DashboardWidget],
386
476
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
387
477
  options: {
388
- title: createMultiLanguageString('Resolved Within SLA (%)', 'حل‌شده در SLA (٪)'),
389
- xAxisLabel: createMultiLanguageString('Week', 'هفته'),
390
- yAxisLabel: createMultiLanguageString('Percent', 'درصد'),
478
+ title: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.chart-title',
479
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.x-axis-label',
480
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-trend-line.y-axis-label',
391
481
  fillArea: true,
392
482
  yAxisStartsAtZero: false,
393
483
  dataSource: RootConfig.dataSources.dashboardChart.slaComplianceTrend,
@@ -399,14 +489,15 @@ const AXMWorkflowSlaViolationsBarChartAXPExtendedWidget = {
399
489
  parentName: AXPBarChartWidget.name,
400
490
  widget: {
401
491
  ...AXPBarChartWidget,
402
- name: 'workflow-sla-violations-bar',
403
- title: createMultiLanguageString('Workflow SLA Violations & Delay', 'تخلفات SLA و تأخیر گردش کار'),
492
+ name: RootConfig.widgets.slaViolationsBar,
493
+ title: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.widget-title',
494
+ description: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.widget-description',
404
495
  groups: [AXPWidgetGroupEnum.DashboardWidget],
405
496
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
406
497
  options: {
407
- title: createMultiLanguageString('Violations and Average Delay', 'تخلفات و میانگین تأخیر'),
408
- xAxisLabel: createMultiLanguageString('Measure', 'معیار'),
409
- yAxisLabel: createMultiLanguageString('Count / Hours', 'تعداد / ساعت'),
498
+ title: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.chart-title',
499
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.x-axis-label',
500
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-sla-violations-bar.y-axis-label',
410
501
  dataSource: RootConfig.dataSources.dashboardChart.slaViolationsAndDelay,
411
502
  },
412
503
  },
@@ -416,14 +507,15 @@ const AXMWorkflowSystemHealthBarChartAXPExtendedWidget = {
416
507
  parentName: AXPBarChartWidget.name,
417
508
  widget: {
418
509
  ...AXPBarChartWidget,
419
- name: 'workflow-system-health-bar',
420
- title: createMultiLanguageString('Workflow System Health Summary', 'خلاصه وضعیت سلامت گردش کار'),
510
+ name: RootConfig.widgets.systemHealthBar,
511
+ title: '@workflow-management:dashboard-widgets.workflow-system-health-bar.widget-title',
512
+ description: '@workflow-management:dashboard-widgets.workflow-system-health-bar.widget-description',
421
513
  groups: [AXPWidgetGroupEnum.DashboardWidget],
422
514
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
423
515
  options: {
424
- title: createMultiLanguageString('Instances, Tasks, and SLA', 'نمونه‌ها، وظایف و SLA'),
425
- xAxisLabel: createMultiLanguageString('Metric', 'شاخص'),
426
- yAxisLabel: createMultiLanguageString('Count / %', 'تعداد / ٪'),
516
+ title: '@workflow-management:dashboard-widgets.workflow-system-health-bar.chart-title',
517
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-system-health-bar.x-axis-label',
518
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-system-health-bar.y-axis-label',
427
519
  dataSource: RootConfig.dataSources.dashboardChart.systemHealthSummary,
428
520
  },
429
521
  },
@@ -433,14 +525,15 @@ const AXMWorkflowOverdueTasksBarChartAXPExtendedWidget = {
433
525
  parentName: AXPBarChartWidget.name,
434
526
  widget: {
435
527
  ...AXPBarChartWidget,
436
- name: 'workflow-overdue-tasks-bar',
437
- title: createMultiLanguageString('Workflow Overdue Tasks by Process', 'وظایف معوقه گردش کار بر اساس فرایند'),
528
+ name: RootConfig.widgets.overdueTasksBar,
529
+ title: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.widget-title',
530
+ description: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.widget-description',
438
531
  groups: [AXPWidgetGroupEnum.DashboardWidget],
439
532
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
440
533
  options: {
441
- title: createMultiLanguageString('Overdue Tasks (by process type)', 'وظایف معوقه (بر اساس نوع فرایند)'),
442
- xAxisLabel: createMultiLanguageString('Process type', 'نوع فرایند'),
443
- yAxisLabel: createMultiLanguageString('Overdue tasks', 'وظایف معوقه'),
534
+ title: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.chart-title',
535
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.x-axis-label',
536
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-overdue-tasks-bar.y-axis-label',
444
537
  dataSource: RootConfig.dataSources.dashboardChart.overdueTasksByProcess,
445
538
  },
446
539
  },
@@ -450,14 +543,15 @@ const AXMWorkflowPendingTasksByAgeBarChartAXPExtendedWidget = {
450
543
  parentName: AXPBarChartWidget.name,
451
544
  widget: {
452
545
  ...AXPBarChartWidget,
453
- name: 'workflow-pending-tasks-by-age-bar',
454
- title: createMultiLanguageString('Workflow Pending Tasks by Age', 'وظایف در انتظار گردش کار بر اساس قدمت'),
546
+ name: RootConfig.widgets.pendingTasksByAgeBar,
547
+ title: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.widget-title',
548
+ description: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.widget-description',
455
549
  groups: [AXPWidgetGroupEnum.DashboardWidget],
456
550
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
457
551
  options: {
458
- title: createMultiLanguageString('Pending Tasks by Age Bucket', 'وظایف در انتظار بر اساس بازه قدمت'),
459
- xAxisLabel: createMultiLanguageString('Age Bucket', 'بازه قدمت'),
460
- yAxisLabel: createMultiLanguageString('Tasks', 'وظایف'),
552
+ title: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.chart-title',
553
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.x-axis-label',
554
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-pending-tasks-by-age-bar.y-axis-label',
461
555
  dataSource: RootConfig.dataSources.dashboardChart.pendingTasksByAge,
462
556
  },
463
557
  },
@@ -467,14 +561,15 @@ const AXMWorkflowLineChartAXPExtendedWidget = {
467
561
  parentName: AXPLineChartWidget.name,
468
562
  widget: {
469
563
  ...AXPLineChartWidget,
470
- name: 'workflow-line-chart',
471
- title: createMultiLanguageString('Workflow Throughput Trend', 'روند توان عملیات گردش کار'),
564
+ name: RootConfig.widgets.lineChart,
565
+ title: '@workflow-management:dashboard-widgets.workflow-line-chart.widget-title',
566
+ description: '@workflow-management:dashboard-widgets.workflow-line-chart.widget-description',
472
567
  groups: [AXPWidgetGroupEnum.DashboardWidget],
473
568
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
474
569
  options: {
475
- title: createMultiLanguageString('Created vs Completed (Last 8 Weeks)', 'ایجادشده و تکمیل‌شده (۸ هفته اخیر)'),
476
- xAxisLabel: createMultiLanguageString('Week', 'هفته'),
477
- yAxisLabel: createMultiLanguageString('Items', 'تعداد'),
570
+ title: '@workflow-management:dashboard-widgets.workflow-line-chart.chart-title',
571
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-line-chart.x-axis-label',
572
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-line-chart.y-axis-label',
478
573
  fillArea: false,
479
574
  /** Focus Y domain on the data range so the two series are readable (not squashed to the top band). */
480
575
  yAxisStartsAtZero: false,
@@ -483,18 +578,50 @@ const AXMWorkflowLineChartAXPExtendedWidget = {
483
578
  },
484
579
  };
485
580
 
581
+ /**
582
+ * Real-world use case:
583
+ * A conversion funnel across workflow instance lifecycle stages (Created -> Assigned -> In progress -> Completed).
584
+ *
585
+ * DataSource contract (items):
586
+ * - `{ name: string, value: number, color?: string }[]`
587
+ */
588
+ const AXMWorkflowInstanceConversionFunnelAXPExtendedWidget = {
589
+ parentName: AXPFunnelChartWidget.name,
590
+ widget: {
591
+ ...AXPFunnelChartWidget,
592
+ name: RootConfig.widgets.instanceConversionFunnel,
593
+ title: '@workflow-management:dashboard-widgets.workflow-instance-conversion-funnel.widget-title',
594
+ description: '@workflow-management:dashboard-widgets.workflow-instance-conversion-funnel.widget-description',
595
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
596
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
597
+ options: {
598
+ showLabels: true,
599
+ showTooltip: true,
600
+ neckWidth: 0.25,
601
+ animationEasing: 'cubic-out',
602
+ animationDuration: 800,
603
+ margin: { top: 16, right: 16, bottom: 16, left: 16 },
604
+ dataSource: RootConfig.dataSources.dashboardChart.instanceConversionFunnel,
605
+ messages: {
606
+ noData: '@workflow-management:dashboard-widgets.common.no-data',
607
+ },
608
+ },
609
+ },
610
+ };
611
+
486
612
  const AXMWorkflowThroughputDailyLineChartAXPExtendedWidget = {
487
613
  parentName: AXPLineChartWidget.name,
488
614
  widget: {
489
615
  ...AXPLineChartWidget,
490
- name: 'workflow-throughput-daily-line',
491
- title: createMultiLanguageString('Workflow Created vs Completed (Daily)', 'ایجاد و تکمیل روزانه گردش کار'),
616
+ name: RootConfig.widgets.throughputDailyLine,
617
+ title: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.widget-title',
618
+ description: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.widget-description',
492
619
  groups: [AXPWidgetGroupEnum.DashboardWidget],
493
620
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
494
621
  options: {
495
- title: createMultiLanguageString('Created vs Completed — Daily', 'ایجاد در مقابل تکمیل — روزانه'),
496
- xAxisLabel: createMultiLanguageString('Day', 'روز'),
497
- yAxisLabel: createMultiLanguageString('Items', 'تعداد'),
622
+ title: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.chart-title',
623
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.x-axis-label',
624
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-daily-line.y-axis-label',
498
625
  fillArea: false,
499
626
  yAxisStartsAtZero: false,
500
627
  dataSource: RootConfig.dataSources.dashboardChart.throughputDaily,
@@ -506,14 +633,15 @@ const AXMWorkflowThroughputWeeklyLineChartAXPExtendedWidget = {
506
633
  parentName: AXPLineChartWidget.name,
507
634
  widget: {
508
635
  ...AXPLineChartWidget,
509
- name: 'workflow-throughput-weekly-line',
510
- title: createMultiLanguageString('Workflow Created vs Completed (Weekly)', 'ایجاد و تکمیل هفتگی گردش کار'),
636
+ name: RootConfig.widgets.throughputWeeklyLine,
637
+ title: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.widget-title',
638
+ description: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.widget-description',
511
639
  groups: [AXPWidgetGroupEnum.DashboardWidget],
512
640
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
513
641
  options: {
514
- title: createMultiLanguageString('Created vs Completed — Weekly', 'ایجاد در مقابل تکمیل — هفتگی'),
515
- xAxisLabel: createMultiLanguageString('Week', 'هفته'),
516
- yAxisLabel: createMultiLanguageString('Items', 'تعداد'),
642
+ title: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.chart-title',
643
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.x-axis-label',
644
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-throughput-weekly-line.y-axis-label',
517
645
  fillArea: false,
518
646
  yAxisStartsAtZero: false,
519
647
  dataSource: RootConfig.dataSources.dashboardChart.throughputWeekly,
@@ -525,14 +653,15 @@ const AXMWorkflowBottleneckBarChartAXPExtendedWidget = {
525
653
  parentName: AXPBarChartWidget.name,
526
654
  widget: {
527
655
  ...AXPBarChartWidget,
528
- name: 'workflow-bottleneck-bar',
529
- title: createMultiLanguageString('Workflow Bottleneck Detection', 'تشخیص گلوگاه گردش کار'),
656
+ name: RootConfig.widgets.bottleneckBar,
657
+ title: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.widget-title',
658
+ description: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.widget-description',
530
659
  groups: [AXPWidgetGroupEnum.DashboardWidget],
531
660
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
532
661
  options: {
533
- title: createMultiLanguageString('Highest average wait by activity', 'بیشترین میانگین انتظار بر اساس فعالیت'),
534
- xAxisLabel: createMultiLanguageString('Activity / step', 'فعالیت / گام'),
535
- yAxisLabel: createMultiLanguageString('Avg wait (hours)', 'میانگین انتظار (ساعت)'),
662
+ title: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.chart-title',
663
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.x-axis-label',
664
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-bottleneck-bar.y-axis-label',
536
665
  dataSource: RootConfig.dataSources.dashboardChart.bottleneckActivities,
537
666
  },
538
667
  },
@@ -542,12 +671,13 @@ const AXMWorkflowDonutChartAXPExtendedWidget = {
542
671
  parentName: AXPDonutChartWidget.name,
543
672
  widget: {
544
673
  ...AXPDonutChartWidget,
545
- name: 'workflow-donut-chart',
546
- title: createMultiLanguageString('Workflow Workload by Process', 'بار کاری گردش کار بر اساس فرایند'),
674
+ name: RootConfig.widgets.donutChart,
675
+ title: '@workflow-management:dashboard-widgets.workflow-donut-chart.widget-title',
676
+ description: '@workflow-management:dashboard-widgets.workflow-donut-chart.widget-description',
547
677
  groups: [AXPWidgetGroupEnum.DashboardWidget],
548
678
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
549
679
  options: {
550
- title: createMultiLanguageString('Workload by Process', 'بار کاری بر اساس فرایند'),
680
+ title: '@workflow-management:dashboard-widgets.workflow-donut-chart.chart-title',
551
681
  dataSource: RootConfig.dataSources.dashboardChart.workloadByProcess,
552
682
  },
553
683
  },
@@ -557,14 +687,15 @@ const AXMWorkflowOverloadedUsersBarChartAXPExtendedWidget = {
557
687
  parentName: AXPBarChartWidget.name,
558
688
  widget: {
559
689
  ...AXPBarChartWidget,
560
- name: 'workflow-overloaded-users-bar',
561
- title: createMultiLanguageString('Workflow Overloaded Users', 'کاربران با بار بیش از حد گردش کار'),
690
+ name: RootConfig.widgets.overloadedUsersBar,
691
+ title: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.widget-title',
692
+ description: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.widget-description',
562
693
  groups: [AXPWidgetGroupEnum.DashboardWidget],
563
694
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
564
695
  options: {
565
- title: createMultiLanguageString('Users above capacity threshold (active tasks)', 'کاربران بالاتر از آستانه ظرفیت (وظایف فعال)'),
566
- xAxisLabel: createMultiLanguageString('User', 'کاربر'),
567
- yAxisLabel: createMultiLanguageString('Active tasks', 'وظایف فعال'),
696
+ title: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.chart-title',
697
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.x-axis-label',
698
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-overloaded-users-bar.y-axis-label',
568
699
  dataSource: RootConfig.dataSources.dashboardChart.workloadOverloadedUsers,
569
700
  },
570
701
  },
@@ -574,14 +705,15 @@ const AXMWorkflowWorkloadPerUserActiveBarChartAXPExtendedWidget = {
574
705
  parentName: AXPBarChartWidget.name,
575
706
  widget: {
576
707
  ...AXPBarChartWidget,
577
- name: 'workflow-workload-per-user-active-bar',
578
- title: createMultiLanguageString('Workflow Workload per User (Active)', 'بار کاری گردش کار به ازای کاربر (فعال)'),
708
+ name: RootConfig.widgets.workloadPerUserActiveBar,
709
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.widget-title',
710
+ description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.widget-description',
579
711
  groups: [AXPWidgetGroupEnum.DashboardWidget],
580
712
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
581
713
  options: {
582
- title: createMultiLanguageString('Active task count by user', 'تعداد وظایف فعال به ازای کاربر'),
583
- xAxisLabel: createMultiLanguageString('User', 'کاربر'),
584
- yAxisLabel: createMultiLanguageString('Active tasks', 'وظایف فعال'),
714
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.chart-title',
715
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.x-axis-label',
716
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-active-bar.y-axis-label',
585
717
  dataSource: RootConfig.dataSources.dashboardChart.workloadPerUserActive,
586
718
  },
587
719
  },
@@ -591,14 +723,15 @@ const AXMWorkflowWorkloadPerUserAvgAgeBarChartAXPExtendedWidget = {
591
723
  parentName: AXPBarChartWidget.name,
592
724
  widget: {
593
725
  ...AXPBarChartWidget,
594
- name: 'workflow-workload-per-user-avg-age-bar',
595
- title: createMultiLanguageString('Workflow Avg Task Age per User', 'میانگین قدمت وظیفه به ازای کاربر'),
726
+ name: RootConfig.widgets.workloadPerUserAvgAgeBar,
727
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.widget-title',
728
+ description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.widget-description',
596
729
  groups: [AXPWidgetGroupEnum.DashboardWidget],
597
730
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
598
731
  options: {
599
- title: createMultiLanguageString('Average age of active tasks (hours)', 'میانگین قدمت وظایف فعال (ساعت)'),
600
- xAxisLabel: createMultiLanguageString('User', 'کاربر'),
601
- yAxisLabel: createMultiLanguageString('Hours', 'ساعت'),
732
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.chart-title',
733
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.x-axis-label',
734
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-avg-age-bar.y-axis-label',
602
735
  dataSource: RootConfig.dataSources.dashboardChart.workloadPerUserAvgAgeHours,
603
736
  },
604
737
  },
@@ -608,31 +741,100 @@ const AXMWorkflowWorkloadPerUserOverdueBarChartAXPExtendedWidget = {
608
741
  parentName: AXPBarChartWidget.name,
609
742
  widget: {
610
743
  ...AXPBarChartWidget,
611
- name: 'workflow-workload-per-user-overdue-bar',
612
- title: createMultiLanguageString('Workflow Workload per User (Overdue)', 'بار کاری گردش کار به ازای کاربر (معوقه)'),
744
+ name: RootConfig.widgets.workloadPerUserOverdueBar,
745
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.widget-title',
746
+ description: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.widget-description',
613
747
  groups: [AXPWidgetGroupEnum.DashboardWidget],
614
748
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
615
749
  options: {
616
- title: createMultiLanguageString('Overdue task count by user', 'تعداد وظایف معوقه به ازای کاربر'),
617
- xAxisLabel: createMultiLanguageString('User', 'کاربر'),
618
- yAxisLabel: createMultiLanguageString('Overdue tasks', 'وظایف معوقه'),
750
+ title: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.chart-title',
751
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.x-axis-label',
752
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-workload-per-user-overdue-bar.y-axis-label',
619
753
  dataSource: RootConfig.dataSources.dashboardChart.workloadPerUserOverdue,
620
754
  },
621
755
  },
622
756
  };
623
757
 
758
+ const AXMWorkflowKpiDetailsAXPExtendedWidget = {
759
+ parentName: AXPKpiDetailsWidget.name,
760
+ widget: {
761
+ ...AXPKpiDetailsWidget,
762
+ name: RootConfig.widgets.kpiDetails,
763
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-details.widget-title',
764
+ description: '@workflow-management:dashboard-widgets.workflow-kpi-details.widget-description',
765
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
766
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
767
+ options: {
768
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-details.options-title',
769
+ subtitle: '@workflow-management:dashboard-widgets.workflow-kpi-details.options-subtitle',
770
+ valueSuffix: '@workflow-management:dashboard-widgets.workflow-kpi-details.value-suffix',
771
+ dataSource: RootConfig.dataSources.dashboardKpi.throughputOverview,
772
+ },
773
+ },
774
+ };
775
+
776
+ const AXMWorkflowKpiProgressAXPExtendedWidget = {
777
+ parentName: AXPKpiProgressWidget.name,
778
+ widget: {
779
+ ...AXPKpiProgressWidget,
780
+ name: RootConfig.widgets.kpiProgress,
781
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-progress.widget-title',
782
+ description: '@workflow-management:dashboard-widgets.workflow-kpi-progress.widget-description',
783
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
784
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
785
+ options: {
786
+ subtitle: '@workflow-management:dashboard-widgets.workflow-kpi-progress.options-subtitle',
787
+ valueSuffix: '%',
788
+ targetValue: 95,
789
+ dataSource: RootConfig.dataSources.dashboardKpi.slaComplianceSnapshot,
790
+ },
791
+ },
792
+ };
793
+
794
+ const AXMWorkflowKpiSegmentedAXPExtendedWidget = {
795
+ parentName: AXPKpiSegmentedWidget.name,
796
+ widget: {
797
+ ...AXPKpiSegmentedWidget,
798
+ name: RootConfig.widgets.kpiSegmented,
799
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-segmented.widget-title',
800
+ description: '@workflow-management:dashboard-widgets.workflow-kpi-segmented.widget-description',
801
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
802
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
803
+ options: {
804
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-segmented.options-title',
805
+ dataSource: RootConfig.dataSources.dashboardKpi.taskStatusBreakdown,
806
+ },
807
+ },
808
+ };
809
+
810
+ const AXMWorkflowKpiStatCardAXPExtendedWidget = {
811
+ parentName: AXPKpiStatCardWidget.name,
812
+ widget: {
813
+ ...AXPKpiStatCardWidget,
814
+ name: RootConfig.widgets.kpiStatCard,
815
+ title: '@workflow-management:dashboard-widgets.workflow-kpi-stat-card.widget-title',
816
+ description: '@workflow-management:dashboard-widgets.workflow-kpi-stat-card.widget-description',
817
+ groups: [AXPWidgetGroupEnum.DashboardWidget],
818
+ categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
819
+ options: {
820
+ dataSource: RootConfig.dataSources.dashboardKpi.kpiStatCard,
821
+ },
822
+ },
823
+ };
824
+
624
825
  const AXMWorkflowBarChartAXPExtendedWidget = {
625
826
  parentName: AXPBarChartWidget.name,
626
827
  widget: {
627
828
  ...AXPBarChartWidget,
628
- name: 'workflow-bar-chart',
629
- title: createMultiLanguageString('Workflow Pending Approvals by Age', 'تأییدهای در انتظار گردش کار بر اساس قدمت'),
829
+ name: RootConfig.widgets.barChart,
830
+ title: '@workflow-management:dashboard-widgets.workflow-bar-chart.widget-title',
831
+ description: '@workflow-management:dashboard-widgets.workflow-bar-chart.widget-description',
630
832
  groups: [AXPWidgetGroupEnum.DashboardWidget],
631
833
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
632
834
  options: {
633
- title: createMultiLanguageString('Pending Approvals by Age', 'تأییدهای در انتظار بر اساس قدمت'),
634
- xAxisLabel: createMultiLanguageString('Age Bucket', 'بازه قدمت'),
635
- yAxisLabel: createMultiLanguageString('Count', 'تعداد'),
835
+ title: '@workflow-management:dashboard-widgets.workflow-bar-chart.chart-title',
836
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-bar-chart.x-axis-label',
837
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-bar-chart.y-axis-label',
636
838
  dataSource: RootConfig.dataSources.dashboardChart.pendingApproval,
637
839
  },
638
840
  },
@@ -642,14 +844,15 @@ const AXMWorkflowTasksNearDeadlineBarChartAXPExtendedWidget = {
642
844
  parentName: AXPBarChartWidget.name,
643
845
  widget: {
644
846
  ...AXPBarChartWidget,
645
- name: 'workflow-tasks-near-deadline-bar',
646
- title: createMultiLanguageString('Workflow Tasks Near Deadline / SLA Risk', 'وظایف نزدیک مهلت / ریسک SLA'),
847
+ name: RootConfig.widgets.tasksNearDeadlineBar,
848
+ title: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.widget-title',
849
+ description: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.widget-description',
647
850
  groups: [AXPWidgetGroupEnum.DashboardWidget],
648
851
  categories: [AXP_WORKFLOW_DASHBOARD_WIDGET_CATEGORY],
649
852
  options: {
650
- title: createMultiLanguageString('Remaining time to deadline (minutes)', 'زمان باقی‌مانده تا مهلت (دقیقه)'),
651
- xAxisLabel: createMultiLanguageString('Task', 'وظیفه'),
652
- yAxisLabel: createMultiLanguageString('Minutes left', 'دقیقه باقی‌مانده'),
853
+ title: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.chart-title',
854
+ xAxisLabel: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.x-axis-label',
855
+ yAxisLabel: '@workflow-management:dashboard-widgets.workflow-tasks-near-deadline-bar.y-axis-label',
653
856
  dataSource: RootConfig.dataSources.dashboardChart.tasksNearDeadline,
654
857
  },
655
858
  },
@@ -681,6 +884,12 @@ const WORKFLOW_DASHBOARD_EXTENDED_WIDGETS = [
681
884
  AXMWorkflowFailedProcessesByTypeDonutChartAXPExtendedWidget,
682
885
  AXMWorkflowStuckProcessesBarChartAXPExtendedWidget,
683
886
  AXMWorkflowErrorsBarChartAXPExtendedWidget,
887
+ AXMWorkflowErrorsHeatmapAXPExtendedWidget,
888
+ AXMWorkflowInstanceConversionFunnelAXPExtendedWidget,
889
+ AXMWorkflowKpiProgressAXPExtendedWidget,
890
+ AXMWorkflowKpiSegmentedAXPExtendedWidget,
891
+ AXMWorkflowKpiDetailsAXPExtendedWidget,
892
+ AXMWorkflowKpiStatCardAXPExtendedWidget,
684
893
  ];
685
894
  //#endregion
686
895
  //#region ---- Provider ----
@@ -735,13 +944,13 @@ const AXMActivityCommandConfiguratorWidget = {
735
944
  ],
736
945
  components: {
737
946
  edit: {
738
- component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BGUPxGXP.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
947
+ component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
739
948
  },
740
949
  designer: {
741
- component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BGUPxGXP.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
950
+ component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-BYJpDQRs.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetEditComponent),
742
951
  },
743
952
  column: {
744
- component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-column.component-C8lgSjfc.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetColumnComponent),
953
+ component: () => import('./acorex-modules-workflow-management-activity-command-configurator-widget-column.component-CDo0QVFy.mjs').then((c) => c.AXMActivityCommandConfiguratorWidgetColumnComponent),
745
954
  },
746
955
  },
747
956
  };
@@ -1953,21 +2162,10 @@ class AXMWorkflowDefinitionProvider {
1953
2162
  }
1954
2163
  //#endregion
1955
2164
  //#region ---- AXPWorkflowProvider Implementation ----
1956
- async getList(categoryId) {
1957
- // Same as report: filter by categoryIds array with 'contains'
2165
+ async getList(_categoryId) {
1958
2166
  const result = await this.workflowDefinitionService.query({
1959
2167
  skip: 0,
1960
2168
  take: 1000,
1961
- filter: {
1962
- logic: 'and',
1963
- filters: [{
1964
- field: 'categoryIds',
1965
- operator: {
1966
- type: 'contains',
1967
- },
1968
- value: categoryId,
1969
- }]
1970
- }
1971
2169
  });
1972
2170
  // Convert entity data to workflow definition format
1973
2171
  return (result.items || []).map((item) => ({
@@ -2053,6 +2251,72 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2053
2251
  type: Injectable
2054
2252
  }] });
2055
2253
 
2254
+ //#region ---- Imports ----
2255
+ //#endregion
2256
+ //#region ---- Workflow definition lifecycle status ----
2257
+ /**
2258
+ * Publication lifecycle for workflow definitions: draft, review, published, archived.
2259
+ */
2260
+ class AXMWorkflowDefinitionStatusProvider extends AXPStatusProvider {
2261
+ constructor() {
2262
+ super(...arguments);
2263
+ this.key = 'workflow-management.status.workflow-definition';
2264
+ this.defaultStatus = AXPSystemStatusType.Draft;
2265
+ this.statuses = [
2266
+ systemStatusToDefinition(AXPSystemStatusType.Draft, {
2267
+ generateView: true,
2268
+ }),
2269
+ systemStatusToDefinition(AXPSystemStatusType.PendingReview, {
2270
+ generateView: true,
2271
+ }),
2272
+ systemStatusToDefinition(AXPSystemStatusType.Published, {
2273
+ generateView: true,
2274
+ }),
2275
+ systemStatusToDefinition(AXPSystemStatusType.Archived, {
2276
+ generateView: false,
2277
+ }),
2278
+ ];
2279
+ this.transitions = [
2280
+ {
2281
+ from: AXPSystemStatusType.Draft,
2282
+ to: AXPSystemStatusType.PendingReview,
2283
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.submit-review',
2284
+ },
2285
+ {
2286
+ from: AXPSystemStatusType.Draft,
2287
+ to: AXPSystemStatusType.Published,
2288
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.publish-direct',
2289
+ },
2290
+ {
2291
+ from: AXPSystemStatusType.PendingReview,
2292
+ to: AXPSystemStatusType.Published,
2293
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.publish',
2294
+ },
2295
+ {
2296
+ from: AXPSystemStatusType.PendingReview,
2297
+ to: AXPSystemStatusType.Draft,
2298
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.revise',
2299
+ },
2300
+ {
2301
+ from: AXPSystemStatusType.Published,
2302
+ to: AXPSystemStatusType.Draft,
2303
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.unpublish',
2304
+ },
2305
+ {
2306
+ from: AXPSystemStatusType.Published,
2307
+ to: AXPSystemStatusType.Archived,
2308
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.archive',
2309
+ },
2310
+ {
2311
+ from: AXPSystemStatusType.Draft,
2312
+ to: AXPSystemStatusType.Archived,
2313
+ title: '@workflow-management:workflow-definitions.entities.workflow-definition.status.transitions.archive',
2314
+ },
2315
+ ];
2316
+ }
2317
+ }
2318
+ //#endregion
2319
+
2056
2320
  //#region ---- Imports ----
2057
2321
  //#endregion
2058
2322
  //#region ---- Manifest Definition ----
@@ -2516,7 +2780,7 @@ class AXPGenericWorkflowTaskProvider extends AXPWorkflowTaskProvider {
2516
2780
  //#endregion
2517
2781
  //#region ---- Component ----
2518
2782
  getComponent() {
2519
- return () => import('./acorex-modules-workflow-management-workflow-task-popover.component-CIakASVR.mjs').then((m) => m.AXMWorkflowTaskPopoverComponent);
2783
+ return () => import('./acorex-modules-workflow-management-workflow-task-popover.component-NpUx0sB5.mjs').then((m) => m.AXMWorkflowTaskPopoverComponent);
2520
2784
  }
2521
2785
  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 }); }
2522
2786
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPGenericWorkflowTaskProvider }); }
@@ -2536,6 +2800,7 @@ function provideTaskWorkflow() {
2536
2800
  useFactory: (injector) => {
2537
2801
  return (async () => {
2538
2802
  const workflowDefinitionService = injector.get(AXPWorkflowDefinitionService);
2803
+ const multiLanguageResolver = injector.get(AXTranslationService);
2539
2804
  const categories = await workflowDefinitionService.getCategories();
2540
2805
  const providers = [];
2541
2806
  for (const category of categories) {
@@ -2543,7 +2808,7 @@ function provideTaskWorkflow() {
2543
2808
  for (const workflow of workflows) {
2544
2809
  const provider = runInInjectionContext(injector, () => new AXPGenericWorkflowTaskProvider({
2545
2810
  name: workflow.name,
2546
- title: workflow.title ?? workflow.name,
2811
+ title: multiLanguageResolver.resolve(workflow.title) ?? workflow.name,
2547
2812
  icon: 'fa-light fa-diagram-project',
2548
2813
  definitionId: workflow.name,
2549
2814
  }));
@@ -2594,13 +2859,21 @@ class AXMWorkflowManagementModule {
2594
2859
  useFactory: routesFactory,
2595
2860
  },
2596
2861
  provideCommandSetups([
2862
+ {
2863
+ key: 'WorkflowManagement.WorkflowDefinition:ExecuteWithInput',
2864
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
2865
+ },
2597
2866
  {
2598
2867
  key: 'WorkflowManagement.WorkflowDefinition:Execute',
2599
- command: () => import('./acorex-modules-workflow-management-index-DWIDQsWq.mjs').then((c) => c.ExecuteWorkflowCommand),
2868
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowCommand),
2600
2869
  },
2601
2870
  {
2602
2871
  key: 'WorkflowManagement.WorkflowDefinition:EditInStudio',
2603
- command: () => import('./acorex-modules-workflow-management-index-DWIDQsWq.mjs').then((c) => c.EditInStudioCommand),
2872
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.EditInStudioCommand),
2873
+ },
2874
+ {
2875
+ key: 'WorkflowManagement.WorkflowDefinition:Activities:Save',
2876
+ command: () => import('./acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs').then((c) => c.SaveWorkflowDefinitionActivitiesCommand),
2604
2877
  },
2605
2878
  {
2606
2879
  key: 'workflow-activity:show-toast',
@@ -2638,6 +2911,8 @@ class AXMWorkflowManagementModule {
2638
2911
  useClass: AXMWorkflowManagementModuleEntityProvider,
2639
2912
  multi: true,
2640
2913
  },
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)),
2641
2916
  // Automation condition builder: default automation.rules(refType, refId); modules override for their refTypes
2642
2917
  {
2643
2918
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
@@ -2645,6 +2920,11 @@ class AXMWorkflowManagementModule {
2645
2920
  multi: true,
2646
2921
  },
2647
2922
  // Menu Provider
2923
+ {
2924
+ provide: AXP_STATUS_PROVIDERS,
2925
+ useClass: AXMWorkflowDefinitionStatusProvider,
2926
+ multi: true,
2927
+ },
2648
2928
  {
2649
2929
  provide: AXP_MENU_PROVIDER,
2650
2930
  useClass: AXMMenuProvider,
@@ -2742,13 +3022,21 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2742
3022
  useFactory: routesFactory,
2743
3023
  },
2744
3024
  provideCommandSetups([
3025
+ {
3026
+ key: 'WorkflowManagement.WorkflowDefinition:ExecuteWithInput',
3027
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowWithInputCommand),
3028
+ },
2745
3029
  {
2746
3030
  key: 'WorkflowManagement.WorkflowDefinition:Execute',
2747
- command: () => import('./acorex-modules-workflow-management-index-DWIDQsWq.mjs').then((c) => c.ExecuteWorkflowCommand),
3031
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.ExecuteWorkflowCommand),
2748
3032
  },
2749
3033
  {
2750
3034
  key: 'WorkflowManagement.WorkflowDefinition:EditInStudio',
2751
- command: () => import('./acorex-modules-workflow-management-index-DWIDQsWq.mjs').then((c) => c.EditInStudioCommand),
3035
+ command: () => import('./acorex-modules-workflow-management-index-C9Qc07oK.mjs').then((c) => c.EditInStudioCommand),
3036
+ },
3037
+ {
3038
+ key: 'WorkflowManagement.WorkflowDefinition:Activities:Save',
3039
+ command: () => import('./acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs').then((c) => c.SaveWorkflowDefinitionActivitiesCommand),
2752
3040
  },
2753
3041
  {
2754
3042
  key: 'workflow-activity:show-toast',
@@ -2786,6 +3074,8 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2786
3074
  useClass: AXMWorkflowManagementModuleEntityProvider,
2787
3075
  multi: true,
2788
3076
  },
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)),
2789
3079
  // Automation condition builder: default automation.rules(refType, refId); modules override for their refTypes
2790
3080
  {
2791
3081
  provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER,
@@ -2793,6 +3083,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImpor
2793
3083
  multi: true,
2794
3084
  },
2795
3085
  // Menu Provider
3086
+ {
3087
+ provide: AXP_STATUS_PROVIDERS,
3088
+ useClass: AXMWorkflowDefinitionStatusProvider,
3089
+ multi: true,
3090
+ },
2796
3091
  {
2797
3092
  provide: AXP_MENU_PROVIDER,
2798
3093
  useClass: AXMMenuProvider,
@@ -2883,7 +3178,7 @@ class AXMActivityCategoriesTreeComponent {
2883
3178
  constructor() {
2884
3179
  //#region ---- Services & Dependencies ----
2885
3180
  this.activityDefinitionService = inject(AXPActivityDefinitionService);
2886
- this.multiLanguageResolver = inject(AXPMultiLanguageStringResolverService);
3181
+ this.multiLanguageResolver = inject(AXTranslationService);
2887
3182
  //#endregion
2888
3183
  //#region ---- Output Events ----
2889
3184
  this.categoryClick = output();
@@ -2910,7 +3205,7 @@ class AXMActivityCategoriesTreeComponent {
2910
3205
  const activities = await this.activityDefinitionService.getActivitiesByCategoryId(parentId);
2911
3206
  const definitionItems = activities.map((item) => ({
2912
3207
  id: `activity_${item.type ?? item.name}`,
2913
- title: item.title ?? item.name ?? item.type ?? '',
3208
+ title: this.multiLanguageResolver.resolve(item.title) || item.name || item.type || '',
2914
3209
  hasChild: false,
2915
3210
  item,
2916
3211
  type: 'definition',
@@ -3014,7 +3309,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3014
3309
  this.cachedPropertyViewerTabs.set([]);
3015
3310
  return;
3016
3311
  }
3017
- const structKey = `${node.id}:${node.type}:${(def?.inputs?.length ?? 0)}`;
3312
+ const structKey = `${node.id}:${node.type}:${def?.inputs?.length ?? 0}`;
3018
3313
  if (this.lastPropertyViewerStructKey === structKey)
3019
3314
  return;
3020
3315
  this.lastPropertyViewerStructKey = structKey;
@@ -3054,7 +3349,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3054
3349
  isLatest: true,
3055
3350
  isPublished: false,
3056
3351
  toolVersion: '1.0.0',
3057
- providerName: 'WorkflowStudio'
3352
+ providerName: 'WorkflowStudio',
3058
3353
  }, ...(ngDevMode ? [{ debugName: "workflowSettings" }] : /* istanbul ignore next */ []));
3059
3354
  /** Data source for variable type select (settings modal). */
3060
3355
  this.variableTypeOptions = [
@@ -3062,7 +3357,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3062
3357
  { value: 'number', label: 'Number' },
3063
3358
  { value: 'boolean', label: 'Boolean' },
3064
3359
  { value: 'object', label: 'Object' },
3065
- { value: 'array', label: 'Array' }
3360
+ { value: 'array', label: 'Array' },
3066
3361
  ];
3067
3362
  // Canvas state
3068
3363
  this.canvasOffset = { x: 0, y: 0 };
@@ -3104,9 +3399,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3104
3399
  }
3105
3400
  await this.loadWorkflowByName(workflowName);
3106
3401
  // Subscribe to query param changes (like drive component)
3107
- this.activatedRoute.queryParams
3108
- .pipe(takeUntilDestroyed(this.destroyRef))
3109
- .subscribe(async (params) => {
3402
+ this.activatedRoute.queryParams.pipe(takeUntilDestroyed(this.destroyRef)).subscribe(async (params) => {
3110
3403
  const newWorkflowName = params['workflow'];
3111
3404
  if (newWorkflowName && newWorkflowName !== workflowName) {
3112
3405
  await this.loadWorkflowByName(newWorkflowName);
@@ -3126,6 +3419,30 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3126
3419
  const value = ev.target.value;
3127
3420
  this.workflowJson.set(value);
3128
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
3129
3446
  /**
3130
3447
  * Load workflow by name
3131
3448
  */
@@ -3133,18 +3450,22 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3133
3450
  try {
3134
3451
  this.addLog('info', `Loading workflow: ${workflowName}...`);
3135
3452
  // Try to get workflow from entity service first
3136
- const workflowEntityService = this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name).data();
3453
+ const workflowEntityService = this.entityService
3454
+ .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3455
+ .data();
3137
3456
  const result = await workflowEntityService.query({
3138
3457
  skip: 0,
3139
3458
  take: 1,
3140
3459
  filter: {
3141
3460
  logic: 'and',
3142
- filters: [{
3461
+ filters: [
3462
+ {
3143
3463
  field: 'name',
3144
3464
  operator: { type: 'equal' },
3145
3465
  value: workflowName,
3146
- }]
3147
- }
3466
+ },
3467
+ ],
3468
+ },
3148
3469
  });
3149
3470
  let workflowDef = null;
3150
3471
  if (result.items && result.items.length > 0) {
@@ -3165,27 +3486,16 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3165
3486
  this.workflowSettings.set({
3166
3487
  definitionId: workflowDef.id || workflowDef.definitionId || workflowDef.name,
3167
3488
  name: workflowDef.name || '',
3168
- description: workflowDef.description || '',
3169
- inputs: (workflowDef.inputs || []).map((input) => ({
3170
- name: input.name,
3171
- title: input.title || input.name,
3172
- description: input.description,
3173
- schema: input.schema || { dataType: 'string' },
3174
- validations: input.validations,
3175
- })),
3176
- outputs: (workflowDef.outputs || []).map((output) => ({
3177
- name: output.name,
3178
- title: output.title || output.name,
3179
- description: output.description,
3180
- schema: output.schema || { dataType: 'string' },
3181
- })),
3489
+ description: this.resolveWorkflowDefinitionDescription(workflowDef),
3490
+ inputs: (workflowDef.inputs || []).map((input) => this.mapDefinitionInputToWorkflowInput(input)),
3491
+ outputs: (workflowDef.outputs || []).map((output) => this.mapDefinitionOutputToWorkflowOutput(output)),
3182
3492
  variables: workflowDef.variables || [],
3183
3493
  outcomes: workflowDef.outcomes || ['Done'],
3184
3494
  usableAsActivity: workflowDef.extensions?.elsa?.options?.usableAsActivity || false,
3185
3495
  autoUpdateConsumingWorkflows: workflowDef.extensions?.elsa?.options?.autoUpdateConsumingWorkflows || false,
3186
3496
  version: workflowDef.version || 1,
3187
3497
  isLatest: workflowDef.isLatest !== undefined ? workflowDef.isLatest : true,
3188
- isPublished: workflowDef.isPublished || false,
3498
+ isPublished: workflowDef.statusId === AXPSystemStatusType.Published,
3189
3499
  toolVersion: workflowDef.toolVersion || '1.0.0',
3190
3500
  providerName: workflowDef.providerName || 'ACoreX',
3191
3501
  });
@@ -3213,7 +3523,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3213
3523
  const rootActivity = {
3214
3524
  id: graph.startActivityId || 'root',
3215
3525
  type: 'workflow-activity:sequence',
3216
- name: workflowDef.title || workflowDef.name || 'Root',
3526
+ name: this.resolveWorkflowDefinitionTitle(workflowDef),
3217
3527
  children: [],
3218
3528
  };
3219
3529
  // Convert activities to children
@@ -3260,7 +3570,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3260
3570
  return {
3261
3571
  id: workflowDef.id || workflowDef.name || 'workflow',
3262
3572
  name: workflowDef.name || '',
3263
- description: workflowDef.description || '',
3573
+ description: this.resolveWorkflowDefinitionDescription(workflowDef),
3264
3574
  version: workflowDef.version || 1,
3265
3575
  root: rootActivity,
3266
3576
  };
@@ -3366,16 +3676,85 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3366
3676
  /**
3367
3677
  * Convert AXPActivityDefinition to ActivityInfo
3368
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
+ }
3369
3748
  convertActivityDefinitionToInfo(activity) {
3370
- const properties = (activity.inputs || []).map(input => ({
3749
+ const properties = (activity.inputs || []).map((input) => ({
3371
3750
  name: input.name,
3372
- type: this.getPropertyTypeFromSchema(input.schema),
3373
- required: !input.schema.nullable,
3374
- description: input.description,
3375
- defaultValue: input.schema.defaultValue
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,
3376
3755
  }));
3377
3756
  const defaultProperties = {};
3378
- properties.forEach(prop => {
3757
+ properties.forEach((prop) => {
3379
3758
  if (prop.defaultValue !== undefined) {
3380
3759
  defaultProperties[prop.name] = prop.defaultValue;
3381
3760
  }
@@ -3383,10 +3762,10 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3383
3762
  return {
3384
3763
  type: activity.type,
3385
3764
  name: activity.name,
3386
- description: activity.description || '',
3765
+ description: this.translationService.resolve(activity.description) || '',
3387
3766
  icon: this.normalizeActivityIcon(activity.icon),
3388
3767
  properties,
3389
- defaultProperties
3768
+ defaultProperties,
3390
3769
  };
3391
3770
  }
3392
3771
  /**
@@ -3400,10 +3779,9 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3400
3779
  return hasStylePrefix ? trimmed : `fa-light ${trimmed}`;
3401
3780
  }
3402
3781
  /**
3403
- * Get property type from schema
3782
+ * Map {@link AXPProperty.dataType} to visual editor property type.
3404
3783
  */
3405
- getPropertyTypeFromSchema(schema) {
3406
- const dataType = schema?.dataType || 'string';
3784
+ getPropertyTypeFromDataType(dataType) {
3407
3785
  if (dataType === 'array')
3408
3786
  return 'array';
3409
3787
  if (dataType === 'object')
@@ -3412,6 +3790,8 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3412
3790
  return 'boolean';
3413
3791
  if (dataType === 'number' || dataType === 'integer')
3414
3792
  return 'number';
3793
+ if (dataType === 'blob')
3794
+ return 'any';
3415
3795
  return 'string';
3416
3796
  }
3417
3797
  /**
@@ -3422,10 +3802,10 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3422
3802
  'workflow-markers': '#10B981',
3423
3803
  'control-flow': '#3B82F6',
3424
3804
  'user-interaction': '#8B5CF6',
3425
- 'data': '#10B981',
3426
- 'navigation': '#F59E0B',
3427
- 'events': '#EF4444',
3428
- 'http': '#06B6D4'
3805
+ data: '#10B981',
3806
+ navigation: '#F59E0B',
3807
+ events: '#EF4444',
3808
+ http: '#06B6D4',
3429
3809
  };
3430
3810
  return colorMap[categoryId] || '#64748B';
3431
3811
  }
@@ -3442,8 +3822,8 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3442
3822
  id: 'root',
3443
3823
  type: 'workflow-activity:sequence',
3444
3824
  name: 'Root',
3445
- children: []
3446
- }
3825
+ children: [],
3826
+ },
3447
3827
  }, null, 2);
3448
3828
  }
3449
3829
  //#endregion
@@ -3490,7 +3870,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3490
3870
  this.workflowInstanceState.set({
3491
3871
  status: 'running',
3492
3872
  startTime: new Date(),
3493
- currentState: null
3873
+ currentState: null,
3494
3874
  });
3495
3875
  this.addLog('info', 'شروع اجرای Workflow...');
3496
3876
  try {
@@ -3506,12 +3886,21 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3506
3886
  }
3507
3887
  // Save or update workflow definition
3508
3888
  try {
3509
- const existing = await this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name).data().byKey(workflowId);
3889
+ const existing = await this.entityService
3890
+ .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3891
+ .data()
3892
+ .byKey(workflowId);
3510
3893
  if (existing) {
3511
- await this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name).data().update(workflowId, definitionToSave);
3894
+ await this.entityService
3895
+ .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3896
+ .data()
3897
+ .update(workflowId, definitionToSave);
3512
3898
  }
3513
3899
  else {
3514
- await this.entityService.withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name).data().create({ ...definitionToSave, id: workflowId });
3900
+ await this.entityService
3901
+ .withEntity(RootConfig.module.name, RootConfig.entities.workflowDefinition.name)
3902
+ .data()
3903
+ .create({ ...definitionToSave, id: workflowId });
3515
3904
  }
3516
3905
  const saveMessage = await this.translationService.translateAsync('@workflow-management:test-pages.messages.success.workflow-saved');
3517
3906
  this.addLog('success', saveMessage);
@@ -3568,7 +3957,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3568
3957
  currentResult = {
3569
3958
  ...currentResult,
3570
3959
  success: false,
3571
- error: error.message || 'Task execution failed'
3960
+ error: error.message || 'Task execution failed',
3572
3961
  };
3573
3962
  break;
3574
3963
  }
@@ -3580,7 +3969,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3580
3969
  startTime: this.workflowInstanceState().startTime || new Date(),
3581
3970
  endTime: new Date(),
3582
3971
  result: currentResult,
3583
- currentState: currentResult.state?.output?.['taskStatus'] || currentResult.state?.output?.['currentState']
3972
+ currentState: currentResult.state?.output?.['taskStatus'] || currentResult.state?.output?.['currentState'],
3584
3973
  });
3585
3974
  if (currentResult.success) {
3586
3975
  this.addLog('success', `✅ Workflow با موفقیت اجرا شد! (${taskCount} task(s) executed)`, currentResult);
@@ -3594,7 +3983,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3594
3983
  this.workflowInstanceState.set({
3595
3984
  status: 'error',
3596
3985
  error: error.message,
3597
- startTime: this.workflowInstanceState().startTime
3986
+ startTime: this.workflowInstanceState().startTime,
3598
3987
  });
3599
3988
  }
3600
3989
  finally {
@@ -3610,7 +3999,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3610
3999
  timestamp: new Date(),
3611
4000
  level,
3612
4001
  message,
3613
- data
4002
+ data,
3614
4003
  });
3615
4004
  this.executionLogs.set([...logs]);
3616
4005
  }
@@ -3622,7 +4011,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3622
4011
  id: `${activity.type.toLowerCase()}-${Date.now()}`,
3623
4012
  type: activity.type,
3624
4013
  name: activity.name,
3625
- properties: {}
4014
+ properties: {},
3626
4015
  };
3627
4016
  // کپی در کلیپ‌بورد
3628
4017
  navigator.clipboard.writeText(JSON.stringify(template, null, 2));
@@ -3661,107 +4050,107 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3661
4050
  usableAsActivity: settings.usableAsActivity,
3662
4051
  autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows,
3663
4052
  toolVersion: settings.toolVersion ?? '1.0.0',
3664
- providerName: settings.providerName ?? 'WorkflowStudio'
4053
+ providerName: settings.providerName ?? 'WorkflowStudio',
3665
4054
  };
3666
4055
  this.layoutBuilder
3667
4056
  .create()
3668
- .dialog(dialog => {
4057
+ .dialog((dialog) => {
3669
4058
  dialog
3670
4059
  .setTitle('@workflow-management:workflow-studio.settings.title')
3671
4060
  .setSize('lg')
3672
4061
  .setCloseButton(true)
3673
4062
  .setContext(dialogContext)
3674
- .content(flex => {
4063
+ .content((flex) => {
3675
4064
  flex
3676
4065
  .setDirection('column')
3677
4066
  .setGap('12px')
3678
- .fieldset(general => {
4067
+ .fieldset((general) => {
3679
4068
  general
3680
4069
  .setTitle('@workflow-management:workflow-studio.settings.tabs.general')
3681
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.name.title', field => {
4070
+ .formField('@workflow-management:workflow-studio.settings.sections.general.fields.name.title', (field) => {
3682
4071
  field.path('name');
3683
4072
  field.textBox({
3684
- placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.name.placeholder'
4073
+ placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.name.placeholder',
3685
4074
  });
3686
4075
  })
3687
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.title', field => {
4076
+ .formField('@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.title', (field) => {
3688
4077
  field.path('definitionId');
3689
4078
  field.textBox({
3690
- placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.placeholder'
4079
+ placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.definition-id.placeholder',
3691
4080
  });
3692
4081
  })
3693
- .formField('@workflow-management:workflow-studio.settings.sections.general.fields.description.title', field => {
4082
+ .formField('@workflow-management:workflow-studio.settings.sections.general.fields.description.title', (field) => {
3694
4083
  field.path('description');
3695
4084
  field.largeTextBox({
3696
4085
  placeholder: '@workflow-management:workflow-studio.settings.sections.general.fields.description.placeholder',
3697
- rows: 4
4086
+ rows: 4,
3698
4087
  });
3699
4088
  });
3700
4089
  })
3701
- .fieldset(inputs => {
4090
+ .fieldset((inputs) => {
3702
4091
  inputs
3703
4092
  .setTitle('@workflow-management:workflow-studio.settings.tabs.inputs')
3704
- .formField('@workflow-management:workflow-studio.settings.sections.inputs.fields.inputs-json', field => {
4093
+ .formField('@workflow-management:workflow-studio.settings.sections.inputs.fields.inputs-json', (field) => {
3705
4094
  field.path('inputsJson');
3706
4095
  field.largeTextBox({ rows: 12 });
3707
4096
  });
3708
4097
  })
3709
- .fieldset(outputs => {
4098
+ .fieldset((outputs) => {
3710
4099
  outputs
3711
4100
  .setTitle('@workflow-management:workflow-studio.settings.tabs.outputs')
3712
- .formField('@workflow-management:workflow-studio.settings.sections.outputs.fields.outputs-json', field => {
4101
+ .formField('@workflow-management:workflow-studio.settings.sections.outputs.fields.outputs-json', (field) => {
3713
4102
  field.path('outputsJson');
3714
4103
  field.largeTextBox({ rows: 12 });
3715
4104
  });
3716
4105
  })
3717
- .fieldset(variables => {
4106
+ .fieldset((variables) => {
3718
4107
  variables
3719
4108
  .setTitle('@workflow-management:workflow-studio.settings.tabs.variables')
3720
- .formField('@workflow-management:workflow-studio.settings.sections.variables.fields.variables-json', field => {
4109
+ .formField('@workflow-management:workflow-studio.settings.sections.variables.fields.variables-json', (field) => {
3721
4110
  field.path('variablesJson');
3722
4111
  field.largeTextBox({ rows: 12 });
3723
4112
  });
3724
4113
  })
3725
- .fieldset(advanced => {
4114
+ .fieldset((advanced) => {
3726
4115
  advanced
3727
4116
  .setTitle('@workflow-management:workflow-studio.settings.tabs.advanced')
3728
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.version', field => {
4117
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.version', (field) => {
3729
4118
  field.path('version');
3730
4119
  field.numberBox({ min: 1 });
3731
4120
  })
3732
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-latest', field => {
4121
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-latest', (field) => {
3733
4122
  field.path('isLatest');
3734
4123
  field.toggleSwitch();
3735
4124
  })
3736
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-published', field => {
4125
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.is-published', (field) => {
3737
4126
  field.path('isPublished');
3738
4127
  field.toggleSwitch();
3739
4128
  })
3740
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.usable-as-activity', field => {
4129
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.usable-as-activity', (field) => {
3741
4130
  field.path('usableAsActivity');
3742
4131
  field.toggleSwitch();
3743
4132
  })
3744
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.auto-update-consuming', field => {
4133
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.auto-update-consuming', (field) => {
3745
4134
  field.path('autoUpdateConsumingWorkflows');
3746
4135
  field.toggleSwitch();
3747
4136
  })
3748
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.tool-version', field => {
4137
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.tool-version', (field) => {
3749
4138
  field.path('toolVersion');
3750
4139
  field.textBox({ placeholder: '1.0.0' });
3751
4140
  })
3752
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.provider-name', field => {
4141
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.provider-name', (field) => {
3753
4142
  field.path('providerName');
3754
4143
  field.textBox({ placeholder: 'WorkflowStudio' });
3755
4144
  })
3756
- .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-label', field => {
4145
+ .formField('@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-label', (field) => {
3757
4146
  field.path('outcomesJson');
3758
4147
  field.textBox({
3759
- placeholder: '@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-placeholder'
4148
+ placeholder: '@workflow-management:workflow-studio.settings.sections.advanced.fields.outcomes-placeholder',
3760
4149
  });
3761
4150
  });
3762
4151
  });
3763
4152
  })
3764
- .setActions(actions => {
4153
+ .setActions((actions) => {
3765
4154
  actions
3766
4155
  .cancel('@workflow-management:workflow-studio.settings.actions.cancel')
3767
4156
  .submit('@workflow-management:workflow-studio.settings.actions.save');
@@ -3802,7 +4191,10 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3802
4191
  this.addLog('error', 'Invalid variables JSON');
3803
4192
  }
3804
4193
  if (typeof ctx.outcomesJson === 'string' && ctx.outcomesJson.trim()) {
3805
- outcomes = ctx.outcomesJson.split(',').map((s) => s.trim()).filter(Boolean);
4194
+ outcomes = ctx.outcomesJson
4195
+ .split(',')
4196
+ .map((s) => s.trim())
4197
+ .filter(Boolean);
3806
4198
  }
3807
4199
  if (outcomes.length === 0)
3808
4200
  outcomes = ['Done'];
@@ -3820,7 +4212,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3820
4212
  usableAsActivity: Boolean(ctx.usableAsActivity),
3821
4213
  autoUpdateConsumingWorkflows: Boolean(ctx.autoUpdateConsumingWorkflows),
3822
4214
  toolVersion: String(ctx.toolVersion ?? '1.0.0'),
3823
- providerName: String(ctx.providerName ?? 'WorkflowStudio')
4215
+ providerName: String(ctx.providerName ?? 'WorkflowStudio'),
3824
4216
  };
3825
4217
  this.workflowSettings.set(newSettings);
3826
4218
  this.applyWorkflowSettingsToJson();
@@ -3834,49 +4226,12 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3834
4226
  syncWorkflowSettingsFromJson() {
3835
4227
  try {
3836
4228
  const workflow = JSON.parse(this.workflowJson());
3837
- const convertInput = (input) => {
3838
- if (input.schema) {
3839
- return {
3840
- name: input.name,
3841
- title: input.title || input.name,
3842
- description: input.description,
3843
- schema: input.schema,
3844
- validations: input.validations
3845
- };
3846
- }
3847
- return {
3848
- name: input.name,
3849
- title: input.name,
3850
- description: input.description,
3851
- schema: {
3852
- dataType: input.typeName || 'string',
3853
- defaultValue: input.defaultValue
3854
- },
3855
- validations: input.isRequired ? [{ rule: 'required' }] : undefined
3856
- };
3857
- };
3858
- const convertOutput = (output) => {
3859
- if (output.schema) {
3860
- return {
3861
- name: output.name,
3862
- title: output.title || output.name,
3863
- description: output.description,
3864
- schema: output.schema
3865
- };
3866
- }
3867
- return {
3868
- name: output.name,
3869
- title: output.title || output.name,
3870
- description: output.description,
3871
- schema: { dataType: output.typeName || 'string' }
3872
- };
3873
- };
3874
4229
  this.workflowSettings.set({
3875
4230
  definitionId: workflow.definitionId || workflow.id || '',
3876
4231
  name: workflow.name || '',
3877
- description: workflow.description || '',
3878
- inputs: (workflow.inputs || []).map(convertInput),
3879
- outputs: (workflow.outputs || []).map(convertOutput),
4232
+ description: this.resolveWorkflowDefinitionDescription(workflow),
4233
+ inputs: (workflow.inputs || []).map((input) => this.mapDefinitionInputToWorkflowInput(input)),
4234
+ outputs: (workflow.outputs || []).map((output) => this.mapDefinitionOutputToWorkflowOutput(output)),
3880
4235
  variables: workflow.variables || [],
3881
4236
  outcomes: workflow.outcomes || ['Done'],
3882
4237
  usableAsActivity: workflow.options?.usableAsActivity || false,
@@ -3885,7 +4240,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3885
4240
  isLatest: workflow.isLatest !== undefined ? workflow.isLatest : true,
3886
4241
  isPublished: workflow.isPublished || false,
3887
4242
  toolVersion: workflow.toolVersion || '1.0.0',
3888
- providerName: workflow.providerName || 'WorkflowStudio'
4243
+ providerName: workflow.providerName || 'WorkflowStudio',
3889
4244
  });
3890
4245
  }
3891
4246
  catch {
@@ -3903,7 +4258,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3903
4258
  isLatest: true,
3904
4259
  isPublished: false,
3905
4260
  toolVersion: '1.0.0',
3906
- providerName: 'WorkflowStudio'
4261
+ providerName: 'WorkflowStudio',
3907
4262
  });
3908
4263
  }
3909
4264
  }
@@ -3924,33 +4279,31 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3924
4279
  workflow.providerName = settings.providerName;
3925
4280
  workflow.options = {
3926
4281
  usableAsActivity: settings.usableAsActivity,
3927
- autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows
4282
+ autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows,
3928
4283
  };
3929
- workflow.variables = settings.variables.map(v => ({
4284
+ workflow.variables = settings.variables.map((v) => ({
3930
4285
  id: v.name,
3931
4286
  name: v.name,
3932
4287
  typeName: v.typeName,
3933
4288
  value: v.value,
3934
- storageDriverType: 'Memory'
4289
+ storageDriverType: 'Memory',
3935
4290
  }));
3936
- workflow.inputs = settings.inputs.map(i => ({
4291
+ workflow.inputs = settings.inputs.map((i) => ({
3937
4292
  name: i.name,
3938
4293
  title: i.title,
3939
4294
  description: i.description,
3940
- schema: {
3941
- dataType: i.schema.dataType,
3942
- nullable: i.schema.nullable,
3943
- readonly: i.schema.readonly,
3944
- hidden: i.schema.hidden,
3945
- defaultValue: i.schema.defaultValue
3946
- },
3947
- validations: i.validations
4295
+ dataType: i.schema.dataType,
4296
+ interface: i.schema.interface ?? { type: 'text-editor', options: {} },
4297
+ validations: i.validations,
3948
4298
  }));
3949
- workflow.outputs = settings.outputs.map(o => ({
4299
+ workflow.outputs = settings.outputs.map((o) => ({
3950
4300
  name: o.name,
3951
4301
  title: o.title,
3952
4302
  description: o.description,
3953
- schema: { dataType: o.schema.dataType }
4303
+ dataType: o.schema.dataType,
4304
+ interface: o.schema.interface ?? { type: 'text-editor', options: {} },
4305
+ path: o.path,
4306
+ metadata: o.metadata,
3954
4307
  }));
3955
4308
  workflow.outcomes = settings.outcomes;
3956
4309
  workflow.customProperties = workflow.customProperties || {};
@@ -3981,50 +4334,46 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
3981
4334
  // Identification fields
3982
4335
  definitionId: settings.definitionId || workflow.id || this.generateId(),
3983
4336
  name: settings.name || workflow.name || 'Untitled Workflow',
3984
- description: settings.description || workflow.description || '',
4337
+ description: settings.description || this.resolveWorkflowDefinitionDescription(workflow),
3985
4338
  toolVersion: settings.toolVersion || '3.0.0',
3986
4339
  // Materialization fields
3987
4340
  providerName: settings.providerName || 'ACoreX',
3988
4341
  materializerContext: {
3989
4342
  materializerName: 'Json',
3990
4343
  // Store the root activity as JSON string
3991
- stringData: JSON.stringify(workflow.root)
4344
+ stringData: JSON.stringify(workflow.root),
3992
4345
  },
3993
4346
  // WorkflowCommon fields
3994
4347
  options: {
3995
4348
  usableAsActivity: settings.usableAsActivity || false,
3996
- autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows || false
4349
+ autoUpdateConsumingWorkflows: settings.autoUpdateConsumingWorkflows || false,
3997
4350
  },
3998
4351
  // Variables array
3999
- variables: settings.variables.map(v => ({
4352
+ variables: settings.variables.map((v) => ({
4000
4353
  id: v.name,
4001
4354
  name: v.name,
4002
4355
  typeName: v.typeName,
4003
4356
  value: v.value,
4004
- storageDriverType: 'Memory'
4357
+ storageDriverType: 'Memory',
4005
4358
  })),
4006
- // Inputs array
4007
- inputs: settings.inputs.map(i => ({
4359
+ // Inputs array (aligned with {@link AXPProperty})
4360
+ inputs: settings.inputs.map((i) => ({
4008
4361
  name: i.name,
4009
4362
  title: i.title,
4010
4363
  description: i.description,
4011
- schema: {
4012
- dataType: i.schema.dataType,
4013
- nullable: i.schema.nullable,
4014
- readonly: i.schema.readonly,
4015
- hidden: i.schema.hidden,
4016
- defaultValue: i.schema.defaultValue
4017
- },
4018
- validations: i.validations || []
4364
+ dataType: i.schema.dataType,
4365
+ interface: i.schema.interface ?? { type: 'text-editor', options: {} },
4366
+ validations: i.validations || [],
4019
4367
  })),
4020
- // Outputs array
4021
- outputs: settings.outputs.map(o => ({
4368
+ // Outputs array (aligned with {@link AXPWorkflowOutputProperty})
4369
+ outputs: settings.outputs.map((o) => ({
4022
4370
  name: o.name,
4023
4371
  title: o.title,
4024
4372
  description: o.description,
4025
- schema: {
4026
- dataType: o.schema.dataType
4027
- }
4373
+ dataType: o.schema.dataType,
4374
+ interface: o.schema.interface ?? { type: 'text-editor', options: {} },
4375
+ path: o.path,
4376
+ metadata: o.metadata,
4028
4377
  })),
4029
4378
  // Outcomes array
4030
4379
  outcomes: settings.outcomes || ['Done'],
@@ -4034,7 +4383,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4034
4383
  isReadonly: false,
4035
4384
  isSystem: false,
4036
4385
  // Root activity (direct reference for Elsa compatibility)
4037
- root: workflow.root
4386
+ root: workflow.root,
4038
4387
  };
4039
4388
  return definition;
4040
4389
  }
@@ -4071,9 +4420,10 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4071
4420
  description: '',
4072
4421
  schema: {
4073
4422
  dataType: 'string',
4074
- defaultValue: undefined
4423
+ defaultValue: undefined,
4424
+ interface: { type: 'text-editor', options: {} },
4075
4425
  },
4076
- validations: undefined
4426
+ validations: undefined,
4077
4427
  });
4078
4428
  this.workflowSettings.set({ ...settings });
4079
4429
  }
@@ -4093,7 +4443,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4093
4443
  // For nested schema properties like 'schema.dataType'
4094
4444
  const schemaField = field.replace('schema.', '');
4095
4445
  if (!input.schema) {
4096
- input.schema = { dataType: 'string' };
4446
+ input.schema = { dataType: 'string', interface: { type: 'text-editor', options: {} } };
4097
4447
  }
4098
4448
  input.schema[schemaField] = value;
4099
4449
  }
@@ -4106,7 +4456,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4106
4456
  const settings = this.workflowSettings();
4107
4457
  const input = settings.inputs[index];
4108
4458
  if (!input.schema) {
4109
- input.schema = { dataType: 'string' };
4459
+ input.schema = { dataType: 'string', interface: { type: 'text-editor', options: {} } };
4110
4460
  }
4111
4461
  input.schema[schemaField] = value;
4112
4462
  this.workflowSettings.set({ ...settings });
@@ -4118,12 +4468,12 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4118
4468
  if (!input.validations) {
4119
4469
  input.validations = [];
4120
4470
  }
4121
- if (!input.validations.some(v => v.rule === 'required')) {
4471
+ if (!input.validations.some((v) => v.rule === 'required')) {
4122
4472
  input.validations.push({ rule: 'required' });
4123
4473
  }
4124
4474
  }
4125
4475
  else {
4126
- input.validations = input.validations?.filter(v => v.rule !== 'required');
4476
+ input.validations = input.validations?.filter((v) => v.rule !== 'required');
4127
4477
  if (input.validations?.length === 0) {
4128
4478
  input.validations = undefined;
4129
4479
  }
@@ -4131,7 +4481,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4131
4481
  this.workflowSettings.set({ ...settings });
4132
4482
  }
4133
4483
  getInputIsRequired(input) {
4134
- return input.validations?.some(v => v.rule === 'required') ?? false;
4484
+ return input.validations?.some((v) => v.rule === 'required') ?? false;
4135
4485
  }
4136
4486
  // ============ Workflow Outputs Management ============
4137
4487
  addWorkflowOutput() {
@@ -4141,8 +4491,8 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4141
4491
  title: `Output ${settings.outputs.length + 1}`,
4142
4492
  description: '',
4143
4493
  schema: {
4144
- dataType: 'string'
4145
- }
4494
+ dataType: 'string',
4495
+ },
4146
4496
  });
4147
4497
  this.workflowSettings.set({ ...settings });
4148
4498
  }
@@ -4183,7 +4533,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4183
4533
  name: `variable${settings.variables.length + 1}`,
4184
4534
  typeName: 'string',
4185
4535
  value: '',
4186
- description: ''
4536
+ description: '',
4187
4537
  });
4188
4538
  this.workflowSettings.set({ ...settings });
4189
4539
  }
@@ -4204,8 +4554,8 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4204
4554
  const settings = this.workflowSettings();
4205
4555
  settings.outcomes = outcomesString
4206
4556
  .split(',')
4207
- .map(o => o.trim())
4208
- .filter(o => o.length > 0);
4557
+ .map((o) => o.trim())
4558
+ .filter((o) => o.length > 0);
4209
4559
  this.workflowSettings.set({ ...settings });
4210
4560
  }
4211
4561
  /**
@@ -4245,10 +4595,10 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4245
4595
  * حذف Node
4246
4596
  */
4247
4597
  deleteNode(nodeId) {
4248
- const nodes = this.visualNodes().filter(n => n.id !== nodeId);
4598
+ const nodes = this.visualNodes().filter((n) => n.id !== nodeId);
4249
4599
  // حذف اتصالات به این نود
4250
- nodes.forEach(n => {
4251
- n.connections = n.connections.filter(c => c !== nodeId);
4600
+ nodes.forEach((n) => {
4601
+ n.connections = n.connections.filter((c) => c !== nodeId);
4252
4602
  });
4253
4603
  this.visualNodes.set(nodes);
4254
4604
  if (this.selectedNode()?.id === nodeId) {
@@ -4261,15 +4611,15 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4261
4611
  */
4262
4612
  connectNodes(fromId, toId, outcome) {
4263
4613
  const nodes = this.visualNodes();
4264
- const fromNodeIndex = nodes.findIndex(n => n.id === fromId);
4265
- const toNode = nodes.find(n => n.id === toId);
4614
+ const fromNodeIndex = nodes.findIndex((n) => n.id === fromId);
4615
+ const toNode = nodes.find((n) => n.id === toId);
4266
4616
  if (fromNodeIndex !== -1 && toNode) {
4267
4617
  const fromNode = nodes[fromNodeIndex];
4268
4618
  // Use outcome-based connections if available
4269
4619
  if (outcome && fromNode.outcomes && fromNode.outcomes.length > 1) {
4270
4620
  const outcomeConnections = fromNode.outcomeConnections || [];
4271
4621
  // Check if this outcome already has a connection
4272
- const existingConnection = outcomeConnections.find(c => c.outcome === outcome);
4622
+ const existingConnection = outcomeConnections.find((c) => c.outcome === outcome);
4273
4623
  if (existingConnection) {
4274
4624
  this.addLog('warning', `⚠️ Outcome "${outcome}" قبلاً متصل شده است`);
4275
4625
  return;
@@ -4279,7 +4629,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4279
4629
  updatedNodes[fromNodeIndex] = {
4280
4630
  ...fromNode,
4281
4631
  outcomeConnections: [...outcomeConnections, { outcome, targetNodeId: toId }],
4282
- connections: [...fromNode.connections, toId] // Keep for backward compat
4632
+ connections: [...fromNode.connections, toId], // Keep for backward compat
4283
4633
  };
4284
4634
  this.visualNodes.set(updatedNodes);
4285
4635
  this.addLog('success', `🔗 ${fromNode.name} [${outcome}] → ${toNode.name}`);
@@ -4290,7 +4640,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4290
4640
  const updatedNodes = [...nodes];
4291
4641
  updatedNodes[fromNodeIndex] = {
4292
4642
  ...fromNode,
4293
- connections: [...fromNode.connections, toId]
4643
+ connections: [...fromNode.connections, toId],
4294
4644
  };
4295
4645
  this.visualNodes.set(updatedNodes);
4296
4646
  this.addLog('success', `🔗 ${fromNode.name} متصل شد به ${toNode.name}`);
@@ -4309,7 +4659,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4309
4659
  */
4310
4660
  disconnectNodes(fromId, toId, outcome) {
4311
4661
  const nodes = this.visualNodes();
4312
- const fromNodeIndex = nodes.findIndex(n => n.id === fromId);
4662
+ const fromNodeIndex = nodes.findIndex((n) => n.id === fromId);
4313
4663
  if (fromNodeIndex !== -1) {
4314
4664
  const fromNode = nodes[fromNodeIndex];
4315
4665
  const updatedNodes = [...nodes];
@@ -4317,16 +4667,16 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4317
4667
  if (outcome && fromNode.outcomeConnections) {
4318
4668
  updatedNodes[fromNodeIndex] = {
4319
4669
  ...fromNode,
4320
- outcomeConnections: fromNode.outcomeConnections.filter(c => !(c.outcome === outcome && c.targetNodeId === toId)),
4321
- connections: fromNode.connections.filter(c => c !== toId)
4670
+ outcomeConnections: fromNode.outcomeConnections.filter((c) => !(c.outcome === outcome && c.targetNodeId === toId)),
4671
+ connections: fromNode.connections.filter((c) => c !== toId),
4322
4672
  };
4323
4673
  }
4324
4674
  else {
4325
4675
  // Simple disconnect
4326
4676
  updatedNodes[fromNodeIndex] = {
4327
4677
  ...fromNode,
4328
- connections: fromNode.connections.filter(c => c !== toId),
4329
- outcomeConnections: fromNode.outcomeConnections?.filter(c => c.targetNodeId !== toId)
4678
+ connections: fromNode.connections.filter((c) => c !== toId),
4679
+ outcomeConnections: fromNode.outcomeConnections?.filter((c) => c.targetNodeId !== toId),
4330
4680
  };
4331
4681
  }
4332
4682
  this.visualNodes.set(updatedNodes);
@@ -4372,12 +4722,12 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4372
4722
  position: { x, y },
4373
4723
  connections: connections,
4374
4724
  outcomeConnections: outcomeConnections,
4375
- outcomes: outcomes
4725
+ outcomes: outcomes,
4376
4726
  };
4377
4727
  nodes.push(node);
4378
4728
  // اگر parent دارد، اتصال برقرار کن (برای Sequence)
4379
4729
  if (parentId && !outcomeConnections.length) {
4380
- const parentNode = nodes.find(n => n.id === parentId);
4730
+ const parentNode = nodes.find((n) => n.id === parentId);
4381
4731
  if (parentNode && !parentNode.connections.includes(nodeId)) {
4382
4732
  parentNode.connections.push(nodeId);
4383
4733
  }
@@ -4386,7 +4736,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4386
4736
  if (activity.children && Array.isArray(activity.children) && !outcomeConnections.length) {
4387
4737
  let childY = y;
4388
4738
  activity.children.forEach((child, index) => {
4389
- childY = y + (index * 100);
4739
+ childY = y + index * 100;
4390
4740
  this.processActivityToNode(child, nodes, x + 250, childY, nodeId);
4391
4741
  });
4392
4742
  }
@@ -4412,7 +4762,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4412
4762
  id: 'visual-workflow-' + Date.now(),
4413
4763
  name: 'Visual Workflow',
4414
4764
  version: 1,
4415
- root: this.nodeToActivity(rootNode, nodes)
4765
+ root: this.nodeToActivity(rootNode, nodes),
4416
4766
  };
4417
4767
  this.workflowJson.set(JSON.stringify(workflow, null, 2));
4418
4768
  this.addLog('success', '✅ Visual به JSON تبدیل شد');
@@ -4427,8 +4777,8 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4427
4777
  findRootNode(nodes) {
4428
4778
  // Node ای که به آن اشاره نشده
4429
4779
  const connectedIds = new Set();
4430
- nodes.forEach(n => n.connections.forEach(c => connectedIds.add(c)));
4431
- const rootNodes = nodes.filter(n => !connectedIds.has(n.id));
4780
+ nodes.forEach((n) => n.connections.forEach((c) => connectedIds.add(c)));
4781
+ const rootNodes = nodes.filter((n) => !connectedIds.has(n.id));
4432
4782
  return rootNodes[0] || nodes[0];
4433
4783
  }
4434
4784
  /**
@@ -4439,14 +4789,14 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4439
4789
  id: node.id,
4440
4790
  type: node.type,
4441
4791
  name: node.name,
4442
- properties: node.properties
4792
+ properties: node.properties,
4443
4793
  };
4444
4794
  // اگر children دارد (connections)
4445
4795
  if (node.connections.length > 0) {
4446
4796
  const children = node.connections
4447
- .map(connId => allNodes.find(n => n.id === connId))
4448
- .filter(n => n !== undefined)
4449
- .map(childNode => this.nodeToActivity(childNode, allNodes));
4797
+ .map((connId) => allNodes.find((n) => n.id === connId))
4798
+ .filter((n) => n !== undefined)
4799
+ .map((childNode) => this.nodeToActivity(childNode, allNodes));
4450
4800
  if (children.length > 0) {
4451
4801
  activity.children = children;
4452
4802
  }
@@ -4468,7 +4818,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4468
4818
  'workflow-activity:entity-create': 'fa-light fa-plus',
4469
4819
  'workflow-activity:entity-read': 'fa-light fa-book-open',
4470
4820
  'workflow-activity:entity-update': 'fa-light fa-pen',
4471
- 'workflow-activity:entity-delete': 'fa-light fa-trash'
4821
+ 'workflow-activity:entity-delete': 'fa-light fa-trash',
4472
4822
  };
4473
4823
  return iconMap[type] || 'fa-light fa-circle';
4474
4824
  }
@@ -4477,46 +4827,47 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4477
4827
  */
4478
4828
  updateNodeProperty(nodeId, propertyName, value) {
4479
4829
  const nodes = this.visualNodes();
4480
- const nodeIndex = nodes.findIndex(n => n.id === nodeId);
4830
+ const nodeIndex = nodes.findIndex((n) => n.id === nodeId);
4481
4831
  if (nodeIndex !== -1) {
4482
4832
  const node = nodes[nodeIndex];
4483
4833
  const updatedNodes = [...nodes];
4484
4834
  if (propertyName === 'name') {
4485
4835
  updatedNodes[nodeIndex] = {
4486
4836
  ...node,
4487
- name: value
4837
+ name: value,
4488
4838
  };
4489
4839
  }
4490
4840
  else {
4491
4841
  const newProperties = {
4492
4842
  ...node.properties,
4493
- [propertyName]: value
4843
+ [propertyName]: value,
4494
4844
  };
4495
4845
  let newOutcomes = node.outcomes;
4496
4846
  const shouldRecomputeOutcomes = (propertyName === 'expectedStatusCodes' && node.type === 'workflow-activity:http-request') ||
4497
4847
  (propertyName === 'actions' && node.type === 'workflow-activity:human-task');
4498
4848
  if (shouldRecomputeOutcomes) {
4499
- this.findActivityInfo(node.type).then(activityInfo => {
4849
+ this.findActivityInfo(node.type)
4850
+ .then((activityInfo) => {
4500
4851
  if (activityInfo) {
4501
4852
  const computedOutcomes = this.computeOutcomes(activityInfo, newProperties);
4502
4853
  const updatedNodes = this.visualNodes();
4503
- const nodeIdx = updatedNodes.findIndex(n => n.id === nodeId);
4854
+ const nodeIdx = updatedNodes.findIndex((n) => n.id === nodeId);
4504
4855
  if (nodeIdx !== -1) {
4505
4856
  updatedNodes[nodeIdx] = {
4506
4857
  ...updatedNodes[nodeIdx],
4507
- outcomes: computedOutcomes
4858
+ outcomes: computedOutcomes,
4508
4859
  };
4509
4860
  this.visualNodes.set([...updatedNodes]);
4510
4861
  this.addLog('info', `🔄 Outcomes updated: [${computedOutcomes.join(', ')}]`);
4511
4862
  }
4512
4863
  }
4513
- }).catch(() => {
4514
- });
4864
+ })
4865
+ .catch(() => { });
4515
4866
  }
4516
4867
  updatedNodes[nodeIndex] = {
4517
4868
  ...node,
4518
4869
  properties: newProperties,
4519
- outcomes: newOutcomes
4870
+ outcomes: newOutcomes,
4520
4871
  };
4521
4872
  }
4522
4873
  this.visualNodes.set(updatedNodes);
@@ -4628,7 +4979,9 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4628
4979
  return;
4629
4980
  visited.add(n.id);
4630
4981
  ordered.push(n);
4631
- const targets = (n.outcomeConnections ?? []).map((c) => this.findNodeById(c.targetNodeId)).filter(Boolean);
4982
+ const targets = (n.outcomeConnections ?? [])
4983
+ .map((c) => this.findNodeById(c.targetNodeId))
4984
+ .filter(Boolean);
4632
4985
  for (const t of targets)
4633
4986
  add(t);
4634
4987
  const fallback = (n.connections ?? []).map((id) => this.findNodeById(id)).filter(Boolean);
@@ -4733,7 +5086,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4733
5086
  'workflow-activity:entity-create': ['Done', 'Failed'],
4734
5087
  'workflow-activity:entity-read': ['Done', 'NotFound', 'Failed'],
4735
5088
  'workflow-activity:entity-update': ['Done', 'Failed'],
4736
- 'workflow-activity:entity-delete': ['Done', 'Failed']
5089
+ 'workflow-activity:entity-delete': ['Done', 'Failed'],
4737
5090
  };
4738
5091
  return outcomeMap[activityInfo.type] || ['Done'];
4739
5092
  }
@@ -4760,7 +5113,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4760
5113
  position: { x: Math.max(0, x), y: Math.max(0, y) },
4761
5114
  connections: [],
4762
5115
  outcomeConnections: [],
4763
- outcomes: this.computeOutcomes(this.draggedActivity, defaultProps)
5116
+ outcomes: this.computeOutcomes(this.draggedActivity, defaultProps),
4764
5117
  };
4765
5118
  this.visualNodes.set([...nodes, newNode]);
4766
5119
  const outcomesInfo = newNode.outcomes && newNode.outcomes.length > 1
@@ -4778,7 +5131,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4778
5131
  const rect = target.getBoundingClientRect();
4779
5132
  this.nodeDragOffset = {
4780
5133
  x: event.clientX - rect.left,
4781
- y: event.clientY - rect.top
5134
+ y: event.clientY - rect.top,
4782
5135
  };
4783
5136
  if (event.dataTransfer) {
4784
5137
  event.dataTransfer.effectAllowed = 'move';
@@ -4802,11 +5155,11 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4802
5155
  const x = event.clientX - rect.left - this.nodeDragOffset.x;
4803
5156
  const y = event.clientY - rect.top - this.nodeDragOffset.y;
4804
5157
  const nodes = this.visualNodes();
4805
- const nodeIndex = nodes.findIndex(n => n.id === node.id);
5158
+ const nodeIndex = nodes.findIndex((n) => n.id === node.id);
4806
5159
  if (nodeIndex !== -1) {
4807
5160
  nodes[nodeIndex].position = {
4808
5161
  x: Math.max(0, x),
4809
- y: Math.max(0, y)
5162
+ y: Math.max(0, y),
4810
5163
  };
4811
5164
  this.visualNodes.set([...nodes]);
4812
5165
  }
@@ -4926,26 +5279,17 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4926
5279
  };
4927
5280
  }
4928
5281
  activityInputToWidgetProperty(input, group, order) {
4929
- const path = `properties.${input.name}`;
4930
- const iface = input.schema?.interface;
4931
- const widgetType = iface?.type ?? 'text-editor';
4932
- return {
4933
- name: input.name,
4934
- title: input.title,
5282
+ return mapAXPPropertyToWidgetProperty(input, {
4935
5283
  group,
4936
5284
  order,
4937
- schema: {
4938
- dataType: input.schema?.dataType ?? 'string',
4939
- defaultValue: input.schema?.defaultValue,
4940
- interface: {
4941
- path,
4942
- name: input.name,
4943
- type: widgetType,
4944
- options: iface?.options ?? {},
4945
- },
4946
- },
4947
- visible: true,
4948
- };
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
+ });
4949
5293
  }
4950
5294
  /**
4951
5295
  * Apply property viewer context changes back to the selected node.
@@ -4968,7 +5312,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
4968
5312
  * پیدا کردن Node با ID
4969
5313
  */
4970
5314
  findNodeById(nodeId) {
4971
- return this.visualNodes().find(n => n.id === nodeId);
5315
+ return this.visualNodes().find((n) => n.id === nodeId);
4972
5316
  }
4973
5317
  /**
4974
5318
  * بررسی اینکه آیا properties خالی است یا نه
@@ -5008,16 +5352,16 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
5008
5352
  getOutcomeColor(outcome) {
5009
5353
  const colorMap = {
5010
5354
  '200': '#10b981', // Green - Success
5011
- 'Done': '#10b981', // Green - Success
5012
- 'Success': '#10b981', // Green - Success
5355
+ Done: '#10b981', // Green - Success
5356
+ Success: '#10b981', // Green - Success
5013
5357
  '404': '#ef4444', // Red - Error
5014
5358
  '500': '#ef4444', // Red - Error
5015
- 'Failed': '#ef4444', // Red - Error
5016
- 'Error': '#ef4444', // Red - Error
5017
- 'Timeout': '#f59e0b', // Orange - Warning
5018
- 'Cancelled': '#f59e0b', // Orange - Warning
5019
- 'Then': '#3b82f6', // Blue - Info
5020
- 'Else': '#64748b', // Gray
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
5021
5365
  };
5022
5366
  return colorMap[outcome] || '#8b5cf6'; // Purple - Default
5023
5367
  }
@@ -5061,7 +5405,7 @@ class WorkflowStudioComponent extends AXPPageLayoutBaseComponent {
5061
5405
  provide: AXPPageLayoutBase,
5062
5406
  useExisting: WorkflowStudioComponent,
5063
5407
  },
5064
- ], 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: i8.AXTranslatorPipe, name: "translate" }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
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 }); }
5065
5409
  }
5066
5410
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: WorkflowStudioComponent, decorators: [{
5067
5411
  type: Component,