@acorex/modules 21.0.0-next.51 → 21.0.0-next.54
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.
- package/ai-management/README.md +1 -0
- package/fesm2022/{acorex-modules-ai-management-assist.entity-513RdKsz.mjs → acorex-modules-ai-management-assist.entity-CnyoIO-Z.mjs} +24 -16
- package/fesm2022/acorex-modules-ai-management-assist.entity-CnyoIO-Z.mjs.map +1 -0
- package/fesm2022/acorex-modules-ai-management.mjs +374 -35
- package/fesm2022/acorex-modules-ai-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-assessment-management-acorex-modules-assessment-management-BD5oxehv.mjs → acorex-modules-assessment-management-acorex-modules-assessment-management-DcPnI9fZ.mjs} +69 -505
- package/fesm2022/acorex-modules-assessment-management-acorex-modules-assessment-management-DcPnI9fZ.mjs.map +1 -0
- package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-BWj2PB39.mjs → acorex-modules-assessment-management-assessment-case.entity-D880d_qz.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-assessment-case.entity-BWj2PB39.mjs.map → acorex-modules-assessment-management-assessment-case.entity-D880d_qz.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-BQnYnNOz.mjs → acorex-modules-assessment-management-assessment-session.entity-DvbocIN1.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-assessment-session.entity-BQnYnNOz.mjs.map → acorex-modules-assessment-management-assessment-session.entity-DvbocIN1.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-fill-assessment-session.command-BiS7QO_E.mjs → acorex-modules-assessment-management-fill-assessment-session.command-BMJ54EPO.mjs} +59 -85
- package/fesm2022/acorex-modules-assessment-management-fill-assessment-session.command-BMJ54EPO.mjs.map +1 -0
- package/fesm2022/{acorex-modules-assessment-management-index-BXw0Lf5c.mjs → acorex-modules-assessment-management-index-XdJCIYG3.mjs} +4 -4
- package/fesm2022/{acorex-modules-assessment-management-index-BXw0Lf5c.mjs.map → acorex-modules-assessment-management-index-XdJCIYG3.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-preview-question.command-Bm1v6ngB.mjs → acorex-modules-assessment-management-preview-question.command-CO8NfjEb.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-preview-question.command-Bm1v6ngB.mjs.map → acorex-modules-assessment-management-preview-question.command-CO8NfjEb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-Dja4PbGz.mjs → acorex-modules-assessment-management-preview-questionnaire.command-DSzbtU0e.mjs} +8 -8
- package/fesm2022/{acorex-modules-assessment-management-preview-questionnaire.command-Dja4PbGz.mjs.map → acorex-modules-assessment-management-preview-questionnaire.command-DSzbtU0e.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-BbkWs23A.mjs → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DbvxAUgb.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-BbkWs23A.mjs.map → acorex-modules-assessment-management-question-bank-interface-editor-widget-edit.component-DbvxAUgb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-X8s42nZH.mjs → acorex-modules-assessment-management-question-bank-item.entity-DBfQhSKR.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-question-bank-item.entity-X8s42nZH.mjs.map → acorex-modules-assessment-management-question-bank-item.entity-DBfQhSKR.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-d8HUAvWp.mjs → acorex-modules-assessment-management-questionnaire-calculation.entity-CL9s20qR.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-questionnaire-calculation.entity-d8HUAvWp.mjs.map → acorex-modules-assessment-management-questionnaire-calculation.entity-CL9s20qR.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-questionnaire-viewer-popup.component-YUDOSypz.mjs → acorex-modules-assessment-management-questionnaire-viewer-popup.component-CH_cJlSf.mjs} +205 -11
- package/fesm2022/acorex-modules-assessment-management-questionnaire-viewer-popup.component-CH_cJlSf.mjs.map +1 -0
- package/fesm2022/{acorex-modules-assessment-management-questionnaire.entity-q3Z4VIiA.mjs → acorex-modules-assessment-management-questionnaire.entity-CrryBMC2.mjs} +40 -3
- package/fesm2022/acorex-modules-assessment-management-questionnaire.entity-CrryBMC2.mjs.map +1 -0
- package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-4OLYEn35.mjs → acorex-modules-assessment-management-save-questionnaire-questions.command-Dq5VComh.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-save-questionnaire-questions.command-4OLYEn35.mjs.map → acorex-modules-assessment-management-save-questionnaire-questions.command-Dq5VComh.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-DWEd-ZM_.mjs → acorex-modules-assessment-management-view-session-answers.command-DpppXekm.mjs} +2 -2
- package/fesm2022/{acorex-modules-assessment-management-view-session-answers.command-DWEd-ZM_.mjs.map → acorex-modules-assessment-management-view-session-answers.command-DpppXekm.mjs.map} +1 -1
- package/fesm2022/acorex-modules-assessment-management.mjs +1 -1
- package/fesm2022/{acorex-modules-asset-management-acorex-modules-asset-management-B1mg2dIR.mjs → acorex-modules-asset-management-acorex-modules-asset-management-BtcY1UQy.mjs} +8 -8
- package/fesm2022/{acorex-modules-asset-management-acorex-modules-asset-management-B1mg2dIR.mjs.map → acorex-modules-asset-management-acorex-modules-asset-management-BtcY1UQy.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-asset-management-asset-system-assignment.entity-lL1FBlzA.mjs → acorex-modules-asset-management-asset-system-assignment.entity-pKZoxsjk.mjs} +2 -2
- package/fesm2022/{acorex-modules-asset-management-asset-system-assignment.entity-lL1FBlzA.mjs.map → acorex-modules-asset-management-asset-system-assignment.entity-pKZoxsjk.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-DFHVqE7a.mjs → acorex-modules-asset-management-asset-system-type.entity-CXz2G5v1.mjs} +2 -2
- package/fesm2022/{acorex-modules-asset-management-asset-system-type.entity-DFHVqE7a.mjs.map → acorex-modules-asset-management-asset-system-type.entity-CXz2G5v1.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-asset-management-asset-system.entity-DlpOp7Xj.mjs → acorex-modules-asset-management-asset-system.entity-C3zf6WVD.mjs} +13 -14
- package/fesm2022/acorex-modules-asset-management-asset-system.entity-C3zf6WVD.mjs.map +1 -0
- package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-CIkXc51V.mjs → acorex-modules-asset-management-asset-type-section-component.entity-DTaeNNBW.mjs} +2 -2
- package/fesm2022/{acorex-modules-asset-management-asset-type-section-component.entity-CIkXc51V.mjs.map → acorex-modules-asset-management-asset-type-section-component.entity-DTaeNNBW.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-Ctxh5hGa.mjs → acorex-modules-asset-management-asset-type-section.entity-Bes5h7aJ.mjs} +2 -2
- package/fesm2022/{acorex-modules-asset-management-asset-type-section.entity-Ctxh5hGa.mjs.map → acorex-modules-asset-management-asset-type-section.entity-Bes5h7aJ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-asset-management-asset-type.entity-CN6K0Uw3.mjs → acorex-modules-asset-management-asset-type.entity-Ch8h0sph.mjs} +21 -22
- package/fesm2022/acorex-modules-asset-management-asset-type.entity-Ch8h0sph.mjs.map +1 -0
- package/fesm2022/{acorex-modules-asset-management-asset.entity-2XZut6JS.mjs → acorex-modules-asset-management-asset.entity-DJ-A6lx1.mjs} +26 -26
- package/fesm2022/acorex-modules-asset-management-asset.entity-DJ-A6lx1.mjs.map +1 -0
- package/fesm2022/acorex-modules-asset-management.mjs +1 -1
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-CGiDe3e-.mjs → acorex-modules-auth-acorex-modules-auth-NPUjHz-F.mjs} +13 -13
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-CGiDe3e-.mjs.map → acorex-modules-auth-acorex-modules-auth-NPUjHz-F.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-app-chooser.component-Dt_2eXel.mjs → acorex-modules-auth-app-chooser.component-h61xNtRT.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-app-chooser.component-Dt_2eXel.mjs.map → acorex-modules-auth-app-chooser.component-h61xNtRT.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-Bl8pAhHc.mjs → acorex-modules-auth-login.module-DF5AHqYe.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-Bl8pAhHc.mjs.map → acorex-modules-auth-login.module-DF5AHqYe.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-B8GSev0J.mjs → acorex-modules-auth-master.layout-00ZTMhc3.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-B8GSev0J.mjs.map → acorex-modules-auth-master.layout-00ZTMhc3.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-oauth-callback.component-DleQ24IP.mjs → acorex-modules-auth-oauth-callback.component-Ce5Fw8Qd.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-oauth-callback.component-DleQ24IP.mjs.map → acorex-modules-auth-oauth-callback.component-Ce5Fw8Qd.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-D6ALMoO4.mjs → acorex-modules-auth-password.component-CU0AY-Ia.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-D6ALMoO4.mjs.map → acorex-modules-auth-password.component-CU0AY-Ia.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-C1GbARlM.mjs → acorex-modules-auth-password.component-DQYCm8wg.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-C1GbARlM.mjs.map → acorex-modules-auth-password.component-DQYCm8wg.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-FDp1SEZA.mjs → acorex-modules-auth-routes-CM4fRaWb.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-FDp1SEZA.mjs.map → acorex-modules-auth-routes-CM4fRaWb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-settings.provider-CN7Lb38l.mjs → acorex-modules-auth-settings.provider-C_3D-9ia.mjs} +2 -2
- package/fesm2022/acorex-modules-auth-settings.provider-C_3D-9ia.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-tenant-chooser.component-o55sauLG.mjs → acorex-modules-auth-tenant-chooser.component-BBztdcvq.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-tenant-chooser.component-o55sauLG.mjs.map → acorex-modules-auth-tenant-chooser.component-BBztdcvq.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-CVrYPw5D.mjs → acorex-modules-auth-two-factor.module-C9AafF86.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-CVrYPw5D.mjs.map → acorex-modules-auth-two-factor.module-C9AafF86.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-user-sessions.component-BVglZAnc.mjs → acorex-modules-auth-user-sessions.component-Qw2sgsEe.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-user-sessions.component-BVglZAnc.mjs.map → acorex-modules-auth-user-sessions.component-Qw2sgsEe.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-common.mjs +8 -5
- package/fesm2022/acorex-modules-common.mjs.map +1 -1
- package/fesm2022/{acorex-modules-conversation-acorex-modules-conversation-ny5TQlkp.mjs → acorex-modules-conversation-acorex-modules-conversation-Bnjyq-wp.mjs} +1010 -164
- package/fesm2022/acorex-modules-conversation-acorex-modules-conversation-Bnjyq-wp.mjs.map +1 -0
- package/fesm2022/{acorex-modules-conversation-assist-delegated-agent-detail-popup.component-7O6som8z.mjs → acorex-modules-conversation-assist-delegated-agent-detail-popup.component-Df5LmYZI.mjs} +7 -6
- package/fesm2022/acorex-modules-conversation-assist-delegated-agent-detail-popup.component-Df5LmYZI.mjs.map +1 -0
- package/fesm2022/{acorex-modules-conversation-comments-page.component-Dm7U0ndQ.mjs → acorex-modules-conversation-comments-page.component-BXI4smIr.mjs} +2 -2
- package/fesm2022/{acorex-modules-conversation-comments-page.component-Dm7U0ndQ.mjs.map → acorex-modules-conversation-comments-page.component-BXI4smIr.mjs.map} +1 -1
- package/fesm2022/acorex-modules-conversation-send-assist-chat-message.command-B5qJnpCK.mjs +90 -0
- package/fesm2022/acorex-modules-conversation-send-assist-chat-message.command-B5qJnpCK.mjs.map +1 -0
- package/fesm2022/{acorex-modules-conversation-start-assist-chat.command-BLYoudtN.mjs → acorex-modules-conversation-start-assist-chat.command-DI3LAaDF.mjs} +2 -2
- package/fesm2022/{acorex-modules-conversation-start-assist-chat.command-BLYoudtN.mjs.map → acorex-modules-conversation-start-assist-chat.command-DI3LAaDF.mjs.map} +1 -1
- package/fesm2022/acorex-modules-conversation.mjs +1 -1
- package/fesm2022/acorex-modules-data-management.mjs +5 -3
- package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-BxQxZBca.mjs → acorex-modules-document-management-drive-choose.component-DyJoXajP.mjs} +4 -4
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-BxQxZBca.mjs.map → acorex-modules-document-management-drive-choose.component-DyJoXajP.mjs.map} +1 -1
- package/fesm2022/acorex-modules-document-management.mjs +98 -24
- package/fesm2022/acorex-modules-document-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-form-template-management.mjs +53 -61
- package/fesm2022/acorex-modules-form-template-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-acorex-modules-human-capital-management-B37ZqEql.mjs → acorex-modules-human-capital-management-acorex-modules-human-capital-management-XhV2JQXs.mjs} +23 -21
- package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-XhV2JQXs.mjs.map +1 -0
- package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-Bf8iPUE-.mjs → acorex-modules-human-capital-management-approve-leave-request.command-Cre30Kp7.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-approve-leave-request.command-Bf8iPUE-.mjs.map → acorex-modules-human-capital-management-approve-leave-request.command-Cre30Kp7.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-assign-position-assignment.command-DqX9OAq4.mjs → acorex-modules-human-capital-management-assign-position-assignment.command-NYgddiaD.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-assign-position-assignment.command-DqX9OAq4.mjs.map → acorex-modules-human-capital-management-assign-position-assignment.command-NYgddiaD.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-DQG0Al0X.mjs → acorex-modules-human-capital-management-cancel-leave-request.command-DPh-KQgN.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-cancel-leave-request.command-DQG0Al0X.mjs.map → acorex-modules-human-capital-management-cancel-leave-request.command-DPh-KQgN.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-employee-lifecycle-process.entity-DSsgKG8S.mjs → acorex-modules-human-capital-management-employee-lifecycle-process.entity-LX68KORg.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-employee-lifecycle-process.entity-DSsgKG8S.mjs.map → acorex-modules-human-capital-management-employee-lifecycle-process.entity-LX68KORg.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-employee.entity-C8PaZEDs.mjs → acorex-modules-human-capital-management-employee.entity-znCbbQUd.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-employee.entity-C8PaZEDs.mjs.map → acorex-modules-human-capital-management-employee.entity-znCbbQUd.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-DhqHdESk.mjs → acorex-modules-human-capital-management-employment-type.entity-DUNB3zAB.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-employment-type.entity-DhqHdESk.mjs.map → acorex-modules-human-capital-management-employment-type.entity-DUNB3zAB.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-CPdV6kiR.mjs → acorex-modules-human-capital-management-leave-request.entity-JyFrrCGE.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-leave-request.entity-CPdV6kiR.mjs.map → acorex-modules-human-capital-management-leave-request.entity-JyFrrCGE.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-D3iarVMG.mjs → acorex-modules-human-capital-management-leave-type.entity-B61MiEPu.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-leave-type.entity-D3iarVMG.mjs.map → acorex-modules-human-capital-management-leave-type.entity-B61MiEPu.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-lifecycle-process-type.entity-EazvPSR6.mjs → acorex-modules-human-capital-management-lifecycle-process-type.entity-DJqo2kTG.mjs} +9 -11
- package/fesm2022/acorex-modules-human-capital-management-lifecycle-process-type.entity-DJqo2kTG.mjs.map +1 -0
- package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-mROyAoz-.mjs → acorex-modules-human-capital-management-position-assignment.entity-CKCC6bKg.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-position-assignment.entity-mROyAoz-.mjs.map → acorex-modules-human-capital-management-position-assignment.entity-CKCC6bKg.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-Bq7OtST6.mjs → acorex-modules-human-capital-management-reject-leave-request.command-Blv08UQZ.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-reject-leave-request.command-Bq7OtST6.mjs.map → acorex-modules-human-capital-management-reject-leave-request.command-Blv08UQZ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-human-capital-management-revoke-position-assignment.command-BpklMLve.mjs → acorex-modules-human-capital-management-revoke-position-assignment.command-lgEAbxYH.mjs} +2 -2
- package/fesm2022/{acorex-modules-human-capital-management-revoke-position-assignment.command-BpklMLve.mjs.map → acorex-modules-human-capital-management-revoke-position-assignment.command-lgEAbxYH.mjs.map} +1 -1
- package/fesm2022/acorex-modules-human-capital-management.mjs +1 -1
- package/fesm2022/acorex-modules-locale-management.mjs +1 -1
- package/fesm2022/acorex-modules-locale-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-acorex-modules-maintenance-management-coPYjl8-.mjs → acorex-modules-maintenance-management-acorex-modules-maintenance-management-DiM2aFgg.mjs} +304 -206
- package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-DiM2aFgg.mjs.map +1 -0
- package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-BdnnavfB.mjs → acorex-modules-maintenance-management-failure-effect.entity-BCMeHmxS.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-effect.entity-BdnnavfB.mjs.map → acorex-modules-maintenance-management-failure-effect.entity-BCMeHmxS.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-tlcqWco6.mjs → acorex-modules-maintenance-management-failure-mode-asset-type.entity-ByBoVQ8D.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-asset-type.entity-tlcqWco6.mjs.map → acorex-modules-maintenance-management-failure-mode-asset-type.entity-ByBoVQ8D.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-DivWl32L.mjs → acorex-modules-maintenance-management-failure-mode-mechanism.entity-BJs4KhkU.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-mechanism.entity-DivWl32L.mjs.map → acorex-modules-maintenance-management-failure-mode-mechanism.entity-BJs4KhkU.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-9FiLeySZ.mjs → acorex-modules-maintenance-management-failure-mode-solution.entity-rw24sQxb.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-mode-solution.entity-9FiLeySZ.mjs.map → acorex-modules-maintenance-management-failure-mode-solution.entity-rw24sQxb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-3cq1KeYM.mjs → acorex-modules-maintenance-management-failure-register-cause.entity-C_6sjW8z.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-cause.entity-3cq1KeYM.mjs.map → acorex-modules-maintenance-management-failure-register-cause.entity-C_6sjW8z.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-CaVb6rDn.mjs → acorex-modules-maintenance-management-failure-register-effect.entity-DCIAzSYQ.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-effect.entity-CaVb6rDn.mjs.map → acorex-modules-maintenance-management-failure-register-effect.entity-DCIAzSYQ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-C2UKW63M.mjs → acorex-modules-maintenance-management-failure-register-mechanism.entity-DlXr6A4i.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-register-mechanism.entity-C2UKW63M.mjs.map → acorex-modules-maintenance-management-failure-register-mechanism.entity-DlXr6A4i.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-KghFLCIJ.mjs → acorex-modules-maintenance-management-failure-register.entity-C4J3um7j.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-register.entity-KghFLCIJ.mjs.map → acorex-modules-maintenance-management-failure-register.entity-C4J3um7j.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BebswR7S.mjs → acorex-modules-maintenance-management-failure-severity.entity-C-spQtYx.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-failure-severity.entity-BebswR7S.mjs.map → acorex-modules-maintenance-management-failure-severity.entity-C-spQtYx.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-maintenance-management-maintenance-template.entity-1V4swUZ4.mjs → acorex-modules-maintenance-management-maintenance-template.entity-Huahnjhd.mjs} +100 -178
- package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-Huahnjhd.mjs.map +1 -0
- package/fesm2022/{acorex-modules-maintenance-management-work-order-list-command-3hlrAtIr.mjs → acorex-modules-maintenance-management-work-order-list-command-1YsWctqu.mjs} +2 -2
- package/fesm2022/{acorex-modules-maintenance-management-work-order-list-command-3hlrAtIr.mjs.map → acorex-modules-maintenance-management-work-order-list-command-1YsWctqu.mjs.map} +1 -1
- package/fesm2022/acorex-modules-maintenance-management.mjs +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-order-management-settings.provider-BFOghuIS.mjs +58 -0
- package/fesm2022/acorex-modules-order-management-settings.provider-BFOghuIS.mjs.map +1 -0
- package/fesm2022/acorex-modules-order-management.mjs +2 -2
- package/fesm2022/{acorex-modules-organization-management-acorex-modules-organization-management-CGzZcKEy.mjs → acorex-modules-organization-management-acorex-modules-organization-management-BZtWfgmH.mjs} +40 -120
- package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-BZtWfgmH.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-add-business-unit-to-business-unit.command-BEJyfR3P.mjs → acorex-modules-organization-management-add-business-unit-to-business-unit.command-C-yO5On4.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-add-business-unit-to-business-unit.command-BEJyfR3P.mjs.map → acorex-modules-organization-management-add-business-unit-to-business-unit.command-C-yO5On4.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-add-position-to-business-unit.command-DKgxg9q5.mjs → acorex-modules-organization-management-add-position-to-business-unit.command-BL5eWJ56.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-add-position-to-business-unit.command-DKgxg9q5.mjs.map → acorex-modules-organization-management-add-position-to-business-unit.command-BL5eWJ56.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-add-team-to-business-unit.command-DJJT7BXT.mjs → acorex-modules-organization-management-add-team-to-business-unit.command-l4N6g0Hc.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-add-team-to-business-unit.command-DJJT7BXT.mjs.map → acorex-modules-organization-management-add-team-to-business-unit.command-l4N6g0Hc.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-business-unit.entity-BAp38sib.mjs → acorex-modules-organization-management-business-unit.entity-CONTwX52.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-business-unit.entity-BAp38sib.mjs.map → acorex-modules-organization-management-business-unit.entity-CONTwX52.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-chart.entity-WfmpWj8R.mjs → acorex-modules-organization-management-chart.entity-DeKPBfgx.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-chart.entity-WfmpWj8R.mjs.map → acorex-modules-organization-management-chart.entity-DeKPBfgx.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-company.entity-BUVLrwjq.mjs → acorex-modules-organization-management-company.entity-BAlz8AfD.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-company.entity-BUVLrwjq.mjs.map → acorex-modules-organization-management-company.entity-BAlz8AfD.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-entity.provider-DH3eUGTu.mjs → acorex-modules-organization-management-entity.provider-DjPSiqcX.mjs} +15 -15
- package/fesm2022/{acorex-modules-organization-management-entity.provider-DH3eUGTu.mjs.map → acorex-modules-organization-management-entity.provider-DjPSiqcX.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-DuScrBze.mjs → acorex-modules-organization-management-feature-definition.provider-BLmayeSc.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-feature-definition.provider-DuScrBze.mjs.map → acorex-modules-organization-management-feature-definition.provider-BLmayeSc.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-definition-pages-component.provider-D-J9JCsU.mjs → acorex-modules-organization-management-job-definition-pages-component.provider-HBi-EMRE.mjs} +3 -3
- package/fesm2022/{acorex-modules-organization-management-job-definition-pages-component.provider-D-J9JCsU.mjs.map → acorex-modules-organization-management-job-definition-pages-component.provider-HBi-EMRE.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-definition-responsibilities-page.component-Dsy5rFGw.mjs → acorex-modules-organization-management-job-definition-responsibilities-page.component-CtIfsZ6x.mjs} +3 -3
- package/fesm2022/{acorex-modules-organization-management-job-definition-responsibilities-page.component-Dsy5rFGw.mjs.map → acorex-modules-organization-management-job-definition-responsibilities-page.component-CtIfsZ6x.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-definition-skills-page.component-B73wLPby.mjs → acorex-modules-organization-management-job-definition-skills-page.component-C1vCQayM.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-job-definition-skills-page.component-B73wLPby.mjs.map → acorex-modules-organization-management-job-definition-skills-page.component-C1vCQayM.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-definition.entity-B7mWKYqb.mjs → acorex-modules-organization-management-job-definition.entity-Db5li0zL.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-job-definition.entity-B7mWKYqb.mjs.map → acorex-modules-organization-management-job-definition.entity-Db5li0zL.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-level.datasource-DibRoKXR.mjs → acorex-modules-organization-management-job-level.datasource-BTRKW7nq.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-job-level.datasource-DibRoKXR.mjs.map → acorex-modules-organization-management-job-level.datasource-BTRKW7nq.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-job-level.entity-C_MzeTw5.mjs → acorex-modules-organization-management-job-level.entity-Cn-91_r8.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-job-level.entity-C_MzeTw5.mjs.map → acorex-modules-organization-management-job-level.entity-Cn-91_r8.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-menu.provider-CQeJINzl.mjs → acorex-modules-organization-management-menu.provider-CVmV-hY5.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-menu.provider-CQeJINzl.mjs.map → acorex-modules-organization-management-menu.provider-CVmV-hY5.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-org-chart-default-node-contribution.provider-D3hCHSr_.mjs → acorex-modules-organization-management-org-chart-default-node-contribution.provider-bdtNexEf.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-org-chart-default-node-contribution.provider-D3hCHSr_.mjs.map → acorex-modules-organization-management-org-chart-default-node-contribution.provider-bdtNexEf.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-Bv0I-45L.mjs → acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-B0aaFv5p.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-Bv0I-45L.mjs.map → acorex-modules-organization-management-org-chart-employee-flyout-contribution.provider-B0aaFv5p.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-DbfYza8q.mjs → acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-Xe4nhY3j.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-DbfYza8q.mjs.map → acorex-modules-organization-management-org-chart-position-employee-node-contribution.provider-Xe4nhY3j.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-org-chart-ux-node-contribution.provider-C9APxguL.mjs → acorex-modules-organization-management-org-chart-ux-node-contribution.provider-CTprHwCi.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-org-chart-ux-node-contribution.provider-C9APxguL.mjs.map → acorex-modules-organization-management-org-chart-ux-node-contribution.provider-CTprHwCi.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-org-chart.page-BcHO5kKP.mjs → acorex-modules-organization-management-org-chart.page-ChXY8ncD.mjs} +133 -12
- package/fesm2022/acorex-modules-organization-management-org-chart.page-ChXY8ncD.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-BcIRJpBt.mjs → acorex-modules-organization-management-permission-definition.provider-8t2vBgtp.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-permission-definition.provider-BcIRJpBt.mjs.map → acorex-modules-organization-management-permission-definition.provider-8t2vBgtp.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-position.entity-DBOpLtSI.mjs → acorex-modules-organization-management-position.entity-BVWbTeks.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-position.entity-DBOpLtSI.mjs.map → acorex-modules-organization-management-position.entity-BVWbTeks.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-remove-position-from-business-unit.command-TqYgfnsy.mjs → acorex-modules-organization-management-remove-position-from-business-unit.command-DWzFncr1.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-remove-position-from-business-unit.command-TqYgfnsy.mjs.map → acorex-modules-organization-management-remove-position-from-business-unit.command-DWzFncr1.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-replace-position-assignee.command-BJ2gn0-A.mjs → acorex-modules-organization-management-replace-position-assignee.command-CNa-CZOv.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-replace-position-assignee.command-BJ2gn0-A.mjs.map → acorex-modules-organization-management-replace-position-assignee.command-CNa-CZOv.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CZdMLIL-.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CTSCcyFv.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CZdMLIL-.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-edit.component-CTSCcyFv.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-BBo97rDN.mjs → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-C82TQFS-.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix-widget-view.component-BBo97rDN.mjs.map → acorex-modules-organization-management-responsibilities-matrix-widget-view.component-C82TQFS-.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-D9oH_Fbb.mjs → acorex-modules-organization-management-responsibilities-matrix.component-DjVuISfE.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-responsibilities-matrix.component-D9oH_Fbb.mjs.map → acorex-modules-organization-management-responsibilities-matrix.component-DjVuISfE.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-responsibility-level.entity-D6IG9Zc7.mjs → acorex-modules-organization-management-responsibility-level.entity-BlENDhF6.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-responsibility-level.entity-D6IG9Zc7.mjs.map → acorex-modules-organization-management-responsibility-level.entity-BlENDhF6.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-responsibility.entity-BosNxYjW.mjs → acorex-modules-organization-management-responsibility.entity-DamPTQMp.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-responsibility.entity-BosNxYjW.mjs.map → acorex-modules-organization-management-responsibility.entity-DamPTQMp.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-settings.provider-CL9C9UXA.mjs → acorex-modules-organization-management-settings.provider-CtQo6YHj.mjs} +3 -3
- package/fesm2022/acorex-modules-organization-management-settings.provider-CtQo6YHj.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-team-business-unit.entity-CYFGTcHe.mjs → acorex-modules-organization-management-team-business-unit.entity-BfvqQb1K.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-team-business-unit.entity-CYFGTcHe.mjs.map → acorex-modules-organization-management-team-business-unit.entity-BfvqQb1K.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-B5vNDne0.mjs → acorex-modules-organization-management-team-member-role.entity-wWoB56Il.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-team-member-role.entity-B5vNDne0.mjs.map → acorex-modules-organization-management-team-member-role.entity-wWoB56Il.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-team-member.entity-DsKuxCRB.mjs → acorex-modules-organization-management-team-member.entity-COGrDN_G.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-team-member.entity-DsKuxCRB.mjs.map → acorex-modules-organization-management-team-member.entity-COGrDN_G.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-organization-management-team.entity-Cg30cho_.mjs → acorex-modules-organization-management-team.entity-DC_rqp9e.mjs} +2 -2
- package/fesm2022/{acorex-modules-organization-management-team.entity-Cg30cho_.mjs.map → acorex-modules-organization-management-team.entity-DC_rqp9e.mjs.map} +1 -1
- package/fesm2022/acorex-modules-organization-management.mjs +1 -1
- package/fesm2022/{acorex-modules-platform-dev-tools-settings.provider-DKmgBUYt.mjs → acorex-modules-platform-dev-tools-settings.provider-BIVP27kT.mjs} +2 -2
- package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-BIVP27kT.mjs.map +1 -0
- package/fesm2022/acorex-modules-platform-dev-tools.mjs +2 -2
- package/fesm2022/{acorex-modules-platform-management-acorex-modules-platform-management-DkOzj2Oy.mjs → acorex-modules-platform-management-acorex-modules-platform-management-5DJoQkx2.mjs} +1919 -4
- package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-5DJoQkx2.mjs.map +1 -0
- package/fesm2022/{acorex-modules-platform-management-menu-list.component-agWZWchQ.mjs → acorex-modules-platform-management-menu-list.component-C3WBYbOt.mjs} +4 -4
- package/fesm2022/{acorex-modules-platform-management-menu-list.component-agWZWchQ.mjs.map → acorex-modules-platform-management-menu-list.component-C3WBYbOt.mjs.map} +1 -1
- package/fesm2022/acorex-modules-platform-management.mjs +1 -1
- package/fesm2022/{acorex-modules-settings-management-acorex-modules-settings-management-oArHHeSx.mjs → acorex-modules-settings-management-acorex-modules-settings-management-Di6Sxtq3.mjs} +5 -5
- package/fesm2022/{acorex-modules-settings-management-acorex-modules-settings-management-oArHHeSx.mjs.map → acorex-modules-settings-management-acorex-modules-settings-management-Di6Sxtq3.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-settings-management-permission-definition.provider-BsFyZ-gS.mjs → acorex-modules-settings-management-permission-definition.provider-Bml5VZUT.mjs} +2 -2
- package/fesm2022/{acorex-modules-settings-management-permission-definition.provider-BsFyZ-gS.mjs.map → acorex-modules-settings-management-permission-definition.provider-Bml5VZUT.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-settings-management-setting-page.component-BftWms4f.mjs → acorex-modules-settings-management-setting-page.component-lN-7sTpD.mjs} +4 -4
- package/fesm2022/{acorex-modules-settings-management-setting-page.component-BftWms4f.mjs.map → acorex-modules-settings-management-setting-page.component-lN-7sTpD.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-settings-management-setting-view.component-paKdiSEr.mjs → acorex-modules-settings-management-setting-view.component-D17G4RNQ.mjs} +15 -28
- package/fesm2022/acorex-modules-settings-management-setting-view.component-D17G4RNQ.mjs.map +1 -0
- package/fesm2022/acorex-modules-settings-management.mjs +1 -1
- package/fesm2022/acorex-modules-system-insight.mjs +1 -1
- package/fesm2022/acorex-modules-system-insight.mjs.map +1 -1
- package/fesm2022/{acorex-modules-task-management-acorex-modules-task-management-BL2IOcx3.mjs → acorex-modules-task-management-acorex-modules-task-management-LQn5gZ6p.mjs} +680 -10
- package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-LQn5gZ6p.mjs.map +1 -0
- package/fesm2022/{acorex-modules-task-management-task-board.page-DUIHtqnr.mjs → acorex-modules-task-management-task-board.page-BokG-G6Z.mjs} +204 -591
- package/fesm2022/acorex-modules-task-management-task-board.page-BokG-G6Z.mjs.map +1 -0
- package/fesm2022/acorex-modules-task-management.mjs +1 -1
- package/fesm2022/acorex-modules-tenant-management.mjs +1 -1
- package/fesm2022/acorex-modules-tenant-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-CYyr1kQk.mjs → acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-OLbCD-7P.mjs} +4 -4
- package/fesm2022/{acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-CYyr1kQk.mjs.map → acorex-modules-workflow-management-activity-command-configurator-widget-edit.component-OLbCD-7P.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-workflow-management-index-CHySddpP.mjs → acorex-modules-workflow-management-index-34UZrsxw.mjs} +2 -2
- package/fesm2022/{acorex-modules-workflow-management-index-CHySddpP.mjs.map → acorex-modules-workflow-management-index-34UZrsxw.mjs.map} +1 -1
- package/fesm2022/acorex-modules-workflow-management-index-BxqOP8AA.mjs +1207 -0
- package/fesm2022/acorex-modules-workflow-management-index-BxqOP8AA.mjs.map +1 -0
- package/fesm2022/{acorex-modules-workflow-management-index-DC_9M9dk.mjs → acorex-modules-workflow-management-index-Eh5DDK-V.mjs} +3 -3
- package/fesm2022/{acorex-modules-workflow-management-index-DC_9M9dk.mjs.map → acorex-modules-workflow-management-index-Eh5DDK-V.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs → acorex-modules-workflow-management-save-workflow-definition-activities.command-CGNwslcn.mjs} +10 -5
- package/fesm2022/acorex-modules-workflow-management-save-workflow-definition-activities.command-CGNwslcn.mjs.map +1 -0
- package/fesm2022/{acorex-modules-workflow-management-workflow-definition.entity-CjQQpjdB.mjs → acorex-modules-workflow-management-workflow-definition.entity-DISpkWE4.mjs} +3 -7
- package/fesm2022/acorex-modules-workflow-management-workflow-definition.entity-DISpkWE4.mjs.map +1 -0
- package/fesm2022/{acorex-modules-workflow-management-workflow-instance.entity-BnKT3Wgh.mjs → acorex-modules-workflow-management-workflow-instance.entity-B_V3uMSI.mjs} +2 -2
- package/fesm2022/{acorex-modules-workflow-management-workflow-instance.entity-BnKT3Wgh.mjs.map → acorex-modules-workflow-management-workflow-instance.entity-B_V3uMSI.mjs.map} +1 -1
- package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-DMszilef.mjs +356 -0
- package/fesm2022/acorex-modules-workflow-management-workflow-task-popover.component-DMszilef.mjs.map +1 -0
- package/fesm2022/acorex-modules-workflow-management.mjs +257 -130
- package/fesm2022/acorex-modules-workflow-management.mjs.map +1 -1
- package/package.json +2 -2
- package/types/acorex-modules-ai-management.d.ts +73 -5
- package/types/acorex-modules-assessment-management.d.ts +161 -97
- package/types/acorex-modules-asset-management.d.ts +3 -0
- package/types/acorex-modules-conversation.d.ts +12 -2
- package/types/acorex-modules-human-capital-management.d.ts +6 -6
- package/types/acorex-modules-maintenance-management.d.ts +28 -11
- package/types/acorex-modules-organization-management.d.ts +1 -27
- package/types/acorex-modules-platform-management.d.ts +518 -23
- package/types/acorex-modules-task-management.d.ts +100 -4
- package/types/acorex-modules-workflow-management.d.ts +53 -5
- package/fesm2022/acorex-modules-ai-management-assist.entity-513RdKsz.mjs.map +0 -1
- package/fesm2022/acorex-modules-assessment-management-acorex-modules-assessment-management-BD5oxehv.mjs.map +0 -1
- package/fesm2022/acorex-modules-assessment-management-fill-assessment-session.command-BiS7QO_E.mjs.map +0 -1
- package/fesm2022/acorex-modules-assessment-management-questionnaire-viewer-popup.component-YUDOSypz.mjs.map +0 -1
- package/fesm2022/acorex-modules-assessment-management-questionnaire.entity-q3Z4VIiA.mjs.map +0 -1
- package/fesm2022/acorex-modules-asset-management-asset-system.entity-DlpOp7Xj.mjs.map +0 -1
- package/fesm2022/acorex-modules-asset-management-asset-type.entity-CN6K0Uw3.mjs.map +0 -1
- package/fesm2022/acorex-modules-asset-management-asset.entity-2XZut6JS.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-settings.provider-CN7Lb38l.mjs.map +0 -1
- package/fesm2022/acorex-modules-conversation-acorex-modules-conversation-ny5TQlkp.mjs.map +0 -1
- package/fesm2022/acorex-modules-conversation-assist-delegated-agent-detail-popup.component-7O6som8z.mjs.map +0 -1
- package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-B37ZqEql.mjs.map +0 -1
- package/fesm2022/acorex-modules-human-capital-management-lifecycle-process-type.entity-EazvPSR6.mjs.map +0 -1
- package/fesm2022/acorex-modules-maintenance-management-acorex-modules-maintenance-management-coPYjl8-.mjs.map +0 -1
- package/fesm2022/acorex-modules-maintenance-management-maintenance-template.entity-1V4swUZ4.mjs.map +0 -1
- package/fesm2022/acorex-modules-order-management-settings.provider-DF8JQ1PZ.mjs +0 -64
- package/fesm2022/acorex-modules-order-management-settings.provider-DF8JQ1PZ.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-acorex-modules-organization-management-CGzZcKEy.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-org-chart.page-BcHO5kKP.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-settings.provider-CL9C9UXA.mjs.map +0 -1
- package/fesm2022/acorex-modules-platform-dev-tools-settings.provider-DKmgBUYt.mjs.map +0 -1
- package/fesm2022/acorex-modules-platform-management-acorex-modules-platform-management-DkOzj2Oy.mjs.map +0 -1
- package/fesm2022/acorex-modules-settings-management-setting-view.component-paKdiSEr.mjs.map +0 -1
- package/fesm2022/acorex-modules-task-management-acorex-modules-task-management-BL2IOcx3.mjs.map +0 -1
- package/fesm2022/acorex-modules-task-management-task-board.page-DUIHtqnr.mjs.map +0 -1
- package/fesm2022/acorex-modules-workflow-management-index-jin24dmb.mjs +0 -726
- package/fesm2022/acorex-modules-workflow-management-index-jin24dmb.mjs.map +0 -1
- package/fesm2022/acorex-modules-workflow-management-save-workflow-definition-activities.command-fFO152ni.mjs.map +0 -1
- package/fesm2022/acorex-modules-workflow-management-workflow-definition.entity-CjQQpjdB.mjs.map +0 -1
|
@@ -5,7 +5,7 @@ import { AXMEntityCrudServiceImpl, AXPEntityService, AXP_ENTITY_DEFINITION_LOADE
|
|
|
5
5
|
import { AXPRootLayoutComponent } from '@acorex/platform/themes/default';
|
|
6
6
|
import { provideCommandSetups, provideQuerySetups } from '@acorex/platform/runtime';
|
|
7
7
|
import * as i0 from '@angular/core';
|
|
8
|
-
import { inject, Injector, Injectable, viewChild, signal, computed, ViewEncapsulation, Component, NgModule } from '@angular/core';
|
|
8
|
+
import { inject, Injector, Injectable, viewChild, signal, computed, ViewEncapsulation, Component, NgModule, input, output, DestroyRef, afterNextRender, effect, ChangeDetectionStrategy, Directive } from '@angular/core';
|
|
9
9
|
import { ROUTES } from '@angular/router';
|
|
10
10
|
import { AXPMenuCustomizerService, AXPMenuCustomizerComponent, AXPThemeLayoutBlockComponent, AXP_MENU_CUSTOMIZER_SERVICE } from '@acorex/platform/layout/components';
|
|
11
11
|
import * as i1 from '@acorex/platform/workflow';
|
|
@@ -19,6 +19,13 @@ import { SwUpdate } from '@angular/service-worker';
|
|
|
19
19
|
import { AXPCommonMenuKeys, AXPWidgetsList } from '@acorex/modules/common';
|
|
20
20
|
import { AXPWidgetsCatalog, AXPWidgetGroupEnum } from '@acorex/platform/layout/widget-core';
|
|
21
21
|
import { AXPRelationshipCardinality, AXPRelationshipKind } from '@acorex/platform/domain';
|
|
22
|
+
import { AXPanViewDirective } from '@acorex/cdk/pan-view';
|
|
23
|
+
import * as i1$2 from '@acorex/components/button';
|
|
24
|
+
import { AXButtonModule } from '@acorex/components/button';
|
|
25
|
+
import * as i2 from '@acorex/components/decorators';
|
|
26
|
+
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
27
|
+
import * as i1$1 from '@angular/common';
|
|
28
|
+
import { CommonModule } from '@angular/common';
|
|
22
29
|
|
|
23
30
|
const config = {
|
|
24
31
|
i18n: 'platform-management',
|
|
@@ -1884,7 +1891,7 @@ function routesFactory() {
|
|
|
1884
1891
|
children: [
|
|
1885
1892
|
{
|
|
1886
1893
|
path: '',
|
|
1887
|
-
loadComponent: () => import('./acorex-modules-platform-management-menu-list.component-
|
|
1894
|
+
loadComponent: () => import('./acorex-modules-platform-management-menu-list.component-C3WBYbOt.mjs').then((c) => c.AXMMenuListComponent),
|
|
1888
1895
|
data: { reuse: true },
|
|
1889
1896
|
},
|
|
1890
1897
|
],
|
|
@@ -6860,11 +6867,1919 @@ var index = /*#__PURE__*/Object.freeze({
|
|
|
6860
6867
|
widgetFieldConfiguratorValueFromInterfaceDefinition: widgetFieldConfiguratorValueFromInterfaceDefinition
|
|
6861
6868
|
});
|
|
6862
6869
|
|
|
6870
|
+
/** MIME type for native drag payloads carrying `AXPWorkflowActivityPaletteItem` JSON. */
|
|
6871
|
+
const AXP_WORKFLOW_PALETTE_MIME = 'application/x-axp-workflow-palette-item';
|
|
6872
|
+
|
|
6873
|
+
//#region ---- Ids ----
|
|
6874
|
+
let idCounter = 0;
|
|
6875
|
+
function createWorkflowNodeId() {
|
|
6876
|
+
idCounter += 1;
|
|
6877
|
+
return `wf-node-${Date.now()}-${idCounter}`;
|
|
6878
|
+
}
|
|
6879
|
+
function createWorkflowConnectorId() {
|
|
6880
|
+
idCounter += 1;
|
|
6881
|
+
return `wf-conn-${Date.now()}-${idCounter}`;
|
|
6882
|
+
}
|
|
6883
|
+
function createWorkflowPortId(prefix) {
|
|
6884
|
+
idCounter += 1;
|
|
6885
|
+
return `${prefix}-port-${idCounter}`;
|
|
6886
|
+
}
|
|
6887
|
+
//#endregion
|
|
6888
|
+
//#region ---- Defaults ----
|
|
6889
|
+
const DEFAULT_SIZE = { width: 180, height: 72 };
|
|
6890
|
+
const DEFAULT_INBOUND = [{ side: 'left', ratio: 0.5, key: 'in' }];
|
|
6891
|
+
const DEFAULT_OUTBOUND = [{ side: 'right', ratio: 0.5, key: 'out' }];
|
|
6892
|
+
function cloneDiagram(model) {
|
|
6893
|
+
return {
|
|
6894
|
+
nodes: model.nodes.map((n) => ({
|
|
6895
|
+
...n,
|
|
6896
|
+
position: { ...n.position },
|
|
6897
|
+
size: { ...n.size },
|
|
6898
|
+
inboundPorts: n.inboundPorts.map((p) => ({
|
|
6899
|
+
...p,
|
|
6900
|
+
data: p.data ? { ...p.data } : undefined,
|
|
6901
|
+
})),
|
|
6902
|
+
outboundPorts: n.outboundPorts.map((p) => ({
|
|
6903
|
+
...p,
|
|
6904
|
+
data: p.data ? { ...p.data } : undefined,
|
|
6905
|
+
})),
|
|
6906
|
+
data: n.data ? { ...n.data } : undefined,
|
|
6907
|
+
})),
|
|
6908
|
+
connectors: model.connectors.map((c) => ({
|
|
6909
|
+
...c,
|
|
6910
|
+
data: c.data ? { ...c.data } : undefined,
|
|
6911
|
+
})),
|
|
6912
|
+
data: model.data ? { ...model.data } : undefined,
|
|
6913
|
+
};
|
|
6914
|
+
}
|
|
6915
|
+
function createPortsFromPalette(nodeId, item) {
|
|
6916
|
+
const inboundSrc = item.inboundPorts !== undefined ? item.inboundPorts : DEFAULT_INBOUND;
|
|
6917
|
+
const outboundSrc = item.outboundPorts !== undefined ? item.outboundPorts : DEFAULT_OUTBOUND;
|
|
6918
|
+
const inbound = inboundSrc.map((p) => ({
|
|
6919
|
+
...p,
|
|
6920
|
+
id: createWorkflowPortId(`${nodeId}-in`),
|
|
6921
|
+
kind: 'inbound',
|
|
6922
|
+
data: p.data ? { ...p.data } : undefined,
|
|
6923
|
+
}));
|
|
6924
|
+
const outbound = outboundSrc.map((p) => ({
|
|
6925
|
+
...p,
|
|
6926
|
+
id: createWorkflowPortId(`${nodeId}-out`),
|
|
6927
|
+
kind: 'outbound',
|
|
6928
|
+
data: p.data ? { ...p.data } : undefined,
|
|
6929
|
+
}));
|
|
6930
|
+
return { inbound, outbound };
|
|
6931
|
+
}
|
|
6932
|
+
function createNodeFromPaletteItem(item, position) {
|
|
6933
|
+
const id = createWorkflowNodeId();
|
|
6934
|
+
const { inbound, outbound } = createPortsFromPalette(id, item);
|
|
6935
|
+
const shape = item.shape ?? 'rounded-rectangle';
|
|
6936
|
+
const size = item.size ? { ...item.size } : { ...DEFAULT_SIZE };
|
|
6937
|
+
if (shape === 'circle') {
|
|
6938
|
+
const d = Math.min(size.width, size.height);
|
|
6939
|
+
size.width = d;
|
|
6940
|
+
size.height = d;
|
|
6941
|
+
}
|
|
6942
|
+
return {
|
|
6943
|
+
id,
|
|
6944
|
+
type: item.type,
|
|
6945
|
+
title: item.title,
|
|
6946
|
+
icon: item.icon,
|
|
6947
|
+
shape,
|
|
6948
|
+
position: { ...position },
|
|
6949
|
+
size: { ...size },
|
|
6950
|
+
inboundPorts: inbound,
|
|
6951
|
+
outboundPorts: outbound,
|
|
6952
|
+
data: item.data ? { ...item.data } : undefined,
|
|
6953
|
+
lockAspectRatio: item.lockAspectRatio ?? shape === 'circle',
|
|
6954
|
+
snapToGrid: item.snapToGrid,
|
|
6955
|
+
color: item.color,
|
|
6956
|
+
};
|
|
6957
|
+
}
|
|
6958
|
+
/**
|
|
6959
|
+
* Parses drag `dataTransfer` JSON into a partial palette item (requires `type`).
|
|
6960
|
+
* Merge with catalog (`paletteItems`) to obtain `title` and defaults.
|
|
6961
|
+
*/
|
|
6962
|
+
function parsePaletteItemDragPayload(raw) {
|
|
6963
|
+
if (!raw)
|
|
6964
|
+
return null;
|
|
6965
|
+
try {
|
|
6966
|
+
const o = JSON.parse(raw);
|
|
6967
|
+
if (typeof o.type !== 'string')
|
|
6968
|
+
return null;
|
|
6969
|
+
return o;
|
|
6970
|
+
}
|
|
6971
|
+
catch {
|
|
6972
|
+
return null;
|
|
6973
|
+
}
|
|
6974
|
+
}
|
|
6975
|
+
//#endregion
|
|
6976
|
+
//#region ---- Snap ----
|
|
6977
|
+
function snapScalar(value, grid) {
|
|
6978
|
+
if (grid <= 0)
|
|
6979
|
+
return value;
|
|
6980
|
+
return Math.round(value / grid) * grid;
|
|
6981
|
+
}
|
|
6982
|
+
function snapPoint(point, grid) {
|
|
6983
|
+
return { x: snapScalar(point.x, grid), y: snapScalar(point.y, grid) };
|
|
6984
|
+
}
|
|
6985
|
+
//#endregion
|
|
6986
|
+
//#region ---- Port anchor (node-local, top-left origin) ----
|
|
6987
|
+
/**
|
|
6988
|
+
* Inbound/outbound anchor on an axis-aligned ellipse inscribed in `w`×`h` (centered),
|
|
6989
|
+
* so ports sit on the true perimeter for circle/ellipse nodes.
|
|
6990
|
+
*/
|
|
6991
|
+
function portAnchorOnEllipsePerimeter(w, h, side, ratio) {
|
|
6992
|
+
const r = Math.min(0.999, Math.max(0.001, ratio));
|
|
6993
|
+
const cx = w * 0.5;
|
|
6994
|
+
const cy = h * 0.5;
|
|
6995
|
+
const rx = w * 0.5;
|
|
6996
|
+
const ry = h * 0.5;
|
|
6997
|
+
let theta = 0;
|
|
6998
|
+
switch (side) {
|
|
6999
|
+
case 'right':
|
|
7000
|
+
theta = -Math.PI / 2 + Math.PI * r;
|
|
7001
|
+
break;
|
|
7002
|
+
case 'left':
|
|
7003
|
+
theta = Math.PI / 2 + Math.PI * r;
|
|
7004
|
+
break;
|
|
7005
|
+
case 'top':
|
|
7006
|
+
theta = Math.PI + Math.PI * r;
|
|
7007
|
+
break;
|
|
7008
|
+
case 'bottom':
|
|
7009
|
+
theta = Math.PI * r;
|
|
7010
|
+
break;
|
|
7011
|
+
default:
|
|
7012
|
+
theta = 0;
|
|
7013
|
+
}
|
|
7014
|
+
return {
|
|
7015
|
+
x: cx + rx * Math.cos(theta),
|
|
7016
|
+
y: cy + ry * Math.sin(theta),
|
|
7017
|
+
};
|
|
7018
|
+
}
|
|
7019
|
+
function portAnchorOnBoxEdge(w, h, side, ratio) {
|
|
7020
|
+
const r = Math.min(0.999, Math.max(0.001, ratio));
|
|
7021
|
+
switch (side) {
|
|
7022
|
+
case 'top':
|
|
7023
|
+
return { x: w * r, y: 0 };
|
|
7024
|
+
case 'bottom':
|
|
7025
|
+
return { x: w * r, y: h };
|
|
7026
|
+
case 'left':
|
|
7027
|
+
return { x: 0, y: h * r };
|
|
7028
|
+
case 'right':
|
|
7029
|
+
return { x: w, y: h * r };
|
|
7030
|
+
default:
|
|
7031
|
+
return { x: w * 0.5, y: h * 0.5 };
|
|
7032
|
+
}
|
|
7033
|
+
}
|
|
7034
|
+
/** Diamond perimeter of a rotated square inside the node bounds. */
|
|
7035
|
+
function portAnchorOnDiamondPerimeter(w, h, side, ratio) {
|
|
7036
|
+
const r = Math.min(0.999, Math.max(0.001, ratio));
|
|
7037
|
+
const top = { x: w * 0.5, y: 0 };
|
|
7038
|
+
const right = { x: w, y: h * 0.5 };
|
|
7039
|
+
const bottom = { x: w * 0.5, y: h };
|
|
7040
|
+
const left = { x: 0, y: h * 0.5 };
|
|
7041
|
+
const lerp = (a, b, t) => ({
|
|
7042
|
+
x: a.x + (b.x - a.x) * t,
|
|
7043
|
+
y: a.y + (b.y - a.y) * t,
|
|
7044
|
+
});
|
|
7045
|
+
switch (side) {
|
|
7046
|
+
case 'top':
|
|
7047
|
+
return r <= 0.5 ? lerp(left, top, r * 2) : lerp(top, right, (r - 0.5) * 2);
|
|
7048
|
+
case 'right':
|
|
7049
|
+
return r <= 0.5 ? lerp(top, right, r * 2) : lerp(right, bottom, (r - 0.5) * 2);
|
|
7050
|
+
case 'bottom':
|
|
7051
|
+
return r <= 0.5 ? lerp(right, bottom, r * 2) : lerp(bottom, left, (r - 0.5) * 2);
|
|
7052
|
+
case 'left':
|
|
7053
|
+
return r <= 0.5 ? lerp(bottom, left, r * 2) : lerp(left, top, (r - 0.5) * 2);
|
|
7054
|
+
default:
|
|
7055
|
+
return { x: w * 0.5, y: h * 0.5 };
|
|
7056
|
+
}
|
|
7057
|
+
}
|
|
7058
|
+
function portAnchorOnNode(node, port) {
|
|
7059
|
+
const { width: w, height: h } = node.size;
|
|
7060
|
+
const r = Math.min(0.999, Math.max(0.001, port.ratio));
|
|
7061
|
+
if (node.shape === 'circle' || node.shape === 'ellipse') {
|
|
7062
|
+
return portAnchorOnEllipsePerimeter(w, h, port.side, r);
|
|
7063
|
+
}
|
|
7064
|
+
if (node.shape === 'diamond') {
|
|
7065
|
+
return portAnchorOnDiamondPerimeter(w, h, port.side, r);
|
|
7066
|
+
}
|
|
7067
|
+
return portAnchorOnBoxEdge(w, h, port.side, r);
|
|
7068
|
+
}
|
|
7069
|
+
function portCanvasPosition(node, port) {
|
|
7070
|
+
const local = portAnchorOnNode(node, port);
|
|
7071
|
+
return { x: node.position.x + local.x, y: node.position.y + local.y };
|
|
7072
|
+
}
|
|
7073
|
+
function inflateRect(r, padding) {
|
|
7074
|
+
return {
|
|
7075
|
+
x: r.position.x - padding,
|
|
7076
|
+
y: r.position.y - padding,
|
|
7077
|
+
width: r.size.width + padding * 2,
|
|
7078
|
+
height: r.size.height + padding * 2,
|
|
7079
|
+
};
|
|
7080
|
+
}
|
|
7081
|
+
function pointInsideRect(p, r) {
|
|
7082
|
+
return p.x > r.x && p.x < r.x + r.width && p.y > r.y && p.y < r.y + r.height;
|
|
7083
|
+
}
|
|
7084
|
+
/**
|
|
7085
|
+
* Returns true if an axis-aligned segment crosses the interior of any obstacle.
|
|
7086
|
+
* Endpoints that only touch the rectangle's edge are not considered a crossing.
|
|
7087
|
+
*/
|
|
7088
|
+
function segmentCrossesObstacles(a, b, obstacles) {
|
|
7089
|
+
const minX = Math.min(a.x, b.x);
|
|
7090
|
+
const maxX = Math.max(a.x, b.x);
|
|
7091
|
+
const minY = Math.min(a.y, b.y);
|
|
7092
|
+
const maxY = Math.max(a.y, b.y);
|
|
7093
|
+
const tolerance = 0.5;
|
|
7094
|
+
for (const r of obstacles) {
|
|
7095
|
+
const right = r.x + r.width;
|
|
7096
|
+
const bottom = r.y + r.height;
|
|
7097
|
+
if (maxX <= r.x + tolerance || minX >= right - tolerance)
|
|
7098
|
+
continue;
|
|
7099
|
+
if (maxY <= r.y + tolerance || minY >= bottom - tolerance)
|
|
7100
|
+
continue;
|
|
7101
|
+
if (Math.abs(a.y - b.y) < 0.0001) {
|
|
7102
|
+
if (a.y > r.y + tolerance && a.y < bottom - tolerance)
|
|
7103
|
+
return true;
|
|
7104
|
+
}
|
|
7105
|
+
else if (Math.abs(a.x - b.x) < 0.0001) {
|
|
7106
|
+
if (a.x > r.x + tolerance && a.x < right - tolerance)
|
|
7107
|
+
return true;
|
|
7108
|
+
}
|
|
7109
|
+
else {
|
|
7110
|
+
return true;
|
|
7111
|
+
}
|
|
7112
|
+
}
|
|
7113
|
+
return false;
|
|
7114
|
+
}
|
|
7115
|
+
function stepOutward(p, side, length) {
|
|
7116
|
+
switch (side) {
|
|
7117
|
+
case 'left':
|
|
7118
|
+
return { x: p.x - length, y: p.y };
|
|
7119
|
+
case 'right':
|
|
7120
|
+
return { x: p.x + length, y: p.y };
|
|
7121
|
+
case 'top':
|
|
7122
|
+
return { x: p.x, y: p.y - length };
|
|
7123
|
+
case 'bottom':
|
|
7124
|
+
return { x: p.x, y: p.y + length };
|
|
7125
|
+
}
|
|
7126
|
+
}
|
|
7127
|
+
function oppositeSide(side) {
|
|
7128
|
+
switch (side) {
|
|
7129
|
+
case 'left':
|
|
7130
|
+
return 'right';
|
|
7131
|
+
case 'right':
|
|
7132
|
+
return 'left';
|
|
7133
|
+
case 'top':
|
|
7134
|
+
return 'bottom';
|
|
7135
|
+
case 'bottom':
|
|
7136
|
+
return 'top';
|
|
7137
|
+
}
|
|
7138
|
+
}
|
|
7139
|
+
function sideAxis(side) {
|
|
7140
|
+
return side === 'left' || side === 'right' ? 'h' : 'v';
|
|
7141
|
+
}
|
|
7142
|
+
/**
|
|
7143
|
+
* Removes consecutive duplicate points and collapses collinear intermediate waypoints.
|
|
7144
|
+
*/
|
|
7145
|
+
function simplifyWaypoints(points) {
|
|
7146
|
+
const deduped = [];
|
|
7147
|
+
for (const p of points) {
|
|
7148
|
+
const last = deduped[deduped.length - 1];
|
|
7149
|
+
if (last && Math.abs(last.x - p.x) < 0.001 && Math.abs(last.y - p.y) < 0.001)
|
|
7150
|
+
continue;
|
|
7151
|
+
deduped.push(p);
|
|
7152
|
+
}
|
|
7153
|
+
if (deduped.length <= 2)
|
|
7154
|
+
return deduped;
|
|
7155
|
+
const out = [deduped[0]];
|
|
7156
|
+
for (let i = 1; i < deduped.length - 1; i++) {
|
|
7157
|
+
const prev = deduped[i - 1];
|
|
7158
|
+
const curr = deduped[i];
|
|
7159
|
+
const next = deduped[i + 1];
|
|
7160
|
+
const collinearH = Math.abs(prev.y - curr.y) < 0.001 && Math.abs(curr.y - next.y) < 0.001;
|
|
7161
|
+
const collinearV = Math.abs(prev.x - curr.x) < 0.001 && Math.abs(curr.x - next.x) < 0.001;
|
|
7162
|
+
if (!collinearH && !collinearV)
|
|
7163
|
+
out.push(curr);
|
|
7164
|
+
}
|
|
7165
|
+
out.push(deduped[deduped.length - 1]);
|
|
7166
|
+
return out;
|
|
7167
|
+
}
|
|
7168
|
+
/**
|
|
7169
|
+
* Generates candidate waypoint sets that connect `a` to `b` while respecting the entry/exit axes.
|
|
7170
|
+
* Strategies are ordered from "most natural" to "more elaborate detour".
|
|
7171
|
+
*/
|
|
7172
|
+
function generateRouteStrategies(a, aAxis, b, bAxis, obstacles) {
|
|
7173
|
+
const strategies = [];
|
|
7174
|
+
const midX = (a.x + b.x) / 2;
|
|
7175
|
+
const midY = (a.y + b.y) / 2;
|
|
7176
|
+
const obstacleXCuts = [];
|
|
7177
|
+
const obstacleYCuts = [];
|
|
7178
|
+
for (const o of obstacles) {
|
|
7179
|
+
obstacleXCuts.push(o.x - 6);
|
|
7180
|
+
obstacleXCuts.push(o.x + o.width + 6);
|
|
7181
|
+
obstacleYCuts.push(o.y - 6);
|
|
7182
|
+
obstacleYCuts.push(o.y + o.height + 6);
|
|
7183
|
+
}
|
|
7184
|
+
obstacleXCuts.sort((x, y) => Math.abs(x - midX) - Math.abs(y - midX));
|
|
7185
|
+
obstacleYCuts.sort((x, y) => Math.abs(x - midY) - Math.abs(y - midY));
|
|
7186
|
+
if (aAxis === 'h' && bAxis === 'h') {
|
|
7187
|
+
strategies.push([
|
|
7188
|
+
{ x: midX, y: a.y },
|
|
7189
|
+
{ x: midX, y: b.y },
|
|
7190
|
+
]);
|
|
7191
|
+
for (const mx of obstacleXCuts) {
|
|
7192
|
+
strategies.push([
|
|
7193
|
+
{ x: mx, y: a.y },
|
|
7194
|
+
{ x: mx, y: b.y },
|
|
7195
|
+
]);
|
|
7196
|
+
}
|
|
7197
|
+
for (const my of obstacleYCuts) {
|
|
7198
|
+
strategies.push([
|
|
7199
|
+
{ x: a.x, y: my },
|
|
7200
|
+
{ x: b.x, y: my },
|
|
7201
|
+
]);
|
|
7202
|
+
}
|
|
7203
|
+
}
|
|
7204
|
+
else if (aAxis === 'v' && bAxis === 'v') {
|
|
7205
|
+
strategies.push([
|
|
7206
|
+
{ x: a.x, y: midY },
|
|
7207
|
+
{ x: b.x, y: midY },
|
|
7208
|
+
]);
|
|
7209
|
+
for (const my of obstacleYCuts) {
|
|
7210
|
+
strategies.push([
|
|
7211
|
+
{ x: a.x, y: my },
|
|
7212
|
+
{ x: b.x, y: my },
|
|
7213
|
+
]);
|
|
7214
|
+
}
|
|
7215
|
+
for (const mx of obstacleXCuts) {
|
|
7216
|
+
strategies.push([
|
|
7217
|
+
{ x: mx, y: a.y },
|
|
7218
|
+
{ x: mx, y: b.y },
|
|
7219
|
+
]);
|
|
7220
|
+
}
|
|
7221
|
+
}
|
|
7222
|
+
else if (aAxis === 'h' && bAxis === 'v') {
|
|
7223
|
+
strategies.push([{ x: b.x, y: a.y }]);
|
|
7224
|
+
for (const my of obstacleYCuts) {
|
|
7225
|
+
strategies.push([
|
|
7226
|
+
{ x: a.x, y: my },
|
|
7227
|
+
{ x: b.x, y: my },
|
|
7228
|
+
]);
|
|
7229
|
+
}
|
|
7230
|
+
}
|
|
7231
|
+
else {
|
|
7232
|
+
strategies.push([{ x: a.x, y: b.y }]);
|
|
7233
|
+
for (const mx of obstacleXCuts) {
|
|
7234
|
+
strategies.push([
|
|
7235
|
+
{ x: mx, y: a.y },
|
|
7236
|
+
{ x: mx, y: b.y },
|
|
7237
|
+
]);
|
|
7238
|
+
}
|
|
7239
|
+
}
|
|
7240
|
+
return strategies;
|
|
7241
|
+
}
|
|
7242
|
+
/**
|
|
7243
|
+
* Picks the first strategy whose segments do not cross any obstacle.
|
|
7244
|
+
* Falls back to the most natural strategy when every candidate is blocked
|
|
7245
|
+
* (best-effort: keeps the connector readable even in tight layouts).
|
|
7246
|
+
*/
|
|
7247
|
+
function pickCleanStrategy(a, b, strategies, obstacles) {
|
|
7248
|
+
for (const wp of strategies) {
|
|
7249
|
+
const full = [a, ...wp, b];
|
|
7250
|
+
let clean = true;
|
|
7251
|
+
for (let i = 0; i < full.length - 1; i++) {
|
|
7252
|
+
if (segmentCrossesObstacles(full[i], full[i + 1], obstacles)) {
|
|
7253
|
+
clean = false;
|
|
7254
|
+
break;
|
|
7255
|
+
}
|
|
7256
|
+
}
|
|
7257
|
+
if (clean)
|
|
7258
|
+
return wp;
|
|
7259
|
+
}
|
|
7260
|
+
return strategies[0] ?? [];
|
|
7261
|
+
}
|
|
7262
|
+
/**
|
|
7263
|
+
* Routes an obstacle-aware orthogonal path between two free-space points.
|
|
7264
|
+
* The returned array includes the start (`from`), stub-outs from each port,
|
|
7265
|
+
* intermediate waypoints, and the end (`to`).
|
|
7266
|
+
*
|
|
7267
|
+
* Obstacles whose inflated rect already contains a stub point are dropped so
|
|
7268
|
+
* that source/target nodes can still emit/receive their connector without the
|
|
7269
|
+
* router fighting itself — but the middle of the path still routes around them.
|
|
7270
|
+
*/
|
|
7271
|
+
function routeOrthogonalConnector(from, sourceSide, to, targetSide, obstacles = [], options = {}) {
|
|
7272
|
+
const stub = Math.max(0, options.stub ?? 18);
|
|
7273
|
+
const padding = Math.max(0, options.obstaclePadding ?? 10);
|
|
7274
|
+
const aStub = stepOutward(from, sourceSide, stub);
|
|
7275
|
+
const bStub = stepOutward(to, targetSide, stub);
|
|
7276
|
+
const inflated = obstacles.map((o) => inflateRect(o, padding));
|
|
7277
|
+
const safe = inflated.filter((o) => !pointInsideRect(aStub, o) && !pointInsideRect(bStub, o));
|
|
7278
|
+
const strategies = generateRouteStrategies(aStub, sideAxis(sourceSide), bStub, sideAxis(targetSide), safe);
|
|
7279
|
+
const middle = pickCleanStrategy(aStub, bStub, strategies, safe);
|
|
7280
|
+
return simplifyWaypoints([from, aStub, ...middle, bStub, to]);
|
|
7281
|
+
}
|
|
7282
|
+
/** Renders waypoints as straight `L` segments. */
|
|
7283
|
+
function waypointsToOrthogonalPath(points) {
|
|
7284
|
+
if (points.length < 2)
|
|
7285
|
+
return '';
|
|
7286
|
+
const cmds = [`M ${points[0].x} ${points[0].y}`];
|
|
7287
|
+
for (let i = 1; i < points.length; i++) {
|
|
7288
|
+
cmds.push(`L ${points[i].x} ${points[i].y}`);
|
|
7289
|
+
}
|
|
7290
|
+
return cmds.join(' ');
|
|
7291
|
+
}
|
|
7292
|
+
/** Renders waypoints with rounded corners (quadratic curves) between segments. */
|
|
7293
|
+
function waypointsToRoundedPath(points, radius) {
|
|
7294
|
+
if (points.length < 2)
|
|
7295
|
+
return '';
|
|
7296
|
+
if (points.length === 2)
|
|
7297
|
+
return `M ${points[0].x} ${points[0].y} L ${points[1].x} ${points[1].y}`;
|
|
7298
|
+
const cmds = [`M ${points[0].x} ${points[0].y}`];
|
|
7299
|
+
for (let i = 1; i < points.length - 1; i++) {
|
|
7300
|
+
const prev = points[i - 1];
|
|
7301
|
+
const curr = points[i];
|
|
7302
|
+
const next = points[i + 1];
|
|
7303
|
+
const inDx = Math.sign(curr.x - prev.x);
|
|
7304
|
+
const inDy = Math.sign(curr.y - prev.y);
|
|
7305
|
+
const outDx = Math.sign(next.x - curr.x);
|
|
7306
|
+
const outDy = Math.sign(next.y - curr.y);
|
|
7307
|
+
const segIn = Math.hypot(curr.x - prev.x, curr.y - prev.y);
|
|
7308
|
+
const segOut = Math.hypot(next.x - curr.x, next.y - curr.y);
|
|
7309
|
+
const r = Math.max(0, Math.min(radius, segIn * 0.5, segOut * 0.5));
|
|
7310
|
+
const cornerStart = { x: curr.x - inDx * r, y: curr.y - inDy * r };
|
|
7311
|
+
const cornerEnd = { x: curr.x + outDx * r, y: curr.y + outDy * r };
|
|
7312
|
+
cmds.push(`L ${cornerStart.x} ${cornerStart.y}`);
|
|
7313
|
+
cmds.push(`Q ${curr.x} ${curr.y} ${cornerEnd.x} ${cornerEnd.y}`);
|
|
7314
|
+
}
|
|
7315
|
+
const last = points[points.length - 1];
|
|
7316
|
+
cmds.push(`L ${last.x} ${last.y}`);
|
|
7317
|
+
return cmds.join(' ');
|
|
7318
|
+
}
|
|
7319
|
+
/**
|
|
7320
|
+
* Builds the SVG `d` string for a connector. When `options.obstacles` is supplied,
|
|
7321
|
+
* orthogonal/rounded routes detour around the obstacle rectangles instead of
|
|
7322
|
+
* passing through them. The `straight` style always draws a direct line.
|
|
7323
|
+
*/
|
|
7324
|
+
function connectorPath(from, to, style, sourceSide, options = {}) {
|
|
7325
|
+
if (style === 'straight') {
|
|
7326
|
+
return `M ${from.x} ${from.y} L ${to.x} ${to.y}`;
|
|
7327
|
+
}
|
|
7328
|
+
const targetSide = options.targetSide ?? oppositeSide(sourceSide);
|
|
7329
|
+
const waypoints = routeOrthogonalConnector(from, sourceSide, to, targetSide, options.obstacles ?? [], {
|
|
7330
|
+
stub: options.stub,
|
|
7331
|
+
obstaclePadding: options.obstaclePadding,
|
|
7332
|
+
});
|
|
7333
|
+
if (style === 'orthogonal') {
|
|
7334
|
+
return waypointsToOrthogonalPath(waypoints);
|
|
7335
|
+
}
|
|
7336
|
+
return waypointsToRoundedPath(waypoints, options.cornerRadius ?? 14);
|
|
7337
|
+
}
|
|
7338
|
+
//#endregion
|
|
7339
|
+
//#region ---- Model helpers ----
|
|
7340
|
+
function findNode(model, nodeId) {
|
|
7341
|
+
return model.nodes.find((n) => n.id === nodeId);
|
|
7342
|
+
}
|
|
7343
|
+
function findPort(node, portId) {
|
|
7344
|
+
const pi = node.inboundPorts.find((p) => p.id === portId);
|
|
7345
|
+
if (pi)
|
|
7346
|
+
return { port: pi, inbound: true };
|
|
7347
|
+
const po = node.outboundPorts.find((p) => p.id === portId);
|
|
7348
|
+
if (po)
|
|
7349
|
+
return { port: po, inbound: false };
|
|
7350
|
+
return undefined;
|
|
7351
|
+
}
|
|
7352
|
+
function findConnector(model, id) {
|
|
7353
|
+
return model.connectors.find((c) => c.id === id);
|
|
7354
|
+
}
|
|
7355
|
+
/**
|
|
7356
|
+
* Built-in rules: valid ports, not disabled, optional single inbound attachment, no duplicate edge.
|
|
7357
|
+
*/
|
|
7358
|
+
function defaultCanConnectRequest(request) {
|
|
7359
|
+
const { model, sourceNodeId, sourcePortId, targetNodeId, targetPortId } = request;
|
|
7360
|
+
const sn = findNode(model, sourceNodeId);
|
|
7361
|
+
const tn = findNode(model, targetNodeId);
|
|
7362
|
+
if (!sn || !tn)
|
|
7363
|
+
return false;
|
|
7364
|
+
const spInfo = findPort(sn, sourcePortId);
|
|
7365
|
+
const tpInfo = findPort(tn, targetPortId);
|
|
7366
|
+
if (!spInfo || !tpInfo)
|
|
7367
|
+
return false;
|
|
7368
|
+
const sp = spInfo.port;
|
|
7369
|
+
const tp = tpInfo.port;
|
|
7370
|
+
if (sp.kind !== 'outbound' || tp.kind !== 'inbound')
|
|
7371
|
+
return false;
|
|
7372
|
+
if (sp.disabled || tp.disabled)
|
|
7373
|
+
return false;
|
|
7374
|
+
const duplicate = model.connectors.some((c) => c.sourceNodeId === sourceNodeId &&
|
|
7375
|
+
c.sourcePortId === sourcePortId &&
|
|
7376
|
+
c.targetNodeId === targetNodeId &&
|
|
7377
|
+
c.targetPortId === targetPortId);
|
|
7378
|
+
if (duplicate)
|
|
7379
|
+
return false;
|
|
7380
|
+
if (!tp.allowMultiple) {
|
|
7381
|
+
const inboundTaken = model.connectors.some((c) => c.targetNodeId === targetNodeId && c.targetPortId === targetPortId);
|
|
7382
|
+
if (inboundTaken)
|
|
7383
|
+
return false;
|
|
7384
|
+
}
|
|
7385
|
+
return true;
|
|
7386
|
+
}
|
|
7387
|
+
//#endregion
|
|
7388
|
+
//#region ---- Auto layout ----
|
|
7389
|
+
const DEFAULT_ARRANGE_MARGIN = 80;
|
|
7390
|
+
// Defaults leave room for inbound/outbound port labels that sit ~18px outside the
|
|
7391
|
+
// port anchor and may extend further as text. Larger gaps keep adjacent nodes from
|
|
7392
|
+
// having their port labels collide with each other or with routed connectors.
|
|
7393
|
+
const DEFAULT_ARRANGE_PRIMARY_GAP = 160;
|
|
7394
|
+
const DEFAULT_ARRANGE_CROSS_GAP = 110;
|
|
7395
|
+
const DEFAULT_ARRANGE_COMPONENT_GAP = 220;
|
|
7396
|
+
/**
|
|
7397
|
+
* Auto-arranges workflow nodes in a layered layout (left→right by default).
|
|
7398
|
+
* Honors `direction`, `alignment`, `origin`, `nodeIds`, and crossing-reduction options.
|
|
7399
|
+
*/
|
|
7400
|
+
function arrangeWorkflowDiagram(model, options = {}) {
|
|
7401
|
+
if (model.nodes.length === 0) {
|
|
7402
|
+
return model;
|
|
7403
|
+
}
|
|
7404
|
+
const margin = options.margin ?? DEFAULT_ARRANGE_MARGIN;
|
|
7405
|
+
const runtime = {
|
|
7406
|
+
direction: options.direction ?? 'horizontal',
|
|
7407
|
+
alignment: options.alignment ?? 'center',
|
|
7408
|
+
primaryGap: options.horizontalGap ?? DEFAULT_ARRANGE_PRIMARY_GAP,
|
|
7409
|
+
crossGap: options.verticalGap ?? DEFAULT_ARRANGE_CROSS_GAP,
|
|
7410
|
+
componentGap: Math.max(options.verticalGap ?? DEFAULT_ARRANGE_CROSS_GAP, DEFAULT_ARRANGE_COMPONENT_GAP),
|
|
7411
|
+
margin,
|
|
7412
|
+
grid: options.gridSize ?? 0,
|
|
7413
|
+
origin: options.origin ?? { x: margin, y: margin },
|
|
7414
|
+
reduceCrossings: options.reduceCrossings ?? true,
|
|
7415
|
+
groupDisconnected: options.groupDisconnected ?? true,
|
|
7416
|
+
};
|
|
7417
|
+
const subsetIds = options.nodeIds && options.nodeIds.length > 0
|
|
7418
|
+
? new Set(options.nodeIds.filter((id) => model.nodes.some((n) => n.id === id)))
|
|
7419
|
+
: null;
|
|
7420
|
+
const targetNodes = subsetIds ? model.nodes.filter((n) => subsetIds.has(n.id)) : model.nodes;
|
|
7421
|
+
if (targetNodes.length === 0) {
|
|
7422
|
+
return model;
|
|
7423
|
+
}
|
|
7424
|
+
const targetIds = new Set(targetNodes.map((n) => n.id));
|
|
7425
|
+
const relevantConnectors = model.connectors.filter((c) => targetIds.has(c.sourceNodeId) && targetIds.has(c.targetNodeId));
|
|
7426
|
+
const components = splitComponents(targetNodes, relevantConnectors, runtime, options.startNodeId);
|
|
7427
|
+
const positionById = new Map();
|
|
7428
|
+
let crossCursor = runtime.direction === 'horizontal' ? runtime.origin.y : runtime.origin.x;
|
|
7429
|
+
for (const component of components) {
|
|
7430
|
+
layoutComponent(component, positionById, runtime, crossCursor);
|
|
7431
|
+
crossCursor += component.crossSize + runtime.componentGap;
|
|
7432
|
+
}
|
|
7433
|
+
return {
|
|
7434
|
+
...model,
|
|
7435
|
+
nodes: model.nodes.map((n) => {
|
|
7436
|
+
const next = positionById.get(n.id);
|
|
7437
|
+
return next ? { ...n, position: { ...next } } : n;
|
|
7438
|
+
}),
|
|
7439
|
+
};
|
|
7440
|
+
}
|
|
7441
|
+
function splitComponents(nodes, connectors, runtime, startNodeId) {
|
|
7442
|
+
const undirected = new Map();
|
|
7443
|
+
const outgoing = new Map();
|
|
7444
|
+
const incomingCount = new Map();
|
|
7445
|
+
for (const n of nodes) {
|
|
7446
|
+
undirected.set(n.id, new Set());
|
|
7447
|
+
outgoing.set(n.id, new Set());
|
|
7448
|
+
incomingCount.set(n.id, 0);
|
|
7449
|
+
}
|
|
7450
|
+
for (const c of connectors) {
|
|
7451
|
+
if (!undirected.has(c.sourceNodeId) || !undirected.has(c.targetNodeId))
|
|
7452
|
+
continue;
|
|
7453
|
+
undirected.get(c.sourceNodeId).add(c.targetNodeId);
|
|
7454
|
+
undirected.get(c.targetNodeId).add(c.sourceNodeId);
|
|
7455
|
+
outgoing.get(c.sourceNodeId).add(c.targetNodeId);
|
|
7456
|
+
incomingCount.set(c.targetNodeId, (incomingCount.get(c.targetNodeId) ?? 0) + 1);
|
|
7457
|
+
}
|
|
7458
|
+
const sortedNodes = [...nodes].sort(compareNodesForLayout);
|
|
7459
|
+
if (startNodeId) {
|
|
7460
|
+
sortedNodes.sort((a, b) => {
|
|
7461
|
+
if (a.id === startNodeId)
|
|
7462
|
+
return -1;
|
|
7463
|
+
if (b.id === startNodeId)
|
|
7464
|
+
return 1;
|
|
7465
|
+
return 0;
|
|
7466
|
+
});
|
|
7467
|
+
}
|
|
7468
|
+
const visited = new Set();
|
|
7469
|
+
const componentBuckets = [];
|
|
7470
|
+
if (runtime.groupDisconnected) {
|
|
7471
|
+
for (const seed of sortedNodes) {
|
|
7472
|
+
if (visited.has(seed.id))
|
|
7473
|
+
continue;
|
|
7474
|
+
const bucket = [];
|
|
7475
|
+
const queue = [seed.id];
|
|
7476
|
+
visited.add(seed.id);
|
|
7477
|
+
while (queue.length > 0) {
|
|
7478
|
+
const id = queue.shift();
|
|
7479
|
+
const node = nodes.find((n) => n.id === id);
|
|
7480
|
+
if (node)
|
|
7481
|
+
bucket.push(node);
|
|
7482
|
+
for (const next of undirected.get(id) ?? []) {
|
|
7483
|
+
if (!visited.has(next)) {
|
|
7484
|
+
visited.add(next);
|
|
7485
|
+
queue.push(next);
|
|
7486
|
+
}
|
|
7487
|
+
}
|
|
7488
|
+
}
|
|
7489
|
+
componentBuckets.push(bucket);
|
|
7490
|
+
}
|
|
7491
|
+
}
|
|
7492
|
+
else {
|
|
7493
|
+
componentBuckets.push([...nodes]);
|
|
7494
|
+
}
|
|
7495
|
+
const components = [];
|
|
7496
|
+
for (const bucket of componentBuckets) {
|
|
7497
|
+
const bucketIds = new Set(bucket.map((n) => n.id));
|
|
7498
|
+
const bucketConnectors = connectors.filter((c) => bucketIds.has(c.sourceNodeId) && bucketIds.has(c.targetNodeId));
|
|
7499
|
+
const ranks = computeRanks(bucket, outgoing, incomingCount, startNodeId);
|
|
7500
|
+
if (runtime.reduceCrossings) {
|
|
7501
|
+
reduceCrossingsInPlace(ranks, bucketConnectors, runtime.direction);
|
|
7502
|
+
}
|
|
7503
|
+
else {
|
|
7504
|
+
for (const rank of ranks)
|
|
7505
|
+
rank.sort(compareNodesForLayout);
|
|
7506
|
+
}
|
|
7507
|
+
const crossSize = estimateCrossSize(ranks, runtime);
|
|
7508
|
+
components.push({ nodes: bucket, ranks, crossSize });
|
|
7509
|
+
}
|
|
7510
|
+
return components;
|
|
7511
|
+
}
|
|
7512
|
+
function computeRanks(nodes, outgoing, incomingCount, startNodeId) {
|
|
7513
|
+
const rank = new Map();
|
|
7514
|
+
const queue = [];
|
|
7515
|
+
const enqueueRoots = (ids) => {
|
|
7516
|
+
for (const id of ids) {
|
|
7517
|
+
if (!rank.has(id)) {
|
|
7518
|
+
rank.set(id, 0);
|
|
7519
|
+
queue.push(id);
|
|
7520
|
+
}
|
|
7521
|
+
}
|
|
7522
|
+
};
|
|
7523
|
+
const localIds = new Set(nodes.map((n) => n.id));
|
|
7524
|
+
if (startNodeId && localIds.has(startNodeId)) {
|
|
7525
|
+
enqueueRoots([startNodeId]);
|
|
7526
|
+
}
|
|
7527
|
+
else {
|
|
7528
|
+
enqueueRoots(nodes.filter((n) => (incomingCount.get(n.id) ?? 0) === 0).map((n) => n.id));
|
|
7529
|
+
}
|
|
7530
|
+
// First-visit BFS handles cycles safely (shortest-distance ranking).
|
|
7531
|
+
const maxSteps = nodes.length * (nodes.length + 1);
|
|
7532
|
+
let steps = 0;
|
|
7533
|
+
while (queue.length > 0 && steps < maxSteps) {
|
|
7534
|
+
steps += 1;
|
|
7535
|
+
const id = queue.shift();
|
|
7536
|
+
const base = rank.get(id) ?? 0;
|
|
7537
|
+
for (const targetId of outgoing.get(id) ?? []) {
|
|
7538
|
+
if (!localIds.has(targetId) || rank.has(targetId))
|
|
7539
|
+
continue;
|
|
7540
|
+
rank.set(targetId, base + 1);
|
|
7541
|
+
queue.push(targetId);
|
|
7542
|
+
}
|
|
7543
|
+
}
|
|
7544
|
+
let orphanRank = nodes.reduce((max, n) => Math.max(max, rank.get(n.id) ?? 0), 0) + 1;
|
|
7545
|
+
const unranked = nodes.filter((n) => !rank.has(n.id)).sort(compareNodesForLayout);
|
|
7546
|
+
for (const n of unranked) {
|
|
7547
|
+
rank.set(n.id, orphanRank);
|
|
7548
|
+
orphanRank += 1;
|
|
7549
|
+
}
|
|
7550
|
+
const byRank = new Map();
|
|
7551
|
+
for (const n of nodes) {
|
|
7552
|
+
const r = rank.get(n.id) ?? 0;
|
|
7553
|
+
const bucket = byRank.get(r) ?? [];
|
|
7554
|
+
bucket.push(n);
|
|
7555
|
+
byRank.set(r, bucket);
|
|
7556
|
+
}
|
|
7557
|
+
return [...byRank.keys()].sort((a, b) => a - b).map((r) => byRank.get(r) ?? []);
|
|
7558
|
+
}
|
|
7559
|
+
/**
|
|
7560
|
+
* Returns a 0–1 fraction along the cross axis (vertical for horizontal flow) where the port sits on the node.
|
|
7561
|
+
*/
|
|
7562
|
+
function portCrossAxisFraction(node, portId, direction) {
|
|
7563
|
+
const info = findPort(node, portId);
|
|
7564
|
+
if (!info) {
|
|
7565
|
+
return 0.5;
|
|
7566
|
+
}
|
|
7567
|
+
const port = info.port;
|
|
7568
|
+
const r = Math.min(0.999, Math.max(0.001, port.ratio));
|
|
7569
|
+
if (direction === 'horizontal') {
|
|
7570
|
+
switch (port.side) {
|
|
7571
|
+
case 'left':
|
|
7572
|
+
case 'right':
|
|
7573
|
+
return r;
|
|
7574
|
+
case 'top':
|
|
7575
|
+
return 0;
|
|
7576
|
+
case 'bottom':
|
|
7577
|
+
return 1;
|
|
7578
|
+
}
|
|
7579
|
+
}
|
|
7580
|
+
switch (port.side) {
|
|
7581
|
+
case 'top':
|
|
7582
|
+
case 'bottom':
|
|
7583
|
+
return r;
|
|
7584
|
+
case 'left':
|
|
7585
|
+
return 0;
|
|
7586
|
+
case 'right':
|
|
7587
|
+
return 1;
|
|
7588
|
+
}
|
|
7589
|
+
return r;
|
|
7590
|
+
}
|
|
7591
|
+
/**
|
|
7592
|
+
* Barycenter heuristic with port-aware weights: targets inherit both their predecessor's rank index
|
|
7593
|
+
* and the source port's cross-axis position so top/bottom (or left/right) ports map to matching targets.
|
|
7594
|
+
*/
|
|
7595
|
+
function reduceCrossingsInPlace(ranks, connectors, direction) {
|
|
7596
|
+
if (ranks.length === 0)
|
|
7597
|
+
return;
|
|
7598
|
+
ranks[0] = [...ranks[0]].sort(compareNodesForLayout);
|
|
7599
|
+
const nodeById = new Map();
|
|
7600
|
+
for (const rank of ranks) {
|
|
7601
|
+
for (const node of rank) {
|
|
7602
|
+
nodeById.set(node.id, node);
|
|
7603
|
+
}
|
|
7604
|
+
}
|
|
7605
|
+
const indexInRank = ranks.map((rank) => {
|
|
7606
|
+
const map = new Map();
|
|
7607
|
+
for (let i = 0; i < rank.length; i++)
|
|
7608
|
+
map.set(rank[i].id, i);
|
|
7609
|
+
return map;
|
|
7610
|
+
});
|
|
7611
|
+
for (let r = 1; r < ranks.length; r++) {
|
|
7612
|
+
const predRank = ranks[r - 1];
|
|
7613
|
+
const predIndex = indexInRank[r - 1];
|
|
7614
|
+
const incomingFromPred = new Map();
|
|
7615
|
+
const predIds = new Set(predRank.map((n) => n.id));
|
|
7616
|
+
for (const c of connectors) {
|
|
7617
|
+
if (!predIds.has(c.sourceNodeId)) {
|
|
7618
|
+
continue;
|
|
7619
|
+
}
|
|
7620
|
+
const idx = predIndex.get(c.sourceNodeId);
|
|
7621
|
+
if (idx === undefined) {
|
|
7622
|
+
continue;
|
|
7623
|
+
}
|
|
7624
|
+
const sourceNode = nodeById.get(c.sourceNodeId);
|
|
7625
|
+
const portFraction = sourceNode ? portCrossAxisFraction(sourceNode, c.sourcePortId, direction) : 0.5;
|
|
7626
|
+
// Keep port ordering within the same predecessor index (fraction ∈ [0, 1)).
|
|
7627
|
+
const weight = idx + portFraction;
|
|
7628
|
+
const arr = incomingFromPred.get(c.targetNodeId) ?? [];
|
|
7629
|
+
arr.push(weight);
|
|
7630
|
+
incomingFromPred.set(c.targetNodeId, arr);
|
|
7631
|
+
}
|
|
7632
|
+
ranks[r] = [...ranks[r]].sort((a, b) => {
|
|
7633
|
+
const ia = incomingFromPred.get(a.id) ?? [];
|
|
7634
|
+
const ib = incomingFromPred.get(b.id) ?? [];
|
|
7635
|
+
const ba = ia.length > 0 ? ia.reduce((s, v) => s + v, 0) / ia.length : Number.POSITIVE_INFINITY;
|
|
7636
|
+
const bb = ib.length > 0 ? ib.reduce((s, v) => s + v, 0) / ib.length : Number.POSITIVE_INFINITY;
|
|
7637
|
+
if (ba !== bb)
|
|
7638
|
+
return ba - bb;
|
|
7639
|
+
return compareNodesForLayout(a, b);
|
|
7640
|
+
});
|
|
7641
|
+
const refreshed = new Map();
|
|
7642
|
+
for (let i = 0; i < ranks[r].length; i++)
|
|
7643
|
+
refreshed.set(ranks[r][i].id, i);
|
|
7644
|
+
indexInRank[r] = refreshed;
|
|
7645
|
+
}
|
|
7646
|
+
}
|
|
7647
|
+
function estimateCrossSize(ranks, runtime) {
|
|
7648
|
+
let max = 0;
|
|
7649
|
+
for (const rank of ranks) {
|
|
7650
|
+
const total = rank.reduce((sum, n) => sum + (runtime.direction === 'horizontal' ? n.size.height : n.size.width), 0);
|
|
7651
|
+
const gaps = Math.max(0, rank.length - 1) * runtime.crossGap;
|
|
7652
|
+
max = Math.max(max, total + gaps);
|
|
7653
|
+
}
|
|
7654
|
+
return max;
|
|
7655
|
+
}
|
|
7656
|
+
function layoutComponent(component, positionById, runtime, crossStart) {
|
|
7657
|
+
const isHorizontal = runtime.direction === 'horizontal';
|
|
7658
|
+
let primaryCursor = isHorizontal ? runtime.origin.x : runtime.origin.y;
|
|
7659
|
+
for (const rank of component.ranks) {
|
|
7660
|
+
if (rank.length === 0)
|
|
7661
|
+
continue;
|
|
7662
|
+
const crossTotal = rank.reduce((sum, n) => sum + (isHorizontal ? n.size.height : n.size.width), 0);
|
|
7663
|
+
const crossGaps = (rank.length - 1) * runtime.crossGap;
|
|
7664
|
+
const crossLen = crossTotal + crossGaps;
|
|
7665
|
+
let cursor = crossStart;
|
|
7666
|
+
if (runtime.alignment === 'center') {
|
|
7667
|
+
cursor = crossStart + (component.crossSize - crossLen) * 0.5;
|
|
7668
|
+
}
|
|
7669
|
+
else if (runtime.alignment === 'end') {
|
|
7670
|
+
cursor = crossStart + (component.crossSize - crossLen);
|
|
7671
|
+
}
|
|
7672
|
+
let primaryMax = 0;
|
|
7673
|
+
for (const node of rank) {
|
|
7674
|
+
const primary = isHorizontal ? primaryCursor : cursor;
|
|
7675
|
+
const cross = isHorizontal ? cursor : primaryCursor;
|
|
7676
|
+
const raw = isHorizontal ? { x: primary, y: cross } : { x: cross, y: primary };
|
|
7677
|
+
const snapped = runtime.grid > 0 ? snapPoint(raw, runtime.grid) : raw;
|
|
7678
|
+
positionById.set(node.id, snapped);
|
|
7679
|
+
const advance = (isHorizontal ? node.size.height : node.size.width) + runtime.crossGap;
|
|
7680
|
+
cursor += advance;
|
|
7681
|
+
primaryMax = Math.max(primaryMax, isHorizontal ? node.size.width : node.size.height);
|
|
7682
|
+
}
|
|
7683
|
+
primaryCursor += primaryMax + runtime.primaryGap;
|
|
7684
|
+
}
|
|
7685
|
+
}
|
|
7686
|
+
function compareNodesForLayout(a, b) {
|
|
7687
|
+
const titleA = a.title?.trim() ?? '';
|
|
7688
|
+
const titleB = b.title?.trim() ?? '';
|
|
7689
|
+
if (titleA !== titleB) {
|
|
7690
|
+
return titleA.localeCompare(titleB);
|
|
7691
|
+
}
|
|
7692
|
+
return a.id.localeCompare(b.id);
|
|
7693
|
+
}
|
|
7694
|
+
//#endregion
|
|
7695
|
+
|
|
7696
|
+
//#endregion
|
|
7697
|
+
class AXPWorkflowDesignerComponent {
|
|
7698
|
+
//#endregion
|
|
7699
|
+
constructor() {
|
|
7700
|
+
/** Unique SVG fragment id so multiple designers on one page do not clash. */
|
|
7701
|
+
this.svgMarkerId = `axp-wf-arrow-${Math.random().toString(36).slice(2, 10)}`;
|
|
7702
|
+
//#region ---- Inputs / outputs ----
|
|
7703
|
+
this.model = input.required(...(ngDevMode ? [{ debugName: "model" }] : /* istanbul ignore next */ []));
|
|
7704
|
+
this.modelChange = output();
|
|
7705
|
+
/** When true, the whole designer is non-interactive unless a nested entity sets its own readonly flag. */
|
|
7706
|
+
this.readonly = input(false, ...(ngDevMode ? [{ debugName: "readonly" }] : /* istanbul ignore next */ []));
|
|
7707
|
+
this.gridSize = input(20, ...(ngDevMode ? [{ debugName: "gridSize" }] : /* istanbul ignore next */ []));
|
|
7708
|
+
/** Default snap when node does not override `snapToGrid`. */
|
|
7709
|
+
this.snapToGrid = input(true, ...(ngDevMode ? [{ debugName: "snapToGrid" }] : /* istanbul ignore next */ []));
|
|
7710
|
+
this.connectionPreviewStyle = input('orthogonal', ...(ngDevMode ? [{ debugName: "connectionPreviewStyle" }] : /* istanbul ignore next */ []));
|
|
7711
|
+
this.backgroundPattern = input('dots', ...(ngDevMode ? [{ debugName: "backgroundPattern" }] : /* istanbul ignore next */ []));
|
|
7712
|
+
this.zoomChange = output();
|
|
7713
|
+
/** When set, replaces built-in `defaultCanConnectRequest` entirely. */
|
|
7714
|
+
this.canConnect = input(null, ...(ngDevMode ? [{ debugName: "canConnect" }] : /* istanbul ignore next */ []));
|
|
7715
|
+
/** Used to resolve native palette drag payloads (`type`) into full defaults. */
|
|
7716
|
+
this.paletteItems = input([], ...(ngDevMode ? [{ debugName: "paletteItems" }] : /* istanbul ignore next */ []));
|
|
7717
|
+
/** When false, port labels are hidden (ports remain interactive). */
|
|
7718
|
+
this.showPortLabels = input(true, ...(ngDevMode ? [{ debugName: "showPortLabels" }] : /* istanbul ignore next */ []));
|
|
7719
|
+
this.nodeBodyTemplate = input(null, ...(ngDevMode ? [{ debugName: "nodeBodyTemplate" }] : /* istanbul ignore next */ []));
|
|
7720
|
+
this.designerPointerDown = output();
|
|
7721
|
+
this.designerClick = output();
|
|
7722
|
+
this.designerDoubleClick = output();
|
|
7723
|
+
this.nodePointerDown = output();
|
|
7724
|
+
this.nodeClick = output();
|
|
7725
|
+
this.nodeDoubleClick = output();
|
|
7726
|
+
this.nodeContextMenu = output();
|
|
7727
|
+
this.nodeDragStart = output();
|
|
7728
|
+
this.nodeDragEnd = output();
|
|
7729
|
+
this.portPointerDown = output();
|
|
7730
|
+
this.linkDragStart = output();
|
|
7731
|
+
this.linkDragMove = output();
|
|
7732
|
+
this.linkDragEnd = output();
|
|
7733
|
+
this.connectorClick = output();
|
|
7734
|
+
this.connectorDoubleClick = output();
|
|
7735
|
+
this.connectionCreated = output();
|
|
7736
|
+
this.connectionRejected = output();
|
|
7737
|
+
this.activationChange = output();
|
|
7738
|
+
//#endregion
|
|
7739
|
+
//#region ---- State ----
|
|
7740
|
+
this.surfaceRef = viewChild.required('surface');
|
|
7741
|
+
this.panViewRef = viewChild(AXPanViewDirective, ...(ngDevMode ? [{ debugName: "panViewRef" }] : /* istanbul ignore next */ []));
|
|
7742
|
+
this.activation = signal(null, ...(ngDevMode ? [{ debugName: "activation" }] : /* istanbul ignore next */ []));
|
|
7743
|
+
this.selectedNodeIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedNodeIds" }] : /* istanbul ignore next */ []));
|
|
7744
|
+
this.selectedConnectorIds = signal(new Set(), ...(ngDevMode ? [{ debugName: "selectedConnectorIds" }] : /* istanbul ignore next */ []));
|
|
7745
|
+
this.panX = signal(0, ...(ngDevMode ? [{ debugName: "panX" }] : /* istanbul ignore next */ []));
|
|
7746
|
+
this.panY = signal(0, ...(ngDevMode ? [{ debugName: "panY" }] : /* istanbul ignore next */ []));
|
|
7747
|
+
this.panZoomLevel = signal(100, ...(ngDevMode ? [{ debugName: "panZoomLevel" }] : /* istanbul ignore next */ []));
|
|
7748
|
+
this.linkDrag = signal(null, ...(ngDevMode ? [{ debugName: "linkDrag" }] : /* istanbul ignore next */ []));
|
|
7749
|
+
/** Inbound port under the pointer while dragging a new connector from an outbound port. */
|
|
7750
|
+
this.linkHoverTarget = signal(null, ...(ngDevMode ? [{ debugName: "linkHoverTarget" }] : /* istanbul ignore next */ []));
|
|
7751
|
+
this.nodeMove = null;
|
|
7752
|
+
this.resize = null;
|
|
7753
|
+
this.suppressNextNodeClick = false;
|
|
7754
|
+
this.wrapperDragoverListener = null;
|
|
7755
|
+
this.wrapperDropListener = null;
|
|
7756
|
+
this.wrapperElement = signal(null, ...(ngDevMode ? [{ debugName: "wrapperElement" }] : /* istanbul ignore next */ []));
|
|
7757
|
+
this.wrapperAttachRetryHandle = null;
|
|
7758
|
+
this.wrapperAttachAttempt = 0;
|
|
7759
|
+
this.destroyRef = inject(DestroyRef);
|
|
7760
|
+
//#endregion
|
|
7761
|
+
//#region ---- Computed ----
|
|
7762
|
+
this.gridStyle = computed(() => {
|
|
7763
|
+
const g = this.gridSize();
|
|
7764
|
+
if (this.backgroundPattern() === 'dots') {
|
|
7765
|
+
return {
|
|
7766
|
+
'background-size': `${g}px ${g}px`,
|
|
7767
|
+
'background-image': `radial-gradient(circle, rgba(148, 163, 184, 0.35) 1px, transparent 1.2px)`,
|
|
7768
|
+
};
|
|
7769
|
+
}
|
|
7770
|
+
return {
|
|
7771
|
+
'background-size': `${g}px ${g}px`,
|
|
7772
|
+
'background-image': `
|
|
7773
|
+
linear-gradient(to right, rgba(148, 163, 184, 0.2) 1px, transparent 1px),
|
|
7774
|
+
linear-gradient(to bottom, rgba(148, 163, 184, 0.2) 1px, transparent 1px)
|
|
7775
|
+
`,
|
|
7776
|
+
};
|
|
7777
|
+
}, ...(ngDevMode ? [{ debugName: "gridStyle" }] : /* istanbul ignore next */ []));
|
|
7778
|
+
this.canvasViewport = computed(() => {
|
|
7779
|
+
const model = this.model();
|
|
7780
|
+
const contentPadding = 320;
|
|
7781
|
+
const minCanvasWidth = 1600;
|
|
7782
|
+
const minCanvasHeight = 1000;
|
|
7783
|
+
const nodeMinX = model.nodes.reduce((acc, node) => Math.min(acc, node.position.x), 0);
|
|
7784
|
+
const nodeMinY = model.nodes.reduce((acc, node) => Math.min(acc, node.position.y), 0);
|
|
7785
|
+
const nodeMaxRight = model.nodes.reduce((acc, node) => Math.max(acc, node.position.x + node.size.width), 0);
|
|
7786
|
+
const nodeMaxBottom = model.nodes.reduce((acc, node) => Math.max(acc, node.position.y + node.size.height), 0);
|
|
7787
|
+
const minX = Math.min(0, nodeMinX);
|
|
7788
|
+
const minY = Math.min(0, nodeMinY);
|
|
7789
|
+
const maxRight = Math.max(minCanvasWidth, nodeMaxRight);
|
|
7790
|
+
const maxBottom = Math.max(minCanvasHeight, nodeMaxBottom);
|
|
7791
|
+
const offsetX = -minX + contentPadding;
|
|
7792
|
+
const offsetY = -minY + contentPadding;
|
|
7793
|
+
return {
|
|
7794
|
+
minX,
|
|
7795
|
+
minY,
|
|
7796
|
+
offsetX,
|
|
7797
|
+
offsetY,
|
|
7798
|
+
width: Math.ceil(maxRight - minX + contentPadding * 2),
|
|
7799
|
+
height: Math.ceil(maxBottom - minY + contentPadding * 2),
|
|
7800
|
+
};
|
|
7801
|
+
}, ...(ngDevMode ? [{ debugName: "canvasViewport" }] : /* istanbul ignore next */ []));
|
|
7802
|
+
this.surfaceStyle = computed(() => {
|
|
7803
|
+
const viewport = this.canvasViewport();
|
|
7804
|
+
return {
|
|
7805
|
+
// ...this.gridStyle(),
|
|
7806
|
+
width: `${viewport.width}px`,
|
|
7807
|
+
height: `${viewport.height}px`,
|
|
7808
|
+
};
|
|
7809
|
+
}, ...(ngDevMode ? [{ debugName: "surfaceStyle" }] : /* istanbul ignore next */ []));
|
|
7810
|
+
this.onWindowPointerMoveForNode = (ev) => {
|
|
7811
|
+
const drag = this.nodeMove;
|
|
7812
|
+
if (!drag)
|
|
7813
|
+
return;
|
|
7814
|
+
const model = this.model();
|
|
7815
|
+
const p = this.canvasPointFromClient(ev.clientX, ev.clientY);
|
|
7816
|
+
const dx = p.x - drag.start.x;
|
|
7817
|
+
const dy = p.y - drag.start.y;
|
|
7818
|
+
if (Math.abs(dx) > 1 || Math.abs(dy) > 1) {
|
|
7819
|
+
drag.moved = true;
|
|
7820
|
+
}
|
|
7821
|
+
const nodes = model.nodes.map((n) => {
|
|
7822
|
+
if (!drag.nodeIds.includes(n.id))
|
|
7823
|
+
return n;
|
|
7824
|
+
const origin = drag.origins[n.id];
|
|
7825
|
+
if (!origin)
|
|
7826
|
+
return n;
|
|
7827
|
+
let nx = origin.x + dx;
|
|
7828
|
+
let ny = origin.y + dy;
|
|
7829
|
+
const snapped = this.applySnapForNode(n, { x: nx, y: ny });
|
|
7830
|
+
nx = snapped.x;
|
|
7831
|
+
ny = snapped.y;
|
|
7832
|
+
return { ...n, position: { x: nx, y: ny } };
|
|
7833
|
+
});
|
|
7834
|
+
this.commit({ ...model, nodes });
|
|
7835
|
+
};
|
|
7836
|
+
this.onWindowPointerUpForNode = (ev) => {
|
|
7837
|
+
const drag = this.nodeMove;
|
|
7838
|
+
this.nodeMove = null;
|
|
7839
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForNode);
|
|
7840
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForNode);
|
|
7841
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForNode);
|
|
7842
|
+
if (drag?.moved) {
|
|
7843
|
+
this.suppressNextNodeClick = true;
|
|
7844
|
+
}
|
|
7845
|
+
if (drag) {
|
|
7846
|
+
const node = findNode(this.model(), drag.nodeIds[0] ?? '');
|
|
7847
|
+
if (node)
|
|
7848
|
+
this.nodeDragEnd.emit({ node, event: ev });
|
|
7849
|
+
}
|
|
7850
|
+
};
|
|
7851
|
+
this.onWindowPointerMoveForResize = (ev) => {
|
|
7852
|
+
const st = this.resize;
|
|
7853
|
+
if (!st)
|
|
7854
|
+
return;
|
|
7855
|
+
const model = this.model();
|
|
7856
|
+
const node = findNode(model, st.nodeId);
|
|
7857
|
+
if (!node)
|
|
7858
|
+
return;
|
|
7859
|
+
const p = this.canvasPointFromClient(ev.clientX, ev.clientY);
|
|
7860
|
+
const dx = p.x - st.startPointer.x;
|
|
7861
|
+
const dy = p.y - st.startPointer.y;
|
|
7862
|
+
let { width, height } = st.startSize;
|
|
7863
|
+
let { x, y } = st.startPosition;
|
|
7864
|
+
const minW = 72;
|
|
7865
|
+
const minH = 40;
|
|
7866
|
+
const growEast = st.handle.includes('e');
|
|
7867
|
+
const growSouth = st.handle.includes('s');
|
|
7868
|
+
const growWest = st.handle.includes('w');
|
|
7869
|
+
const growNorth = st.handle.includes('n');
|
|
7870
|
+
if (growEast)
|
|
7871
|
+
width = Math.max(minW, st.startSize.width + dx);
|
|
7872
|
+
if (growSouth)
|
|
7873
|
+
height = Math.max(minH, st.startSize.height + dy);
|
|
7874
|
+
if (growWest) {
|
|
7875
|
+
const nw = Math.max(minW, st.startSize.width - dx);
|
|
7876
|
+
x = st.startPosition.x + st.startSize.width - nw;
|
|
7877
|
+
width = nw;
|
|
7878
|
+
}
|
|
7879
|
+
if (growNorth) {
|
|
7880
|
+
const nh = Math.max(minH, st.startSize.height - dy);
|
|
7881
|
+
y = st.startPosition.y + st.startSize.height - nh;
|
|
7882
|
+
height = nh;
|
|
7883
|
+
}
|
|
7884
|
+
if (node.shape === 'circle' || node.lockAspectRatio) {
|
|
7885
|
+
const a = st.aspect;
|
|
7886
|
+
if (growEast || growWest) {
|
|
7887
|
+
height = width / a;
|
|
7888
|
+
if (growNorth)
|
|
7889
|
+
y = st.startPosition.y + st.startSize.height - height;
|
|
7890
|
+
}
|
|
7891
|
+
else {
|
|
7892
|
+
width = height * a;
|
|
7893
|
+
if (growWest)
|
|
7894
|
+
x = st.startPosition.x + st.startSize.width - width;
|
|
7895
|
+
}
|
|
7896
|
+
}
|
|
7897
|
+
const g = this.gridSize();
|
|
7898
|
+
const useSnap = node.snapToGrid ?? this.snapToGrid();
|
|
7899
|
+
if (useSnap && g > 0) {
|
|
7900
|
+
width = Math.max(minW, snapScalar(width, g));
|
|
7901
|
+
height = Math.max(minH, snapScalar(height, g));
|
|
7902
|
+
x = snapScalar(x, g);
|
|
7903
|
+
y = snapScalar(y, g);
|
|
7904
|
+
}
|
|
7905
|
+
const nodes = model.nodes.map((n) => n.id === node.id ? { ...n, position: { x, y }, size: { width, height } } : n);
|
|
7906
|
+
this.commit({ ...model, nodes });
|
|
7907
|
+
};
|
|
7908
|
+
this.onWindowPointerUpForResize = () => {
|
|
7909
|
+
this.resize = null;
|
|
7910
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForResize);
|
|
7911
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForResize);
|
|
7912
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForResize);
|
|
7913
|
+
};
|
|
7914
|
+
this.onWindowPointerMoveForLink = (ev) => {
|
|
7915
|
+
const st = this.linkDrag();
|
|
7916
|
+
if (!st)
|
|
7917
|
+
return;
|
|
7918
|
+
const to = this.canvasPointFromClient(ev.clientX, ev.clientY);
|
|
7919
|
+
this.linkDrag.set({ ...st, to });
|
|
7920
|
+
const model = this.model();
|
|
7921
|
+
const node = findNode(model, st.sourceNodeId);
|
|
7922
|
+
const port = node ? findPort(node, st.sourcePortId)?.port : undefined;
|
|
7923
|
+
if (node && port) {
|
|
7924
|
+
this.linkDragMove.emit({ sourceNode: node, sourcePort: port, point: to, event: ev });
|
|
7925
|
+
}
|
|
7926
|
+
const hover = this.pickInboundPortAtPoint(model, to, st.sourceNodeId);
|
|
7927
|
+
this.linkHoverTarget.set(hover ? { nodeId: hover.node.id, portId: hover.port.id } : null);
|
|
7928
|
+
};
|
|
7929
|
+
this.onWindowPointerUpForLink = (ev) => {
|
|
7930
|
+
const st = this.linkDrag();
|
|
7931
|
+
this.linkDrag.set(null);
|
|
7932
|
+
this.linkHoverTarget.set(null);
|
|
7933
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForLink);
|
|
7934
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForLink);
|
|
7935
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForLink);
|
|
7936
|
+
if (!st)
|
|
7937
|
+
return;
|
|
7938
|
+
const model = this.model();
|
|
7939
|
+
const sourceNode = findNode(model, st.sourceNodeId);
|
|
7940
|
+
const sourcePort = sourceNode ? findPort(sourceNode, st.sourcePortId)?.port : undefined;
|
|
7941
|
+
if (!sourceNode || !sourcePort)
|
|
7942
|
+
return;
|
|
7943
|
+
const target = this.pickInboundPortAtPoint(model, st.to, sourceNode.id);
|
|
7944
|
+
if (!target) {
|
|
7945
|
+
this.linkDragEnd.emit({ sourceNode, sourcePort, cancelled: true, event: ev });
|
|
7946
|
+
return;
|
|
7947
|
+
}
|
|
7948
|
+
const request = {
|
|
7949
|
+
model,
|
|
7950
|
+
sourceNodeId: st.sourceNodeId,
|
|
7951
|
+
sourcePortId: st.sourcePortId,
|
|
7952
|
+
targetNodeId: target.node.id,
|
|
7953
|
+
targetPortId: target.port.id,
|
|
7954
|
+
};
|
|
7955
|
+
if (!this.evaluateConnect(request)) {
|
|
7956
|
+
this.connectionRejected.emit({ reason: 'canConnect returned false', request, event: ev });
|
|
7957
|
+
this.linkDragEnd.emit({ sourceNode, sourcePort, cancelled: true, event: ev });
|
|
7958
|
+
return;
|
|
7959
|
+
}
|
|
7960
|
+
const connector = {
|
|
7961
|
+
id: createWorkflowConnectorId(),
|
|
7962
|
+
sourceNodeId: st.sourceNodeId,
|
|
7963
|
+
sourcePortId: st.sourcePortId,
|
|
7964
|
+
targetNodeId: target.node.id,
|
|
7965
|
+
targetPortId: target.port.id,
|
|
7966
|
+
data: {},
|
|
7967
|
+
color: sourceNode.color,
|
|
7968
|
+
};
|
|
7969
|
+
const next = {
|
|
7970
|
+
nodes: [...model.nodes],
|
|
7971
|
+
connectors: [...model.connectors, connector],
|
|
7972
|
+
};
|
|
7973
|
+
this.commit(next);
|
|
7974
|
+
this.connectionCreated.emit({ connector, model: next });
|
|
7975
|
+
this.setActivation({ kind: 'connector', id: connector.id });
|
|
7976
|
+
this.linkDragEnd.emit({ sourceNode, sourcePort, cancelled: false, event: ev });
|
|
7977
|
+
};
|
|
7978
|
+
afterNextRender(() => this.attachWrapperDropTargetsWithRetry());
|
|
7979
|
+
effect(() => this.syncWrapperBackgroundStyle());
|
|
7980
|
+
effect(() => {
|
|
7981
|
+
this.zoomChange.emit(this.panZoomLevel());
|
|
7982
|
+
});
|
|
7983
|
+
this.destroyRef.onDestroy(() => this.detachWindowListeners());
|
|
7984
|
+
}
|
|
7985
|
+
zoomIn() {
|
|
7986
|
+
this.panViewRef()?.zoomIn();
|
|
7987
|
+
}
|
|
7988
|
+
zoomOut() {
|
|
7989
|
+
this.panViewRef()?.zoomOut();
|
|
7990
|
+
}
|
|
7991
|
+
zoomReset() {
|
|
7992
|
+
this.panViewRef()?.resetPosition();
|
|
7993
|
+
}
|
|
7994
|
+
getZoomLevel() {
|
|
7995
|
+
return this.panZoomLevel();
|
|
7996
|
+
}
|
|
7997
|
+
//#region ---- Readonly helpers ----
|
|
7998
|
+
isNodeReadonly(node) {
|
|
7999
|
+
return this.readonly() || node.readonly === true;
|
|
8000
|
+
}
|
|
8001
|
+
isConnectorReadonly(c) {
|
|
8002
|
+
return this.readonly() || c.readonly === true;
|
|
8003
|
+
}
|
|
8004
|
+
//#endregion
|
|
8005
|
+
//#region ---- Activation ----
|
|
8006
|
+
isNodeActive(nodeId) {
|
|
8007
|
+
return this.selectedNodeIds().has(nodeId);
|
|
8008
|
+
}
|
|
8009
|
+
isConnectorActive(id) {
|
|
8010
|
+
return this.selectedConnectorIds().has(id);
|
|
8011
|
+
}
|
|
8012
|
+
isPortActive(nodeId, portId) {
|
|
8013
|
+
const a = this.activation();
|
|
8014
|
+
return a?.kind === 'port' && a.nodeId === nodeId && a.id === portId;
|
|
8015
|
+
}
|
|
8016
|
+
isPortLinkHoverTarget(nodeId, portId) {
|
|
8017
|
+
if (!this.linkDrag())
|
|
8018
|
+
return false;
|
|
8019
|
+
const h = this.linkHoverTarget();
|
|
8020
|
+
return h !== null && h.nodeId === nodeId && h.portId === portId;
|
|
8021
|
+
}
|
|
8022
|
+
setActivation(next) {
|
|
8023
|
+
this.activation.set(next);
|
|
8024
|
+
this.activationChange.emit(next);
|
|
8025
|
+
}
|
|
8026
|
+
clearSelections() {
|
|
8027
|
+
this.selectedNodeIds.set(new Set());
|
|
8028
|
+
this.selectedConnectorIds.set(new Set());
|
|
8029
|
+
}
|
|
8030
|
+
//#endregion
|
|
8031
|
+
//#region ---- Model commit ----
|
|
8032
|
+
commit(next) {
|
|
8033
|
+
this.modelChange.emit(next);
|
|
8034
|
+
}
|
|
8035
|
+
/**
|
|
8036
|
+
* Auto-arranges nodes into a layered layout and commits the result.
|
|
8037
|
+
*
|
|
8038
|
+
* Honors layout options such as `direction` (`'horizontal'` / `'vertical'`),
|
|
8039
|
+
* `alignment`, `origin`, `nodeIds` (subset arrange), and `reduceCrossings`.
|
|
8040
|
+
* When `gridSize` is omitted the designer's own `gridSize` input is used.
|
|
8041
|
+
*/
|
|
8042
|
+
arrangeNicely(options) {
|
|
8043
|
+
if (this.readonly()) {
|
|
8044
|
+
return;
|
|
8045
|
+
}
|
|
8046
|
+
this.commit(this.computeArrangedLayout(options));
|
|
8047
|
+
}
|
|
8048
|
+
/**
|
|
8049
|
+
* Computes an arranged layout without committing it. Useful for previews,
|
|
8050
|
+
* comparing the result before applying it, or rendering ghost positions.
|
|
8051
|
+
*/
|
|
8052
|
+
computeArrangedLayout(options) {
|
|
8053
|
+
return arrangeWorkflowDiagram(cloneDiagram(this.model()), {
|
|
8054
|
+
gridSize: this.gridSize(),
|
|
8055
|
+
...options,
|
|
8056
|
+
});
|
|
8057
|
+
}
|
|
8058
|
+
resolvePaletteItem(type) {
|
|
8059
|
+
return this.paletteItems().find((i) => i.type === type);
|
|
8060
|
+
}
|
|
8061
|
+
/**
|
|
8062
|
+
* Full drag payload merged with `paletteItems()` entry when the payload omits optional fields.
|
|
8063
|
+
*/
|
|
8064
|
+
resolveDroppedPaletteItem(raw) {
|
|
8065
|
+
const parsed = parsePaletteItemDragPayload(raw);
|
|
8066
|
+
if (!parsed)
|
|
8067
|
+
return null;
|
|
8068
|
+
const base = this.resolvePaletteItem(parsed.type);
|
|
8069
|
+
const item = { ...(base ?? {}), ...parsed };
|
|
8070
|
+
if (typeof item.title !== 'string')
|
|
8071
|
+
return null;
|
|
8072
|
+
return item;
|
|
8073
|
+
}
|
|
8074
|
+
evaluateConnect(request) {
|
|
8075
|
+
const fn = this.canConnect();
|
|
8076
|
+
if (fn)
|
|
8077
|
+
return fn(request);
|
|
8078
|
+
return defaultCanConnectRequest(request);
|
|
8079
|
+
}
|
|
8080
|
+
//#endregion
|
|
8081
|
+
//#region ---- Canvas / surface ----
|
|
8082
|
+
onSurfacePointerDown(event) {
|
|
8083
|
+
if (!this.isBackgroundInteractionTarget(event.target))
|
|
8084
|
+
return;
|
|
8085
|
+
this.designerPointerDown.emit(event);
|
|
8086
|
+
}
|
|
8087
|
+
onSurfaceClick(event) {
|
|
8088
|
+
if (!this.isBackgroundInteractionTarget(event.target))
|
|
8089
|
+
return;
|
|
8090
|
+
this.clearSelections();
|
|
8091
|
+
this.setActivation({ kind: 'canvas', id: 'canvas' });
|
|
8092
|
+
this.designerClick.emit(event);
|
|
8093
|
+
}
|
|
8094
|
+
onSurfaceDoubleClick(event) {
|
|
8095
|
+
if (!this.isBackgroundInteractionTarget(event.target))
|
|
8096
|
+
return;
|
|
8097
|
+
this.designerDoubleClick.emit(event);
|
|
8098
|
+
}
|
|
8099
|
+
isBackgroundInteractionTarget(target) {
|
|
8100
|
+
if (!target)
|
|
8101
|
+
return false;
|
|
8102
|
+
if (target.closest('.axp-workflow-designer__node'))
|
|
8103
|
+
return false;
|
|
8104
|
+
if (target.closest('.axp-workflow-designer__connector-actions'))
|
|
8105
|
+
return false;
|
|
8106
|
+
if (target.closest('.axp-workflow-designer__port-cluster'))
|
|
8107
|
+
return false;
|
|
8108
|
+
if (target.closest('path.axp-workflow-designer__edge-hit'))
|
|
8109
|
+
return false;
|
|
8110
|
+
if (target.closest('ax-button'))
|
|
8111
|
+
return false;
|
|
8112
|
+
return true;
|
|
8113
|
+
}
|
|
8114
|
+
canvasPointFromClient(clientX, clientY) {
|
|
8115
|
+
const surface = this.surfaceRef().nativeElement;
|
|
8116
|
+
const wrapper = surface.closest('.ax-pan-view-wrapper');
|
|
8117
|
+
const basisRect = (wrapper ?? surface).getBoundingClientRect();
|
|
8118
|
+
const localX = clientX - basisRect.left;
|
|
8119
|
+
const localY = clientY - basisRect.top;
|
|
8120
|
+
const computed = getComputedStyle(surface);
|
|
8121
|
+
const transform = computed.transform;
|
|
8122
|
+
if (!transform || transform === 'none') {
|
|
8123
|
+
return this.surfacePointToModel({ x: localX, y: localY });
|
|
8124
|
+
}
|
|
8125
|
+
const matrix = new DOMMatrixReadOnly(transform);
|
|
8126
|
+
const originParts = computed.transformOrigin.split(' ');
|
|
8127
|
+
const originX = Number.parseFloat(originParts[0] ?? '0') || 0;
|
|
8128
|
+
const originY = Number.parseFloat(originParts[1] ?? '0') || 0;
|
|
8129
|
+
// CSS transform is applied around transform-origin, so include origin translation in matrix inversion.
|
|
8130
|
+
const withOrigin = new DOMMatrixReadOnly()
|
|
8131
|
+
.translate(originX, originY)
|
|
8132
|
+
.multiply(matrix)
|
|
8133
|
+
.translate(-originX, -originY);
|
|
8134
|
+
const point = new DOMPoint(localX, localY).matrixTransform(withOrigin.inverse());
|
|
8135
|
+
return this.surfacePointToModel({ x: point.x, y: point.y });
|
|
8136
|
+
}
|
|
8137
|
+
//#endregion
|
|
8138
|
+
//#region ---- Drag / drop (palette) ----
|
|
8139
|
+
onCanvasDragOver(event) {
|
|
8140
|
+
if (this.readonly())
|
|
8141
|
+
return;
|
|
8142
|
+
event.preventDefault();
|
|
8143
|
+
if (event.dataTransfer)
|
|
8144
|
+
event.dataTransfer.dropEffect = 'copy';
|
|
8145
|
+
}
|
|
8146
|
+
onCanvasDrop(event) {
|
|
8147
|
+
if (this.readonly())
|
|
8148
|
+
return;
|
|
8149
|
+
event.preventDefault();
|
|
8150
|
+
event.stopPropagation();
|
|
8151
|
+
const raw = event.dataTransfer?.getData(AXP_WORKFLOW_PALETTE_MIME);
|
|
8152
|
+
const item = this.resolveDroppedPaletteItem(raw);
|
|
8153
|
+
if (!item)
|
|
8154
|
+
return;
|
|
8155
|
+
const pt = this.canvasPointFromClient(event.clientX, event.clientY);
|
|
8156
|
+
const node = createNodeFromPaletteItem(item, this.applySnapToPointForNewNode(item, pt));
|
|
8157
|
+
const model = this.model();
|
|
8158
|
+
const next = {
|
|
8159
|
+
nodes: [...model.nodes, node],
|
|
8160
|
+
connectors: [...model.connectors],
|
|
8161
|
+
};
|
|
8162
|
+
this.commit(next);
|
|
8163
|
+
this.setActivation({ kind: 'node', id: node.id });
|
|
8164
|
+
}
|
|
8165
|
+
applySnapToPointForNewNode(item, pt) {
|
|
8166
|
+
const nodeSnap = item.snapToGrid;
|
|
8167
|
+
const useSnap = nodeSnap ?? this.snapToGrid();
|
|
8168
|
+
const g = this.gridSize();
|
|
8169
|
+
if (!useSnap || g <= 0)
|
|
8170
|
+
return pt;
|
|
8171
|
+
return snapPoint(pt, g);
|
|
8172
|
+
}
|
|
8173
|
+
applySnapForNode(node, pt) {
|
|
8174
|
+
const useSnap = node.snapToGrid ?? this.snapToGrid();
|
|
8175
|
+
const g = this.gridSize();
|
|
8176
|
+
if (!useSnap || g <= 0)
|
|
8177
|
+
return pt;
|
|
8178
|
+
return snapPoint(pt, g);
|
|
8179
|
+
}
|
|
8180
|
+
//#endregion
|
|
8181
|
+
//#region ---- Wrapper drop bridge ----
|
|
8182
|
+
attachWrapperDropTargetsWithRetry() {
|
|
8183
|
+
this.clearWrapperAttachRetry();
|
|
8184
|
+
this.wrapperAttachAttempt = 0;
|
|
8185
|
+
const tryAttach = () => {
|
|
8186
|
+
const attached = this.attachWrapperDropTargets();
|
|
8187
|
+
if (attached) {
|
|
8188
|
+
return;
|
|
8189
|
+
}
|
|
8190
|
+
this.wrapperAttachAttempt += 1;
|
|
8191
|
+
if (this.wrapperAttachAttempt >= 20) {
|
|
8192
|
+
return;
|
|
8193
|
+
}
|
|
8194
|
+
this.wrapperAttachRetryHandle = setTimeout(tryAttach, 50);
|
|
8195
|
+
};
|
|
8196
|
+
tryAttach();
|
|
8197
|
+
}
|
|
8198
|
+
/**
|
|
8199
|
+
* Binds drag/drop to pan-view wrapper so users can drop while panning far away
|
|
8200
|
+
* from current finite surface bounds.
|
|
8201
|
+
*/
|
|
8202
|
+
attachWrapperDropTargets() {
|
|
8203
|
+
const surface = this.surfaceRef().nativeElement;
|
|
8204
|
+
const wrapper = surface.closest('.ax-pan-view-wrapper');
|
|
8205
|
+
if (!wrapper) {
|
|
8206
|
+
return false;
|
|
8207
|
+
}
|
|
8208
|
+
this.detachWrapperDropTargets();
|
|
8209
|
+
this.wrapperElement.set(wrapper);
|
|
8210
|
+
this.wrapperDragoverListener = (event) => {
|
|
8211
|
+
const target = event.target;
|
|
8212
|
+
if (target?.closest('.axp-workflow-designer__surface')) {
|
|
8213
|
+
return;
|
|
8214
|
+
}
|
|
8215
|
+
this.onCanvasDragOver(event);
|
|
8216
|
+
};
|
|
8217
|
+
this.wrapperDropListener = (event) => {
|
|
8218
|
+
const target = event.target;
|
|
8219
|
+
if (target?.closest('.axp-workflow-designer__surface')) {
|
|
8220
|
+
return;
|
|
8221
|
+
}
|
|
8222
|
+
this.onCanvasDrop(event);
|
|
8223
|
+
};
|
|
8224
|
+
wrapper.addEventListener('dragover', this.wrapperDragoverListener);
|
|
8225
|
+
wrapper.addEventListener('drop', this.wrapperDropListener);
|
|
8226
|
+
this.syncWrapperBackgroundStyle();
|
|
8227
|
+
return true;
|
|
8228
|
+
}
|
|
8229
|
+
detachWrapperDropTargets() {
|
|
8230
|
+
const surface = this.surfaceRef().nativeElement;
|
|
8231
|
+
const wrapper = surface.closest('.ax-pan-view-wrapper');
|
|
8232
|
+
if (!wrapper) {
|
|
8233
|
+
this.wrapperElement.set(null);
|
|
8234
|
+
this.wrapperDragoverListener = null;
|
|
8235
|
+
this.wrapperDropListener = null;
|
|
8236
|
+
return;
|
|
8237
|
+
}
|
|
8238
|
+
if (this.wrapperDragoverListener) {
|
|
8239
|
+
wrapper.removeEventListener('dragover', this.wrapperDragoverListener);
|
|
8240
|
+
this.wrapperDragoverListener = null;
|
|
8241
|
+
}
|
|
8242
|
+
if (this.wrapperDropListener) {
|
|
8243
|
+
wrapper.removeEventListener('drop', this.wrapperDropListener);
|
|
8244
|
+
this.wrapperDropListener = null;
|
|
8245
|
+
}
|
|
8246
|
+
this.wrapperElement.set(null);
|
|
8247
|
+
}
|
|
8248
|
+
clearWrapperAttachRetry() {
|
|
8249
|
+
if (this.wrapperAttachRetryHandle != null) {
|
|
8250
|
+
clearTimeout(this.wrapperAttachRetryHandle);
|
|
8251
|
+
this.wrapperAttachRetryHandle = null;
|
|
8252
|
+
}
|
|
8253
|
+
}
|
|
8254
|
+
//#endregion
|
|
8255
|
+
//#region ---- Keyboard ----
|
|
8256
|
+
onWindowKeydown(ev) {
|
|
8257
|
+
if (this.readonly())
|
|
8258
|
+
return;
|
|
8259
|
+
const target = ev.target;
|
|
8260
|
+
if (target?.closest('input,textarea,select,[contenteditable="true"]'))
|
|
8261
|
+
return;
|
|
8262
|
+
if (ev.key === 'Escape') {
|
|
8263
|
+
ev.preventDefault();
|
|
8264
|
+
this.cancelLinkDrag(ev);
|
|
8265
|
+
this.clearSelections();
|
|
8266
|
+
this.setActivation(null);
|
|
8267
|
+
return;
|
|
8268
|
+
}
|
|
8269
|
+
if (ev.key !== 'Delete' && ev.key !== 'Backspace')
|
|
8270
|
+
return;
|
|
8271
|
+
ev.preventDefault();
|
|
8272
|
+
const selectedConnectorIds = this.selectedConnectorIds();
|
|
8273
|
+
const selectedNodeIds = this.selectedNodeIds();
|
|
8274
|
+
const model = this.model();
|
|
8275
|
+
if (selectedConnectorIds.size > 0 || selectedNodeIds.size > 0) {
|
|
8276
|
+
const nodes = model.nodes.filter((n) => !selectedNodeIds.has(n.id));
|
|
8277
|
+
const connectors = model.connectors.filter((c) => !selectedConnectorIds.has(c.id) &&
|
|
8278
|
+
!selectedNodeIds.has(c.sourceNodeId) &&
|
|
8279
|
+
!selectedNodeIds.has(c.targetNodeId));
|
|
8280
|
+
this.commit({ ...model, nodes, connectors });
|
|
8281
|
+
this.clearSelections();
|
|
8282
|
+
this.setActivation(null);
|
|
8283
|
+
return;
|
|
8284
|
+
}
|
|
8285
|
+
const a = this.activation();
|
|
8286
|
+
if (!a || a.kind === 'canvas')
|
|
8287
|
+
return;
|
|
8288
|
+
if (a.kind === 'connector') {
|
|
8289
|
+
const c = findConnector(model, a.id);
|
|
8290
|
+
if (c && !this.isConnectorReadonly(c)) {
|
|
8291
|
+
const connectors = model.connectors.filter((x) => x.id !== c.id);
|
|
8292
|
+
this.commit({ ...model, connectors });
|
|
8293
|
+
this.setActivation(null);
|
|
8294
|
+
}
|
|
8295
|
+
return;
|
|
8296
|
+
}
|
|
8297
|
+
const nodeId = a.kind === 'node' ? a.id : a.nodeId;
|
|
8298
|
+
if (!nodeId)
|
|
8299
|
+
return;
|
|
8300
|
+
const node = findNode(model, nodeId);
|
|
8301
|
+
if (!node || this.isNodeReadonly(node))
|
|
8302
|
+
return;
|
|
8303
|
+
const nodes = model.nodes.filter((n) => n.id !== nodeId);
|
|
8304
|
+
const connectors = model.connectors.filter((c) => c.sourceNodeId !== nodeId && c.targetNodeId !== nodeId);
|
|
8305
|
+
this.commit({ ...model, nodes, connectors });
|
|
8306
|
+
this.setActivation(null);
|
|
8307
|
+
}
|
|
8308
|
+
cancelLinkDrag(ev) {
|
|
8309
|
+
const st = this.linkDrag();
|
|
8310
|
+
if (!st)
|
|
8311
|
+
return;
|
|
8312
|
+
this.linkDrag.set(null);
|
|
8313
|
+
this.linkHoverTarget.set(null);
|
|
8314
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForLink);
|
|
8315
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForLink);
|
|
8316
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForLink);
|
|
8317
|
+
const model = this.model();
|
|
8318
|
+
const sourceNode = findNode(model, st.sourceNodeId);
|
|
8319
|
+
const sourcePort = sourceNode ? findPort(sourceNode, st.sourcePortId)?.port : undefined;
|
|
8320
|
+
if (sourceNode && sourcePort) {
|
|
8321
|
+
this.linkDragEnd.emit({ sourceNode, sourcePort, cancelled: true, event: ev });
|
|
8322
|
+
}
|
|
8323
|
+
}
|
|
8324
|
+
//#endregion
|
|
8325
|
+
//#region ---- Node chrome ----
|
|
8326
|
+
shapeClass(shape) {
|
|
8327
|
+
return `axp-workflow-designer__node-shape--${shape}`;
|
|
8328
|
+
}
|
|
8329
|
+
semanticSurfaceClass(color) {
|
|
8330
|
+
return color ? `axp-${color}-surface` : '';
|
|
8331
|
+
}
|
|
8332
|
+
nodeShapeClasses(node) {
|
|
8333
|
+
return ['axp-workflow-designer__node-shape', this.shapeClass(node.shape), this.semanticSurfaceClass(node.color)]
|
|
8334
|
+
.filter(Boolean)
|
|
8335
|
+
.join(' ');
|
|
8336
|
+
}
|
|
8337
|
+
connectorEdgeClasses(c) {
|
|
8338
|
+
const parts = [
|
|
8339
|
+
'axp-workflow-designer__edge',
|
|
8340
|
+
this.semanticSurfaceClass(c.color),
|
|
8341
|
+
this.isConnectorActive(c.id) ? 'axp-workflow-designer__edge--active' : '',
|
|
8342
|
+
];
|
|
8343
|
+
return parts.filter(Boolean).join(' ');
|
|
8344
|
+
}
|
|
8345
|
+
onNodePointerDown(node, event) {
|
|
8346
|
+
if (this.isNodeReadonly(node))
|
|
8347
|
+
return;
|
|
8348
|
+
if (event.button !== 0)
|
|
8349
|
+
return;
|
|
8350
|
+
this.nodePointerDown.emit({ node, event });
|
|
8351
|
+
}
|
|
8352
|
+
onNodeClick(node, event) {
|
|
8353
|
+
if (this.suppressNextNodeClick) {
|
|
8354
|
+
this.suppressNextNodeClick = false;
|
|
8355
|
+
event.stopPropagation();
|
|
8356
|
+
return;
|
|
8357
|
+
}
|
|
8358
|
+
event.stopPropagation();
|
|
8359
|
+
const append = event.ctrlKey || event.metaKey;
|
|
8360
|
+
if (append) {
|
|
8361
|
+
const next = new Set(this.selectedNodeIds());
|
|
8362
|
+
if (next.has(node.id))
|
|
8363
|
+
next.delete(node.id);
|
|
8364
|
+
else
|
|
8365
|
+
next.add(node.id);
|
|
8366
|
+
this.selectedNodeIds.set(next);
|
|
8367
|
+
this.selectedConnectorIds.set(new Set());
|
|
8368
|
+
}
|
|
8369
|
+
else {
|
|
8370
|
+
this.selectedNodeIds.set(new Set([node.id]));
|
|
8371
|
+
this.selectedConnectorIds.set(new Set());
|
|
8372
|
+
}
|
|
8373
|
+
this.setActivation({ kind: 'node', id: node.id });
|
|
8374
|
+
this.nodeClick.emit({ node, event: event });
|
|
8375
|
+
}
|
|
8376
|
+
onNodeDoubleClick(node, event) {
|
|
8377
|
+
event.stopPropagation();
|
|
8378
|
+
this.nodeDoubleClick.emit({ node, event });
|
|
8379
|
+
}
|
|
8380
|
+
onNodeContextMenu(node, event) {
|
|
8381
|
+
if (this.isNodeReadonly(node)) {
|
|
8382
|
+
return;
|
|
8383
|
+
}
|
|
8384
|
+
event.preventDefault();
|
|
8385
|
+
event.stopPropagation();
|
|
8386
|
+
this.selectedNodeIds.set(new Set([node.id]));
|
|
8387
|
+
this.selectedConnectorIds.set(new Set());
|
|
8388
|
+
this.setActivation({ kind: 'node', id: node.id });
|
|
8389
|
+
this.nodeContextMenu.emit({ node, event });
|
|
8390
|
+
}
|
|
8391
|
+
onNodeBodyPointerDown(node, event) {
|
|
8392
|
+
if (this.isNodeReadonly(node))
|
|
8393
|
+
return;
|
|
8394
|
+
if (event.button !== 0)
|
|
8395
|
+
return;
|
|
8396
|
+
if (event.target.closest('.axp-workflow-designer__port-cluster'))
|
|
8397
|
+
return;
|
|
8398
|
+
if (event.target.closest('.axp-workflow-designer__resize'))
|
|
8399
|
+
return;
|
|
8400
|
+
// Ctrl/Cmd click is reserved for multi-select toggling in click handler; do not start drag here.
|
|
8401
|
+
if (event.ctrlKey || event.metaKey)
|
|
8402
|
+
return;
|
|
8403
|
+
event.stopPropagation();
|
|
8404
|
+
const selected = this.selectedNodeIds();
|
|
8405
|
+
const moveIds = selected.has(node.id) && selected.size > 0 ? [...selected] : [node.id];
|
|
8406
|
+
if (!selected.has(node.id) || selected.size === 0) {
|
|
8407
|
+
this.selectedNodeIds.set(new Set([node.id]));
|
|
8408
|
+
this.selectedConnectorIds.set(new Set());
|
|
8409
|
+
}
|
|
8410
|
+
this.setActivation({ kind: 'node', id: node.id });
|
|
8411
|
+
const p = this.canvasPointFromClient(event.clientX, event.clientY);
|
|
8412
|
+
const model = this.model();
|
|
8413
|
+
const origins = {};
|
|
8414
|
+
for (const moveId of moveIds) {
|
|
8415
|
+
const n = findNode(model, moveId);
|
|
8416
|
+
if (n)
|
|
8417
|
+
origins[moveId] = { ...n.position };
|
|
8418
|
+
}
|
|
8419
|
+
this.nodeMove = {
|
|
8420
|
+
nodeIds: moveIds,
|
|
8421
|
+
start: p,
|
|
8422
|
+
origins,
|
|
8423
|
+
moved: false,
|
|
8424
|
+
};
|
|
8425
|
+
this.nodeDragStart.emit({ node, event });
|
|
8426
|
+
window.addEventListener('pointermove', this.onWindowPointerMoveForNode);
|
|
8427
|
+
window.addEventListener('pointerup', this.onWindowPointerUpForNode, { once: false });
|
|
8428
|
+
window.addEventListener('pointercancel', this.onWindowPointerUpForNode, { once: false });
|
|
8429
|
+
event.target.setPointerCapture?.(event.pointerId);
|
|
8430
|
+
}
|
|
8431
|
+
//#endregion
|
|
8432
|
+
//#region ---- Resize ----
|
|
8433
|
+
onResizePointerDown(node, handle, event) {
|
|
8434
|
+
if (this.isNodeReadonly(node))
|
|
8435
|
+
return;
|
|
8436
|
+
if (event.button !== 0)
|
|
8437
|
+
return;
|
|
8438
|
+
event.stopPropagation();
|
|
8439
|
+
this.resize = {
|
|
8440
|
+
nodeId: node.id,
|
|
8441
|
+
handle,
|
|
8442
|
+
startPointer: this.canvasPointFromClient(event.clientX, event.clientY),
|
|
8443
|
+
startPosition: { ...node.position },
|
|
8444
|
+
startSize: { ...node.size },
|
|
8445
|
+
aspect: node.size.width / Math.max(1, node.size.height),
|
|
8446
|
+
};
|
|
8447
|
+
window.addEventListener('pointermove', this.onWindowPointerMoveForResize);
|
|
8448
|
+
window.addEventListener('pointerup', this.onWindowPointerUpForResize);
|
|
8449
|
+
window.addEventListener('pointercancel', this.onWindowPointerUpForResize);
|
|
8450
|
+
}
|
|
8451
|
+
//#endregion
|
|
8452
|
+
//#region ---- Ports & linking ----
|
|
8453
|
+
onPortPointerDown(node, port, event) {
|
|
8454
|
+
if (this.isNodeReadonly(node))
|
|
8455
|
+
return;
|
|
8456
|
+
if (port.readonly)
|
|
8457
|
+
return;
|
|
8458
|
+
if (event.button !== 0)
|
|
8459
|
+
return;
|
|
8460
|
+
event.stopPropagation();
|
|
8461
|
+
this.portPointerDown.emit({ node, port, event });
|
|
8462
|
+
this.setActivation({ kind: 'port', id: port.id, nodeId: node.id });
|
|
8463
|
+
if (port.kind === 'outbound' && !port.disabled) {
|
|
8464
|
+
this.linkHoverTarget.set(null);
|
|
8465
|
+
const from = portCanvasPosition(node, port);
|
|
8466
|
+
this.linkDrag.set({
|
|
8467
|
+
sourceNodeId: node.id,
|
|
8468
|
+
sourcePortId: port.id,
|
|
8469
|
+
from,
|
|
8470
|
+
to: from,
|
|
8471
|
+
});
|
|
8472
|
+
this.linkDragStart.emit({ sourceNode: node, sourcePort: port, event });
|
|
8473
|
+
window.addEventListener('pointermove', this.onWindowPointerMoveForLink);
|
|
8474
|
+
window.addEventListener('pointerup', this.onWindowPointerUpForLink);
|
|
8475
|
+
window.addEventListener('pointercancel', this.onWindowPointerUpForLink);
|
|
8476
|
+
}
|
|
8477
|
+
}
|
|
8478
|
+
pickInboundPortAtPoint(model, point, excludeSourceNodeId) {
|
|
8479
|
+
let best = null;
|
|
8480
|
+
const hitR = 18;
|
|
8481
|
+
for (const node of model.nodes) {
|
|
8482
|
+
if (node.id === excludeSourceNodeId)
|
|
8483
|
+
continue;
|
|
8484
|
+
if (this.isNodeReadonly(node))
|
|
8485
|
+
continue;
|
|
8486
|
+
for (const port of node.inboundPorts) {
|
|
8487
|
+
if (port.disabled || port.readonly)
|
|
8488
|
+
continue;
|
|
8489
|
+
const c = portCanvasPosition(node, port);
|
|
8490
|
+
const d = Math.hypot(c.x - point.x, c.y - point.y);
|
|
8491
|
+
if (d <= hitR && (!best || d < best.d))
|
|
8492
|
+
best = { node, port, d };
|
|
8493
|
+
}
|
|
8494
|
+
}
|
|
8495
|
+
return best ? { node: best.node, port: best.port } : null;
|
|
8496
|
+
}
|
|
8497
|
+
//#endregion
|
|
8498
|
+
//#region ---- Connectors UI ----
|
|
8499
|
+
connectorPathD(c) {
|
|
8500
|
+
const model = this.model();
|
|
8501
|
+
const sn = findNode(model, c.sourceNodeId);
|
|
8502
|
+
const tn = findNode(model, c.targetNodeId);
|
|
8503
|
+
if (!sn || !tn)
|
|
8504
|
+
return '';
|
|
8505
|
+
const sp = findPort(sn, c.sourcePortId)?.port;
|
|
8506
|
+
const tp = findPort(tn, c.targetPortId)?.port;
|
|
8507
|
+
if (!sp || !tp)
|
|
8508
|
+
return '';
|
|
8509
|
+
const from = this.modelPointToSurface(portCanvasPosition(sn, sp));
|
|
8510
|
+
const to = this.trimmedConnectorTarget(from, this.modelPointToSurface(portCanvasPosition(tn, tp)));
|
|
8511
|
+
return connectorPath(from, to, this.connectionPreviewStyle(), sp.side, {
|
|
8512
|
+
targetSide: tp.side,
|
|
8513
|
+
obstacles: this.collectObstaclesInSurface(),
|
|
8514
|
+
});
|
|
8515
|
+
}
|
|
8516
|
+
connectorMidpoint(c) {
|
|
8517
|
+
const model = this.model();
|
|
8518
|
+
const sn = findNode(model, c.sourceNodeId);
|
|
8519
|
+
const tn = findNode(model, c.targetNodeId);
|
|
8520
|
+
if (!sn || !tn)
|
|
8521
|
+
return { x: 0, y: 0 };
|
|
8522
|
+
const sp = findPort(sn, c.sourcePortId)?.port;
|
|
8523
|
+
const tp = findPort(tn, c.targetPortId)?.port;
|
|
8524
|
+
if (!sp || !tp)
|
|
8525
|
+
return { x: 0, y: 0 };
|
|
8526
|
+
const a = this.modelPointToSurface(portCanvasPosition(sn, sp));
|
|
8527
|
+
const b = this.modelPointToSurface(portCanvasPosition(tn, tp));
|
|
8528
|
+
return { x: (a.x + b.x) * 0.5, y: (a.y + b.y) * 0.5 };
|
|
8529
|
+
}
|
|
8530
|
+
onConnectorClick(c, event) {
|
|
8531
|
+
event.stopPropagation();
|
|
8532
|
+
event.preventDefault();
|
|
8533
|
+
const append = event.ctrlKey || event.metaKey;
|
|
8534
|
+
if (append) {
|
|
8535
|
+
const next = new Set(this.selectedConnectorIds());
|
|
8536
|
+
if (next.has(c.id))
|
|
8537
|
+
next.delete(c.id);
|
|
8538
|
+
else
|
|
8539
|
+
next.add(c.id);
|
|
8540
|
+
this.selectedConnectorIds.set(next);
|
|
8541
|
+
this.selectedNodeIds.set(new Set());
|
|
8542
|
+
}
|
|
8543
|
+
else {
|
|
8544
|
+
this.selectedConnectorIds.set(new Set([c.id]));
|
|
8545
|
+
this.selectedNodeIds.set(new Set());
|
|
8546
|
+
}
|
|
8547
|
+
this.setActivation({ kind: 'connector', id: c.id });
|
|
8548
|
+
this.connectorClick.emit({ connector: c, event });
|
|
8549
|
+
}
|
|
8550
|
+
onConnectorDoubleClick(c, event) {
|
|
8551
|
+
event.stopPropagation();
|
|
8552
|
+
event.preventDefault();
|
|
8553
|
+
this.connectorDoubleClick.emit({ connector: c, event });
|
|
8554
|
+
}
|
|
8555
|
+
removeConnector(c) {
|
|
8556
|
+
if (this.isConnectorReadonly(c))
|
|
8557
|
+
return;
|
|
8558
|
+
const model = this.model();
|
|
8559
|
+
const connectors = model.connectors.filter((x) => x.id !== c.id);
|
|
8560
|
+
this.commit({ ...model, connectors });
|
|
8561
|
+
this.setActivation(null);
|
|
8562
|
+
}
|
|
8563
|
+
previewPath() {
|
|
8564
|
+
const st = this.linkDrag();
|
|
8565
|
+
if (!st)
|
|
8566
|
+
return '';
|
|
8567
|
+
const model = this.model();
|
|
8568
|
+
const sn = findNode(model, st.sourceNodeId);
|
|
8569
|
+
const sp = sn ? findPort(sn, st.sourcePortId)?.port : undefined;
|
|
8570
|
+
if (!sn || !sp)
|
|
8571
|
+
return '';
|
|
8572
|
+
const from = this.modelPointToSurface(st.from);
|
|
8573
|
+
const to = this.modelPointToSurface(st.to);
|
|
8574
|
+
const hover = this.linkHoverTarget();
|
|
8575
|
+
const hoverNode = hover ? findNode(model, hover.nodeId) : undefined;
|
|
8576
|
+
const hoverPort = hover && hoverNode ? findPort(hoverNode, hover.portId)?.port : undefined;
|
|
8577
|
+
return connectorPath(from, this.trimmedConnectorTarget(from, to), this.connectionPreviewStyle(), sp.side, {
|
|
8578
|
+
targetSide: hoverPort?.side,
|
|
8579
|
+
obstacles: this.collectObstaclesInSurface(),
|
|
8580
|
+
});
|
|
8581
|
+
}
|
|
8582
|
+
//#endregion
|
|
8583
|
+
//#region ---- Template context ----
|
|
8584
|
+
templateContext(node) {
|
|
8585
|
+
return { $implicit: node, node };
|
|
8586
|
+
}
|
|
8587
|
+
portClusterStyle(node, port) {
|
|
8588
|
+
const local = portAnchorOnNode(node, port);
|
|
8589
|
+
const w = Math.max(1, node.size.width);
|
|
8590
|
+
const h = Math.max(1, node.size.height);
|
|
8591
|
+
return {
|
|
8592
|
+
position: 'absolute',
|
|
8593
|
+
left: `${(local.x / w) * 100}%`,
|
|
8594
|
+
top: `${(local.y / h) * 100}%`,
|
|
8595
|
+
'z-index': '3',
|
|
8596
|
+
};
|
|
8597
|
+
}
|
|
8598
|
+
portLabelText(port) {
|
|
8599
|
+
return (port.label ?? port.key ?? '').trim();
|
|
8600
|
+
}
|
|
8601
|
+
portLabelX(node, port) {
|
|
8602
|
+
return this.portLabelCanvasPoint(node, port).x;
|
|
8603
|
+
}
|
|
8604
|
+
portLabelY(node, port) {
|
|
8605
|
+
return this.portLabelCanvasPoint(node, port).y;
|
|
8606
|
+
}
|
|
8607
|
+
portLabelAnchor(node, port) {
|
|
8608
|
+
const centerX = this.modelPointToSurface({ x: node.position.x + node.size.width * 0.5, y: node.position.y }).x;
|
|
8609
|
+
const anchor = this.modelPointToSurface(portCanvasPosition(node, port));
|
|
8610
|
+
const dx = anchor.x - centerX;
|
|
8611
|
+
if (Math.abs(dx) < 6)
|
|
8612
|
+
return 'middle';
|
|
8613
|
+
return dx < 0 ? 'end' : 'start';
|
|
8614
|
+
}
|
|
8615
|
+
nodeSurfaceLeft(node) {
|
|
8616
|
+
return node.position.x + this.canvasViewport().offsetX;
|
|
8617
|
+
}
|
|
8618
|
+
nodeSurfaceTop(node) {
|
|
8619
|
+
return node.position.y + this.canvasViewport().offsetY;
|
|
8620
|
+
}
|
|
8621
|
+
trimmedConnectorTarget(from, to) {
|
|
8622
|
+
const dx = to.x - from.x;
|
|
8623
|
+
const dy = to.y - from.y;
|
|
8624
|
+
const len = Math.hypot(dx, dy);
|
|
8625
|
+
if (len < 0.001)
|
|
8626
|
+
return to;
|
|
8627
|
+
// Keep arrowhead just outside the 14px port without creating a visible gap.
|
|
8628
|
+
const trim = 7;
|
|
8629
|
+
return {
|
|
8630
|
+
x: to.x - (dx / len) * trim,
|
|
8631
|
+
y: to.y - (dy / len) * trim,
|
|
8632
|
+
};
|
|
8633
|
+
}
|
|
8634
|
+
portLabelCanvasPoint(node, port) {
|
|
8635
|
+
const anchor = this.modelPointToSurface(portCanvasPosition(node, port));
|
|
8636
|
+
const center = {
|
|
8637
|
+
x: node.position.x + node.size.width * 0.5 + this.canvasViewport().offsetX,
|
|
8638
|
+
y: node.position.y + node.size.height * 0.5 + this.canvasViewport().offsetY,
|
|
8639
|
+
};
|
|
8640
|
+
const vx = anchor.x - center.x;
|
|
8641
|
+
const vy = anchor.y - center.y;
|
|
8642
|
+
const len = Math.hypot(vx, vy);
|
|
8643
|
+
if (len < 0.001)
|
|
8644
|
+
return anchor;
|
|
8645
|
+
const outward = 18;
|
|
8646
|
+
return {
|
|
8647
|
+
x: anchor.x + (vx / len) * outward,
|
|
8648
|
+
y: anchor.y + (vy / len) * outward,
|
|
8649
|
+
};
|
|
8650
|
+
}
|
|
8651
|
+
//#endregion
|
|
8652
|
+
//#region ---- Canvas mapping ----
|
|
8653
|
+
modelPointToSurface(point) {
|
|
8654
|
+
const viewport = this.canvasViewport();
|
|
8655
|
+
return {
|
|
8656
|
+
x: point.x + viewport.offsetX,
|
|
8657
|
+
y: point.y + viewport.offsetY,
|
|
8658
|
+
};
|
|
8659
|
+
}
|
|
8660
|
+
surfacePointToModel(point) {
|
|
8661
|
+
const viewport = this.canvasViewport();
|
|
8662
|
+
return {
|
|
8663
|
+
x: point.x - viewport.offsetX,
|
|
8664
|
+
y: point.y - viewport.offsetY,
|
|
8665
|
+
};
|
|
8666
|
+
}
|
|
8667
|
+
/**
|
|
8668
|
+
* Returns node bounding boxes in surface coordinates.
|
|
8669
|
+
*
|
|
8670
|
+
* All nodes are returned so the router can route AROUND every node, including
|
|
8671
|
+
* the source and target of a connector. The router itself drops obstacles that
|
|
8672
|
+
* already contain the stub-out point so the connector can still exit/enter its port.
|
|
8673
|
+
*/
|
|
8674
|
+
collectObstaclesInSurface() {
|
|
8675
|
+
const viewport = this.canvasViewport();
|
|
8676
|
+
const obstacles = [];
|
|
8677
|
+
for (const node of this.model().nodes) {
|
|
8678
|
+
obstacles.push({
|
|
8679
|
+
position: { x: node.position.x + viewport.offsetX, y: node.position.y + viewport.offsetY },
|
|
8680
|
+
size: { width: node.size.width, height: node.size.height },
|
|
8681
|
+
});
|
|
8682
|
+
}
|
|
8683
|
+
return obstacles;
|
|
8684
|
+
}
|
|
8685
|
+
//#endregion
|
|
8686
|
+
//#region ---- Wrapper visuals ----
|
|
8687
|
+
syncWrapperBackgroundStyle() {
|
|
8688
|
+
const wrapper = this.wrapperElement();
|
|
8689
|
+
if (!wrapper) {
|
|
8690
|
+
return;
|
|
8691
|
+
}
|
|
8692
|
+
const gridStyle = this.gridStyle();
|
|
8693
|
+
wrapper.style.backgroundColor = 'var(--ax-sys-color-lightest-surface)';
|
|
8694
|
+
wrapper.style.backgroundImage = String(gridStyle['background-image'] ?? '');
|
|
8695
|
+
wrapper.style.backgroundSize = String(gridStyle['background-size'] ?? '');
|
|
8696
|
+
wrapper.style.borderRadius = '10px';
|
|
8697
|
+
}
|
|
8698
|
+
//#endregion
|
|
8699
|
+
detachWindowListeners() {
|
|
8700
|
+
this.clearWrapperAttachRetry();
|
|
8701
|
+
this.detachWrapperDropTargets();
|
|
8702
|
+
this.linkHoverTarget.set(null);
|
|
8703
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForNode);
|
|
8704
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForNode);
|
|
8705
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForNode);
|
|
8706
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForResize);
|
|
8707
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForResize);
|
|
8708
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForResize);
|
|
8709
|
+
window.removeEventListener('pointermove', this.onWindowPointerMoveForLink);
|
|
8710
|
+
window.removeEventListener('pointerup', this.onWindowPointerUpForLink);
|
|
8711
|
+
window.removeEventListener('pointercancel', this.onWindowPointerUpForLink);
|
|
8712
|
+
}
|
|
8713
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWorkflowDesignerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
8714
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPWorkflowDesignerComponent, isStandalone: true, selector: "axp-workflow-designer", inputs: { model: { classPropertyName: "model", publicName: "model", isSignal: true, isRequired: true, transformFunction: null }, readonly: { classPropertyName: "readonly", publicName: "readonly", isSignal: true, isRequired: false, transformFunction: null }, gridSize: { classPropertyName: "gridSize", publicName: "gridSize", isSignal: true, isRequired: false, transformFunction: null }, snapToGrid: { classPropertyName: "snapToGrid", publicName: "snapToGrid", isSignal: true, isRequired: false, transformFunction: null }, connectionPreviewStyle: { classPropertyName: "connectionPreviewStyle", publicName: "connectionPreviewStyle", isSignal: true, isRequired: false, transformFunction: null }, backgroundPattern: { classPropertyName: "backgroundPattern", publicName: "backgroundPattern", isSignal: true, isRequired: false, transformFunction: null }, canConnect: { classPropertyName: "canConnect", publicName: "canConnect", isSignal: true, isRequired: false, transformFunction: null }, paletteItems: { classPropertyName: "paletteItems", publicName: "paletteItems", isSignal: true, isRequired: false, transformFunction: null }, showPortLabels: { classPropertyName: "showPortLabels", publicName: "showPortLabels", isSignal: true, isRequired: false, transformFunction: null }, nodeBodyTemplate: { classPropertyName: "nodeBodyTemplate", publicName: "nodeBodyTemplate", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { modelChange: "modelChange", zoomChange: "zoomChange", designerPointerDown: "designerPointerDown", designerClick: "designerClick", designerDoubleClick: "designerDoubleClick", nodePointerDown: "nodePointerDown", nodeClick: "nodeClick", nodeDoubleClick: "nodeDoubleClick", nodeContextMenu: "nodeContextMenu", nodeDragStart: "nodeDragStart", nodeDragEnd: "nodeDragEnd", portPointerDown: "portPointerDown", linkDragStart: "linkDragStart", linkDragMove: "linkDragMove", linkDragEnd: "linkDragEnd", connectorClick: "connectorClick", connectorDoubleClick: "connectorDoubleClick", connectionCreated: "connectionCreated", connectionRejected: "connectionRejected", activationChange: "activationChange" }, host: { listeners: { "window:keydown": "onWindowKeydown($event)" }, classAttribute: "axp-workflow-designer-host" }, viewQueries: [{ propertyName: "surfaceRef", first: true, predicate: ["surface"], descendants: true, isSignal: true }, { propertyName: "panViewRef", first: true, predicate: AXPanViewDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<div class=\"axp-workflow-designer\" [ngStyle]=\"gridStyle()\">\n <div\n #surface\n class=\"axp-workflow-designer__surface\"\n axPanView\n [(panX)]=\"panX\"\n [(panY)]=\"panY\"\n [(zoom)]=\"panZoomLevel\"\n [maxZoom]=\"10000\"\n [freeMode]=\"false\"\n [fitContent]=\"true\"\n wrapperClasses=\"h\"\n [ngStyle]=\"surfaceStyle()\"\n (pointerdown)=\"onSurfacePointerDown($event)\"\n (click)=\"onSurfaceClick($event)\"\n (dblclick)=\"onSurfaceDoubleClick($event)\"\n (dragover)=\"onCanvasDragOver($event)\"\n (drop)=\"onCanvasDrop($event)\"\n >\n <svg class=\"axp-workflow-designer__svg\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"xMinYMin meet\">\n <defs>\n <marker [attr.id]=\"svgMarkerId\" markerWidth=\"6\" markerHeight=\"6\" refX=\"3.9\" refY=\"3\" orient=\"auto\">\n <path d=\"M0,0 L4,3 L0,6 Q1.5,3 0,0 Z\" class=\"axp-workflow-designer__arrow-head\"></path>\n </marker>\n </defs>\n @for (c of model().connectors; track c.id) {\n <path\n class=\"axp-workflow-designer__edge-hit\"\n [attr.d]=\"connectorPathD(c)\"\n fill=\"none\"\n stroke=\"transparent\"\n stroke-width=\"16\"\n pointer-events=\"stroke\"\n (click)=\"onConnectorClick(c, $event)\"\n (dblclick)=\"onConnectorDoubleClick(c, $event)\"\n />\n <path\n [class]=\"connectorEdgeClasses(c)\"\n [attr.d]=\"connectorPathD(c)\"\n fill=\"none\"\n [attr.marker-end]=\"'url(#' + svgMarkerId + ')'\"\n />\n }\n @if (linkDrag()) {\n <path class=\"axp-workflow-designer__edge-preview\" [attr.d]=\"previewPath()\" fill=\"none\" />\n }\n @if (showPortLabels()) {\n @for (node of model().nodes; track node.id) {\n @for (port of node.inboundPorts; track port.id) {\n @if (portLabelText(port)) {\n <text\n class=\"axp-workflow-designer__port-label-svg\"\n [attr.x]=\"portLabelX(node, port)\"\n [attr.y]=\"portLabelY(node, port)\"\n [attr.text-anchor]=\"portLabelAnchor(node, port)\"\n >\n {{ portLabelText(port) }}\n </text>\n }\n }\n @for (port of node.outboundPorts; track port.id) {\n @if (portLabelText(port)) {\n <text\n class=\"axp-workflow-designer__port-label-svg\"\n [attr.x]=\"portLabelX(node, port)\"\n [attr.y]=\"portLabelY(node, port)\"\n [attr.text-anchor]=\"portLabelAnchor(node, port)\"\n >\n {{ portLabelText(port) }}\n </text>\n }\n }\n }\n }\n </svg>\n\n @for (c of model().connectors; track c.id) {\n @if (isConnectorActive(c.id) && !isConnectorReadonly(c)) {\n <div\n class=\"axp-workflow-designer__connector-actions\"\n [style.left.px]=\"connectorMidpoint(c).x - 16\"\n [style.top.px]=\"connectorMidpoint(c).y - 16\"\n >\n <ax-button look=\"blank\" class=\"ax-xs axp-workflow-designer__icon-btn\" (onClick)=\"removeConnector(c)\">\n <ax-icon class=\"fa-solid fa-minus\"></ax-icon>\n </ax-button>\n </div>\n }\n }\n\n @for (node of model().nodes; track node.id) {\n <div\n class=\"axp-workflow-designer__node\"\n [class.axp-workflow-designer__node--active]=\"isNodeActive(node.id)\"\n [style.left.px]=\"nodeSurfaceLeft(node)\"\n [style.top.px]=\"nodeSurfaceTop(node)\"\n [style.width.px]=\"node.size.width\"\n [style.height.px]=\"node.size.height\"\n (pointerdown)=\"onNodePointerDown(node, $event)\"\n (click)=\"onNodeClick(node, $event)\"\n (dblclick)=\"onNodeDoubleClick(node, $event)\"\n (contextmenu)=\"onNodeContextMenu(node, $event)\"\n >\n <div [class]=\"nodeShapeClasses(node)\">\n <div class=\"axp-workflow-designer__node-body\" (pointerdown)=\"onNodeBodyPointerDown(node, $event)\">\n @if (nodeBodyTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"templateContext(node)\" />\n } @else {\n <div class=\"axp-workflow-designer__node-default\">\n @if (node.icon) {\n <ax-icon class=\"axp-workflow-designer__node-default-icon\" [class]=\"node.icon\"></ax-icon>\n }\n <span class=\"axp-workflow-designer__node-default-title\">{{ node.title }}</span>\n </div>\n }\n </div>\n </div>\n\n @for (port of node.inboundPorts; track port.id) {\n <div\n class=\"axp-workflow-designer__port-cluster\"\n [class.axp-workflow-designer__port-cluster--side-top]=\"port.side === 'top'\"\n [class.axp-workflow-designer__port-cluster--side-right]=\"port.side === 'right'\"\n [class.axp-workflow-designer__port-cluster--side-bottom]=\"port.side === 'bottom'\"\n [class.axp-workflow-designer__port-cluster--side-left]=\"port.side === 'left'\"\n [ngStyle]=\"portClusterStyle(node, port)\"\n >\n <button\n type=\"button\"\n class=\"axp-workflow-designer__port axp-workflow-designer__port--inbound\"\n [class.axp-workflow-designer__port--active]=\"isPortActive(node.id, port.id)\"\n [class.axp-workflow-designer__port--link-hover]=\"isPortLinkHoverTarget(node.id, port.id)\"\n [class.axp-workflow-designer__port--disabled]=\"port.disabled\"\n [disabled]=\"isNodeReadonly(node) || port.disabled === true\"\n (pointerdown)=\"onPortPointerDown(node, port, $event)\"\n ></button>\n </div>\n }\n @for (port of node.outboundPorts; track port.id) {\n <div\n class=\"axp-workflow-designer__port-cluster\"\n [class.axp-workflow-designer__port-cluster--side-top]=\"port.side === 'top'\"\n [class.axp-workflow-designer__port-cluster--side-right]=\"port.side === 'right'\"\n [class.axp-workflow-designer__port-cluster--side-bottom]=\"port.side === 'bottom'\"\n [class.axp-workflow-designer__port-cluster--side-left]=\"port.side === 'left'\"\n [ngStyle]=\"portClusterStyle(node, port)\"\n >\n <button\n type=\"button\"\n class=\"axp-workflow-designer__port axp-workflow-designer__port--outbound\"\n [class.axp-workflow-designer__port--active]=\"isPortActive(node.id, port.id)\"\n [class.axp-workflow-designer__port--disabled]=\"port.disabled\"\n [disabled]=\"isNodeReadonly(node) || port.disabled === true\"\n (pointerdown)=\"onPortPointerDown(node, port, $event)\"\n ></button>\n </div>\n }\n\n @if (isNodeActive(node.id) && !isNodeReadonly(node)) {\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--nw\"\n (pointerdown)=\"onResizePointerDown(node, 'nw', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--ne\"\n (pointerdown)=\"onResizePointerDown(node, 'ne', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--sw\"\n (pointerdown)=\"onResizePointerDown(node, 'sw', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--se\"\n (pointerdown)=\"onResizePointerDown(node, 'se', $event)\"\n ></span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".axp-workflow-designer-host{display:block;width:100%;height:100%;min-height:360px;user-select:none;-webkit-user-select:none}.axp-workflow-designer{display:flex;width:100%;height:100%;min-height:inherit}.axp-workflow-designer__surface{position:relative;flex:1;min-width:100%;min-height:100%;overflow:auto;border-radius:10px;user-select:none;-webkit-user-select:none}.axp-workflow-designer__surface::ng-deep .ax-pan-view__wrapper{width:100%;height:100%}.axp-workflow-designer__svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1}.axp-workflow-designer__edge-hit{pointer-events:stroke;cursor:pointer}.axp-workflow-designer__edge{pointer-events:none;stroke:rgb(var(--ax-sys-color-neutral-500));stroke-width:2;transition:stroke .12s ease}.axp-workflow-designer__edge--active{stroke:rgb(var(--ax-sys-color-primary-500));stroke-dasharray:2}.axp-workflow-designer__edge.ax-primary-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__edge.ax-secondary-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-secondary-500))}.axp-workflow-designer__edge.ax-success-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-success-500))}.axp-workflow-designer__edge.ax-warning-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-warning-500))}.axp-workflow-designer__edge.ax-danger-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-danger-500))}.axp-workflow-designer__edge-preview{pointer-events:none;stroke:rgb(var(--ax-sys-color-primary-400));stroke-width:2;stroke-dasharray:6 4}.axp-workflow-designer__port-label-svg{fill:rgb(var(--ax-sys-color-on-surface));font-size:10px;font-weight:600;dominant-baseline:middle;pointer-events:none;paint-order:stroke;stroke:rgb(var(--ax-sys-color-surface));stroke-width:4px;stroke-linejoin:round}.axp-workflow-designer__arrow-head{fill:rgb(var(--ax-sys-color-neutral-500))}.axp-workflow-designer__connector-actions{position:absolute;z-index:4;display:flex;align-items:center;justify-content:center}.axp-workflow-designer__icon-btn{border-radius:999px;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node{position:absolute;z-index:2;box-sizing:border-box;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node-shape{position:absolute;inset:0;box-sizing:border-box;background:rgb(var(--ax-sys-color-surface));overflow:visible}.axp-workflow-designer__node-shape.axp-primary-surface{background:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface))}.axp-workflow-designer__node-shape.axp-secondary-surface{background:rgb(var(--ax-sys-color-secondary-surface));color:rgb(var(--ax-sys-color-on-secondary-surface))}.axp-workflow-designer__node-shape.axp-success-surface{background:rgb(var(--ax-sys-color-success-surface));color:rgb(var(--ax-sys-color-on-success-surface))}.axp-workflow-designer__node-shape.axp-warning-surface{background:rgb(var(--ax-sys-color-warning-surface));color:rgb(var(--ax-sys-color-on-warning-surface))}.axp-workflow-designer__node-shape.axp-danger-surface{background:rgb(var(--ax-sys-color-danger-surface));border-color:rgb(var(--ax-sys-color-danger-500));color:rgb(var(--ax-sys-color-on-danger-surface))}.axp-workflow-designer__node.axp-workflow-designer__node--active .axp-workflow-designer__node-shape{border:2px dotted rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__node-shape--rectangle{border-radius:4px}.axp-workflow-designer__node-shape--rounded-rectangle{border-radius:14px}.axp-workflow-designer__node-shape--circle,.axp-workflow-designer__node-shape--ellipse{border-radius:50%}.axp-workflow-designer__node-shape--diamond{border-radius:0;clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}.axp-workflow-designer__node-body{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:8px 12px;cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node-default{display:flex;align-items:center;gap:8px;min-width:0}.axp-workflow-designer__node-default-icon{flex-shrink:0}.axp-workflow-designer__node-default-title{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.axp-workflow-designer__port-cluster{position:absolute;width:0;height:0;overflow:visible;pointer-events:none;transform:translate(-50%,-50%);z-index:3}.axp-workflow-designer__port{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);flex-shrink:0;width:14px;height:14px;padding:0;border-radius:999px;border:1px solid rgb(var(--ax-sys-color-surface));cursor:crosshair;touch-action:none;pointer-events:auto;transition:transform .12s ease}.axp-workflow-designer__port--inbound{background:rgb(var(--ax-sys-color-success-500))}.axp-workflow-designer__port--outbound{background:rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__port--active{box-shadow:0 0 0 3px #3b82f659}.axp-workflow-designer__port--link-hover{border:1px solid rgb(var(--ax-sys-color-primary-500));transform:translate(-50%,-50%) scale(1.12)}.axp-workflow-designer__port--disabled{opacity:.45;cursor:not-allowed}.axp-workflow-designer__port:disabled{opacity:.45;cursor:not-allowed}.axp-workflow-designer__resize{position:absolute;width:7px;height:7px;border-radius:999px;background:rgb(var(--ax-sys-color-primary-500));border:1px solid rgb(var(--ax-sys-color-surface));z-index:4;touch-action:none;user-select:none;-webkit-user-select:none}.axp-workflow-designer__resize--nw{left:-6px;top:-6px;cursor:nwse-resize}.axp-workflow-designer__resize--ne{right:-6px;top:-6px;cursor:nesw-resize}.axp-workflow-designer__resize--sw{left:-6px;bottom:-6px;cursor:nesw-resize}.axp-workflow-designer__resize--se{right:-6px;bottom:-6px;cursor:nwse-resize}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1$1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i1$1.NgStyle, selector: "[ngStyle]", inputs: ["ngStyle"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i2.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i1$2.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: "directive", type: AXPanViewDirective, selector: "[axPanView]", inputs: ["zoomStep", "minZoom", "maxZoom", "freeMode", "fitContent", "disablePan", "disableZoom", "wrapperClasses", "panX", "panY", "zoom"], outputs: ["panXChange", "panYChange", "zoomChange", "positionChange"], exportAs: ["axPanView"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
|
8715
|
+
}
|
|
8716
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWorkflowDesignerComponent, decorators: [{
|
|
8717
|
+
type: Component,
|
|
8718
|
+
args: [{ selector: 'axp-workflow-designer', imports: [CommonModule, AXDecoratorModule, AXButtonModule, AXPanViewDirective], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, host: {
|
|
8719
|
+
class: 'axp-workflow-designer-host',
|
|
8720
|
+
'(window:keydown)': 'onWindowKeydown($event)',
|
|
8721
|
+
}, template: "<div class=\"axp-workflow-designer\" [ngStyle]=\"gridStyle()\">\n <div\n #surface\n class=\"axp-workflow-designer__surface\"\n axPanView\n [(panX)]=\"panX\"\n [(panY)]=\"panY\"\n [(zoom)]=\"panZoomLevel\"\n [maxZoom]=\"10000\"\n [freeMode]=\"false\"\n [fitContent]=\"true\"\n wrapperClasses=\"h\"\n [ngStyle]=\"surfaceStyle()\"\n (pointerdown)=\"onSurfacePointerDown($event)\"\n (click)=\"onSurfaceClick($event)\"\n (dblclick)=\"onSurfaceDoubleClick($event)\"\n (dragover)=\"onCanvasDragOver($event)\"\n (drop)=\"onCanvasDrop($event)\"\n >\n <svg class=\"axp-workflow-designer__svg\" width=\"100%\" height=\"100%\" preserveAspectRatio=\"xMinYMin meet\">\n <defs>\n <marker [attr.id]=\"svgMarkerId\" markerWidth=\"6\" markerHeight=\"6\" refX=\"3.9\" refY=\"3\" orient=\"auto\">\n <path d=\"M0,0 L4,3 L0,6 Q1.5,3 0,0 Z\" class=\"axp-workflow-designer__arrow-head\"></path>\n </marker>\n </defs>\n @for (c of model().connectors; track c.id) {\n <path\n class=\"axp-workflow-designer__edge-hit\"\n [attr.d]=\"connectorPathD(c)\"\n fill=\"none\"\n stroke=\"transparent\"\n stroke-width=\"16\"\n pointer-events=\"stroke\"\n (click)=\"onConnectorClick(c, $event)\"\n (dblclick)=\"onConnectorDoubleClick(c, $event)\"\n />\n <path\n [class]=\"connectorEdgeClasses(c)\"\n [attr.d]=\"connectorPathD(c)\"\n fill=\"none\"\n [attr.marker-end]=\"'url(#' + svgMarkerId + ')'\"\n />\n }\n @if (linkDrag()) {\n <path class=\"axp-workflow-designer__edge-preview\" [attr.d]=\"previewPath()\" fill=\"none\" />\n }\n @if (showPortLabels()) {\n @for (node of model().nodes; track node.id) {\n @for (port of node.inboundPorts; track port.id) {\n @if (portLabelText(port)) {\n <text\n class=\"axp-workflow-designer__port-label-svg\"\n [attr.x]=\"portLabelX(node, port)\"\n [attr.y]=\"portLabelY(node, port)\"\n [attr.text-anchor]=\"portLabelAnchor(node, port)\"\n >\n {{ portLabelText(port) }}\n </text>\n }\n }\n @for (port of node.outboundPorts; track port.id) {\n @if (portLabelText(port)) {\n <text\n class=\"axp-workflow-designer__port-label-svg\"\n [attr.x]=\"portLabelX(node, port)\"\n [attr.y]=\"portLabelY(node, port)\"\n [attr.text-anchor]=\"portLabelAnchor(node, port)\"\n >\n {{ portLabelText(port) }}\n </text>\n }\n }\n }\n }\n </svg>\n\n @for (c of model().connectors; track c.id) {\n @if (isConnectorActive(c.id) && !isConnectorReadonly(c)) {\n <div\n class=\"axp-workflow-designer__connector-actions\"\n [style.left.px]=\"connectorMidpoint(c).x - 16\"\n [style.top.px]=\"connectorMidpoint(c).y - 16\"\n >\n <ax-button look=\"blank\" class=\"ax-xs axp-workflow-designer__icon-btn\" (onClick)=\"removeConnector(c)\">\n <ax-icon class=\"fa-solid fa-minus\"></ax-icon>\n </ax-button>\n </div>\n }\n }\n\n @for (node of model().nodes; track node.id) {\n <div\n class=\"axp-workflow-designer__node\"\n [class.axp-workflow-designer__node--active]=\"isNodeActive(node.id)\"\n [style.left.px]=\"nodeSurfaceLeft(node)\"\n [style.top.px]=\"nodeSurfaceTop(node)\"\n [style.width.px]=\"node.size.width\"\n [style.height.px]=\"node.size.height\"\n (pointerdown)=\"onNodePointerDown(node, $event)\"\n (click)=\"onNodeClick(node, $event)\"\n (dblclick)=\"onNodeDoubleClick(node, $event)\"\n (contextmenu)=\"onNodeContextMenu(node, $event)\"\n >\n <div [class]=\"nodeShapeClasses(node)\">\n <div class=\"axp-workflow-designer__node-body\" (pointerdown)=\"onNodeBodyPointerDown(node, $event)\">\n @if (nodeBodyTemplate(); as tpl) {\n <ng-container [ngTemplateOutlet]=\"tpl\" [ngTemplateOutletContext]=\"templateContext(node)\" />\n } @else {\n <div class=\"axp-workflow-designer__node-default\">\n @if (node.icon) {\n <ax-icon class=\"axp-workflow-designer__node-default-icon\" [class]=\"node.icon\"></ax-icon>\n }\n <span class=\"axp-workflow-designer__node-default-title\">{{ node.title }}</span>\n </div>\n }\n </div>\n </div>\n\n @for (port of node.inboundPorts; track port.id) {\n <div\n class=\"axp-workflow-designer__port-cluster\"\n [class.axp-workflow-designer__port-cluster--side-top]=\"port.side === 'top'\"\n [class.axp-workflow-designer__port-cluster--side-right]=\"port.side === 'right'\"\n [class.axp-workflow-designer__port-cluster--side-bottom]=\"port.side === 'bottom'\"\n [class.axp-workflow-designer__port-cluster--side-left]=\"port.side === 'left'\"\n [ngStyle]=\"portClusterStyle(node, port)\"\n >\n <button\n type=\"button\"\n class=\"axp-workflow-designer__port axp-workflow-designer__port--inbound\"\n [class.axp-workflow-designer__port--active]=\"isPortActive(node.id, port.id)\"\n [class.axp-workflow-designer__port--link-hover]=\"isPortLinkHoverTarget(node.id, port.id)\"\n [class.axp-workflow-designer__port--disabled]=\"port.disabled\"\n [disabled]=\"isNodeReadonly(node) || port.disabled === true\"\n (pointerdown)=\"onPortPointerDown(node, port, $event)\"\n ></button>\n </div>\n }\n @for (port of node.outboundPorts; track port.id) {\n <div\n class=\"axp-workflow-designer__port-cluster\"\n [class.axp-workflow-designer__port-cluster--side-top]=\"port.side === 'top'\"\n [class.axp-workflow-designer__port-cluster--side-right]=\"port.side === 'right'\"\n [class.axp-workflow-designer__port-cluster--side-bottom]=\"port.side === 'bottom'\"\n [class.axp-workflow-designer__port-cluster--side-left]=\"port.side === 'left'\"\n [ngStyle]=\"portClusterStyle(node, port)\"\n >\n <button\n type=\"button\"\n class=\"axp-workflow-designer__port axp-workflow-designer__port--outbound\"\n [class.axp-workflow-designer__port--active]=\"isPortActive(node.id, port.id)\"\n [class.axp-workflow-designer__port--disabled]=\"port.disabled\"\n [disabled]=\"isNodeReadonly(node) || port.disabled === true\"\n (pointerdown)=\"onPortPointerDown(node, port, $event)\"\n ></button>\n </div>\n }\n\n @if (isNodeActive(node.id) && !isNodeReadonly(node)) {\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--nw\"\n (pointerdown)=\"onResizePointerDown(node, 'nw', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--ne\"\n (pointerdown)=\"onResizePointerDown(node, 'ne', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--sw\"\n (pointerdown)=\"onResizePointerDown(node, 'sw', $event)\"\n ></span>\n <span\n class=\"axp-workflow-designer__resize axp-workflow-designer__resize--se\"\n (pointerdown)=\"onResizePointerDown(node, 'se', $event)\"\n ></span>\n }\n </div>\n }\n </div>\n</div>\n", styles: [".axp-workflow-designer-host{display:block;width:100%;height:100%;min-height:360px;user-select:none;-webkit-user-select:none}.axp-workflow-designer{display:flex;width:100%;height:100%;min-height:inherit}.axp-workflow-designer__surface{position:relative;flex:1;min-width:100%;min-height:100%;overflow:auto;border-radius:10px;user-select:none;-webkit-user-select:none}.axp-workflow-designer__surface::ng-deep .ax-pan-view__wrapper{width:100%;height:100%}.axp-workflow-designer__svg{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;z-index:1}.axp-workflow-designer__edge-hit{pointer-events:stroke;cursor:pointer}.axp-workflow-designer__edge{pointer-events:none;stroke:rgb(var(--ax-sys-color-neutral-500));stroke-width:2;transition:stroke .12s ease}.axp-workflow-designer__edge--active{stroke:rgb(var(--ax-sys-color-primary-500));stroke-dasharray:2}.axp-workflow-designer__edge.ax-primary-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__edge.ax-secondary-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-secondary-500))}.axp-workflow-designer__edge.ax-success-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-success-500))}.axp-workflow-designer__edge.ax-warning-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-warning-500))}.axp-workflow-designer__edge.ax-danger-surface:not(.axp-workflow-designer__edge--active){stroke:rgb(var(--ax-sys-color-danger-500))}.axp-workflow-designer__edge-preview{pointer-events:none;stroke:rgb(var(--ax-sys-color-primary-400));stroke-width:2;stroke-dasharray:6 4}.axp-workflow-designer__port-label-svg{fill:rgb(var(--ax-sys-color-on-surface));font-size:10px;font-weight:600;dominant-baseline:middle;pointer-events:none;paint-order:stroke;stroke:rgb(var(--ax-sys-color-surface));stroke-width:4px;stroke-linejoin:round}.axp-workflow-designer__arrow-head{fill:rgb(var(--ax-sys-color-neutral-500))}.axp-workflow-designer__connector-actions{position:absolute;z-index:4;display:flex;align-items:center;justify-content:center}.axp-workflow-designer__icon-btn{border-radius:999px;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node{position:absolute;z-index:2;box-sizing:border-box;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node-shape{position:absolute;inset:0;box-sizing:border-box;background:rgb(var(--ax-sys-color-surface));overflow:visible}.axp-workflow-designer__node-shape.axp-primary-surface{background:rgb(var(--ax-sys-color-primary-surface));color:rgb(var(--ax-sys-color-on-primary-surface))}.axp-workflow-designer__node-shape.axp-secondary-surface{background:rgb(var(--ax-sys-color-secondary-surface));color:rgb(var(--ax-sys-color-on-secondary-surface))}.axp-workflow-designer__node-shape.axp-success-surface{background:rgb(var(--ax-sys-color-success-surface));color:rgb(var(--ax-sys-color-on-success-surface))}.axp-workflow-designer__node-shape.axp-warning-surface{background:rgb(var(--ax-sys-color-warning-surface));color:rgb(var(--ax-sys-color-on-warning-surface))}.axp-workflow-designer__node-shape.axp-danger-surface{background:rgb(var(--ax-sys-color-danger-surface));border-color:rgb(var(--ax-sys-color-danger-500));color:rgb(var(--ax-sys-color-on-danger-surface))}.axp-workflow-designer__node.axp-workflow-designer__node--active .axp-workflow-designer__node-shape{border:2px dotted rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__node-shape--rectangle{border-radius:4px}.axp-workflow-designer__node-shape--rounded-rectangle{border-radius:14px}.axp-workflow-designer__node-shape--circle,.axp-workflow-designer__node-shape--ellipse{border-radius:50%}.axp-workflow-designer__node-shape--diamond{border-radius:0;clip-path:polygon(50% 0%,100% 50%,50% 100%,0% 50%)}.axp-workflow-designer__node-body{position:absolute;inset:0;display:flex;align-items:center;justify-content:center;padding:8px 12px;cursor:grab;touch-action:none;user-select:none;-webkit-user-select:none}.axp-workflow-designer__node-default{display:flex;align-items:center;gap:8px;min-width:0}.axp-workflow-designer__node-default-icon{flex-shrink:0}.axp-workflow-designer__node-default-title{font-size:13px;font-weight:600;white-space:nowrap;overflow:hidden;text-overflow:ellipsis}.axp-workflow-designer__port-cluster{position:absolute;width:0;height:0;overflow:visible;pointer-events:none;transform:translate(-50%,-50%);z-index:3}.axp-workflow-designer__port{position:absolute;left:50%;top:50%;transform:translate(-50%,-50%);flex-shrink:0;width:14px;height:14px;padding:0;border-radius:999px;border:1px solid rgb(var(--ax-sys-color-surface));cursor:crosshair;touch-action:none;pointer-events:auto;transition:transform .12s ease}.axp-workflow-designer__port--inbound{background:rgb(var(--ax-sys-color-success-500))}.axp-workflow-designer__port--outbound{background:rgb(var(--ax-sys-color-primary-500))}.axp-workflow-designer__port--active{box-shadow:0 0 0 3px #3b82f659}.axp-workflow-designer__port--link-hover{border:1px solid rgb(var(--ax-sys-color-primary-500));transform:translate(-50%,-50%) scale(1.12)}.axp-workflow-designer__port--disabled{opacity:.45;cursor:not-allowed}.axp-workflow-designer__port:disabled{opacity:.45;cursor:not-allowed}.axp-workflow-designer__resize{position:absolute;width:7px;height:7px;border-radius:999px;background:rgb(var(--ax-sys-color-primary-500));border:1px solid rgb(var(--ax-sys-color-surface));z-index:4;touch-action:none;user-select:none;-webkit-user-select:none}.axp-workflow-designer__resize--nw{left:-6px;top:-6px;cursor:nwse-resize}.axp-workflow-designer__resize--ne{right:-6px;top:-6px;cursor:nesw-resize}.axp-workflow-designer__resize--sw{left:-6px;bottom:-6px;cursor:nesw-resize}.axp-workflow-designer__resize--se{right:-6px;bottom:-6px;cursor:nwse-resize}\n"] }]
|
|
8722
|
+
}], ctorParameters: () => [], propDecorators: { model: [{ type: i0.Input, args: [{ isSignal: true, alias: "model", required: true }] }], modelChange: [{ type: i0.Output, args: ["modelChange"] }], readonly: [{ type: i0.Input, args: [{ isSignal: true, alias: "readonly", required: false }] }], gridSize: [{ type: i0.Input, args: [{ isSignal: true, alias: "gridSize", required: false }] }], snapToGrid: [{ type: i0.Input, args: [{ isSignal: true, alias: "snapToGrid", required: false }] }], connectionPreviewStyle: [{ type: i0.Input, args: [{ isSignal: true, alias: "connectionPreviewStyle", required: false }] }], backgroundPattern: [{ type: i0.Input, args: [{ isSignal: true, alias: "backgroundPattern", required: false }] }], zoomChange: [{ type: i0.Output, args: ["zoomChange"] }], canConnect: [{ type: i0.Input, args: [{ isSignal: true, alias: "canConnect", required: false }] }], paletteItems: [{ type: i0.Input, args: [{ isSignal: true, alias: "paletteItems", required: false }] }], showPortLabels: [{ type: i0.Input, args: [{ isSignal: true, alias: "showPortLabels", required: false }] }], nodeBodyTemplate: [{ type: i0.Input, args: [{ isSignal: true, alias: "nodeBodyTemplate", required: false }] }], designerPointerDown: [{ type: i0.Output, args: ["designerPointerDown"] }], designerClick: [{ type: i0.Output, args: ["designerClick"] }], designerDoubleClick: [{ type: i0.Output, args: ["designerDoubleClick"] }], nodePointerDown: [{ type: i0.Output, args: ["nodePointerDown"] }], nodeClick: [{ type: i0.Output, args: ["nodeClick"] }], nodeDoubleClick: [{ type: i0.Output, args: ["nodeDoubleClick"] }], nodeContextMenu: [{ type: i0.Output, args: ["nodeContextMenu"] }], nodeDragStart: [{ type: i0.Output, args: ["nodeDragStart"] }], nodeDragEnd: [{ type: i0.Output, args: ["nodeDragEnd"] }], portPointerDown: [{ type: i0.Output, args: ["portPointerDown"] }], linkDragStart: [{ type: i0.Output, args: ["linkDragStart"] }], linkDragMove: [{ type: i0.Output, args: ["linkDragMove"] }], linkDragEnd: [{ type: i0.Output, args: ["linkDragEnd"] }], connectorClick: [{ type: i0.Output, args: ["connectorClick"] }], connectorDoubleClick: [{ type: i0.Output, args: ["connectorDoubleClick"] }], connectionCreated: [{ type: i0.Output, args: ["connectionCreated"] }], connectionRejected: [{ type: i0.Output, args: ["connectionRejected"] }], activationChange: [{ type: i0.Output, args: ["activationChange"] }], surfaceRef: [{ type: i0.ViewChild, args: ['surface', { isSignal: true }] }], panViewRef: [{ type: i0.ViewChild, args: [i0.forwardRef(() => AXPanViewDirective), { isSignal: true }] }] } });
|
|
8723
|
+
|
|
8724
|
+
/**
|
|
8725
|
+
* Makes any host element a draggable palette source. Set `[axpWorkflowPaletteItem]="item"` and optional outputs.
|
|
8726
|
+
* Drop target: `axp-workflow-designer` canvas (same MIME as drag payload).
|
|
8727
|
+
*/
|
|
8728
|
+
class AXPWorkflowPaletteItemDragDirective {
|
|
8729
|
+
constructor() {
|
|
8730
|
+
/** Palette definition serialized into the drag payload. */
|
|
8731
|
+
this.axpWorkflowPaletteItem = input.required({ ...(ngDevMode ? { debugName: "axpWorkflowPaletteItem" } : /* istanbul ignore next */ {}), alias: 'axpWorkflowPaletteItem' });
|
|
8732
|
+
/** When true, drag is disabled. */
|
|
8733
|
+
this.axpWorkflowPaletteDragDisabled = input(false, { ...(ngDevMode ? { debugName: "axpWorkflowPaletteDragDisabled" } : /* istanbul ignore next */ {}), alias: 'axpWorkflowPaletteDragDisabled' });
|
|
8734
|
+
this.axpWorkflowPaletteDragStart = output({
|
|
8735
|
+
alias: 'axpWorkflowPaletteDragStart',
|
|
8736
|
+
});
|
|
8737
|
+
this.axpWorkflowPaletteDragEnd = output({
|
|
8738
|
+
alias: 'axpWorkflowPaletteDragEnd',
|
|
8739
|
+
});
|
|
8740
|
+
this.hostDraggable = computed(() => (this.axpWorkflowPaletteDragDisabled() ? null : true), ...(ngDevMode ? [{ debugName: "hostDraggable" }] : /* istanbul ignore next */ []));
|
|
8741
|
+
this.lastItem = null;
|
|
8742
|
+
}
|
|
8743
|
+
onDragStart(event) {
|
|
8744
|
+
if (this.axpWorkflowPaletteDragDisabled()) {
|
|
8745
|
+
event.preventDefault();
|
|
8746
|
+
return;
|
|
8747
|
+
}
|
|
8748
|
+
const item = this.axpWorkflowPaletteItem();
|
|
8749
|
+
this.lastItem = item;
|
|
8750
|
+
event.dataTransfer?.setData(AXP_WORKFLOW_PALETTE_MIME, JSON.stringify(item));
|
|
8751
|
+
event.dataTransfer?.setData('text/plain', item.title);
|
|
8752
|
+
if (event.dataTransfer)
|
|
8753
|
+
event.dataTransfer.effectAllowed = 'copy';
|
|
8754
|
+
this.axpWorkflowPaletteDragStart.emit({ item, event });
|
|
8755
|
+
}
|
|
8756
|
+
onDragEnd(event) {
|
|
8757
|
+
this.axpWorkflowPaletteDragEnd.emit({ item: this.lastItem, event });
|
|
8758
|
+
this.lastItem = null;
|
|
8759
|
+
}
|
|
8760
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWorkflowPaletteItemDragDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
|
|
8761
|
+
static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "21.2.9", type: AXPWorkflowPaletteItemDragDirective, isStandalone: true, selector: "[axpWorkflowPaletteItem]", inputs: { axpWorkflowPaletteItem: { classPropertyName: "axpWorkflowPaletteItem", publicName: "axpWorkflowPaletteItem", isSignal: true, isRequired: true, transformFunction: null }, axpWorkflowPaletteDragDisabled: { classPropertyName: "axpWorkflowPaletteDragDisabled", publicName: "axpWorkflowPaletteDragDisabled", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { axpWorkflowPaletteDragStart: "axpWorkflowPaletteDragStart", axpWorkflowPaletteDragEnd: "axpWorkflowPaletteDragEnd" }, host: { listeners: { "dragstart": "onDragStart($event)", "dragend": "onDragEnd($event)" }, properties: { "attr.draggable": "hostDraggable()" } }, ngImport: i0 }); }
|
|
8762
|
+
}
|
|
8763
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPWorkflowPaletteItemDragDirective, decorators: [{
|
|
8764
|
+
type: Directive,
|
|
8765
|
+
args: [{
|
|
8766
|
+
selector: '[axpWorkflowPaletteItem]',
|
|
8767
|
+
host: {
|
|
8768
|
+
'[attr.draggable]': 'hostDraggable()',
|
|
8769
|
+
'(dragstart)': 'onDragStart($event)',
|
|
8770
|
+
'(dragend)': 'onDragEnd($event)',
|
|
8771
|
+
},
|
|
8772
|
+
}]
|
|
8773
|
+
}], propDecorators: { axpWorkflowPaletteItem: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpWorkflowPaletteItem", required: true }] }], axpWorkflowPaletteDragDisabled: [{ type: i0.Input, args: [{ isSignal: true, alias: "axpWorkflowPaletteDragDisabled", required: false }] }], axpWorkflowPaletteDragStart: [{ type: i0.Output, args: ["axpWorkflowPaletteDragStart"] }], axpWorkflowPaletteDragEnd: [{ type: i0.Output, args: ["axpWorkflowPaletteDragEnd"] }] } });
|
|
8774
|
+
|
|
8775
|
+
//#region ---- Point & geometry ----
|
|
8776
|
+
//#endregion
|
|
8777
|
+
|
|
6863
8778
|
// export * from './lib/features';
|
|
6864
8779
|
|
|
6865
8780
|
/**
|
|
6866
8781
|
* Generated bundle index. Do not edit.
|
|
6867
8782
|
*/
|
|
6868
8783
|
|
|
6869
|
-
export { AXPMenuManagementService as A, RootConfig as R, AXMPlatformManagementModule as a, AXMTokenEntityModule as b, AXMTokensService as c, AXMTokensServiceImpl as d, AXPPlatformManagementFeatureKeys as e,
|
|
6870
|
-
//# sourceMappingURL=acorex-modules-platform-management-acorex-modules-platform-management-
|
|
8784
|
+
export { AXPMenuManagementService as A, menuDefinitionEntityFactory as B, moduleDefinitionEntityFactory as C, parsePaletteItemDragPayload as D, permissionGroupDefinitionEntityFactory as E, pluginDefinitionEntityFactory as F, portAnchorOnNode as G, portCanvasPosition as H, queryDefinitionEntityFactory as I, relationDefinitionEntityFactory as J, routeOrthogonalConnector as K, snapPoint as L, snapScalar as M, toWidgetFieldConfiguratorColumnNode as N, tokenEntityFactory as O, validationDefinitionEntityFactory as P, widgetFieldConfiguratorValueFromInterfaceDefinition as Q, RootConfig as R, AXMPlatformManagementModule as a, AXMTokenEntityModule as b, AXMTokensService as c, AXMTokensServiceImpl as d, AXPPlatformManagementFeatureKeys as e, AXPWorkflowDesignerComponent as f, AXPWorkflowPaletteItemDragDirective as g, AXP_WORKFLOW_PALETTE_MIME as h, aggregateDefinitionEntityFactory as i, arrangeWorkflowDiagram as j, cloneDiagram as k, commandDefinitionEntityFactory as l, connectorPath as m, createNodeFromPaletteItem as n, createPortsFromPalette as o, createWorkflowConnectorId as p, createWorkflowNodeId as q, createWorkflowPortId as r, defaultCanConnectRequest as s, findConnector as t, findNode as u, findPort as v, interfaceDefinitionEntityFactory as w, interfaceDefinitionFromWidgetFieldConfiguratorValue as x, mapEntityFieldRowsInterfaceForForm as y, mapEntityFieldRowsInterfaceToDomain as z };
|
|
8785
|
+
//# sourceMappingURL=acorex-modules-platform-management-acorex-modules-platform-management-5DJoQkx2.mjs.map
|