@acorex/modules 20.2.4-next.3 → 20.2.4-next.5
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/common/index.d.ts +19 -1
- package/fesm2022/acorex-modules-application-management.mjs +24 -214
- package/fesm2022/acorex-modules-application-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-C3KbvhSU.mjs → acorex-modules-auth-acorex-modules-auth-BbO_ea5W.mjs} +10 -10
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-C3KbvhSU.mjs.map → acorex-modules-auth-acorex-modules-auth-BbO_ea5W.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-app-chooser.component-1rAktuKq.mjs → acorex-modules-auth-app-chooser.component-y0HLrwJM.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-app-chooser.component-1rAktuKq.mjs.map → acorex-modules-auth-app-chooser.component-y0HLrwJM.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-Bq2itSg_.mjs → acorex-modules-auth-login.module-1U_5UgDs.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-Bq2itSg_.mjs.map → acorex-modules-auth-login.module-1U_5UgDs.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-master.layout-DONbu77t.mjs → acorex-modules-auth-master.layout-DGsAGhOH.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-master.layout-DONbu77t.mjs.map → acorex-modules-auth-master.layout-DGsAGhOH.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-oauth-callback.component-BgzmfTlY.mjs → acorex-modules-auth-oauth-callback.component-CPHBV5bA.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-oauth-callback.component-BgzmfTlY.mjs.map → acorex-modules-auth-oauth-callback.component-CPHBV5bA.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-BuGTsfLH.mjs → acorex-modules-auth-password.component-C85NgQxA.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-BuGTsfLH.mjs.map → acorex-modules-auth-password.component-C85NgQxA.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-B9LqFrEG.mjs → acorex-modules-auth-password.component-CF3ReHyw.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-B9LqFrEG.mjs.map → acorex-modules-auth-password.component-CF3ReHyw.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-833kPM6o.mjs → acorex-modules-auth-routes-BJh0Fwpy.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-833kPM6o.mjs.map → acorex-modules-auth-routes-BJh0Fwpy.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-BS1Pcbxp.mjs → acorex-modules-auth-two-factor.module-Bsh2_A5L.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-BS1Pcbxp.mjs.map → acorex-modules-auth-two-factor.module-Bsh2_A5L.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-user-sessions.component-BXHfWAbP.mjs → acorex-modules-auth-user-sessions.component-ChMkstLg.mjs} +3 -3
- package/fesm2022/acorex-modules-auth-user-sessions.component-ChMkstLg.mjs.map +1 -0
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-common.mjs +2695 -1288
- package/fesm2022/acorex-modules-common.mjs.map +1 -1
- package/fesm2022/{acorex-modules-customer-management-acorex-modules-customer-management-OQ1bNJgq.mjs → acorex-modules-customer-management-acorex-modules-customer-management-DZBixdOT.mjs} +33 -12
- package/fesm2022/acorex-modules-customer-management-acorex-modules-customer-management-DZBixdOT.mjs.map +1 -0
- package/fesm2022/{acorex-modules-customer-management-activity.entity-DMe1FSzX.mjs → acorex-modules-customer-management-activity.entity-By32mnXN.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-activity.entity-DMe1FSzX.mjs.map → acorex-modules-customer-management-activity.entity-By32mnXN.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-customer-segment.entity-BwaPguXv.mjs → acorex-modules-customer-management-customer-segment.entity-CjFYqTMc.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-customer-segment.entity-BwaPguXv.mjs.map → acorex-modules-customer-management-customer-segment.entity-CjFYqTMc.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-customer-type.entity--593B7S-.mjs → acorex-modules-customer-management-customer-type.entity-Bk_Ng_DS.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-customer-type.entity--593B7S-.mjs.map → acorex-modules-customer-management-customer-type.entity-Bk_Ng_DS.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-customer.entity-Bh9tz06I.mjs → acorex-modules-customer-management-customer.entity-rUNC9glL.mjs} +51 -57
- package/fesm2022/acorex-modules-customer-management-customer.entity-rUNC9glL.mjs.map +1 -0
- package/fesm2022/{acorex-modules-customer-management-deal-contact-role.entity-CZIIOqbm.mjs → acorex-modules-customer-management-deal-contact-role.entity-BWX44lzi.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-deal-contact-role.entity-CZIIOqbm.mjs.map → acorex-modules-customer-management-deal-contact-role.entity-BWX44lzi.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-lead.entity-DGtsH0mF.mjs → acorex-modules-customer-management-lead.entity-B3gv0YnT.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-lead.entity-DGtsH0mF.mjs.map → acorex-modules-customer-management-lead.entity-B3gv0YnT.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-lifecycle-stage.entity-BAsoYXzc.mjs → acorex-modules-customer-management-lifecycle-stage.entity-cs1hb_Ro.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-lifecycle-stage.entity-BAsoYXzc.mjs.map → acorex-modules-customer-management-lifecycle-stage.entity-cs1hb_Ro.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-opportunity-stage.entity-CwWixlpD.mjs → acorex-modules-customer-management-opportunity-stage.entity-C-opdmDW.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-opportunity-stage.entity-CwWixlpD.mjs.map → acorex-modules-customer-management-opportunity-stage.entity-C-opdmDW.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-opportunity.entity-U0QaZb0W.mjs → acorex-modules-customer-management-opportunity.entity-D5n_4xgK.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-opportunity.entity-U0QaZb0W.mjs.map → acorex-modules-customer-management-opportunity.entity-D5n_4xgK.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-sales-pipeline.entity-BKl_WTld.mjs → acorex-modules-customer-management-sales-pipeline.entity-AeLhcil2.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-sales-pipeline.entity-BKl_WTld.mjs.map → acorex-modules-customer-management-sales-pipeline.entity-AeLhcil2.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-customer-management-sales-territory.entity-DKV0CYPg.mjs → acorex-modules-customer-management-sales-territory.entity-uK9N7p_k.mjs} +2 -2
- package/fesm2022/{acorex-modules-customer-management-sales-territory.entity-DKV0CYPg.mjs.map → acorex-modules-customer-management-sales-territory.entity-uK9N7p_k.mjs.map} +1 -1
- package/fesm2022/acorex-modules-customer-management.mjs +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs +1 -1
- package/fesm2022/acorex-modules-dashboard-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-data-management.mjs +3 -3
- package/fesm2022/acorex-modules-data-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-document-management-acorex-modules-document-management-uQnZ0m0T.mjs → acorex-modules-document-management-acorex-modules-document-management-BraIQGrY.mjs} +25 -24
- package/fesm2022/acorex-modules-document-management-acorex-modules-document-management-BraIQGrY.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-attachment-widget.component-Be8WgyUR.mjs → acorex-modules-document-management-attachment-widget.component-Dp1ioMjR.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-attachment-widget.component-Be8WgyUR.mjs.map → acorex-modules-document-management-attachment-widget.component-Dp1ioMjR.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-create-folder-dialog.component-BlyK5a50.mjs → acorex-modules-document-management-create-folder-dialog.component-C1Lvxwwf.mjs} +3 -3
- package/fesm2022/acorex-modules-document-management-create-folder-dialog.component-C1Lvxwwf.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-details-view.component-BlTJ_p5m.mjs → acorex-modules-document-management-details-view.component-C7x2n-uL.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-details-view.component-BlTJ_p5m.mjs.map → acorex-modules-document-management-details-view.component-C7x2n-uL.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-document-signature-popup.component-BONQz9u3.mjs → acorex-modules-document-management-document-signature-popup.component-DJMLGeBo.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-document-signature-popup.component-BONQz9u3.mjs.map → acorex-modules-document-management-document-signature-popup.component-DJMLGeBo.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-B1CoE7aP.mjs → acorex-modules-document-management-drive-choose.component-BiApSZ5Z.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-drive-choose.component-B1CoE7aP.mjs.map → acorex-modules-document-management-drive-choose.component-BiApSZ5Z.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-drive.component-I5pzEVVg.mjs → acorex-modules-document-management-drive.component-C3LZf1EE.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-drive.component-I5pzEVVg.mjs.map → acorex-modules-document-management-drive.component-C3LZf1EE.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-large-icons-view.component-9GtpGvk4.mjs → acorex-modules-document-management-large-icons-view.component-CUox2dHw.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-large-icons-view.component-9GtpGvk4.mjs.map → acorex-modules-document-management-large-icons-view.component-CUox2dHw.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-ByBZUD_u.mjs → acorex-modules-document-management-large-tiles-view.component-CPaqX_Gj.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-large-tiles-view.component-ByBZUD_u.mjs.map → acorex-modules-document-management-large-tiles-view.component-CPaqX_Gj.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-link-dialog.component-DKOod11R.mjs → acorex-modules-document-management-link-dialog.component-DM1Djews.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-link-dialog.component-DM1Djews.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-list-view.component-ClW5GdHG.mjs → acorex-modules-document-management-list-view.component-DHR1nZii.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-list-view.component-ClW5GdHG.mjs.map → acorex-modules-document-management-list-view.component-DHR1nZii.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CljbPHm-.mjs → acorex-modules-document-management-permission-definition.provider-SLETM1r-.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-permission-definition.provider-CljbPHm-.mjs.map → acorex-modules-document-management-permission-definition.provider-SLETM1r-.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-rename-node-dialog.component-xeY0XzAG.mjs → acorex-modules-document-management-rename-node-dialog.component-CLkMT7A9.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-rename-node-dialog.component-xeY0XzAG.mjs.map → acorex-modules-document-management-rename-node-dialog.component-CLkMT7A9.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-share-dialog.component-mBEu2KpG.mjs → acorex-modules-document-management-share-dialog.component-BNN3t8AV.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-share-dialog.component-BNN3t8AV.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-share-email-dialog.component-CI4SKdjk.mjs → acorex-modules-document-management-share-email-dialog.component-8WAUtRyJ.mjs} +2 -2
- package/fesm2022/acorex-modules-document-management-share-email-dialog.component-8WAUtRyJ.mjs.map +1 -0
- package/fesm2022/{acorex-modules-document-management-small-icons-view.component--GP3AYPi.mjs → acorex-modules-document-management-small-icons-view.component-DFxM61cD.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-small-icons-view.component--GP3AYPi.mjs.map → acorex-modules-document-management-small-icons-view.component-DFxM61cD.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-BVxR6ndq.mjs → acorex-modules-document-management-small-tiles-view.component-DhzxwNEY.mjs} +2 -2
- package/fesm2022/{acorex-modules-document-management-small-tiles-view.component-BVxR6ndq.mjs.map → acorex-modules-document-management-small-tiles-view.component-DhzxwNEY.mjs.map} +1 -1
- package/fesm2022/acorex-modules-document-management.mjs +1 -1
- package/fesm2022/{acorex-modules-form-template-management-acorex-modules-form-template-management-COVNekIY.mjs → acorex-modules-form-template-management-acorex-modules-form-template-management-BhU14Qou.mjs} +9 -9
- package/fesm2022/acorex-modules-form-template-management-acorex-modules-form-template-management-BhU14Qou.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-permission-definition.provider-BEkbbQH2.mjs → acorex-modules-form-template-management-permission-definition.provider-D4lGFRCA.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-permission-definition.provider-BEkbbQH2.mjs.map → acorex-modules-form-template-management-permission-definition.provider-D4lGFRCA.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-form-template-management-settings.provider-DSI7cmrW.mjs → acorex-modules-form-template-management-settings.provider-499Y4rLb.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-settings.provider-DSI7cmrW.mjs.map → acorex-modules-form-template-management-settings.provider-499Y4rLb.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-form-template-management-template-picker.component-5n_kQMuQ.mjs → acorex-modules-form-template-management-template-picker.component-2EkzMuIy.mjs} +2 -2
- package/fesm2022/acorex-modules-form-template-management-template-picker.component-2EkzMuIy.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-template-widget-edit.component-BtCYeGB-.mjs → acorex-modules-form-template-management-template-widget-edit.component-DwgbgFrf.mjs} +2 -2
- package/fesm2022/acorex-modules-form-template-management-template-widget-edit.component-DwgbgFrf.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-template.entity-Cm-AVAF_.mjs → acorex-modules-form-template-management-template.entity-D_14HgMr.mjs} +85 -87
- package/fesm2022/acorex-modules-form-template-management-template.entity-D_14HgMr.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-viewer-popup.component-C8TC42DL.mjs → acorex-modules-form-template-management-viewer-popup.component-BLgx_xby.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-viewer-popup.component-C8TC42DL.mjs.map → acorex-modules-form-template-management-viewer-popup.component-BLgx_xby.mjs.map} +1 -1
- package/fesm2022/acorex-modules-form-template-management.mjs +1 -1
- package/fesm2022/{acorex-modules-help-desk-acorex-modules-help-desk-UzQZBc6W.mjs → acorex-modules-help-desk-acorex-modules-help-desk-BvDYd3fI.mjs} +3 -3
- package/fesm2022/{acorex-modules-help-desk-acorex-modules-help-desk-UzQZBc6W.mjs.map → acorex-modules-help-desk-acorex-modules-help-desk-BvDYd3fI.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-help-desk-capture-screen.component-C4veMiCB.mjs → acorex-modules-help-desk-capture-screen.component-DH_FG8iE.mjs} +2 -2
- package/fesm2022/{acorex-modules-help-desk-capture-screen.component-C4veMiCB.mjs.map → acorex-modules-help-desk-capture-screen.component-DH_FG8iE.mjs.map} +1 -1
- package/fesm2022/acorex-modules-help-desk.mjs +1 -1
- package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-1PmjMC7i.mjs +444 -0
- package/fesm2022/acorex-modules-human-capital-management-acorex-modules-human-capital-management-1PmjMC7i.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-employee-skill.entity-DyOHJWW_.mjs +153 -0
- package/fesm2022/acorex-modules-human-capital-management-employee-skill.entity-DyOHJWW_.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-employee.entity-5J-FoLiT.mjs +160 -0
- package/fesm2022/acorex-modules-human-capital-management-employee.entity-5J-FoLiT.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-employment-type.entity-DFpRtSOh.mjs +97 -0
- package/fesm2022/acorex-modules-human-capital-management-employment-type.entity-DFpRtSOh.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-position-assignment.entity-DuNvJq-k.mjs +196 -0
- package/fesm2022/acorex-modules-human-capital-management-position-assignment.entity-DuNvJq-k.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-settings.provider-rRaBaVeh.mjs +17 -0
- package/fesm2022/acorex-modules-human-capital-management-settings.provider-rRaBaVeh.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-skill-level.entity-0ZzRent7.mjs +52 -0
- package/fesm2022/acorex-modules-human-capital-management-skill-level.entity-0ZzRent7.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management-skill.entity-Dd7p11vj.mjs +82 -0
- package/fesm2022/acorex-modules-human-capital-management-skill.entity-Dd7p11vj.mjs.map +1 -0
- package/fesm2022/acorex-modules-human-capital-management.mjs +2 -0
- package/fesm2022/acorex-modules-human-capital-management.mjs.map +1 -0
- package/fesm2022/acorex-modules-identifier-management.mjs +2 -1
- package/fesm2022/acorex-modules-identifier-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-log-management.mjs +21 -21
- package/fesm2022/acorex-modules-log-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-organization-management-add-item.component-DkXcoyHa.mjs → acorex-modules-organization-management-add-item.component-B7AYaZrD.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-add-item.component-B7AYaZrD.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-division.entity-Dg68kBto.mjs → acorex-modules-organization-management-branch.entity-bajoE99c.mjs} +81 -179
- package/fesm2022/acorex-modules-organization-management-branch.entity-bajoE99c.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-employment-type.entity-Dw3TLMtD.mjs → acorex-modules-organization-management-department.entity-BkEbajpN.mjs} +67 -16
- package/fesm2022/acorex-modules-organization-management-department.entity-BkEbajpN.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-branch.entity-Dres_jqx.mjs → acorex-modules-organization-management-division.entity-Cds8jkR5.mjs} +162 -186
- package/fesm2022/acorex-modules-organization-management-division.entity-Cds8jkR5.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-org-chart.page-DuyhYwnh.mjs → acorex-modules-organization-management-org-chart.page-5fHaWyGW.mjs} +6 -4
- package/fesm2022/acorex-modules-organization-management-org-chart.page-5fHaWyGW.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-role.entity-DVoKtduv.mjs → acorex-modules-organization-management-role.entity-Cz8VrdMl.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-role.entity-Cz8VrdMl.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-management-team.entity-D6iNAU4g.mjs → acorex-modules-organization-management-team.entity-CNYXXHM7.mjs} +3 -3
- package/fesm2022/acorex-modules-organization-management-team.entity-CNYXXHM7.mjs.map +1 -0
- package/fesm2022/acorex-modules-organization-management.mjs +89 -329
- package/fesm2022/acorex-modules-organization-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-party-management-acorex-modules-party-management-BY6hXmhQ.mjs → acorex-modules-party-management-acorex-modules-party-management-DJNXviBH.mjs} +8 -7
- package/fesm2022/acorex-modules-party-management-acorex-modules-party-management-DJNXviBH.mjs.map +1 -0
- package/fesm2022/{acorex-modules-party-management-industry.entity-CALiUOAF.mjs → acorex-modules-party-management-industry.entity-D01GclFe.mjs} +2 -2
- package/fesm2022/{acorex-modules-party-management-industry.entity-CALiUOAF.mjs.map → acorex-modules-party-management-industry.entity-D01GclFe.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-party-management-party-identifier-type.entity-BTkKl8Ka.mjs → acorex-modules-party-management-party-identifier-type.entity-DoXx0nyF.mjs} +2 -2
- package/fesm2022/{acorex-modules-party-management-party-identifier-type.entity-BTkKl8Ka.mjs.map → acorex-modules-party-management-party-identifier-type.entity-DoXx0nyF.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-party-management-party-identifier.entity-eDKHu-Ek.mjs → acorex-modules-party-management-party-identifier.entity-_tLoTcUC.mjs} +2 -2
- package/fesm2022/{acorex-modules-party-management-party-identifier.entity-eDKHu-Ek.mjs.map → acorex-modules-party-management-party-identifier.entity-_tLoTcUC.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-party-management-party-relationship.entity-BNTNx-oY.mjs → acorex-modules-party-management-party-relationship.entity-B-hI_r6b.mjs} +2 -2
- package/fesm2022/{acorex-modules-party-management-party-relationship.entity-BNTNx-oY.mjs.map → acorex-modules-party-management-party-relationship.entity-B-hI_r6b.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-party-management-party-role.entity-iETQVgTK.mjs → acorex-modules-party-management-party-role.entity-Dxs6yXKd.mjs} +6 -2
- package/fesm2022/acorex-modules-party-management-party-role.entity-Dxs6yXKd.mjs.map +1 -0
- package/fesm2022/{acorex-modules-party-management-party.entity-lRpTfdRp.mjs → acorex-modules-party-management-party.entity-BFEy4rXT.mjs} +83 -20
- package/fesm2022/acorex-modules-party-management-party.entity-BFEy4rXT.mjs.map +1 -0
- package/fesm2022/acorex-modules-party-management.mjs +1 -1
- package/fesm2022/{acorex-modules-report-management-report-create-root.component-L-7aG8op.mjs → acorex-modules-report-management-report-create-root.component-DAOMkt_F.mjs} +2 -2
- package/fesm2022/acorex-modules-report-management-report-create-root.component-DAOMkt_F.mjs.map +1 -0
- package/fesm2022/acorex-modules-report-management.mjs +10 -6
- package/fesm2022/acorex-modules-report-management.mjs.map +1 -1
- package/fesm2022/{acorex-modules-task-management-task-board.page-DsaCXemI.mjs → acorex-modules-task-management-task-board.page-zbl3g-sI.mjs} +63 -55
- package/fesm2022/acorex-modules-task-management-task-board.page-zbl3g-sI.mjs.map +1 -0
- package/fesm2022/acorex-modules-task-management.mjs +283 -151
- package/fesm2022/acorex-modules-task-management.mjs.map +1 -1
- package/form-template-management/index.d.ts +1 -1
- package/human-capital-management/index.d.ts +97 -0
- package/identifier-management/index.d.ts +1 -1
- package/organization-management/index.d.ts +73 -184
- package/package.json +5 -1
- package/party-management/index.d.ts +1 -0
- package/task-management/index.d.ts +3 -1
- package/fesm2022/acorex-modules-auth-user-sessions.component-BXHfWAbP.mjs.map +0 -1
- package/fesm2022/acorex-modules-customer-management-acorex-modules-customer-management-OQ1bNJgq.mjs.map +0 -1
- package/fesm2022/acorex-modules-customer-management-customer.entity-Bh9tz06I.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-acorex-modules-document-management-uQnZ0m0T.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-create-folder-dialog.component-BlyK5a50.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-link-dialog.component-DKOod11R.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-share-dialog.component-mBEu2KpG.mjs.map +0 -1
- package/fesm2022/acorex-modules-document-management-share-email-dialog.component-CI4SKdjk.mjs.map +0 -1
- package/fesm2022/acorex-modules-form-template-management-acorex-modules-form-template-management-COVNekIY.mjs.map +0 -1
- package/fesm2022/acorex-modules-form-template-management-template-picker.component-5n_kQMuQ.mjs.map +0 -1
- package/fesm2022/acorex-modules-form-template-management-template-widget-edit.component-BtCYeGB-.mjs.map +0 -1
- package/fesm2022/acorex-modules-form-template-management-template.entity-Cm-AVAF_.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-add-item.component-DkXcoyHa.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-branch.entity-Dres_jqx.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-department.entity-Cot-9HVC.mjs +0 -483
- package/fesm2022/acorex-modules-organization-management-department.entity-Cot-9HVC.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-division.entity-Dg68kBto.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-employee-skill.entity-DoQcCwQz.mjs +0 -296
- package/fesm2022/acorex-modules-organization-management-employee-skill.entity-DoQcCwQz.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-employee.entity-BuvyXqnP.mjs +0 -573
- package/fesm2022/acorex-modules-organization-management-employee.entity-BuvyXqnP.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-employment-type.entity-Dw3TLMtD.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-org-chart.page-DuyhYwnh.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-role.entity-DVoKtduv.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-skill.entity-O1453j6I.mjs +0 -235
- package/fesm2022/acorex-modules-organization-management-skill.entity-O1453j6I.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-management-team.entity-D6iNAU4g.mjs.map +0 -1
- package/fesm2022/acorex-modules-party-management-acorex-modules-party-management-BY6hXmhQ.mjs.map +0 -1
- package/fesm2022/acorex-modules-party-management-party-role.entity-iETQVgTK.mjs.map +0 -1
- package/fesm2022/acorex-modules-party-management-party.entity-lRpTfdRp.mjs.map +0 -1
- package/fesm2022/acorex-modules-report-management-report-create-root.component-L-7aG8op.mjs.map +0 -1
- package/fesm2022/acorex-modules-task-management-task-board.page-DsaCXemI.mjs.map +0 -1
|
@@ -1,32 +1,34 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import * as i0 from '@angular/core';
|
|
4
|
-
import { inject, Injectable, input, signal, ViewEncapsulation, Component, NgModule, InjectionToken, HostListener, computed, Injector, runInInjectionContext, viewChild } from '@angular/core';
|
|
5
|
-
import { firstValueFrom, Subject } from 'rxjs';
|
|
1
|
+
import { AXP_PERMISSION_DEFINITION_PROVIDER, AXPSessionService } from '@acorex/platform/auth';
|
|
2
|
+
import { AXPEntityCommandScope, createQueryView, AXPRefreshEvent, createAllQueryView, AXPEntityQueryType, AXPSettingService, AXPSearchService, AXPLockService, AXPHomePageService, AXPSearchCommandProvider, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex/platform/common';
|
|
6
3
|
import * as i1$2 from '@acorex/platform/core';
|
|
7
|
-
import {
|
|
4
|
+
import { AXPActivityLogService, AXPExpressionEvaluatorService, getSmart, AXPPlatformScope, AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, AXPSystemActionType, extractTextFromHtml, AXPDataGenerator } from '@acorex/platform/core';
|
|
5
|
+
import { AXPWidgetsModule } from '@acorex/platform/widgets';
|
|
6
|
+
import * as i0 from '@angular/core';
|
|
7
|
+
import { inject, Injectable, NgModule, Injector, runInInjectionContext, input, signal, ViewEncapsulation, Component, InjectionToken, HostListener, computed, viewChild } from '@angular/core';
|
|
8
|
+
import { ensureListActions, actionExists, AXPEntityDefinitionRegistryService, AXP_ENTITY_ACTION_PLUGIN, AXMEntityCrudServiceImpl, entityMasterCrudActions, entityMasterDeleteAction, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_STORAGE_MIDDLEWARE, detectEntityChanges } from '@acorex/platform/layout/entity';
|
|
9
|
+
import * as i1 from '@acorex/platform/workflow';
|
|
10
|
+
import { createWorkFlowEvent, AXPWorkflowAction, AXPWorkflowModule, AXPWorkflowService } from '@acorex/platform/workflow';
|
|
11
|
+
import { AXDialogService } from '@acorex/components/dialog';
|
|
12
|
+
import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
|
|
8
13
|
import * as i4 from '@acorex/core/translation';
|
|
9
14
|
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
|
10
15
|
import { AXPWidgetsCatalog } from '@acorex/platform/layout/builder';
|
|
11
|
-
import { AXPWidgetsModule } from '@acorex/platform/widgets';
|
|
12
16
|
import * as i3 from '@angular/common';
|
|
13
17
|
import { CommonModule } from '@angular/common';
|
|
14
18
|
import * as i2 from '@acorex/components/button';
|
|
15
19
|
import { AXButtonModule } from '@acorex/components/button';
|
|
16
20
|
import { AXBasePageComponent } from '@acorex/components/page';
|
|
17
|
-
import * as i1 from '@acorex/components/decorators';
|
|
21
|
+
import * as i1$1 from '@acorex/components/decorators';
|
|
18
22
|
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
19
23
|
import * as i2$1 from '@acorex/platform/layout/components';
|
|
20
|
-
import { AXPCompareViewComponent,
|
|
21
|
-
import * as i1$1 from '@acorex/platform/workflow';
|
|
22
|
-
import { AXPWorkflowAction, AXPWorkflowModule, AXPWorkflowService } from '@acorex/platform/workflow';
|
|
24
|
+
import { AXPCompareViewComponent, AXP_EXTRA_PROPERTY_TYPES, AXPComponentSlotModule } from '@acorex/platform/layout/components';
|
|
23
25
|
import { AXPopupService } from '@acorex/components/popup';
|
|
24
|
-
import { AXPEntityDefinitionRegistryService, AXP_ENTITY_STORAGE_BACKEND, detectEntityChanges, ensureListActions, actionExists, AXP_ENTITY_STORAGE_MIDDLEWARE, AXP_ENTITY_ACTION_PLUGIN, AXMEntityCrudServiceImpl, entityMasterCrudActions, entityMasterDeleteAction, AXP_ENTITY_DEFINITION_LOADER } from '@acorex/platform/layout/entity';
|
|
25
26
|
import { AXFormatService } from '@acorex/core/format';
|
|
27
|
+
import { get, set } from 'lodash-es';
|
|
28
|
+
import { provideCommandSetups } from '@acorex/platform/runtime';
|
|
26
29
|
import { AXTextBoxModule } from '@acorex/components/text-box';
|
|
30
|
+
import { Subject, firstValueFrom } from 'rxjs';
|
|
27
31
|
import { AXCalendarService } from '@acorex/core/date-time';
|
|
28
|
-
import { AXDialogService } from '@acorex/components/dialog';
|
|
29
|
-
import { provideCommandSetups } from '@acorex/platform/runtime';
|
|
30
32
|
import * as i1$3 from '@angular/forms';
|
|
31
33
|
import { FormsModule } from '@angular/forms';
|
|
32
34
|
import * as i4$1 from '@acorex/components/form';
|
|
@@ -39,1187 +41,1956 @@ import * as i7 from '@acorex/components/text-area';
|
|
|
39
41
|
import { AXTextAreaModule } from '@acorex/components/text-area';
|
|
40
42
|
import { AXValidationModule } from '@acorex/core/validation';
|
|
41
43
|
|
|
42
|
-
const
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
44
|
+
const AXPWidgetsList = {
|
|
45
|
+
Editors: {
|
|
46
|
+
DocumentAttachment: 'document-attachment-editor',
|
|
47
|
+
TagBox: 'tagable-editor',
|
|
48
|
+
CheckBox: 'checkbox-editor',
|
|
49
|
+
ColorBox: 'color-editor',
|
|
50
|
+
DateTimeBox: 'date-time-editor',
|
|
51
|
+
Direction: 'direction',
|
|
52
|
+
LargeTextBox: 'large-text-editor',
|
|
53
|
+
NumberBox: 'number-editor',
|
|
54
|
+
UnitValueBox: 'number-unit-editor',
|
|
55
|
+
PasswordBox: 'password-editor',
|
|
56
|
+
QueryBuilder: 'query-builder-editor',
|
|
57
|
+
RichText: 'rich-text-editor',
|
|
58
|
+
SelectBox: 'select-editor',
|
|
59
|
+
SelectionList: 'selection-list-editor',
|
|
60
|
+
TextBox: 'text-editor',
|
|
61
|
+
InlineDataTable: 'table-editor',
|
|
62
|
+
ToggleSwitch: 'toggle-editor',
|
|
63
|
+
FileTypeExtension: 'file-type-extension',
|
|
64
|
+
MapBox: 'map',
|
|
65
|
+
MediaGallery: 'gallery',
|
|
66
|
+
SignatureBox: 'signature',
|
|
67
|
+
LookupBox: 'lookup-editor',
|
|
68
|
+
},
|
|
69
|
+
Layouts: {
|
|
70
|
+
BlockLayout: 'block-layout',
|
|
71
|
+
RepeaterLayout: 'repeater-layout',
|
|
72
|
+
TextBlockLayout: 'text-block-layout',
|
|
73
|
+
FormField: 'form-field',
|
|
74
|
+
},
|
|
75
|
+
Actions: {
|
|
76
|
+
ActionButton: 'button-action',
|
|
77
|
+
},
|
|
78
|
+
Advanced: {
|
|
79
|
+
QRCode: 'qrcode',
|
|
80
|
+
},
|
|
81
|
+
Templates: {
|
|
82
|
+
Designer: 'template-designer',
|
|
52
83
|
},
|
|
53
|
-
entities: {},
|
|
54
84
|
};
|
|
55
85
|
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
const
|
|
64
|
-
const
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
return;
|
|
86
|
+
const archivePlugin = {
|
|
87
|
+
name: 'archive',
|
|
88
|
+
order: 65,
|
|
89
|
+
apply: (ctx) => {
|
|
90
|
+
ensureListActions(ctx);
|
|
91
|
+
//#region ---- Add isArchived Property ----
|
|
92
|
+
// Ensure settings group exists
|
|
93
|
+
const groupId = 'settings';
|
|
94
|
+
const groups = ctx.groups.list() ?? [];
|
|
95
|
+
if (!groups.some((g) => g.id === groupId)) {
|
|
96
|
+
ctx.groups.add({ id: groupId, title: '@general:terms.settings' });
|
|
68
97
|
}
|
|
69
|
-
//
|
|
70
|
-
const
|
|
71
|
-
if (
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
98
|
+
// Add isArchived property if it doesn't exist
|
|
99
|
+
const props = ctx.properties.list();
|
|
100
|
+
if (!props.some((p) => p.name === 'isArchived')) {
|
|
101
|
+
ctx.properties.add({
|
|
102
|
+
name: 'isArchived',
|
|
103
|
+
title: '@general:terms.is-archived',
|
|
104
|
+
groupId,
|
|
105
|
+
schema: {
|
|
106
|
+
dataType: 'boolean',
|
|
107
|
+
interface: {
|
|
108
|
+
type: AXPWidgetsList.Editors.ToggleSwitch,
|
|
109
|
+
options: {
|
|
110
|
+
// Default to false (not archived)
|
|
111
|
+
defaultValue: false,
|
|
112
|
+
// trulyText: '@general:terms.archived',
|
|
113
|
+
// falsyText: '@general:terms.active',
|
|
114
|
+
negative: true,
|
|
115
|
+
nullValue: false,
|
|
116
|
+
},
|
|
80
117
|
},
|
|
81
118
|
},
|
|
82
|
-
|
|
119
|
+
validations: [],
|
|
120
|
+
options: {
|
|
121
|
+
sort: { enabled: true },
|
|
122
|
+
filter: {
|
|
123
|
+
advance: { enabled: true },
|
|
124
|
+
inline: { enabled: true }
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
});
|
|
83
128
|
}
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
}
|
|
129
|
+
// Add isArchived to columns for list view
|
|
130
|
+
const columns = ctx.columns.list() ?? [];
|
|
131
|
+
if (!columns.some((c) => c.name === 'isArchived')) {
|
|
132
|
+
ctx.columns.add({
|
|
133
|
+
name: 'isArchived',
|
|
134
|
+
title: '@general:terms.is-active',
|
|
135
|
+
width: 100,
|
|
136
|
+
sortable: true,
|
|
137
|
+
filterable: true,
|
|
138
|
+
});
|
|
139
|
+
}
|
|
140
|
+
//#endregion
|
|
141
|
+
//#region ---- Add Archive Actions ----
|
|
142
|
+
ctx.interfaces.update((i) => {
|
|
143
|
+
const archiveCmdName = 'archive-entity';
|
|
144
|
+
const restoreArchiveCmdName = 'restore-archive-entity';
|
|
145
|
+
const bulkArchiveCmdName = 'bulk-archive-entity';
|
|
146
|
+
const bulkRestoreArchiveCmdName = 'bulk-restore-archive-entity';
|
|
147
|
+
// Add archive action to list view
|
|
148
|
+
const listActions = i.master.list.actions;
|
|
149
|
+
if (!actionExists(listActions, archiveCmdName)) {
|
|
150
|
+
listActions.push({
|
|
151
|
+
title: '@general:actions.archive.title',
|
|
152
|
+
command: {
|
|
153
|
+
name: archiveCmdName,
|
|
154
|
+
options: {
|
|
155
|
+
refId: '{{ context.eval("id") }}',
|
|
156
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
157
|
+
},
|
|
158
|
+
},
|
|
159
|
+
priority: 'secondary',
|
|
160
|
+
type: 'archive',
|
|
161
|
+
scope: AXPEntityCommandScope.Individual,
|
|
162
|
+
hidden: `{{ context.eval("isArchived") }}`,
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
// Add restore archive action to list view
|
|
166
|
+
if (!actionExists(listActions, restoreArchiveCmdName)) {
|
|
167
|
+
listActions.push({
|
|
168
|
+
title: '@general:actions.restore-archive.title',
|
|
169
|
+
command: {
|
|
170
|
+
name: restoreArchiveCmdName,
|
|
171
|
+
options: {
|
|
172
|
+
refId: '{{ context.eval("id") }}',
|
|
173
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
174
|
+
},
|
|
175
|
+
},
|
|
176
|
+
priority: 'secondary',
|
|
177
|
+
type: 'update',
|
|
178
|
+
scope: AXPEntityCommandScope.Individual,
|
|
179
|
+
hidden: `{{ !context.eval("isArchived") }}`,
|
|
180
|
+
});
|
|
181
|
+
}
|
|
182
|
+
// Add bulk archive action to list view
|
|
183
|
+
if (!actionExists(listActions, bulkArchiveCmdName)) {
|
|
184
|
+
listActions.push({
|
|
185
|
+
title: '@general:actions.bulk-archive.title',
|
|
186
|
+
command: {
|
|
187
|
+
name: bulkArchiveCmdName,
|
|
188
|
+
options: {
|
|
189
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
190
|
+
},
|
|
191
|
+
},
|
|
192
|
+
priority: 'secondary',
|
|
193
|
+
type: 'archive',
|
|
194
|
+
scope: AXPEntityCommandScope.Selected,
|
|
195
|
+
});
|
|
196
|
+
}
|
|
197
|
+
// Add bulk restore archive action to list view
|
|
198
|
+
if (!actionExists(listActions, bulkRestoreArchiveCmdName)) {
|
|
199
|
+
listActions.push({
|
|
200
|
+
title: '@general:actions.bulk-restore-archive.title',
|
|
201
|
+
command: {
|
|
202
|
+
name: bulkRestoreArchiveCmdName,
|
|
203
|
+
options: {
|
|
204
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
205
|
+
},
|
|
206
|
+
},
|
|
207
|
+
priority: 'secondary',
|
|
208
|
+
type: 'update',
|
|
209
|
+
scope: AXPEntityCommandScope.Selected,
|
|
210
|
+
});
|
|
211
|
+
}
|
|
212
|
+
// Add archive action to single view
|
|
213
|
+
const singleActions = i.master.single.actions;
|
|
214
|
+
if (!actionExists(singleActions, archiveCmdName)) {
|
|
215
|
+
singleActions.push({
|
|
216
|
+
title: '@general:actions.archive.title',
|
|
217
|
+
command: {
|
|
218
|
+
name: archiveCmdName,
|
|
219
|
+
options: {
|
|
220
|
+
refId: '{{ context.eval("id") }}',
|
|
221
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
222
|
+
},
|
|
223
|
+
},
|
|
224
|
+
priority: 'secondary',
|
|
225
|
+
type: 'archive',
|
|
226
|
+
scope: AXPEntityCommandScope.Individual,
|
|
227
|
+
hidden: `{{ context.eval("isArchived") }}`,
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
// Add restore archive action to single view
|
|
231
|
+
if (!actionExists(singleActions, restoreArchiveCmdName)) {
|
|
232
|
+
singleActions.push({
|
|
233
|
+
title: '@general:actions.restore-archive.title',
|
|
234
|
+
command: {
|
|
235
|
+
name: restoreArchiveCmdName,
|
|
236
|
+
options: {
|
|
237
|
+
refId: '{{ context.eval("id") }}',
|
|
238
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
239
|
+
},
|
|
240
|
+
},
|
|
241
|
+
priority: 'secondary',
|
|
242
|
+
type: 'update',
|
|
243
|
+
scope: AXPEntityCommandScope.Individual,
|
|
244
|
+
hidden: `{{ !context.eval("isArchived") }}`,
|
|
245
|
+
});
|
|
246
|
+
}
|
|
247
|
+
return i;
|
|
248
|
+
});
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region ---- Update Interface Layouts ----
|
|
251
|
+
// Ensure update view includes isArchived
|
|
252
|
+
ctx.interfaces.master.modify.update((update) => {
|
|
253
|
+
const next = update ?? { sections: [], properties: [] };
|
|
254
|
+
next.sections = next.sections ?? [];
|
|
255
|
+
if (!next.sections.some((s) => s.id === groupId)) {
|
|
256
|
+
next.sections.push({ id: groupId });
|
|
257
|
+
}
|
|
258
|
+
next.properties = next.properties ?? [];
|
|
259
|
+
if (!next.properties.some((p) => p.name === 'isArchived')) {
|
|
260
|
+
next.properties.push({
|
|
261
|
+
name: 'isArchived',
|
|
262
|
+
layout: {
|
|
263
|
+
positions: { lg: { colSpan: 6, order: 90 } },
|
|
264
|
+
},
|
|
265
|
+
});
|
|
266
|
+
}
|
|
267
|
+
return next;
|
|
268
|
+
});
|
|
269
|
+
// Ensure single view includes isArchived
|
|
270
|
+
ctx.interfaces.master.single.update((single) => {
|
|
271
|
+
const next = single ?? { title: ctx.entity.title, sections: [], properties: [] };
|
|
272
|
+
next.sections = next.sections ?? [];
|
|
273
|
+
if (!next.sections.some((s) => s.id === groupId)) {
|
|
274
|
+
next.sections.push({ id: groupId });
|
|
275
|
+
}
|
|
276
|
+
next.properties = next.properties ?? [];
|
|
277
|
+
if (!next.properties.some((p) => p.name === 'isArchived')) {
|
|
278
|
+
next.properties.push({
|
|
279
|
+
name: 'isArchived',
|
|
280
|
+
layout: {
|
|
281
|
+
positions: { lg: { colSpan: 6, order: 90 } },
|
|
282
|
+
},
|
|
283
|
+
});
|
|
284
|
+
}
|
|
285
|
+
return next;
|
|
286
|
+
});
|
|
287
|
+
// Add archive view to show only archived items
|
|
288
|
+
ctx.interfaces.master.list.update((list) => {
|
|
289
|
+
const next = list ?? { actions: [], views: [] };
|
|
290
|
+
next.views = next.views ?? [];
|
|
291
|
+
// Check if archive view already exists
|
|
292
|
+
if (!next.views.some((v) => v.name === 'archived')) {
|
|
293
|
+
next.views.push(createQueryView('archived', '@general:terms.archived', false, {
|
|
294
|
+
conditions: [
|
|
295
|
+
{
|
|
296
|
+
name: 'isArchived',
|
|
297
|
+
operator: { type: 'equal' },
|
|
298
|
+
value: true,
|
|
299
|
+
hidden: true
|
|
300
|
+
},
|
|
301
|
+
],
|
|
302
|
+
sorts: [
|
|
303
|
+
{ name: 'archivedAt', dir: 'desc' },
|
|
304
|
+
{ name: 'title', dir: 'asc' },
|
|
305
|
+
],
|
|
306
|
+
}));
|
|
307
|
+
}
|
|
308
|
+
return next;
|
|
309
|
+
});
|
|
310
|
+
//#endregion
|
|
311
|
+
},
|
|
312
|
+
};
|
|
119
313
|
|
|
120
|
-
|
|
314
|
+
const AXPEntityArchivedEvent = createWorkFlowEvent('[Entity] Archived');
|
|
315
|
+
class AXPEntityArchiveAction extends AXPWorkflowAction {
|
|
121
316
|
constructor() {
|
|
122
317
|
super(...arguments);
|
|
123
|
-
this.
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
// icon: RootConfig.entities.template.icon,
|
|
128
|
-
// description: 'Create a new form template for designing reusable forms.', // Added description
|
|
129
|
-
// commands: {
|
|
130
|
-
// 'create-entity': {
|
|
131
|
-
// entity: `${RootConfig.module.name}.${RootConfig.entities.template.name}`,
|
|
132
|
-
// },
|
|
133
|
-
// },
|
|
134
|
-
// }
|
|
135
|
-
];
|
|
136
|
-
}
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
var AXMLockSystemSettings;
|
|
140
|
-
(function (AXMLockSystemSettings) {
|
|
141
|
-
AXMLockSystemSettings["LockSystem"] = "general:lock-system:lock";
|
|
142
|
-
})(AXMLockSystemSettings || (AXMLockSystemSettings = {}));
|
|
143
|
-
|
|
144
|
-
class AXMSettingProvider {
|
|
145
|
-
constructor(injector) {
|
|
146
|
-
this.injector = injector;
|
|
147
|
-
this.translateService = this.injector.get(AXTranslationService);
|
|
318
|
+
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
319
|
+
this.dialogService = inject(AXDialogService);
|
|
320
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
|
321
|
+
this.translationService = inject(AXTranslationService);
|
|
148
322
|
}
|
|
149
|
-
async
|
|
150
|
-
const
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
323
|
+
async execute(context) {
|
|
324
|
+
const refId = context.getVariable('options.refId');
|
|
325
|
+
const refType = context.getVariable('options.refType');
|
|
326
|
+
if (!refId || !refType) {
|
|
327
|
+
throw new Error('Missing required parameters: refId and refType');
|
|
328
|
+
}
|
|
329
|
+
const [moduleName, entityName] = refType.split('.');
|
|
330
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
331
|
+
// Show confirmation dialog
|
|
332
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@general:actions.archive.confirm.title'), await this.translationService.translateAsync('@general:actions.archive.confirm.message'), 'warning', 'horizontal', false, 'cancel');
|
|
333
|
+
if (!dialogResult.result) {
|
|
334
|
+
context.setOutput('isCanceled', true);
|
|
335
|
+
context.setOutput('error', 'Operation cancelled by user');
|
|
154
336
|
return;
|
|
155
337
|
}
|
|
156
|
-
//
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
isInherited: true,
|
|
162
|
-
defaultValue: false,
|
|
163
|
-
valueTransforms: objectKeyValueTransforms('id'),
|
|
164
|
-
widget: {
|
|
165
|
-
type: AXPWidgetsCatalog.toggle,
|
|
166
|
-
options: {
|
|
167
|
-
label: null,
|
|
168
|
-
}
|
|
169
|
-
},
|
|
170
|
-
description: await trans('general.lock-system.lock.description'),
|
|
338
|
+
// Show loading dialog
|
|
339
|
+
const loadingDialog = this.loadingDialog.show({
|
|
340
|
+
title: await this.translationService.translateAsync('@general:actions.archive.confirm.processing'),
|
|
341
|
+
mode: 'indeterminate',
|
|
342
|
+
status: 'Archiving...',
|
|
171
343
|
});
|
|
344
|
+
try {
|
|
345
|
+
// Get the current entity data
|
|
346
|
+
const currentData = await this.getEntityData(refType, refId);
|
|
347
|
+
// Prepare archive data
|
|
348
|
+
const archiveData = this.prepareArchiveData(currentData);
|
|
349
|
+
// Update the entity to mark it as archived
|
|
350
|
+
if (entityDefinition.commands?.update) {
|
|
351
|
+
const updateExec = entityDefinition.commands.update.execute;
|
|
352
|
+
await updateExec(archiveData);
|
|
353
|
+
context.setOutput('id', refId);
|
|
354
|
+
context.setOutput('isCanceled', false);
|
|
355
|
+
// Set refresh metadata
|
|
356
|
+
if (entityDefinition.parentKey && currentData[entityDefinition.parentKey]) {
|
|
357
|
+
context.setVariable('meta', { refreshTargetId: currentData[entityDefinition.parentKey] });
|
|
358
|
+
}
|
|
359
|
+
}
|
|
360
|
+
else {
|
|
361
|
+
throw new Error('Entity does not support update operation');
|
|
362
|
+
}
|
|
363
|
+
}
|
|
364
|
+
catch (error) {
|
|
365
|
+
console.error('Archive operation failed:', error);
|
|
366
|
+
context.setOutput('error', error instanceof Error ? error.message : 'Unknown error');
|
|
367
|
+
context.setOutput('isCanceled', true);
|
|
368
|
+
}
|
|
369
|
+
finally {
|
|
370
|
+
loadingDialog.close();
|
|
371
|
+
}
|
|
172
372
|
}
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
373
|
+
async getEntityData(refType, refId) {
|
|
374
|
+
try {
|
|
375
|
+
// Use the entity's byKey query to get actual data
|
|
376
|
+
const [moduleName, entityName] = refType.split('.');
|
|
377
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
378
|
+
if (entityDefinition.queries?.byKey) {
|
|
379
|
+
const queryExec = entityDefinition.queries.byKey.execute;
|
|
380
|
+
return await queryExec(refId);
|
|
381
|
+
}
|
|
382
|
+
// Fallback to basic structure if no query available
|
|
383
|
+
return { id: refId };
|
|
384
|
+
}
|
|
385
|
+
catch (error) {
|
|
386
|
+
console.error('Failed to retrieve entity data:', error);
|
|
387
|
+
throw new Error(`Failed to retrieve entity data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
388
|
+
}
|
|
186
389
|
}
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
//
|
|
390
|
+
prepareArchiveData(currentData) {
|
|
391
|
+
const archiveData = { ...currentData };
|
|
392
|
+
// Set the archived flag
|
|
393
|
+
archiveData.isArchived = true;
|
|
394
|
+
// Optionally add archive timestamp
|
|
395
|
+
archiveData.archivedAt = new Date();
|
|
396
|
+
return archiveData;
|
|
190
397
|
}
|
|
191
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
192
|
-
static { this.ɵ
|
|
193
|
-
// Angular
|
|
194
|
-
CommonModule }, { kind: "ngmodule", type:
|
|
195
|
-
// ACoreX
|
|
196
|
-
AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
|
|
197
|
-
// Compare View
|
|
198
|
-
AXPCompareViewComponent, selector: "axp-compare-view", inputs: ["inputs", "mode"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
398
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
399
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveAction }); }
|
|
199
400
|
}
|
|
200
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
201
|
-
type:
|
|
202
|
-
args: [{ selector: 'axp-compare-popup', standalone: true, imports: [
|
|
203
|
-
// Angular
|
|
204
|
-
CommonModule,
|
|
205
|
-
// ACoreX
|
|
206
|
-
AXDecoratorModule,
|
|
207
|
-
AXButtonModule,
|
|
208
|
-
AXTranslationModule,
|
|
209
|
-
// Compare View
|
|
210
|
-
AXPCompareViewComponent
|
|
211
|
-
], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-content>\n <div class=\"ax-p-6 ax-min-h-[30vh] ax-overflow-y-auto\">\n <axp-compare-view [inputs]=\"inputs()\" [mode]=\"mode()\"></axp-compare-view>\n </div>\n</ax-content>\n<ax-footer>\n <ax-prefix></ax-prefix>\n <ax-suffix>\n <ax-button [text]=\"'close' | translate | async\" look=\"solid\" color=\"primary\" (onClick)=\"close()\"> </ax-button>\n </ax-suffix>\n</ax-footer>" }]
|
|
401
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveAction, decorators: [{
|
|
402
|
+
type: Injectable
|
|
212
403
|
}] });
|
|
213
|
-
|
|
214
|
-
var comparePopup_component = /*#__PURE__*/Object.freeze({
|
|
215
|
-
__proto__: null,
|
|
216
|
-
AXPComparePopupComponent: AXPComparePopupComponent
|
|
217
|
-
});
|
|
218
|
-
|
|
219
|
-
class AXMComparePopupStartAction extends AXPWorkflowAction {
|
|
220
|
-
constructor() {
|
|
221
|
-
super(...arguments);
|
|
222
|
-
this.popupService = inject(AXPopupService);
|
|
223
|
-
this.translate = inject(AXTranslationService);
|
|
224
|
-
}
|
|
404
|
+
class AXPEntityArchiveSuccessAction extends AXPWorkflowAction {
|
|
225
405
|
async execute(context) {
|
|
226
|
-
const
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
});
|
|
406
|
+
const refType = context.getVariable('options.refType');
|
|
407
|
+
const id = context.getOutput('id');
|
|
408
|
+
const meta = context.getVariable('meta');
|
|
409
|
+
// Dispatch archive event
|
|
410
|
+
this.dispatch(AXPEntityArchivedEvent({
|
|
411
|
+
entity: refType,
|
|
412
|
+
id,
|
|
413
|
+
meta
|
|
414
|
+
}));
|
|
415
|
+
// Refresh the entity list
|
|
416
|
+
this.dispatch(AXPRefreshEvent({
|
|
417
|
+
entity: refType,
|
|
418
|
+
meta
|
|
419
|
+
}));
|
|
235
420
|
}
|
|
236
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
237
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
421
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveSuccessAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
422
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveSuccessAction }); }
|
|
238
423
|
}
|
|
239
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
424
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityArchiveSuccessAction, decorators: [{
|
|
240
425
|
type: Injectable
|
|
241
426
|
}] });
|
|
242
|
-
|
|
427
|
+
const AXPArchiveEntityWorkflow = {
|
|
428
|
+
startStepId: 'archive-entity',
|
|
429
|
+
steps: {
|
|
430
|
+
'archive-entity': {
|
|
431
|
+
action: 'AXPEntityArchiveAction',
|
|
432
|
+
nextSteps: [
|
|
433
|
+
{
|
|
434
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
435
|
+
nextStepId: 'show-success-toast',
|
|
436
|
+
},
|
|
437
|
+
],
|
|
438
|
+
},
|
|
439
|
+
'show-success-toast': {
|
|
440
|
+
action: 'AXPToastAction',
|
|
441
|
+
input: {
|
|
442
|
+
color: 'success',
|
|
443
|
+
title: 'workflow.entity-archived',
|
|
444
|
+
content: 'workflow.entity-archived-body',
|
|
445
|
+
},
|
|
446
|
+
nextSteps: [
|
|
447
|
+
{
|
|
448
|
+
conditions: [],
|
|
449
|
+
nextStepId: 'archive-success',
|
|
450
|
+
},
|
|
451
|
+
],
|
|
452
|
+
},
|
|
453
|
+
'archive-success': {
|
|
454
|
+
action: 'AXPEntityArchiveSuccessAction',
|
|
455
|
+
},
|
|
456
|
+
},
|
|
457
|
+
};
|
|
458
|
+
|
|
459
|
+
const AXPEntityUnarchivedEvent = createWorkFlowEvent('[Entity] Unarchived');
|
|
460
|
+
class AXPEntityUnarchiveAction extends AXPWorkflowAction {
|
|
243
461
|
constructor() {
|
|
244
462
|
super(...arguments);
|
|
245
|
-
this.
|
|
463
|
+
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
464
|
+
this.dialogService = inject(AXDialogService);
|
|
465
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
|
466
|
+
this.translationService = inject(AXTranslationService);
|
|
246
467
|
}
|
|
247
468
|
async execute(context) {
|
|
248
|
-
const
|
|
249
|
-
const
|
|
250
|
-
|
|
251
|
-
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
|
|
282
|
-
|
|
283
|
-
|
|
469
|
+
const refId = context.getVariable('options.refId');
|
|
470
|
+
const refType = context.getVariable('options.refType');
|
|
471
|
+
if (!refId || !refType) {
|
|
472
|
+
throw new Error('Missing required parameters: refId and refType');
|
|
473
|
+
}
|
|
474
|
+
const [moduleName, entityName] = refType.split('.');
|
|
475
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
476
|
+
// Show confirmation dialog
|
|
477
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@general:actions.restore-archive.confirm.title'), await this.translationService.translateAsync('@general:actions.restore-archive.confirm.message'), 'warning', 'horizontal', false, 'cancel');
|
|
478
|
+
if (!dialogResult.result) {
|
|
479
|
+
context.setOutput('isCanceled', true);
|
|
480
|
+
context.setOutput('error', 'Operation cancelled by user');
|
|
481
|
+
return;
|
|
482
|
+
}
|
|
483
|
+
// Show loading dialog
|
|
484
|
+
const loadingDialog = this.loadingDialog.show({
|
|
485
|
+
title: await this.translationService.translateAsync('@general:actions.restore-archive.confirm.processing'),
|
|
486
|
+
mode: 'indeterminate',
|
|
487
|
+
status: 'Unarchiving...',
|
|
488
|
+
});
|
|
489
|
+
try {
|
|
490
|
+
// Get the current entity data
|
|
491
|
+
const currentData = await this.getEntityData(refType, refId);
|
|
492
|
+
// Prepare unarchive data
|
|
493
|
+
const unarchiveData = this.prepareUnarchiveData(currentData);
|
|
494
|
+
// Update the entity to mark it as not archived
|
|
495
|
+
if (entityDefinition.commands?.update) {
|
|
496
|
+
const updateExec = entityDefinition.commands.update.execute;
|
|
497
|
+
await updateExec(unarchiveData);
|
|
498
|
+
context.setOutput('id', refId);
|
|
499
|
+
context.setOutput('isCanceled', false);
|
|
500
|
+
// Set refresh metadata
|
|
501
|
+
if (entityDefinition.parentKey && currentData[entityDefinition.parentKey]) {
|
|
502
|
+
context.setVariable('meta', { refreshTargetId: currentData[entityDefinition.parentKey] });
|
|
503
|
+
}
|
|
504
|
+
}
|
|
505
|
+
else {
|
|
506
|
+
throw new Error('Entity does not support update operation');
|
|
507
|
+
}
|
|
508
|
+
}
|
|
509
|
+
catch (error) {
|
|
510
|
+
console.error('Unarchive operation failed:', error);
|
|
511
|
+
context.setOutput('error', error instanceof Error ? error.message : 'Unknown error');
|
|
512
|
+
context.setOutput('isCanceled', true);
|
|
513
|
+
}
|
|
514
|
+
finally {
|
|
515
|
+
loadingDialog.close();
|
|
516
|
+
}
|
|
284
517
|
}
|
|
285
|
-
|
|
286
|
-
|
|
518
|
+
async getEntityData(refType, refId) {
|
|
519
|
+
try {
|
|
520
|
+
// Use the entity's byKey query to get actual data
|
|
521
|
+
const [moduleName, entityName] = refType.split('.');
|
|
522
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
523
|
+
if (entityDefinition.queries?.byKey) {
|
|
524
|
+
const queryExec = entityDefinition.queries.byKey.execute;
|
|
525
|
+
return await queryExec(refId);
|
|
526
|
+
}
|
|
527
|
+
// Fallback to basic structure if no query available
|
|
528
|
+
return { id: refId };
|
|
529
|
+
}
|
|
530
|
+
catch (error) {
|
|
531
|
+
console.error('Failed to retrieve entity data:', error);
|
|
532
|
+
throw new Error(`Failed to retrieve entity data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
533
|
+
}
|
|
534
|
+
}
|
|
535
|
+
prepareUnarchiveData(currentData) {
|
|
536
|
+
const unarchiveData = { ...currentData };
|
|
537
|
+
// Set the archived flag to false
|
|
538
|
+
unarchiveData.isArchived = false;
|
|
539
|
+
// Remove archive timestamp
|
|
540
|
+
delete unarchiveData.archivedAt;
|
|
541
|
+
return unarchiveData;
|
|
542
|
+
}
|
|
543
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
544
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveAction }); }
|
|
287
545
|
}
|
|
288
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
546
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveAction, decorators: [{
|
|
289
547
|
type: Injectable
|
|
290
548
|
}] });
|
|
291
|
-
class
|
|
292
|
-
constructor() {
|
|
293
|
-
super(...arguments);
|
|
294
|
-
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
295
|
-
this.activityLogService = inject(AXPActivityLogService);
|
|
296
|
-
this.formatService = inject(AXFormatService);
|
|
297
|
-
this.translate = inject(AXTranslationService);
|
|
298
|
-
}
|
|
549
|
+
class AXPEntityUnarchiveSuccessAction extends AXPWorkflowAction {
|
|
299
550
|
async execute(context) {
|
|
300
|
-
const
|
|
301
|
-
const
|
|
302
|
-
const
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
widget: {
|
|
314
|
-
type: p.schema.interface?.type,
|
|
315
|
-
name: p.name,
|
|
316
|
-
path: p.name,
|
|
317
|
-
options: p.schema.interface?.options,
|
|
318
|
-
},
|
|
551
|
+
const refType = context.getVariable('options.refType');
|
|
552
|
+
const id = context.getOutput('id');
|
|
553
|
+
const meta = context.getVariable('meta');
|
|
554
|
+
// Dispatch unarchive event
|
|
555
|
+
this.dispatch(AXPEntityUnarchivedEvent({
|
|
556
|
+
entity: refType,
|
|
557
|
+
id,
|
|
558
|
+
meta
|
|
559
|
+
}));
|
|
560
|
+
// Refresh the entity list
|
|
561
|
+
this.dispatch(AXPRefreshEvent({
|
|
562
|
+
entity: refType,
|
|
563
|
+
meta
|
|
319
564
|
}));
|
|
320
|
-
const objects = await Promise.all(histories.map(async (h) => ({
|
|
321
|
-
id: h.id,
|
|
322
|
-
title: await this.translate.translateAsync(`@activity-log:${h.changeType == 'update' ? 'updated' : 'created'}-by-title`, {
|
|
323
|
-
params: {
|
|
324
|
-
user: h.user?.title,
|
|
325
|
-
date: this.formatService.format(h.date, 'datetime', { format: 'short' }),
|
|
326
|
-
}
|
|
327
|
-
}),
|
|
328
|
-
description: h.user?.title,
|
|
329
|
-
context: h.data,
|
|
330
|
-
})));
|
|
331
|
-
const inputs = {
|
|
332
|
-
fields: fields,
|
|
333
|
-
objects: objects,
|
|
334
|
-
};
|
|
335
|
-
//
|
|
336
|
-
context.setVariable('inputs', inputs);
|
|
337
|
-
context.setVariable('mode', 'changes');
|
|
338
|
-
context.setOutput('result', true);
|
|
339
565
|
}
|
|
340
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
341
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
566
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveSuccessAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
567
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveSuccessAction }); }
|
|
342
568
|
}
|
|
343
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
569
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityUnarchiveSuccessAction, decorators: [{
|
|
344
570
|
type: Injectable
|
|
345
571
|
}] });
|
|
346
|
-
const
|
|
347
|
-
startStepId: '
|
|
572
|
+
const AXPUnarchiveEntityWorkflow = {
|
|
573
|
+
startStepId: 'unarchive-entity',
|
|
348
574
|
steps: {
|
|
349
|
-
|
|
350
|
-
action: '
|
|
575
|
+
'unarchive-entity': {
|
|
576
|
+
action: 'AXPEntityUnarchiveAction',
|
|
351
577
|
nextSteps: [
|
|
352
578
|
{
|
|
353
|
-
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("
|
|
354
|
-
nextStepId: 'show-
|
|
355
|
-
}
|
|
579
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
580
|
+
nextStepId: 'show-success-toast',
|
|
581
|
+
},
|
|
356
582
|
],
|
|
357
583
|
},
|
|
358
|
-
'show-
|
|
359
|
-
action: '
|
|
584
|
+
'show-success-toast': {
|
|
585
|
+
action: 'AXPToastAction',
|
|
586
|
+
input: {
|
|
587
|
+
color: 'success',
|
|
588
|
+
title: 'workflow.entity-unarchived',
|
|
589
|
+
content: 'workflow.entity-unarchived-body',
|
|
590
|
+
},
|
|
591
|
+
nextSteps: [
|
|
592
|
+
{
|
|
593
|
+
conditions: [],
|
|
594
|
+
nextStepId: 'unarchive-success',
|
|
595
|
+
},
|
|
596
|
+
],
|
|
597
|
+
},
|
|
598
|
+
'unarchive-success': {
|
|
599
|
+
action: 'AXPEntityUnarchiveSuccessAction',
|
|
360
600
|
},
|
|
361
601
|
},
|
|
362
602
|
};
|
|
363
|
-
|
|
364
|
-
|
|
603
|
+
|
|
604
|
+
const AXPEntityBulkArchivedEvent = createWorkFlowEvent('[Entity] Bulk Archived');
|
|
605
|
+
class AXPEntityBulkArchiveAction extends AXPWorkflowAction {
|
|
606
|
+
constructor() {
|
|
607
|
+
super(...arguments);
|
|
608
|
+
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
609
|
+
this.dialogService = inject(AXDialogService);
|
|
610
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
|
611
|
+
this.translationService = inject(AXTranslationService);
|
|
612
|
+
}
|
|
613
|
+
async execute(context) {
|
|
614
|
+
const refType = context.getVariable('options.refType');
|
|
615
|
+
const selectedIds = context.getVariable('selectedIds') || [];
|
|
616
|
+
if (!refType || selectedIds.length === 0) {
|
|
617
|
+
throw new Error('Missing required parameters: refType and selectedIds');
|
|
618
|
+
}
|
|
619
|
+
const [moduleName, entityName] = refType.split('.');
|
|
620
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
621
|
+
// Show confirmation dialog
|
|
622
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@general:actions.bulk-archive.confirm.title'), await this.translationService.translateAsync('@general:actions.bulk-archive.confirm.message', {
|
|
623
|
+
params: { count: selectedIds.length }
|
|
624
|
+
}), 'warning', 'horizontal', false, 'cancel');
|
|
625
|
+
if (!dialogResult.result) {
|
|
626
|
+
context.setOutput('isCanceled', true);
|
|
627
|
+
context.setOutput('error', 'Operation cancelled by user');
|
|
628
|
+
return;
|
|
629
|
+
}
|
|
630
|
+
// Show loading dialog
|
|
631
|
+
const loadingDialog = this.loadingDialog.show({
|
|
632
|
+
title: await this.translationService.translateAsync('@general:actions.bulk-archive.confirm.processing'),
|
|
633
|
+
mode: 'indeterminate',
|
|
634
|
+
status: `Archiving ${selectedIds.length} items...`,
|
|
635
|
+
});
|
|
636
|
+
try {
|
|
637
|
+
const processedIds = [];
|
|
638
|
+
const failedIds = [];
|
|
639
|
+
// Process each selected entity
|
|
640
|
+
for (const id of selectedIds) {
|
|
641
|
+
try {
|
|
642
|
+
// Get the current entity data
|
|
643
|
+
const currentData = await this.getEntityData(refType, id);
|
|
644
|
+
// Prepare archive data
|
|
645
|
+
const archiveData = this.prepareArchiveData(currentData);
|
|
646
|
+
// Update the entity to mark it as archived
|
|
647
|
+
if (entityDefinition.commands?.update) {
|
|
648
|
+
const updateExec = entityDefinition.commands.update.execute;
|
|
649
|
+
await updateExec(archiveData);
|
|
650
|
+
processedIds.push(id);
|
|
651
|
+
}
|
|
652
|
+
else {
|
|
653
|
+
failedIds.push(id);
|
|
654
|
+
}
|
|
655
|
+
}
|
|
656
|
+
catch (error) {
|
|
657
|
+
console.error(`Failed to archive entity ${id}:`, error);
|
|
658
|
+
failedIds.push(id);
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
context.setOutput('processedIds', processedIds);
|
|
662
|
+
context.setOutput('failedIds', failedIds);
|
|
663
|
+
context.setOutput('isCanceled', false);
|
|
664
|
+
context.setOutput('totalProcessed', processedIds.length);
|
|
665
|
+
context.setOutput('totalFailed', failedIds.length);
|
|
666
|
+
}
|
|
667
|
+
catch (error) {
|
|
668
|
+
console.error('Bulk archive operation failed:', error);
|
|
669
|
+
context.setOutput('error', error instanceof Error ? error.message : 'Unknown error');
|
|
670
|
+
context.setOutput('isCanceled', true);
|
|
671
|
+
}
|
|
672
|
+
finally {
|
|
673
|
+
loadingDialog.close();
|
|
674
|
+
}
|
|
675
|
+
}
|
|
676
|
+
async getEntityData(refType, refId) {
|
|
677
|
+
try {
|
|
678
|
+
// Use the entity's byKey query to get actual data
|
|
679
|
+
const [moduleName, entityName] = refType.split('.');
|
|
680
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
681
|
+
if (entityDefinition.queries?.byKey) {
|
|
682
|
+
const queryExec = entityDefinition.queries.byKey.execute;
|
|
683
|
+
return await queryExec(refId);
|
|
684
|
+
}
|
|
685
|
+
// Fallback to basic structure if no query available
|
|
686
|
+
return { id: refId };
|
|
687
|
+
}
|
|
688
|
+
catch (error) {
|
|
689
|
+
console.error('Failed to retrieve entity data:', error);
|
|
690
|
+
throw new Error(`Failed to retrieve entity data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
691
|
+
}
|
|
692
|
+
}
|
|
693
|
+
prepareArchiveData(currentData) {
|
|
694
|
+
const archiveData = { ...currentData };
|
|
695
|
+
// Set the archived flag
|
|
696
|
+
archiveData.isArchived = true;
|
|
697
|
+
// Optionally add archive timestamp
|
|
698
|
+
archiveData.archivedAt = new Date();
|
|
699
|
+
return archiveData;
|
|
700
|
+
}
|
|
701
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
702
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveAction }); }
|
|
703
|
+
}
|
|
704
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveAction, decorators: [{
|
|
705
|
+
type: Injectable
|
|
706
|
+
}] });
|
|
707
|
+
class AXPEntityBulkArchiveSuccessAction extends AXPWorkflowAction {
|
|
708
|
+
async execute(context) {
|
|
709
|
+
const refType = context.getVariable('options.refType');
|
|
710
|
+
const processedIds = context.getOutput('processedIds') || [];
|
|
711
|
+
const failedIds = context.getOutput('failedIds') || [];
|
|
712
|
+
const totalProcessed = context.getOutput('totalProcessed') || 0;
|
|
713
|
+
const totalFailed = context.getOutput('totalFailed') || 0;
|
|
714
|
+
// Dispatch bulk archive event
|
|
715
|
+
this.dispatch(AXPEntityBulkArchivedEvent({
|
|
716
|
+
entity: refType,
|
|
717
|
+
ids: processedIds,
|
|
718
|
+
meta: { failedIds, totalProcessed, totalFailed }
|
|
719
|
+
}));
|
|
720
|
+
// Refresh the entity list
|
|
721
|
+
this.dispatch(AXPRefreshEvent({
|
|
722
|
+
entity: refType,
|
|
723
|
+
meta: { refreshType: 'bulk-archive' }
|
|
724
|
+
}));
|
|
725
|
+
}
|
|
726
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveSuccessAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
727
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveSuccessAction }); }
|
|
728
|
+
}
|
|
729
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkArchiveSuccessAction, decorators: [{
|
|
730
|
+
type: Injectable
|
|
731
|
+
}] });
|
|
732
|
+
const AXPBulkArchiveEntityWorkflow = {
|
|
733
|
+
startStepId: 'bulk-archive-entity',
|
|
365
734
|
steps: {
|
|
366
|
-
|
|
367
|
-
action: '
|
|
735
|
+
'bulk-archive-entity': {
|
|
736
|
+
action: 'AXPEntityBulkArchiveAction',
|
|
368
737
|
nextSteps: [
|
|
369
738
|
{
|
|
370
|
-
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("
|
|
371
|
-
nextStepId: 'show-
|
|
739
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
740
|
+
nextStepId: 'show-success-toast',
|
|
741
|
+
},
|
|
742
|
+
],
|
|
743
|
+
},
|
|
744
|
+
'show-success-toast': {
|
|
745
|
+
action: 'AXPToastAction',
|
|
746
|
+
input: {
|
|
747
|
+
color: 'success',
|
|
748
|
+
title: 'workflow.entity-bulk-archived',
|
|
749
|
+
content: 'workflow.entity-bulk-archived-body',
|
|
750
|
+
},
|
|
751
|
+
nextSteps: [
|
|
752
|
+
{
|
|
753
|
+
conditions: [],
|
|
754
|
+
nextStepId: 'bulk-archive-success',
|
|
755
|
+
},
|
|
756
|
+
],
|
|
757
|
+
},
|
|
758
|
+
'bulk-archive-success': {
|
|
759
|
+
action: 'AXPEntityBulkArchiveSuccessAction',
|
|
760
|
+
},
|
|
761
|
+
},
|
|
762
|
+
};
|
|
763
|
+
|
|
764
|
+
const AXPEntityBulkUnarchivedEvent = createWorkFlowEvent('[Entity] Bulk Unarchived');
|
|
765
|
+
class AXPEntityBulkUnarchiveAction extends AXPWorkflowAction {
|
|
766
|
+
constructor() {
|
|
767
|
+
super(...arguments);
|
|
768
|
+
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
769
|
+
this.dialogService = inject(AXDialogService);
|
|
770
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
|
771
|
+
this.translationService = inject(AXTranslationService);
|
|
772
|
+
}
|
|
773
|
+
async execute(context) {
|
|
774
|
+
const refType = context.getVariable('options.refType');
|
|
775
|
+
const selectedIds = context.getVariable('selectedIds') || [];
|
|
776
|
+
if (!refType || selectedIds.length === 0) {
|
|
777
|
+
throw new Error('Missing required parameters: refType and selectedIds');
|
|
778
|
+
}
|
|
779
|
+
const [moduleName, entityName] = refType.split('.');
|
|
780
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
781
|
+
// Show confirmation dialog
|
|
782
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@general:actions.bulk-restore-archive.confirm.title'), await this.translationService.translateAsync('@general:actions.bulk-restore-archive.confirm.message', {
|
|
783
|
+
params: { count: selectedIds.length }
|
|
784
|
+
}), 'warning', 'horizontal', false, 'cancel');
|
|
785
|
+
if (!dialogResult.result) {
|
|
786
|
+
context.setOutput('isCanceled', true);
|
|
787
|
+
context.setOutput('error', 'Operation cancelled by user');
|
|
788
|
+
return;
|
|
789
|
+
}
|
|
790
|
+
// Show loading dialog
|
|
791
|
+
const loadingDialog = this.loadingDialog.show({
|
|
792
|
+
title: await this.translationService.translateAsync('@general:actions.bulk-restore-archive.confirm.processing'),
|
|
793
|
+
mode: 'indeterminate',
|
|
794
|
+
status: `Unarchiving ${selectedIds.length} items...`,
|
|
795
|
+
});
|
|
796
|
+
try {
|
|
797
|
+
const processedIds = [];
|
|
798
|
+
const failedIds = [];
|
|
799
|
+
// Process each selected entity
|
|
800
|
+
for (const id of selectedIds) {
|
|
801
|
+
try {
|
|
802
|
+
// Get the current entity data
|
|
803
|
+
const currentData = await this.getEntityData(refType, id);
|
|
804
|
+
// Prepare unarchive data
|
|
805
|
+
const unarchiveData = this.prepareUnarchiveData(currentData);
|
|
806
|
+
// Update the entity to mark it as not archived
|
|
807
|
+
if (entityDefinition.commands?.update) {
|
|
808
|
+
const updateExec = entityDefinition.commands.update.execute;
|
|
809
|
+
await updateExec(unarchiveData);
|
|
810
|
+
processedIds.push(id);
|
|
811
|
+
}
|
|
812
|
+
else {
|
|
813
|
+
failedIds.push(id);
|
|
814
|
+
}
|
|
372
815
|
}
|
|
816
|
+
catch (error) {
|
|
817
|
+
console.error(`Failed to restore entity ${id}:`, error);
|
|
818
|
+
failedIds.push(id);
|
|
819
|
+
}
|
|
820
|
+
}
|
|
821
|
+
context.setOutput('processedIds', processedIds);
|
|
822
|
+
context.setOutput('failedIds', failedIds);
|
|
823
|
+
context.setOutput('isCanceled', false);
|
|
824
|
+
context.setOutput('totalProcessed', processedIds.length);
|
|
825
|
+
context.setOutput('totalFailed', failedIds.length);
|
|
826
|
+
}
|
|
827
|
+
catch (error) {
|
|
828
|
+
console.error('Bulk unarchive operation failed:', error);
|
|
829
|
+
context.setOutput('error', error instanceof Error ? error.message : 'Unknown error');
|
|
830
|
+
context.setOutput('isCanceled', true);
|
|
831
|
+
}
|
|
832
|
+
finally {
|
|
833
|
+
loadingDialog.close();
|
|
834
|
+
}
|
|
835
|
+
}
|
|
836
|
+
async getEntityData(refType, refId) {
|
|
837
|
+
try {
|
|
838
|
+
// Use the entity's byKey query to get actual data
|
|
839
|
+
const [moduleName, entityName] = refType.split('.');
|
|
840
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
841
|
+
if (entityDefinition.queries?.byKey) {
|
|
842
|
+
const queryExec = entityDefinition.queries.byKey.execute;
|
|
843
|
+
return await queryExec(refId);
|
|
844
|
+
}
|
|
845
|
+
// Fallback to basic structure if no query available
|
|
846
|
+
return { id: refId };
|
|
847
|
+
}
|
|
848
|
+
catch (error) {
|
|
849
|
+
console.error('Failed to retrieve entity data:', error);
|
|
850
|
+
throw new Error(`Failed to retrieve entity data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
851
|
+
}
|
|
852
|
+
}
|
|
853
|
+
prepareUnarchiveData(currentData) {
|
|
854
|
+
const unarchiveData = { ...currentData };
|
|
855
|
+
// Set the archived flag to false
|
|
856
|
+
unarchiveData.isArchived = false;
|
|
857
|
+
// Remove archive timestamp
|
|
858
|
+
delete unarchiveData.archivedAt;
|
|
859
|
+
return unarchiveData;
|
|
860
|
+
}
|
|
861
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
862
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveAction }); }
|
|
863
|
+
}
|
|
864
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveAction, decorators: [{
|
|
865
|
+
type: Injectable
|
|
866
|
+
}] });
|
|
867
|
+
class AXPEntityBulkUnarchiveSuccessAction extends AXPWorkflowAction {
|
|
868
|
+
async execute(context) {
|
|
869
|
+
const refType = context.getVariable('options.refType');
|
|
870
|
+
const processedIds = context.getOutput('processedIds') || [];
|
|
871
|
+
const failedIds = context.getOutput('failedIds') || [];
|
|
872
|
+
const totalProcessed = context.getOutput('totalProcessed') || 0;
|
|
873
|
+
const totalFailed = context.getOutput('totalFailed') || 0;
|
|
874
|
+
// Dispatch bulk unarchive event
|
|
875
|
+
this.dispatch(AXPEntityBulkUnarchivedEvent({
|
|
876
|
+
entity: refType,
|
|
877
|
+
ids: processedIds,
|
|
878
|
+
meta: { failedIds, totalProcessed, totalFailed }
|
|
879
|
+
}));
|
|
880
|
+
// Refresh the entity list
|
|
881
|
+
this.dispatch(AXPRefreshEvent({
|
|
882
|
+
entity: refType,
|
|
883
|
+
meta: { refreshType: 'bulk-unarchive' }
|
|
884
|
+
}));
|
|
885
|
+
}
|
|
886
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveSuccessAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
887
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveSuccessAction }); }
|
|
888
|
+
}
|
|
889
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityBulkUnarchiveSuccessAction, decorators: [{
|
|
890
|
+
type: Injectable
|
|
891
|
+
}] });
|
|
892
|
+
const AXPBulkUnarchiveEntityWorkflow = {
|
|
893
|
+
startStepId: 'bulk-unarchive-entity',
|
|
894
|
+
steps: {
|
|
895
|
+
'bulk-unarchive-entity': {
|
|
896
|
+
action: 'AXPEntityBulkUnarchiveAction',
|
|
897
|
+
nextSteps: [
|
|
898
|
+
{
|
|
899
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
900
|
+
nextStepId: 'show-success-toast',
|
|
901
|
+
},
|
|
373
902
|
],
|
|
374
903
|
},
|
|
375
|
-
'show-
|
|
376
|
-
action: '
|
|
904
|
+
'show-success-toast': {
|
|
905
|
+
action: 'AXPToastAction',
|
|
906
|
+
input: {
|
|
907
|
+
color: 'success',
|
|
908
|
+
title: 'workflow.entity-bulk-unarchived',
|
|
909
|
+
content: 'workflow.entity-bulk-unarchived-body',
|
|
910
|
+
},
|
|
911
|
+
nextSteps: [
|
|
912
|
+
{
|
|
913
|
+
conditions: [],
|
|
914
|
+
nextStepId: 'bulk-unarchive-success',
|
|
915
|
+
},
|
|
916
|
+
],
|
|
917
|
+
},
|
|
918
|
+
'bulk-unarchive-success': {
|
|
919
|
+
action: 'AXPEntityBulkUnarchiveSuccessAction',
|
|
377
920
|
},
|
|
378
921
|
},
|
|
379
922
|
};
|
|
380
923
|
|
|
381
|
-
class
|
|
382
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
383
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type:
|
|
384
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
385
|
-
|
|
924
|
+
class AXPArchivePluginModule {
|
|
925
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPArchivePluginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
926
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPArchivePluginModule, imports: [i1.AXPWorkflowModule] }); }
|
|
927
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPArchivePluginModule, providers: [
|
|
928
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: archivePlugin },
|
|
929
|
+
], imports: [AXPWorkflowModule.forChild({
|
|
386
930
|
actions: {
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
931
|
+
AXPEntityArchiveAction,
|
|
932
|
+
AXPEntityArchiveSuccessAction,
|
|
933
|
+
AXPEntityUnarchiveAction,
|
|
934
|
+
AXPEntityUnarchiveSuccessAction,
|
|
935
|
+
AXPEntityBulkArchiveAction,
|
|
936
|
+
AXPEntityBulkArchiveSuccessAction,
|
|
937
|
+
AXPEntityBulkUnarchiveAction,
|
|
938
|
+
AXPEntityBulkUnarchiveSuccessAction,
|
|
390
939
|
},
|
|
391
940
|
workflows: {
|
|
392
|
-
'
|
|
393
|
-
'
|
|
941
|
+
'archive-entity': AXPArchiveEntityWorkflow,
|
|
942
|
+
'restore-archive-entity': AXPUnarchiveEntityWorkflow,
|
|
943
|
+
'bulk-archive-entity': AXPBulkArchiveEntityWorkflow,
|
|
944
|
+
'bulk-restore-archive-entity': AXPBulkUnarchiveEntityWorkflow,
|
|
394
945
|
},
|
|
395
946
|
})] }); }
|
|
396
947
|
}
|
|
397
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
948
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPArchivePluginModule, decorators: [{
|
|
398
949
|
type: NgModule,
|
|
399
950
|
args: [{
|
|
400
951
|
imports: [
|
|
401
|
-
AXPComparePopupComponent,
|
|
402
952
|
AXPWorkflowModule.forChild({
|
|
403
953
|
actions: {
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
954
|
+
AXPEntityArchiveAction,
|
|
955
|
+
AXPEntityArchiveSuccessAction,
|
|
956
|
+
AXPEntityUnarchiveAction,
|
|
957
|
+
AXPEntityUnarchiveSuccessAction,
|
|
958
|
+
AXPEntityBulkArchiveAction,
|
|
959
|
+
AXPEntityBulkArchiveSuccessAction,
|
|
960
|
+
AXPEntityBulkUnarchiveAction,
|
|
961
|
+
AXPEntityBulkUnarchiveSuccessAction,
|
|
407
962
|
},
|
|
408
963
|
workflows: {
|
|
409
|
-
'
|
|
410
|
-
'
|
|
964
|
+
'archive-entity': AXPArchiveEntityWorkflow,
|
|
965
|
+
'restore-archive-entity': AXPUnarchiveEntityWorkflow,
|
|
966
|
+
'bulk-archive-entity': AXPBulkArchiveEntityWorkflow,
|
|
967
|
+
'bulk-restore-archive-entity': AXPBulkUnarchiveEntityWorkflow,
|
|
411
968
|
},
|
|
412
969
|
}),
|
|
413
970
|
],
|
|
414
|
-
|
|
971
|
+
providers: [
|
|
972
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: archivePlugin },
|
|
973
|
+
],
|
|
415
974
|
}]
|
|
416
975
|
}] });
|
|
417
976
|
|
|
418
|
-
const
|
|
977
|
+
const categoryPlugin = {
|
|
978
|
+
name: 'category',
|
|
979
|
+
order: 45,
|
|
980
|
+
apply: (ctx, options) => {
|
|
981
|
+
const moduleName = ctx.entity.module;
|
|
982
|
+
const baseEntityName = ctx.entity.name;
|
|
983
|
+
const categoryEntityName = `${baseEntityName}Category`;
|
|
984
|
+
const propertyName = options?.propertyName?.trim()?.length ? options.propertyName : 'categoryIds';
|
|
985
|
+
const allowMultiple = options?.allowMultiple ?? true;
|
|
986
|
+
// Ensure group exists (prefer basic-info)
|
|
987
|
+
const groups = ctx.groups.list() ?? [];
|
|
988
|
+
const hasBasic = groups.some((g) => g.id === 'basic-info');
|
|
989
|
+
if (!hasBasic) {
|
|
990
|
+
ctx.groups.add({ id: 'basic-info', title: '@general:terms.basic-info' });
|
|
991
|
+
}
|
|
992
|
+
ctx.columns.add({ name: 'categoryIds', options: { dataPath: 'categories' } });
|
|
993
|
+
// Ensure property exists
|
|
994
|
+
const props = ctx.properties.list();
|
|
995
|
+
if (!props.some((p) => p.name === propertyName)) {
|
|
996
|
+
ctx.properties.add({
|
|
997
|
+
name: propertyName,
|
|
998
|
+
title: '@general:terms.category.plural',
|
|
999
|
+
groupId: 'basic-info',
|
|
1000
|
+
schema: {
|
|
1001
|
+
dataType: 'string',
|
|
1002
|
+
interface: {
|
|
1003
|
+
type: AXPWidgetsList.Editors.LookupBox,
|
|
1004
|
+
options: {
|
|
1005
|
+
entity: `${moduleName}.${categoryEntityName}`,
|
|
1006
|
+
multiple: allowMultiple,
|
|
1007
|
+
expose: [
|
|
1008
|
+
{ source: 'id', target: 'categories.{id}' },
|
|
1009
|
+
{ source: 'title', target: 'categories.{title}' },
|
|
1010
|
+
],
|
|
1011
|
+
},
|
|
1012
|
+
},
|
|
1013
|
+
},
|
|
1014
|
+
});
|
|
1015
|
+
}
|
|
1016
|
+
// Ensure category sidebar/filter block
|
|
1017
|
+
ctx.category.update((cat) => {
|
|
1018
|
+
return {
|
|
1019
|
+
entity: `${moduleName}.${categoryEntityName}`,
|
|
1020
|
+
title: '@general:terms.category.plural',
|
|
1021
|
+
textField: 'title',
|
|
1022
|
+
valueField: 'id',
|
|
1023
|
+
applyConditions: [
|
|
1024
|
+
{
|
|
1025
|
+
name: propertyName,
|
|
1026
|
+
operator: { type: 'contains' },
|
|
1027
|
+
value: 'id',
|
|
1028
|
+
},
|
|
1029
|
+
],
|
|
1030
|
+
};
|
|
1031
|
+
});
|
|
1032
|
+
// Ensure layout includes property in create/modify/single
|
|
1033
|
+
const ensureLayoutProperty = (layout) => {
|
|
1034
|
+
layout.sections = layout.sections ?? [];
|
|
1035
|
+
if (!layout.sections.some((s) => s.id === 'basic-info')) {
|
|
1036
|
+
layout.sections.push({ id: 'basic-info' });
|
|
1037
|
+
}
|
|
1038
|
+
layout.properties = layout.properties ?? [];
|
|
1039
|
+
if (!layout.properties.some((p) => p.name === propertyName)) {
|
|
1040
|
+
layout.properties.push({
|
|
1041
|
+
name: propertyName,
|
|
1042
|
+
layout: {
|
|
1043
|
+
positions: { lg: { colSpan: 12, order: 12 } },
|
|
1044
|
+
},
|
|
1045
|
+
});
|
|
1046
|
+
}
|
|
1047
|
+
return layout;
|
|
1048
|
+
};
|
|
1049
|
+
ctx.interfaces.master.create.update((create) => ensureLayoutProperty(create ?? { sections: [], properties: [] }));
|
|
1050
|
+
ctx.interfaces.master.modify.update((modify) => ensureLayoutProperty(modify ?? { sections: [], properties: [] }));
|
|
1051
|
+
ctx.interfaces.master.single.update((single) => ensureLayoutProperty(single ?? { title: ctx.entity.title, sections: [], properties: [] }));
|
|
1052
|
+
// Mark extension for dynamic category entity generation
|
|
1053
|
+
ctx.entity.extensions ??= {};
|
|
1054
|
+
ctx.entity.extensions.category = {
|
|
1055
|
+
entity: `${moduleName}.${categoryEntityName}`,
|
|
1056
|
+
propertyName,
|
|
1057
|
+
allowMultiple,
|
|
1058
|
+
};
|
|
1059
|
+
},
|
|
1060
|
+
};
|
|
419
1061
|
|
|
420
|
-
class
|
|
1062
|
+
class AXMEntityCategoryProvider {
|
|
421
1063
|
constructor() {
|
|
422
|
-
this.
|
|
1064
|
+
this.injector = inject(Injector);
|
|
423
1065
|
}
|
|
424
|
-
|
|
425
|
-
|
|
1066
|
+
preload() {
|
|
1067
|
+
return [];
|
|
426
1068
|
}
|
|
427
|
-
async
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
1069
|
+
async get(moduleName, entityName) {
|
|
1070
|
+
// Generic per-entity Category provider (works for any module)
|
|
1071
|
+
if (entityName.endsWith('Category')) {
|
|
1072
|
+
const fullKey = `${moduleName}.${entityName}`;
|
|
1073
|
+
const dataService = runInInjectionContext(this.injector, () => new AXMEntityCrudServiceImpl(fullKey));
|
|
1074
|
+
const entityDef = {
|
|
1075
|
+
module: moduleName,
|
|
1076
|
+
name: entityName,
|
|
1077
|
+
parentKey: 'parentId',
|
|
1078
|
+
plugins: [
|
|
1079
|
+
// { name: 'history' },
|
|
1080
|
+
// { name: 'lock' },
|
|
1081
|
+
// { name: 'compare' },
|
|
1082
|
+
],
|
|
1083
|
+
source: '',
|
|
1084
|
+
title: '@general:terms.category.individual',
|
|
1085
|
+
formats: {
|
|
1086
|
+
individual: '@general:terms.category.individual',
|
|
1087
|
+
plural: '@general:terms.category.plural',
|
|
1088
|
+
searchResult: {
|
|
1089
|
+
title: '{{ title }}',
|
|
1090
|
+
description: '{{ module }}',
|
|
1091
|
+
},
|
|
1092
|
+
},
|
|
1093
|
+
relatedEntities: [],
|
|
1094
|
+
groups: [
|
|
1095
|
+
{ id: 'basic-info', title: '@general:terms.basic-info' },
|
|
1096
|
+
],
|
|
1097
|
+
properties: [
|
|
1098
|
+
{
|
|
1099
|
+
name: 'title',
|
|
1100
|
+
title: '@general:terms.title',
|
|
1101
|
+
groupId: 'basic-info',
|
|
1102
|
+
options: {
|
|
1103
|
+
sort: { enabled: true },
|
|
1104
|
+
filter: { advance: { enabled: true }, inline: { enabled: true } },
|
|
1105
|
+
},
|
|
1106
|
+
schema: { dataType: 'string', interface: { type: AXPWidgetsCatalog.text } },
|
|
1107
|
+
validations: [{ rule: 'required' }],
|
|
1108
|
+
},
|
|
1109
|
+
{
|
|
1110
|
+
name: 'parentId',
|
|
1111
|
+
title: '@general:terms.parent-id',
|
|
1112
|
+
groupId: 'basic-info',
|
|
1113
|
+
schema: {
|
|
1114
|
+
dataType: 'string',
|
|
1115
|
+
interface: {
|
|
1116
|
+
type: AXPWidgetsList.Editors.LookupBox,
|
|
1117
|
+
options: { entity: `${moduleName}.${entityName}` },
|
|
1118
|
+
},
|
|
1119
|
+
},
|
|
1120
|
+
},
|
|
1121
|
+
{
|
|
1122
|
+
name: 'description',
|
|
1123
|
+
title: '@general:terms.description',
|
|
1124
|
+
groupId: 'basic-info',
|
|
1125
|
+
schema: { dataType: 'string', interface: { type: AXPWidgetsCatalog.largeText } },
|
|
1126
|
+
},
|
|
1127
|
+
],
|
|
1128
|
+
columns: [{ name: 'title' }, { name: 'description' }],
|
|
1129
|
+
commands: {
|
|
1130
|
+
create: { execute: async (data) => ({ id: await dataService.insertOne(data) }) },
|
|
1131
|
+
delete: { execute: async (id) => dataService.deleteOne(id) },
|
|
1132
|
+
update: { execute: async (data) => dataService.updateOne(data.id, data) },
|
|
1133
|
+
},
|
|
1134
|
+
queries: {
|
|
1135
|
+
byKey: { execute: async (id) => dataService.getOne(id), type: AXPEntityQueryType.Single },
|
|
1136
|
+
list: {
|
|
1137
|
+
execute: async (e) => {
|
|
1138
|
+
const res = await dataService.query(e);
|
|
1139
|
+
// enrich hasChild for tree views if childCount is available
|
|
1140
|
+
return {
|
|
1141
|
+
items: res.items.map((item) => ({ ...item, hasChild: (item.childCount ?? 0) > 0 })),
|
|
1142
|
+
total: res.total,
|
|
1143
|
+
};
|
|
1144
|
+
},
|
|
1145
|
+
type: AXPEntityQueryType.List,
|
|
1146
|
+
},
|
|
1147
|
+
},
|
|
1148
|
+
interfaces: {
|
|
1149
|
+
master: {
|
|
1150
|
+
create: {
|
|
1151
|
+
sections: [{ id: 'basic-info' }],
|
|
1152
|
+
properties: [
|
|
1153
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 12, order: 1 } } } },
|
|
1154
|
+
{ name: 'parentId', layout: { positions: { lg: { colSpan: 12, order: 2 } } } },
|
|
1155
|
+
{ name: 'description', layout: { positions: { lg: { colSpan: 12, order: 3 } } } },
|
|
1156
|
+
],
|
|
1157
|
+
},
|
|
1158
|
+
update: {
|
|
1159
|
+
sections: [{ id: 'basic-info' }],
|
|
1160
|
+
properties: [
|
|
1161
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 12, order: 1 } } } },
|
|
1162
|
+
{ name: 'parentId', layout: { positions: { lg: { colSpan: 12, order: 2 } } } },
|
|
1163
|
+
{ name: 'description', layout: { positions: { lg: { colSpan: 12, order: 3 } } } },
|
|
1164
|
+
],
|
|
1165
|
+
},
|
|
1166
|
+
single: {
|
|
1167
|
+
title: '{{title}}',
|
|
1168
|
+
sections: [{ id: 'basic-info', layout: { positions: { lg: { colSpan: 12 } } } }],
|
|
1169
|
+
properties: [
|
|
1170
|
+
{ name: 'title', layout: { positions: { lg: { colSpan: 12, order: 1 } } } },
|
|
1171
|
+
{ name: 'parentId', layout: { positions: { lg: { colSpan: 12, order: 2 } } } },
|
|
1172
|
+
{ name: 'description', layout: { positions: { lg: { colSpan: 12, order: 3 } } } },
|
|
1173
|
+
],
|
|
1174
|
+
actions: [entityMasterDeleteAction()],
|
|
1175
|
+
},
|
|
1176
|
+
list: {
|
|
1177
|
+
actions: [...entityMasterCrudActions()],
|
|
1178
|
+
views: [createAllQueryView({ sorts: [{ name: 'title', dir: 'asc' }] })],
|
|
1179
|
+
},
|
|
1180
|
+
},
|
|
1181
|
+
},
|
|
1182
|
+
};
|
|
1183
|
+
return entityDef;
|
|
499
1184
|
}
|
|
1185
|
+
return null;
|
|
500
1186
|
}
|
|
501
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
502
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1187
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMEntityCategoryProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1188
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMEntityCategoryProvider }); }
|
|
503
1189
|
}
|
|
504
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1190
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMEntityCategoryProvider, decorators: [{
|
|
505
1191
|
type: Injectable
|
|
506
1192
|
}] });
|
|
507
|
-
const AXPGlobalSearchWorkflow = {
|
|
508
|
-
startStepId: 'start',
|
|
509
|
-
steps: {
|
|
510
|
-
start: {
|
|
511
|
-
action: 'AXPGlobalSearchStartAction',
|
|
512
|
-
},
|
|
513
|
-
},
|
|
514
|
-
};
|
|
515
1193
|
|
|
516
|
-
class
|
|
517
|
-
|
|
518
|
-
}
|
|
519
|
-
static { this.ɵ
|
|
520
|
-
|
|
521
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchModule, providers: [
|
|
1194
|
+
class AXPCategoryModule {
|
|
1195
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCategoryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1196
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPCategoryModule }); }
|
|
1197
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCategoryModule, providers: [
|
|
1198
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: categoryPlugin },
|
|
522
1199
|
{
|
|
523
|
-
provide:
|
|
524
|
-
|
|
525
|
-
|
|
1200
|
+
provide: AXP_PERMISSION_DEFINITION_PROVIDER,
|
|
1201
|
+
multi: true,
|
|
1202
|
+
useFactory: () => {
|
|
1203
|
+
const provider = {
|
|
1204
|
+
define: async (context) => {
|
|
1205
|
+
// Generate permissions for any entity that declared category extension
|
|
1206
|
+
// We can’t scan registry here reliably at bootstrap; rely on generic pattern per module via wildcard
|
|
1207
|
+
// Consumers can still override with module-level providers.
|
|
1208
|
+
// No-op here; permissions will be added when category entity is resolved via provideEntity elsewhere if needed.
|
|
1209
|
+
},
|
|
1210
|
+
};
|
|
1211
|
+
return provider;
|
|
526
1212
|
},
|
|
527
1213
|
},
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
},
|
|
535
|
-
],
|
|
536
|
-
}),
|
|
537
|
-
//
|
|
538
|
-
AXPWorkflowModule.forChild({
|
|
539
|
-
actions: {
|
|
540
|
-
AXPGlobalSearchStartAction
|
|
541
|
-
},
|
|
542
|
-
workflows: {
|
|
543
|
-
'global-search': AXPGlobalSearchWorkflow,
|
|
544
|
-
},
|
|
545
|
-
})] }); }
|
|
1214
|
+
{
|
|
1215
|
+
provide: AXP_ENTITY_DEFINITION_LOADER,
|
|
1216
|
+
useClass: AXMEntityCategoryProvider,
|
|
1217
|
+
multi: true,
|
|
1218
|
+
},
|
|
1219
|
+
] }); }
|
|
546
1220
|
}
|
|
547
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1221
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCategoryModule, decorators: [{
|
|
548
1222
|
type: NgModule,
|
|
549
1223
|
args: [{
|
|
550
|
-
imports: [
|
|
551
|
-
AXPComponentSlotModule.forChild({
|
|
552
|
-
'root-header-start': [
|
|
553
|
-
{
|
|
554
|
-
priority: 0,
|
|
555
|
-
name: 'search',
|
|
556
|
-
component: AXPGlobalSearchSlotComponent,
|
|
557
|
-
},
|
|
558
|
-
],
|
|
559
|
-
}),
|
|
560
|
-
//
|
|
561
|
-
AXPWorkflowModule.forChild({
|
|
562
|
-
actions: {
|
|
563
|
-
AXPGlobalSearchStartAction
|
|
564
|
-
},
|
|
565
|
-
workflows: {
|
|
566
|
-
'global-search': AXPGlobalSearchWorkflow,
|
|
567
|
-
},
|
|
568
|
-
})
|
|
569
|
-
],
|
|
570
|
-
exports: [],
|
|
571
|
-
declarations: [],
|
|
572
1224
|
providers: [
|
|
1225
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: categoryPlugin },
|
|
573
1226
|
{
|
|
574
|
-
provide:
|
|
575
|
-
|
|
576
|
-
|
|
1227
|
+
provide: AXP_PERMISSION_DEFINITION_PROVIDER,
|
|
1228
|
+
multi: true,
|
|
1229
|
+
useFactory: () => {
|
|
1230
|
+
const provider = {
|
|
1231
|
+
define: async (context) => {
|
|
1232
|
+
// Generate permissions for any entity that declared category extension
|
|
1233
|
+
// We can’t scan registry here reliably at bootstrap; rely on generic pattern per module via wildcard
|
|
1234
|
+
// Consumers can still override with module-level providers.
|
|
1235
|
+
// No-op here; permissions will be added when category entity is resolved via provideEntity elsewhere if needed.
|
|
1236
|
+
},
|
|
1237
|
+
};
|
|
1238
|
+
return provider;
|
|
577
1239
|
},
|
|
578
1240
|
},
|
|
579
|
-
|
|
1241
|
+
{
|
|
1242
|
+
provide: AXP_ENTITY_DEFINITION_LOADER,
|
|
1243
|
+
useClass: AXMEntityCategoryProvider,
|
|
1244
|
+
multi: true,
|
|
1245
|
+
},
|
|
1246
|
+
],
|
|
580
1247
|
}]
|
|
581
|
-
}]
|
|
1248
|
+
}] });
|
|
582
1249
|
|
|
583
|
-
|
|
1250
|
+
const clonePlugin = {
|
|
1251
|
+
name: 'clone',
|
|
1252
|
+
order: 60,
|
|
1253
|
+
apply: (ctx) => {
|
|
1254
|
+
ensureListActions(ctx);
|
|
1255
|
+
ctx.interfaces.update((i) => {
|
|
1256
|
+
const cmdName = 'clone-entity';
|
|
1257
|
+
// Add clone action to list view
|
|
1258
|
+
const listActions = i.master.list.actions;
|
|
1259
|
+
if (!actionExists(listActions, cmdName)) {
|
|
1260
|
+
listActions.push({
|
|
1261
|
+
title: '@general:actions.clone.title',
|
|
1262
|
+
command: {
|
|
1263
|
+
name: cmdName,
|
|
1264
|
+
options: {
|
|
1265
|
+
refId: '{{ context.eval("id") }}',
|
|
1266
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1267
|
+
},
|
|
1268
|
+
},
|
|
1269
|
+
priority: 'secondary',
|
|
1270
|
+
type: 'copy',
|
|
1271
|
+
scope: AXPEntityCommandScope.Individual,
|
|
1272
|
+
});
|
|
1273
|
+
}
|
|
1274
|
+
// Add clone action to single view
|
|
1275
|
+
const singleActions = i.master.single.actions;
|
|
1276
|
+
if (!actionExists(singleActions, cmdName)) {
|
|
1277
|
+
singleActions.push({
|
|
1278
|
+
title: '@general:actions.clone.title',
|
|
1279
|
+
command: {
|
|
1280
|
+
name: cmdName,
|
|
1281
|
+
options: {
|
|
1282
|
+
refId: '{{ context.eval("id") }}',
|
|
1283
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1284
|
+
},
|
|
1285
|
+
},
|
|
1286
|
+
priority: 'secondary',
|
|
1287
|
+
type: 'copy',
|
|
1288
|
+
scope: AXPEntityCommandScope.Individual,
|
|
1289
|
+
});
|
|
1290
|
+
}
|
|
1291
|
+
return i;
|
|
1292
|
+
});
|
|
1293
|
+
},
|
|
1294
|
+
};
|
|
1295
|
+
|
|
1296
|
+
const AXPEntityClonedEvent = createWorkFlowEvent('[Entity] Cloned');
|
|
1297
|
+
class AXPEntityCloneAction extends AXPWorkflowAction {
|
|
584
1298
|
constructor() {
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
|
|
589
|
-
this.
|
|
590
|
-
this.settingService = inject(AXPSettingService);
|
|
591
|
-
this._text = signal(null, ...(ngDevMode ? [{ debugName: "_text" }] : []));
|
|
592
|
-
this.text = this._text.asReadonly();
|
|
593
|
-
this._results = signal([], ...(ngDevMode ? [{ debugName: "_results" }] : []));
|
|
594
|
-
this.results = this._results.asReadonly();
|
|
595
|
-
this._isBusy = signal(false, ...(ngDevMode ? [{ debugName: "_isBusy" }] : []));
|
|
596
|
-
this.isBusy = this._isBusy.asReadonly();
|
|
597
|
-
this.isEmpty = computed(() => this.text() && this.results().length == 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
|
|
598
|
-
this.isValid = computed(() => (this.text()?.length ?? 0) > 2, ...(ngDevMode ? [{ debugName: "isValid" }] : []));
|
|
599
|
-
this.isStart = computed(() => !this.isEmpty() && this.results().length == 0, ...(ngDevMode ? [{ debugName: "isStart" }] : []));
|
|
600
|
-
this.isWelcome = computed(() => this.isStart() && this.pinnedItems().length == 0 && this.recentItems().length == 0, ...(ngDevMode ? [{ debugName: "isWelcome" }] : []));
|
|
601
|
-
this._recentItems = signal([], ...(ngDevMode ? [{ debugName: "_recentItems" }] : []));
|
|
602
|
-
this._pinnedItems = signal([], ...(ngDevMode ? [{ debugName: "_pinnedItems" }] : []));
|
|
603
|
-
this.pinnedItems = this._pinnedItems.asReadonly();
|
|
604
|
-
this.recentItems = computed(() => this.getTopRecentItems(), ...(ngDevMode ? [{ debugName: "recentItems" }] : []));
|
|
605
|
-
this.onItemSelected = new Subject();
|
|
606
|
-
this.loadSettings();
|
|
1299
|
+
super(...arguments);
|
|
1300
|
+
this.entityRegistery = inject(AXPEntityDefinitionRegistryService);
|
|
1301
|
+
this.dialogService = inject(AXDialogService);
|
|
1302
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
|
1303
|
+
this.translationService = inject(AXTranslationService);
|
|
607
1304
|
}
|
|
608
|
-
async
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
if (!
|
|
612
|
-
|
|
1305
|
+
async execute(context) {
|
|
1306
|
+
const refId = context.getVariable('options.refId');
|
|
1307
|
+
const refType = context.getVariable('options.refType');
|
|
1308
|
+
if (!refId || !refType) {
|
|
1309
|
+
throw new Error('Missing required parameters: refId and refType');
|
|
613
1310
|
}
|
|
614
|
-
|
|
615
|
-
|
|
616
|
-
|
|
617
|
-
|
|
1311
|
+
const [moduleName, entityName] = refType.split('.');
|
|
1312
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
1313
|
+
// Show confirmation dialog
|
|
1314
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@general:actions.clone.confirm.title'), await this.translationService.translateAsync('@general:actions.clone.confirm.message'), 'warning', 'horizontal', false, 'cancel');
|
|
1315
|
+
if (!dialogResult.result) {
|
|
1316
|
+
context.setOutput('isCanceled', true);
|
|
1317
|
+
context.setOutput('error', 'Operation cancelled by user');
|
|
1318
|
+
return;
|
|
618
1319
|
}
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
1320
|
+
// Show loading dialog
|
|
1321
|
+
const loadingDialog = this.loadingDialog.show({
|
|
1322
|
+
title: await this.translationService.translateAsync('@general:actions.clone.confirm.processing'),
|
|
1323
|
+
mode: 'indeterminate',
|
|
1324
|
+
status: 'Cloning...',
|
|
1325
|
+
});
|
|
1326
|
+
try {
|
|
1327
|
+
// Get the original entity data
|
|
1328
|
+
const originalData = await this.getEntityData(refType, refId);
|
|
1329
|
+
// Clone the data (remove id and other unique fields)
|
|
1330
|
+
const clonedData = this.prepareClonedData(originalData, entityDefinition);
|
|
1331
|
+
// Create the new entity
|
|
1332
|
+
if (entityDefinition.commands?.create) {
|
|
1333
|
+
const createExec = entityDefinition.commands.create.execute;
|
|
1334
|
+
const newId = await createExec(clonedData);
|
|
1335
|
+
context.setOutput('originalId', refId);
|
|
1336
|
+
context.setOutput('newId', newId);
|
|
1337
|
+
context.setOutput('isCanceled', false);
|
|
1338
|
+
// Set refresh metadata
|
|
1339
|
+
if (entityDefinition.parentKey && clonedData[entityDefinition.parentKey]) {
|
|
1340
|
+
context.setVariable('meta', { refreshTargetId: clonedData[entityDefinition.parentKey] });
|
|
1341
|
+
}
|
|
1342
|
+
}
|
|
1343
|
+
else {
|
|
1344
|
+
throw new Error('Entity does not support create operation');
|
|
1345
|
+
}
|
|
630
1346
|
}
|
|
631
|
-
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
await this.saveSettings();
|
|
636
|
-
}
|
|
637
|
-
async togglePin(item) {
|
|
638
|
-
if (this.isPinned(item)) {
|
|
639
|
-
await this.unpin(item);
|
|
1347
|
+
catch (error) {
|
|
1348
|
+
console.error('Clone operation failed:', error);
|
|
1349
|
+
context.setOutput('error', error instanceof Error ? error.message : 'Unknown error');
|
|
1350
|
+
context.setOutput('isCanceled', true);
|
|
640
1351
|
}
|
|
641
|
-
|
|
642
|
-
|
|
1352
|
+
finally {
|
|
1353
|
+
loadingDialog.close();
|
|
643
1354
|
}
|
|
644
1355
|
}
|
|
645
|
-
|
|
646
|
-
|
|
647
|
-
|
|
648
|
-
|
|
649
|
-
|
|
650
|
-
|
|
651
|
-
|
|
652
|
-
|
|
653
|
-
|
|
654
|
-
|
|
655
|
-
|
|
656
|
-
}
|
|
657
|
-
getTopRecentItems() {
|
|
658
|
-
const pinnedIds = new Set(this._pinnedItems().map(item => item.id));
|
|
659
|
-
return this._recentItems().filter(item => !pinnedIds.has(item.id)).slice(0, 5);
|
|
660
|
-
}
|
|
661
|
-
async clearRecentItems() {
|
|
662
|
-
this._recentItems.set([]);
|
|
663
|
-
await this.settingService.scope(AXPPlatformScope.User).set(this.settingKeys.recent, []);
|
|
664
|
-
}
|
|
665
|
-
async loadSettings() {
|
|
666
|
-
// Load recent selections
|
|
667
|
-
const recent = await this.settingService.get(this.settingKeys.recent);
|
|
668
|
-
if (recent) {
|
|
669
|
-
this._recentItems.set(recent.slice(0, 5));
|
|
1356
|
+
async getEntityData(refType, refId) {
|
|
1357
|
+
try {
|
|
1358
|
+
// Use the entity's byKey query to get actual data
|
|
1359
|
+
const [moduleName, entityName] = refType.split('.');
|
|
1360
|
+
const entityDefinition = await this.entityRegistery.resolve(moduleName, entityName);
|
|
1361
|
+
if (entityDefinition.queries?.byKey) {
|
|
1362
|
+
const queryExec = entityDefinition.queries.byKey.execute;
|
|
1363
|
+
return await queryExec(refId);
|
|
1364
|
+
}
|
|
1365
|
+
// Fallback to basic structure if no query available
|
|
1366
|
+
return { id: refId };
|
|
670
1367
|
}
|
|
671
|
-
|
|
672
|
-
|
|
673
|
-
|
|
674
|
-
this._pinnedItems.set(pinned.slice(0, 5));
|
|
1368
|
+
catch (error) {
|
|
1369
|
+
console.error('Failed to retrieve entity data:', error);
|
|
1370
|
+
throw new Error(`Failed to retrieve entity data: ${error instanceof Error ? error.message : 'Unknown error'}`);
|
|
675
1371
|
}
|
|
676
1372
|
}
|
|
677
|
-
|
|
678
|
-
|
|
679
|
-
|
|
680
|
-
|
|
681
|
-
|
|
1373
|
+
prepareClonedData(originalData, entityDefinition) {
|
|
1374
|
+
const clonedData = { ...originalData };
|
|
1375
|
+
// Remove unique identifiers and system fields
|
|
1376
|
+
delete clonedData.id;
|
|
1377
|
+
delete clonedData.createdAt;
|
|
1378
|
+
delete clonedData.updatedAt;
|
|
1379
|
+
delete clonedData.createdBy;
|
|
1380
|
+
delete clonedData.updatedBy;
|
|
1381
|
+
delete clonedData.version;
|
|
1382
|
+
delete clonedData.isArchived;
|
|
1383
|
+
delete clonedData.archivedAt;
|
|
1384
|
+
// Update title to indicate it's a clone
|
|
1385
|
+
if (clonedData.title) {
|
|
1386
|
+
clonedData.title = `${clonedData.title} (Copy)`;
|
|
1387
|
+
}
|
|
1388
|
+
// Update name to indicate it's a clone
|
|
1389
|
+
if (clonedData.name) {
|
|
1390
|
+
clonedData.name = `${clonedData.name} (Copy)`;
|
|
1391
|
+
}
|
|
1392
|
+
// Update code if it exists
|
|
1393
|
+
if (clonedData.code) {
|
|
1394
|
+
clonedData.code = `${clonedData.code}_COPY`;
|
|
1395
|
+
}
|
|
1396
|
+
// Handle parent relationships if they exist
|
|
1397
|
+
if (entityDefinition.parentKey && clonedData[entityDefinition.parentKey]) {
|
|
1398
|
+
// Keep the parent relationship - don't delete
|
|
1399
|
+
}
|
|
1400
|
+
// Reset status fields to default values
|
|
1401
|
+
if (clonedData.isActive !== undefined) {
|
|
1402
|
+
clonedData.isActive = true;
|
|
1403
|
+
}
|
|
1404
|
+
if (clonedData.status !== undefined) {
|
|
1405
|
+
clonedData.status = 'draft'; // or appropriate default status
|
|
1406
|
+
}
|
|
1407
|
+
return clonedData;
|
|
682
1408
|
}
|
|
1409
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1410
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneAction }); }
|
|
683
1411
|
}
|
|
684
|
-
|
|
685
|
-
|
|
686
|
-
|
|
687
|
-
|
|
688
|
-
this.popupService = inject(AXPopupService);
|
|
689
|
-
this.translate = inject(AXTranslationService);
|
|
690
|
-
}
|
|
1412
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneAction, decorators: [{
|
|
1413
|
+
type: Injectable
|
|
1414
|
+
}] });
|
|
1415
|
+
class AXPEntityCloneSuccessAction extends AXPWorkflowAction {
|
|
691
1416
|
async execute(context) {
|
|
692
|
-
const
|
|
693
|
-
|
|
694
|
-
|
|
695
|
-
|
|
696
|
-
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
1417
|
+
const refType = context.getVariable('options.refType');
|
|
1418
|
+
const originalId = context.getOutput('originalId');
|
|
1419
|
+
const newId = context.getOutput('newId');
|
|
1420
|
+
const meta = context.getVariable('meta');
|
|
1421
|
+
// Dispatch clone event
|
|
1422
|
+
this.dispatch(AXPEntityClonedEvent({
|
|
1423
|
+
entity: refType,
|
|
1424
|
+
originalId,
|
|
1425
|
+
newId,
|
|
1426
|
+
meta
|
|
1427
|
+
}));
|
|
1428
|
+
// Refresh the entity list
|
|
1429
|
+
this.dispatch(AXPRefreshEvent({
|
|
1430
|
+
entity: refType,
|
|
1431
|
+
meta
|
|
1432
|
+
}));
|
|
704
1433
|
}
|
|
705
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
706
|
-
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1434
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneSuccessAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1435
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneSuccessAction }); }
|
|
707
1436
|
}
|
|
708
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1437
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPEntityCloneSuccessAction, decorators: [{
|
|
709
1438
|
type: Injectable
|
|
710
1439
|
}] });
|
|
711
|
-
const
|
|
712
|
-
startStepId: '
|
|
1440
|
+
const AXPCloneEntityWorkflow = {
|
|
1441
|
+
startStepId: 'clone-entity',
|
|
713
1442
|
steps: {
|
|
714
|
-
|
|
715
|
-
action: '
|
|
1443
|
+
'clone-entity': {
|
|
1444
|
+
action: 'AXPEntityCloneAction',
|
|
1445
|
+
nextSteps: [
|
|
1446
|
+
{
|
|
1447
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
1448
|
+
nextStepId: 'show-success-toast',
|
|
1449
|
+
},
|
|
1450
|
+
],
|
|
1451
|
+
},
|
|
1452
|
+
'show-success-toast': {
|
|
1453
|
+
action: 'AXPToastAction',
|
|
1454
|
+
input: {
|
|
1455
|
+
color: 'success',
|
|
1456
|
+
title: 'workflow.entity-cloned',
|
|
1457
|
+
content: 'workflow.entity-cloned-body',
|
|
1458
|
+
},
|
|
1459
|
+
nextSteps: [
|
|
1460
|
+
{
|
|
1461
|
+
conditions: [],
|
|
1462
|
+
nextStepId: 'clone-success',
|
|
1463
|
+
},
|
|
1464
|
+
],
|
|
1465
|
+
},
|
|
1466
|
+
'clone-success': {
|
|
1467
|
+
action: 'AXPEntityCloneSuccessAction',
|
|
716
1468
|
},
|
|
717
1469
|
},
|
|
718
1470
|
};
|
|
719
1471
|
|
|
720
|
-
|
|
721
|
-
|
|
722
|
-
|
|
723
|
-
|
|
724
|
-
|
|
725
|
-
const backend = inject(AXP_ENTITY_STORAGE_BACKEND);
|
|
726
|
-
// Capture previous for update/delete
|
|
727
|
-
if (ctx.op === 'update' || ctx.op === 'delete') {
|
|
728
|
-
try {
|
|
729
|
-
ctx.previous = await ctx.backend.getOneRaw(ctx.entityName, ctx.id);
|
|
730
|
-
}
|
|
731
|
-
catch { /* ignore */ }
|
|
732
|
-
}
|
|
733
|
-
await next();
|
|
734
|
-
// Build history entry
|
|
735
|
-
const now = new Date();
|
|
736
|
-
const [moduleName, entityModuleName] = ctx.entityName.split('.');
|
|
737
|
-
const entityConfig = await entityRegistry.resolve(moduleName, entityModuleName);
|
|
738
|
-
const actions = [];
|
|
739
|
-
if (ctx.op === 'update' && ctx.previous && ctx.result) {
|
|
740
|
-
const changes = detectEntityChanges(ctx.previous, ctx.result);
|
|
741
|
-
// Build actions similar to old addToHistory mapping by widget type
|
|
742
|
-
if (entityConfig) {
|
|
743
|
-
for (const [key, value] of Object.entries(changes)) {
|
|
744
|
-
const property = entityConfig.properties.find((p) => p.name === key);
|
|
745
|
-
if (property && property.schema?.interface) {
|
|
746
|
-
const widgetType = property.schema.interface.type;
|
|
747
|
-
switch (widgetType) {
|
|
748
|
-
case 'file-uploader':
|
|
749
|
-
if (value.added?.length) {
|
|
750
|
-
actions.push({
|
|
751
|
-
type: AXPSystemActionType.Upload,
|
|
752
|
-
description: `"${value.added?.map((item) => item.name).join(', ')}"`,
|
|
753
|
-
});
|
|
754
|
-
}
|
|
755
|
-
if (value.removed?.length) {
|
|
756
|
-
actions.push({
|
|
757
|
-
type: AXPSystemActionType.Delete,
|
|
758
|
-
description: `"${value.removed?.map((item) => item.name).join(', ')}"`,
|
|
759
|
-
});
|
|
760
|
-
}
|
|
761
|
-
break;
|
|
762
|
-
case 'large-text-editor':
|
|
763
|
-
case 'rich-text-editor': {
|
|
764
|
-
const safeValue = extractTextFromHtml(value.newValue);
|
|
765
|
-
actions.push({
|
|
766
|
-
type: AXPSystemActionType.Update,
|
|
767
|
-
description: `${property.title} to "${safeValue.length > 100 ? safeValue.slice(0, 30) + '...' : safeValue}"`,
|
|
768
|
-
});
|
|
769
|
-
break;
|
|
770
|
-
}
|
|
771
|
-
case 'text-editor':
|
|
772
|
-
actions.push({
|
|
773
|
-
type: AXPSystemActionType.Update,
|
|
774
|
-
description: `${property.title} to "${value.newValue.length > 100 ? value.newValue.slice(0, 30) + '...' : value.newValue}"`,
|
|
775
|
-
});
|
|
776
|
-
break;
|
|
777
|
-
default:
|
|
778
|
-
actions.push({ type: AXPSystemActionType.Update, description: `${property.title}` });
|
|
779
|
-
}
|
|
780
|
-
}
|
|
781
|
-
}
|
|
782
|
-
}
|
|
783
|
-
// Expose raw changes to event middleware
|
|
784
|
-
ctx.locals.set('changes', changes);
|
|
785
|
-
}
|
|
786
|
-
// Compute reference ID and final data per operation
|
|
787
|
-
let referenceId;
|
|
788
|
-
let finalData = undefined;
|
|
789
|
-
if (ctx.op === 'create') {
|
|
790
|
-
const createdId = String(ctx.result);
|
|
791
|
-
const createdEntity = { ...ctx.data, id: createdId };
|
|
792
|
-
referenceId = createdId;
|
|
793
|
-
finalData = createdEntity;
|
|
794
|
-
}
|
|
795
|
-
else if (ctx.op === 'update') {
|
|
796
|
-
referenceId = String(ctx.id);
|
|
797
|
-
finalData = ctx.result;
|
|
798
|
-
}
|
|
799
|
-
else {
|
|
800
|
-
// delete
|
|
801
|
-
referenceId = String(ctx.id);
|
|
802
|
-
finalData = ctx.previous;
|
|
803
|
-
}
|
|
804
|
-
const record = {
|
|
805
|
-
id: AXPDataGenerator.uuid(),
|
|
806
|
-
title: entityConfig?.title ?? now.toISOString(),
|
|
807
|
-
date: now,
|
|
808
|
-
user: {
|
|
809
|
-
id: sessionService.user?.id ?? 'system',
|
|
810
|
-
name: sessionService.user?.name ?? 'System',
|
|
811
|
-
title: sessionService.user?.title ?? 'System',
|
|
812
|
-
},
|
|
813
|
-
reference: { id: referenceId, type: ctx.entityName },
|
|
814
|
-
changeType: ctx.op === 'create'
|
|
815
|
-
? AXPSystemActionType.Create
|
|
816
|
-
: ctx.op === 'update'
|
|
817
|
-
? AXPSystemActionType.Update
|
|
818
|
-
: AXPSystemActionType.Delete,
|
|
819
|
-
changes: actions,
|
|
820
|
-
data: finalData,
|
|
821
|
-
};
|
|
822
|
-
// Persist via backend raw insert to avoid recursive middleware
|
|
823
|
-
try {
|
|
824
|
-
await backend.insertOne(`${ctx.entityName}-history`, { ...record, isCurrent: true });
|
|
825
|
-
}
|
|
826
|
-
catch (error) {
|
|
827
|
-
console.error(error);
|
|
828
|
-
// swallow errors to avoid breaking main flow
|
|
829
|
-
}
|
|
830
|
-
},
|
|
831
|
-
};
|
|
832
|
-
|
|
833
|
-
const historyPlugin = {
|
|
834
|
-
name: 'history',
|
|
835
|
-
order: 50,
|
|
836
|
-
apply: (ctx) => {
|
|
837
|
-
ensureListActions(ctx);
|
|
838
|
-
ctx.interfaces.update((i) => {
|
|
839
|
-
const cmdName = 'show-version-history-popup';
|
|
840
|
-
//
|
|
841
|
-
const listActions = i.master.list.actions;
|
|
842
|
-
if (!actionExists(listActions, cmdName)) {
|
|
843
|
-
listActions.push({
|
|
844
|
-
title: '@activity-log:actions.view-history',
|
|
845
|
-
command: {
|
|
846
|
-
name: cmdName,
|
|
847
|
-
options: {
|
|
848
|
-
refId: '{{ context.eval("id") }}',
|
|
849
|
-
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
850
|
-
},
|
|
851
|
-
},
|
|
852
|
-
priority: 'secondary',
|
|
853
|
-
type: 'version-history',
|
|
854
|
-
scope: AXPEntityCommandScope.Individual,
|
|
855
|
-
});
|
|
856
|
-
}
|
|
857
|
-
//
|
|
858
|
-
const singleActions = i.master.single.actions;
|
|
859
|
-
if (!actionExists(singleActions, cmdName)) {
|
|
860
|
-
singleActions.push({
|
|
861
|
-
title: '@activity-log:actions.view-history',
|
|
862
|
-
command: {
|
|
863
|
-
name: cmdName,
|
|
864
|
-
options: {
|
|
865
|
-
refId: '{{ context.eval("id") }}',
|
|
866
|
-
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
867
|
-
},
|
|
868
|
-
},
|
|
869
|
-
priority: 'secondary',
|
|
870
|
-
type: 'version-history',
|
|
871
|
-
scope: AXPEntityCommandScope.Individual,
|
|
872
|
-
});
|
|
873
|
-
}
|
|
874
|
-
//
|
|
875
|
-
return i;
|
|
876
|
-
});
|
|
877
|
-
},
|
|
878
|
-
};
|
|
879
|
-
|
|
880
|
-
const comparePlugin = {
|
|
881
|
-
name: 'compare',
|
|
882
|
-
order: 50,
|
|
883
|
-
apply: (ctx) => {
|
|
884
|
-
ensureListActions(ctx);
|
|
885
|
-
ctx.interfaces.update((i) => {
|
|
886
|
-
const actions = i.master.list.actions;
|
|
887
|
-
const cmdName = 'show-entity-records-compare';
|
|
888
|
-
if (!actionExists(actions, cmdName)) {
|
|
889
|
-
actions.push({
|
|
890
|
-
title: '@activity-log:actions.compare-records',
|
|
891
|
-
command: { name: cmdName },
|
|
892
|
-
priority: 'secondary',
|
|
893
|
-
type: 'compare',
|
|
894
|
-
scope: AXPEntityCommandScope.Selected,
|
|
895
|
-
});
|
|
896
|
-
}
|
|
897
|
-
return i;
|
|
898
|
-
});
|
|
899
|
-
},
|
|
900
|
-
};
|
|
901
|
-
|
|
902
|
-
class AXPVersionHistoryModule {
|
|
903
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
904
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, imports: [i1$1.AXPWorkflowModule] }); }
|
|
905
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, providers: [
|
|
906
|
-
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: historyLoggerMiddleware },
|
|
907
|
-
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: historyPlugin },
|
|
908
|
-
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: comparePlugin },
|
|
1472
|
+
class AXPClonePluginModule {
|
|
1473
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPClonePluginModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1474
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPClonePluginModule, imports: [i1.AXPWorkflowModule] }); }
|
|
1475
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPClonePluginModule, providers: [
|
|
1476
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: clonePlugin },
|
|
909
1477
|
], imports: [AXPWorkflowModule.forChild({
|
|
910
1478
|
actions: {
|
|
911
|
-
|
|
1479
|
+
AXPEntityCloneAction,
|
|
1480
|
+
AXPEntityCloneSuccessAction,
|
|
912
1481
|
},
|
|
913
1482
|
workflows: {
|
|
914
|
-
'
|
|
1483
|
+
'clone-entity': AXPCloneEntityWorkflow,
|
|
915
1484
|
},
|
|
916
1485
|
})] }); }
|
|
917
1486
|
}
|
|
918
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1487
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPClonePluginModule, decorators: [{
|
|
919
1488
|
type: NgModule,
|
|
920
1489
|
args: [{
|
|
921
1490
|
imports: [
|
|
922
1491
|
AXPWorkflowModule.forChild({
|
|
923
1492
|
actions: {
|
|
924
|
-
|
|
1493
|
+
AXPEntityCloneAction,
|
|
1494
|
+
AXPEntityCloneSuccessAction,
|
|
925
1495
|
},
|
|
926
1496
|
workflows: {
|
|
927
|
-
'
|
|
1497
|
+
'clone-entity': AXPCloneEntityWorkflow,
|
|
928
1498
|
},
|
|
929
1499
|
}),
|
|
930
1500
|
],
|
|
931
|
-
exports: [],
|
|
932
1501
|
providers: [
|
|
933
|
-
{ provide:
|
|
934
|
-
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: historyPlugin },
|
|
935
|
-
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: comparePlugin },
|
|
1502
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: clonePlugin },
|
|
936
1503
|
],
|
|
937
1504
|
}]
|
|
938
1505
|
}] });
|
|
939
1506
|
|
|
940
|
-
class
|
|
1507
|
+
class AXPComparePopupComponent extends AXBasePageComponent {
|
|
941
1508
|
constructor() {
|
|
942
|
-
|
|
1509
|
+
super(...arguments);
|
|
1510
|
+
this.inputs = input(...(ngDevMode ? [undefined, { debugName: "inputs" }] : []));
|
|
1511
|
+
this.isBusy = signal(false, ...(ngDevMode ? [{ debugName: "isBusy" }] : []));
|
|
1512
|
+
this.mode = input('compare', ...(ngDevMode ? [{ debugName: "mode" }] : []));
|
|
943
1513
|
}
|
|
944
|
-
|
|
945
|
-
|
|
946
|
-
|
|
947
|
-
return this.calendarService.now();
|
|
948
|
-
},
|
|
949
|
-
tomorrow: () => {
|
|
950
|
-
return this.calendarService.create(this.calendarService.now()).add('day', 1).startOf('day').date;
|
|
951
|
-
},
|
|
952
|
-
yesterday: () => {
|
|
953
|
-
return this.calendarService.create(this.calendarService.now()).add('day', -1).startOf('day').date;
|
|
954
|
-
},
|
|
955
|
-
addDays: (date, days) => {
|
|
956
|
-
return this.calendarService.create(date).add('day', days).date;
|
|
957
|
-
},
|
|
958
|
-
});
|
|
1514
|
+
ngOnInit() {
|
|
1515
|
+
super.ngOnInit();
|
|
1516
|
+
// Any additional initialization logic can go here
|
|
959
1517
|
}
|
|
1518
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComparePopupComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1519
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "20.1.6", type: AXPComparePopupComponent, isStandalone: true, selector: "axp-compare-popup", inputs: { inputs: { classPropertyName: "inputs", publicName: "inputs", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, providers: [], usesInheritance: true, ngImport: i0, template: "<ax-content>\n <div class=\"ax-p-6 ax-min-h-[30vh] ax-overflow-y-auto\">\n <axp-compare-view [inputs]=\"inputs()\" [mode]=\"mode()\"></axp-compare-view>\n </div>\n</ax-content>\n<ax-footer>\n <ax-prefix></ax-prefix>\n <ax-suffix>\n <ax-button [text]=\"'close' | translate | async\" look=\"solid\" color=\"primary\" (onClick)=\"close()\"> </ax-button>\n </ax-suffix>\n</ax-footer>", dependencies: [{ kind: "ngmodule", type:
|
|
1520
|
+
// Angular
|
|
1521
|
+
CommonModule }, { kind: "ngmodule", type:
|
|
1522
|
+
// ACoreX
|
|
1523
|
+
AXDecoratorModule }, { kind: "component", type: i1$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "component", type:
|
|
1524
|
+
// Compare View
|
|
1525
|
+
AXPCompareViewComponent, selector: "axp-compare-view", inputs: ["inputs", "mode"] }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }, { kind: "pipe", type: i4.AXTranslatorPipe, name: "translate" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
960
1526
|
}
|
|
1527
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComparePopupComponent, decorators: [{
|
|
1528
|
+
type: Component,
|
|
1529
|
+
args: [{ selector: 'axp-compare-popup', standalone: true, imports: [
|
|
1530
|
+
// Angular
|
|
1531
|
+
CommonModule,
|
|
1532
|
+
// ACoreX
|
|
1533
|
+
AXDecoratorModule,
|
|
1534
|
+
AXButtonModule,
|
|
1535
|
+
AXTranslationModule,
|
|
1536
|
+
// Compare View
|
|
1537
|
+
AXPCompareViewComponent
|
|
1538
|
+
], encapsulation: ViewEncapsulation.None, providers: [], template: "<ax-content>\n <div class=\"ax-p-6 ax-min-h-[30vh] ax-overflow-y-auto\">\n <axp-compare-view [inputs]=\"inputs()\" [mode]=\"mode()\"></axp-compare-view>\n </div>\n</ax-content>\n<ax-footer>\n <ax-prefix></ax-prefix>\n <ax-suffix>\n <ax-button [text]=\"'close' | translate | async\" look=\"solid\" color=\"primary\" (onClick)=\"close()\"> </ax-button>\n </ax-suffix>\n</ax-footer>" }]
|
|
1539
|
+
}] });
|
|
961
1540
|
|
|
962
|
-
|
|
1541
|
+
var comparePopup_component = /*#__PURE__*/Object.freeze({
|
|
1542
|
+
__proto__: null,
|
|
1543
|
+
AXPComparePopupComponent: AXPComparePopupComponent
|
|
1544
|
+
});
|
|
1545
|
+
|
|
1546
|
+
class AXMComparePopupStartAction extends AXPWorkflowAction {
|
|
963
1547
|
constructor() {
|
|
964
|
-
|
|
1548
|
+
super(...arguments);
|
|
1549
|
+
this.popupService = inject(AXPopupService);
|
|
1550
|
+
this.translate = inject(AXTranslationService);
|
|
965
1551
|
}
|
|
966
|
-
async
|
|
967
|
-
|
|
968
|
-
|
|
969
|
-
|
|
1552
|
+
async execute(context) {
|
|
1553
|
+
const comp = (await Promise.resolve().then(function () { return comparePopup_component; })).AXPComparePopupComponent;
|
|
1554
|
+
this.popupService.open(comp, {
|
|
1555
|
+
title: await this.translate.translateAsync('Compare'),
|
|
1556
|
+
size: 'lg',
|
|
1557
|
+
data: {
|
|
1558
|
+
inputs: signal(context.getVariable('inputs')),
|
|
1559
|
+
mode: signal(context.getVariable('mode')),
|
|
970
1560
|
},
|
|
971
1561
|
});
|
|
972
1562
|
}
|
|
1563
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMComparePopupStartAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1564
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMComparePopupStartAction }); }
|
|
973
1565
|
}
|
|
974
|
-
|
|
975
|
-
|
|
976
|
-
|
|
977
|
-
|
|
978
|
-
const lockService = inject(AXPLockService);
|
|
979
|
-
const session = inject(AXPSessionService);
|
|
980
|
-
const lock = await lockService.check({ refId: ctx.id, refType: ctx.entityName });
|
|
981
|
-
if (lock) {
|
|
982
|
-
const info = await lockService.getInfo({ refId: ctx.id, refType: ctx.entityName });
|
|
983
|
-
if (info && session.user && info.lockedBy.id !== session.user.id) {
|
|
984
|
-
throw new Error('This record is locked and cannot be edited.');
|
|
985
|
-
}
|
|
986
|
-
}
|
|
987
|
-
await next();
|
|
988
|
-
},
|
|
989
|
-
};
|
|
990
|
-
|
|
991
|
-
class AXMLockPopupWorkflowAction extends AXPWorkflowAction {
|
|
1566
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMComparePopupStartAction, decorators: [{
|
|
1567
|
+
type: Injectable
|
|
1568
|
+
}] });
|
|
1569
|
+
class AXMCompareEntityRecordsAction extends AXPWorkflowAction {
|
|
992
1570
|
constructor() {
|
|
993
1571
|
super(...arguments);
|
|
994
|
-
this.
|
|
995
|
-
this.translationService = inject(AXTranslationService);
|
|
1572
|
+
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
996
1573
|
}
|
|
997
1574
|
async execute(context) {
|
|
998
|
-
const
|
|
999
|
-
const
|
|
1000
|
-
|
|
1001
|
-
|
|
1002
|
-
|
|
1003
|
-
|
|
1575
|
+
const [moduleName, entityName] = context.getVariable('entity').split('.');
|
|
1576
|
+
const entityRef = await this.entityRegistry.resolve(moduleName, entityName);
|
|
1577
|
+
const records = context.getVariable('data');
|
|
1578
|
+
const ids = records?.map((r) => r.id);
|
|
1579
|
+
const getById = entityRef.queries.byKey?.execute;
|
|
1580
|
+
//
|
|
1581
|
+
const fields = entityRef.properties
|
|
1582
|
+
.filter(p => p.schema.interface && p.schema.hidden != true)
|
|
1583
|
+
.map((p) => ({
|
|
1584
|
+
path: p.name,
|
|
1585
|
+
title: p.title,
|
|
1586
|
+
description: p.description,
|
|
1587
|
+
widget: {
|
|
1588
|
+
type: p.schema.interface?.type,
|
|
1589
|
+
name: p.name,
|
|
1590
|
+
path: p.name,
|
|
1591
|
+
options: p.schema.interface?.options,
|
|
1004
1592
|
},
|
|
1005
|
-
});
|
|
1006
|
-
|
|
1007
|
-
|
|
1008
|
-
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
|
|
1012
|
-
|
|
1013
|
-
|
|
1014
|
-
|
|
1015
|
-
|
|
1593
|
+
}));
|
|
1594
|
+
const objects = await Promise.all(ids.map(async (c) => {
|
|
1595
|
+
const object = await getById(c);
|
|
1596
|
+
return {
|
|
1597
|
+
id: object.id,
|
|
1598
|
+
title: object.title,
|
|
1599
|
+
description: object.description,
|
|
1600
|
+
context: object,
|
|
1601
|
+
};
|
|
1602
|
+
}));
|
|
1603
|
+
const inputs = {
|
|
1604
|
+
fields: fields,
|
|
1605
|
+
objects: objects,
|
|
1606
|
+
};
|
|
1607
|
+
//
|
|
1608
|
+
context.setVariable('inputs', inputs);
|
|
1609
|
+
context.setVariable('mode', 'records');
|
|
1610
|
+
context.setOutput('result', true);
|
|
1016
1611
|
}
|
|
1612
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordsAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1613
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordsAction }); }
|
|
1017
1614
|
}
|
|
1018
|
-
|
|
1019
|
-
|
|
1020
|
-
|
|
1021
|
-
|
|
1022
|
-
action: 'AXMLockPopupWorkflowAction',
|
|
1023
|
-
nextSteps: [
|
|
1024
|
-
{
|
|
1025
|
-
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
1026
|
-
nextStepId: 'successToast',
|
|
1027
|
-
},
|
|
1028
|
-
],
|
|
1029
|
-
},
|
|
1030
|
-
successToast: {
|
|
1031
|
-
id: 'successToast',
|
|
1032
|
-
action: 'AXPToastAction',
|
|
1033
|
-
input: {
|
|
1034
|
-
color: 'success',
|
|
1035
|
-
title: 'workflow.entity-modified-title',
|
|
1036
|
-
content: 'workflow.entity-modified-body',
|
|
1037
|
-
},
|
|
1038
|
-
nextSteps: [
|
|
1039
|
-
{
|
|
1040
|
-
conditions: [],
|
|
1041
|
-
nextStepId: 'modifyConfirmed',
|
|
1042
|
-
},
|
|
1043
|
-
],
|
|
1044
|
-
},
|
|
1045
|
-
modifyConfirmed: {
|
|
1046
|
-
id: 'modifyConfirmed',
|
|
1047
|
-
action: 'AXPEntityModifyConfirmedAction',
|
|
1048
|
-
},
|
|
1049
|
-
},
|
|
1050
|
-
};
|
|
1051
|
-
|
|
1052
|
-
class AXMUnlockConfirmWorkflowAction extends AXPWorkflowAction {
|
|
1615
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordsAction, decorators: [{
|
|
1616
|
+
type: Injectable
|
|
1617
|
+
}] });
|
|
1618
|
+
class AXMCompareEntityRecordVersionsAction extends AXPWorkflowAction {
|
|
1053
1619
|
constructor() {
|
|
1054
1620
|
super(...arguments);
|
|
1055
|
-
this.
|
|
1056
|
-
this.
|
|
1057
|
-
this.
|
|
1058
|
-
this.
|
|
1621
|
+
this.entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
1622
|
+
this.activityLogService = inject(AXPActivityLogService);
|
|
1623
|
+
this.formatService = inject(AXFormatService);
|
|
1624
|
+
this.translate = inject(AXTranslationService);
|
|
1059
1625
|
}
|
|
1060
1626
|
async execute(context) {
|
|
1061
|
-
const
|
|
1062
|
-
const
|
|
1063
|
-
|
|
1064
|
-
const
|
|
1065
|
-
|
|
1066
|
-
|
|
1067
|
-
|
|
1068
|
-
|
|
1069
|
-
|
|
1070
|
-
|
|
1071
|
-
|
|
1072
|
-
|
|
1073
|
-
|
|
1074
|
-
|
|
1075
|
-
|
|
1076
|
-
|
|
1077
|
-
|
|
1078
|
-
|
|
1079
|
-
|
|
1080
|
-
|
|
1081
|
-
|
|
1082
|
-
|
|
1083
|
-
|
|
1084
|
-
|
|
1085
|
-
|
|
1086
|
-
|
|
1087
|
-
|
|
1627
|
+
const [moduleName, entityName] = context.getVariable('entity').split('.');
|
|
1628
|
+
const entityRef = await this.entityRegistry.resolve(moduleName, entityName);
|
|
1629
|
+
const refId = context.getVariable('data.refId');
|
|
1630
|
+
const refType = context.getVariable('data.refType');
|
|
1631
|
+
const ids = context.getVariable('data.ids');
|
|
1632
|
+
const histories = await this.activityLogService.getHistoryByIds(refId, refType, ids);
|
|
1633
|
+
//
|
|
1634
|
+
const fields = entityRef.properties
|
|
1635
|
+
.filter(p => p.schema.interface && p.schema.hidden != true)
|
|
1636
|
+
.map((p) => ({
|
|
1637
|
+
path: p.name,
|
|
1638
|
+
title: p.title,
|
|
1639
|
+
description: p.description,
|
|
1640
|
+
widget: {
|
|
1641
|
+
type: p.schema.interface?.type,
|
|
1642
|
+
name: p.name,
|
|
1643
|
+
path: p.name,
|
|
1644
|
+
options: p.schema.interface?.options,
|
|
1645
|
+
},
|
|
1646
|
+
}));
|
|
1647
|
+
const objects = await Promise.all(histories.map(async (h) => ({
|
|
1648
|
+
id: h.id,
|
|
1649
|
+
title: await this.translate.translateAsync(`@activity-log:${h.changeType == 'update' ? 'updated' : 'created'}-by-title`, {
|
|
1650
|
+
params: {
|
|
1651
|
+
user: h.user?.title,
|
|
1652
|
+
date: this.formatService.format(h.date, 'datetime', { format: 'short' }),
|
|
1653
|
+
}
|
|
1654
|
+
}),
|
|
1655
|
+
description: h.user?.title,
|
|
1656
|
+
context: h.data,
|
|
1657
|
+
})));
|
|
1658
|
+
const inputs = {
|
|
1659
|
+
fields: fields,
|
|
1660
|
+
objects: objects,
|
|
1661
|
+
};
|
|
1662
|
+
//
|
|
1663
|
+
context.setVariable('inputs', inputs);
|
|
1664
|
+
context.setVariable('mode', 'changes');
|
|
1665
|
+
context.setOutput('result', true);
|
|
1088
1666
|
}
|
|
1667
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordVersionsAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1668
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordVersionsAction }); }
|
|
1089
1669
|
}
|
|
1090
|
-
|
|
1091
|
-
|
|
1670
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCompareEntityRecordVersionsAction, decorators: [{
|
|
1671
|
+
type: Injectable
|
|
1672
|
+
}] });
|
|
1673
|
+
const AXMCompareEntityRecordsWorkflow = {
|
|
1674
|
+
startStepId: 'start',
|
|
1092
1675
|
steps: {
|
|
1093
|
-
|
|
1094
|
-
action: '
|
|
1676
|
+
start: {
|
|
1677
|
+
action: 'show-entity-records-compare-action',
|
|
1095
1678
|
nextSteps: [
|
|
1096
1679
|
{
|
|
1097
|
-
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("
|
|
1098
|
-
nextStepId: '
|
|
1099
|
-
}
|
|
1680
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("result") == true' }],
|
|
1681
|
+
nextStepId: 'show-popup',
|
|
1682
|
+
}
|
|
1100
1683
|
],
|
|
1101
1684
|
},
|
|
1102
|
-
|
|
1103
|
-
|
|
1104
|
-
|
|
1105
|
-
|
|
1106
|
-
|
|
1107
|
-
|
|
1108
|
-
|
|
1109
|
-
|
|
1685
|
+
'show-popup': {
|
|
1686
|
+
action: 'show-compare-popup-action',
|
|
1687
|
+
},
|
|
1688
|
+
},
|
|
1689
|
+
};
|
|
1690
|
+
const AXMCompareEntityRecordVersionsWorkflow = {
|
|
1691
|
+
startStepId: 'start',
|
|
1692
|
+
steps: {
|
|
1693
|
+
start: {
|
|
1694
|
+
action: 'show-entity-record-versions-compare-action',
|
|
1110
1695
|
nextSteps: [
|
|
1111
1696
|
{
|
|
1112
|
-
conditions: [],
|
|
1113
|
-
nextStepId: '
|
|
1114
|
-
}
|
|
1697
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("result") == true' }],
|
|
1698
|
+
nextStepId: 'show-popup',
|
|
1699
|
+
}
|
|
1115
1700
|
],
|
|
1116
1701
|
},
|
|
1117
|
-
|
|
1118
|
-
|
|
1119
|
-
action: 'AXPEntityModifyConfirmedAction',
|
|
1702
|
+
'show-popup': {
|
|
1703
|
+
action: 'show-compare-popup-action',
|
|
1120
1704
|
},
|
|
1121
1705
|
},
|
|
1122
1706
|
};
|
|
1123
1707
|
|
|
1124
|
-
class
|
|
1125
|
-
|
|
1126
|
-
|
|
1127
|
-
|
|
1128
|
-
|
|
1129
|
-
context.addScope('lock', {
|
|
1130
|
-
check: async (refId, refType) => {
|
|
1131
|
-
const lock = await this.lockService.check({
|
|
1132
|
-
refId, refType
|
|
1133
|
-
});
|
|
1134
|
-
return lock;
|
|
1135
|
-
}
|
|
1136
|
-
});
|
|
1137
|
-
}
|
|
1138
|
-
}
|
|
1139
|
-
|
|
1140
|
-
const lockPlugin = {
|
|
1141
|
-
name: 'lock',
|
|
1142
|
-
order: 50,
|
|
1143
|
-
apply: (ctx) => {
|
|
1144
|
-
ensureListActions(ctx);
|
|
1145
|
-
ctx.interfaces.update((i) => {
|
|
1146
|
-
const actions = i.master.list.actions;
|
|
1147
|
-
if (!actions.some((a) => a.name === 'lock-entity')) {
|
|
1148
|
-
actions.push({
|
|
1149
|
-
title: '@lock-system:lock.title',
|
|
1150
|
-
name: 'lock-entity',
|
|
1151
|
-
command: {
|
|
1152
|
-
name: 'lock-popup',
|
|
1153
|
-
options: {
|
|
1154
|
-
refId: '{{ context.eval("id") }}',
|
|
1155
|
-
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1156
|
-
},
|
|
1157
|
-
},
|
|
1158
|
-
priority: 'secondary',
|
|
1159
|
-
type: 'lock',
|
|
1160
|
-
scope: AXPEntityCommandScope.Individual,
|
|
1161
|
-
hidden: `{{ lock.check(context.eval("id"), "${ctx.entity.module}.${ctx.entity.name}") }}`,
|
|
1162
|
-
});
|
|
1163
|
-
}
|
|
1164
|
-
if (!actions.some((a) => a.name === 'unlock-entity')) {
|
|
1165
|
-
actions.push({
|
|
1166
|
-
title: '@lock-system:unlock.title',
|
|
1167
|
-
name: 'unlock-entity',
|
|
1168
|
-
command: {
|
|
1169
|
-
name: 'unlock-confirm',
|
|
1170
|
-
options: {
|
|
1171
|
-
refId: '{{ context.eval("id") }}',
|
|
1172
|
-
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1173
|
-
},
|
|
1174
|
-
},
|
|
1175
|
-
priority: 'secondary',
|
|
1176
|
-
type: 'unlock',
|
|
1177
|
-
scope: AXPEntityCommandScope.Individual,
|
|
1178
|
-
hidden: `{{ (await lock.check(context.eval("id"), "${ctx.entity.module}.${ctx.entity.name}")) == false }}`,
|
|
1179
|
-
});
|
|
1180
|
-
}
|
|
1181
|
-
return i;
|
|
1182
|
-
});
|
|
1183
|
-
},
|
|
1184
|
-
};
|
|
1185
|
-
|
|
1186
|
-
class AXMLockSystemModule {
|
|
1187
|
-
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1188
|
-
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, imports: [i1$1.AXPWorkflowModule] }); }
|
|
1189
|
-
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, providers: [
|
|
1190
|
-
{ provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, multi: true, useClass: AXMLockEvaluatorScopeProvider },
|
|
1191
|
-
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: lockPlugin },
|
|
1192
|
-
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: lockGuardMiddleware },
|
|
1193
|
-
], imports: [AXPWorkflowModule.forChild({
|
|
1708
|
+
class AXPCompareModule {
|
|
1709
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1710
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareModule, imports: [AXPComparePopupComponent, i1.AXPWorkflowModule], exports: [AXPComparePopupComponent] }); }
|
|
1711
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareModule, imports: [AXPComparePopupComponent,
|
|
1712
|
+
AXPWorkflowModule.forChild({
|
|
1194
1713
|
actions: {
|
|
1195
|
-
|
|
1196
|
-
|
|
1714
|
+
'show-compare-popup-action': AXMComparePopupStartAction,
|
|
1715
|
+
'show-entity-records-compare-action': AXMCompareEntityRecordsAction,
|
|
1716
|
+
'show-entity-record-versions-compare-action': AXMCompareEntityRecordVersionsAction,
|
|
1197
1717
|
},
|
|
1198
1718
|
workflows: {
|
|
1199
|
-
'
|
|
1200
|
-
'
|
|
1719
|
+
'show-entity-records-compare': AXMCompareEntityRecordsWorkflow,
|
|
1720
|
+
'show-entity-record-versions-compare': AXMCompareEntityRecordVersionsWorkflow,
|
|
1201
1721
|
},
|
|
1202
1722
|
})] }); }
|
|
1203
1723
|
}
|
|
1204
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
1724
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPCompareModule, decorators: [{
|
|
1205
1725
|
type: NgModule,
|
|
1206
1726
|
args: [{
|
|
1207
1727
|
imports: [
|
|
1728
|
+
AXPComparePopupComponent,
|
|
1208
1729
|
AXPWorkflowModule.forChild({
|
|
1209
1730
|
actions: {
|
|
1210
|
-
|
|
1211
|
-
|
|
1731
|
+
'show-compare-popup-action': AXMComparePopupStartAction,
|
|
1732
|
+
'show-entity-records-compare-action': AXMCompareEntityRecordsAction,
|
|
1733
|
+
'show-entity-record-versions-compare-action': AXMCompareEntityRecordVersionsAction,
|
|
1212
1734
|
},
|
|
1213
1735
|
workflows: {
|
|
1214
|
-
'
|
|
1215
|
-
'
|
|
1736
|
+
'show-entity-records-compare': AXMCompareEntityRecordsWorkflow,
|
|
1737
|
+
'show-entity-record-versions-compare': AXMCompareEntityRecordVersionsWorkflow,
|
|
1216
1738
|
},
|
|
1217
1739
|
}),
|
|
1218
1740
|
],
|
|
1741
|
+
exports: [AXPComparePopupComponent],
|
|
1742
|
+
}]
|
|
1743
|
+
}] });
|
|
1744
|
+
|
|
1745
|
+
function extractTemplateTokens(template) {
|
|
1746
|
+
const tokens = [];
|
|
1747
|
+
if (!template) {
|
|
1748
|
+
return tokens;
|
|
1749
|
+
}
|
|
1750
|
+
const regex = /\{\{\s*([\s\S]*?)\s*\}\}/g; // capture lazily until closing }}
|
|
1751
|
+
let match;
|
|
1752
|
+
while ((match = regex.exec(template)) !== null) {
|
|
1753
|
+
const token = (match[1] || '').trim();
|
|
1754
|
+
if (token) {
|
|
1755
|
+
tokens.push(token);
|
|
1756
|
+
}
|
|
1757
|
+
}
|
|
1758
|
+
return tokens;
|
|
1759
|
+
}
|
|
1760
|
+
function getRootFromPath(path) {
|
|
1761
|
+
const trimmed = path.trim();
|
|
1762
|
+
const clean = trimmed.replace(/^context\.eval\(['"]|['"]\)$/g, '');
|
|
1763
|
+
const first = clean.split('.')[0];
|
|
1764
|
+
return first.replace(/\{.*\}$/, '');
|
|
1765
|
+
}
|
|
1766
|
+
function defaultIdField(dataPath) {
|
|
1767
|
+
const leaf = (dataPath || '').split('.').filter(Boolean).pop() || 'related';
|
|
1768
|
+
return `${leaf}Id`;
|
|
1769
|
+
}
|
|
1770
|
+
const computedPropertiesMiddleware = {
|
|
1771
|
+
target: { ops: ['getOne', 'getAll', 'query'], order: 12 },
|
|
1772
|
+
execute: async (ctx, next) => {
|
|
1773
|
+
const backend = inject(AXP_ENTITY_STORAGE_BACKEND);
|
|
1774
|
+
const registry = inject(AXPEntityDefinitionRegistryService);
|
|
1775
|
+
const expressionEvaluator = inject(AXPExpressionEvaluatorService);
|
|
1776
|
+
await next();
|
|
1777
|
+
try {
|
|
1778
|
+
const [moduleName, entityName] = ctx.entityName.split('.');
|
|
1779
|
+
const def = await registry.resolve(moduleName, entityName);
|
|
1780
|
+
const plugin = (def?.plugins || []).find((p) => p?.name === 'computed-property');
|
|
1781
|
+
if (!plugin?.options?.['fields']?.length)
|
|
1782
|
+
return;
|
|
1783
|
+
const fields = plugin.options['fields'];
|
|
1784
|
+
const related = def?.relatedEntities || [];
|
|
1785
|
+
const rows = Array.isArray(ctx.result)
|
|
1786
|
+
? ctx.result
|
|
1787
|
+
: Array.isArray(ctx.result?.items)
|
|
1788
|
+
? ctx.result.items
|
|
1789
|
+
: ctx.result
|
|
1790
|
+
? [ctx.result]
|
|
1791
|
+
: [];
|
|
1792
|
+
if (!rows.length)
|
|
1793
|
+
return;
|
|
1794
|
+
// Pre-hydrate merge-detail children used by fields (by root token)
|
|
1795
|
+
const roots = new Set();
|
|
1796
|
+
for (const f of fields) {
|
|
1797
|
+
const tokens = extractTemplateTokens(f.value);
|
|
1798
|
+
tokens.forEach((t) => roots.add(getRootFromPath(t)));
|
|
1799
|
+
}
|
|
1800
|
+
// For merge-detail referenced children, batch hydrate
|
|
1801
|
+
for (const root of roots) {
|
|
1802
|
+
const re = related.find((r) => r?.persistence?.dataPath === root && (r?.persistence?.strategy || 'embedded') === 'referenced');
|
|
1803
|
+
if (!re)
|
|
1804
|
+
continue;
|
|
1805
|
+
const p = re.persistence || {};
|
|
1806
|
+
const idField = p.idField || defaultIdField(p.dataPath);
|
|
1807
|
+
const ids = Array.from(new Set(rows.map((r) => get(r, idField)).filter((v) => v != null)));
|
|
1808
|
+
if (!ids.length)
|
|
1809
|
+
continue;
|
|
1810
|
+
try {
|
|
1811
|
+
const resp = await backend.query(re.entity, {
|
|
1812
|
+
skip: 0,
|
|
1813
|
+
take: ids.length || 1000,
|
|
1814
|
+
filter: { field: 'id', operator: { type: 'in' }, value: ids },
|
|
1815
|
+
});
|
|
1816
|
+
const items = resp?.items ?? [];
|
|
1817
|
+
const map = new Map();
|
|
1818
|
+
for (const it of items)
|
|
1819
|
+
map.set(it.id, it);
|
|
1820
|
+
for (const row of rows) {
|
|
1821
|
+
const cid = get(row, idField);
|
|
1822
|
+
if (!cid)
|
|
1823
|
+
continue;
|
|
1824
|
+
const child = map.get(cid);
|
|
1825
|
+
if (child && p?.dataPath)
|
|
1826
|
+
set(row, p.dataPath, child);
|
|
1827
|
+
}
|
|
1828
|
+
}
|
|
1829
|
+
catch { }
|
|
1830
|
+
}
|
|
1831
|
+
// Compute per field for each row
|
|
1832
|
+
for (const row of rows) {
|
|
1833
|
+
for (const f of fields) {
|
|
1834
|
+
const tokens = extractTemplateTokens(f.value);
|
|
1835
|
+
// Try to ensure data availability for each token
|
|
1836
|
+
for (const t of tokens) {
|
|
1837
|
+
const raw = String(t).trim();
|
|
1838
|
+
const path = raw.replace(/^context\.eval\(['"]|['"]\)$/g, '');
|
|
1839
|
+
const root = getRootFromPath(path);
|
|
1840
|
+
let current = getSmart(row, root);
|
|
1841
|
+
if (current == null) {
|
|
1842
|
+
// Try merge-detail already covered above. If still missing, try list-related entities by entity name
|
|
1843
|
+
const reList = related.find((r) => (r?.layout?.type === 'page-list' || r?.layout?.type === 'tab-list') &&
|
|
1844
|
+
r?.persistence?.dataPath === root);
|
|
1845
|
+
if (reList) {
|
|
1846
|
+
// Build filters: reList.conditions + field.conditions
|
|
1847
|
+
const baseFilters = (reList.conditions ?? []).map((c) => ({ ...c }));
|
|
1848
|
+
const extraFilters = (f.conditions ?? []).map((c) => ({ ...c }));
|
|
1849
|
+
const buildScope = () => ({ ...(row ?? {}), context: { eval: (path) => get(row, path) } });
|
|
1850
|
+
const evaluateValue = async (val) => {
|
|
1851
|
+
if (typeof val === 'string' && expressionEvaluator.isExpression(val)) {
|
|
1852
|
+
return await expressionEvaluator.evaluate(val, buildScope());
|
|
1853
|
+
}
|
|
1854
|
+
return val;
|
|
1855
|
+
};
|
|
1856
|
+
let allFilters = await Promise.all([...baseFilters, ...extraFilters].map(async (fl) => ({
|
|
1857
|
+
field: fl.name ?? fl.field,
|
|
1858
|
+
operator: fl.operator,
|
|
1859
|
+
value: await evaluateValue(fl.value),
|
|
1860
|
+
})));
|
|
1861
|
+
// If no explicit parent filter exists, infer it: child.parentKey == row.id
|
|
1862
|
+
try {
|
|
1863
|
+
const [cm, ce] = (reList.entity || '').split('.');
|
|
1864
|
+
const childDef = await registry.resolve(cm, ce);
|
|
1865
|
+
const parentKey = childDef?.parentKey;
|
|
1866
|
+
if (parentKey && !allFilters.some((fl) => fl.field === parentKey)) {
|
|
1867
|
+
allFilters.push({ field: parentKey, operator: { type: 'equal' }, value: row?.id });
|
|
1868
|
+
}
|
|
1869
|
+
}
|
|
1870
|
+
catch { }
|
|
1871
|
+
try {
|
|
1872
|
+
const resp = await backend.query(reList.entity, {
|
|
1873
|
+
skip: 0,
|
|
1874
|
+
take: 1000,
|
|
1875
|
+
filter: allFilters.length ? { logic: 'and', filters: allFilters } : undefined,
|
|
1876
|
+
});
|
|
1877
|
+
const items = resp?.items ?? [];
|
|
1878
|
+
set(row, root, items);
|
|
1879
|
+
}
|
|
1880
|
+
catch { }
|
|
1881
|
+
}
|
|
1882
|
+
}
|
|
1883
|
+
}
|
|
1884
|
+
// Evaluate template and set computed value using expression evaluator
|
|
1885
|
+
const scope = {
|
|
1886
|
+
...(row ?? {}),
|
|
1887
|
+
context: {
|
|
1888
|
+
eval: (path) => {
|
|
1889
|
+
return getSmart(row, path);
|
|
1890
|
+
},
|
|
1891
|
+
},
|
|
1892
|
+
};
|
|
1893
|
+
const evaluated = await expressionEvaluator.evaluate(f.value, scope);
|
|
1894
|
+
set(row, f.name, evaluated || undefined);
|
|
1895
|
+
}
|
|
1896
|
+
}
|
|
1897
|
+
}
|
|
1898
|
+
catch {
|
|
1899
|
+
// swallow to avoid breaking main flow
|
|
1900
|
+
}
|
|
1901
|
+
},
|
|
1902
|
+
};
|
|
1903
|
+
|
|
1904
|
+
//#endregion
|
|
1905
|
+
//#region ---- Plugin ----
|
|
1906
|
+
const computedPropertiesPlugin = {
|
|
1907
|
+
name: 'computed-property',
|
|
1908
|
+
order: 55,
|
|
1909
|
+
apply: (ctx, options) => {
|
|
1910
|
+
const fields = options?.fields ?? [];
|
|
1911
|
+
if (!fields.length) {
|
|
1912
|
+
return;
|
|
1913
|
+
}
|
|
1914
|
+
// Ensure default group exists
|
|
1915
|
+
const defaultGroupId = 'additional';
|
|
1916
|
+
const ensureGroup = (group) => {
|
|
1917
|
+
const id = group?.id || defaultGroupId;
|
|
1918
|
+
const groups = ctx.groups.list() ?? [];
|
|
1919
|
+
if (!groups.some((g) => g.id === id)) {
|
|
1920
|
+
ctx.groups.add({ id, title: group?.title });
|
|
1921
|
+
}
|
|
1922
|
+
return id;
|
|
1923
|
+
};
|
|
1924
|
+
for (const f of fields) {
|
|
1925
|
+
const groupId = ensureGroup(f.group || { id: defaultGroupId });
|
|
1926
|
+
// If group is newly created and a custom title is provided, update it
|
|
1927
|
+
const groups = ctx.groups.list() ?? [];
|
|
1928
|
+
if (!groups.some((g) => g.id === groupId) && f.group?.title) {
|
|
1929
|
+
ctx.groups.add({ id: groupId, title: f.group.title });
|
|
1930
|
+
}
|
|
1931
|
+
// Ensure property exists on entity
|
|
1932
|
+
const existing = ctx.properties.list().some((p) => p.name === f.name);
|
|
1933
|
+
if (!existing) {
|
|
1934
|
+
ctx.properties.add({
|
|
1935
|
+
name: f.name,
|
|
1936
|
+
title: f.title,
|
|
1937
|
+
groupId,
|
|
1938
|
+
schema: {
|
|
1939
|
+
dataType: 'string',
|
|
1940
|
+
readonly: true,
|
|
1941
|
+
defaultValue: f.value,
|
|
1942
|
+
interface: {
|
|
1943
|
+
type: f.showAs?.type || 'text-editor',
|
|
1944
|
+
options: { ...(f.showAs?.options ?? {}), readonly: true },
|
|
1945
|
+
},
|
|
1946
|
+
},
|
|
1947
|
+
});
|
|
1948
|
+
}
|
|
1949
|
+
// Ensure the field appears in list columns
|
|
1950
|
+
const entityAny = ctx.entity;
|
|
1951
|
+
const currentColumns = Array.isArray(entityAny.columns) ? entityAny.columns : [];
|
|
1952
|
+
const hasColumn = currentColumns.some((c) => (typeof c === 'string' ? c === f.name : c?.name === f.name));
|
|
1953
|
+
if (!hasColumn) {
|
|
1954
|
+
entityAny.columns = [...currentColumns, { name: f.name }];
|
|
1955
|
+
}
|
|
1956
|
+
// Ensure Single (details) view shows it
|
|
1957
|
+
ctx.interfaces.master.single.update((single) => {
|
|
1958
|
+
const next = single ?? { title: ctx.entity.title, sections: [], properties: [] };
|
|
1959
|
+
next.sections = next.sections ?? [];
|
|
1960
|
+
if (!next.sections.some((s) => s.id === groupId)) {
|
|
1961
|
+
next.sections.push({ id: groupId, order: 90 });
|
|
1962
|
+
}
|
|
1963
|
+
next.properties = next.properties ?? [];
|
|
1964
|
+
if (!next.properties.some((p) => p.name === f.name)) {
|
|
1965
|
+
next.properties.push({
|
|
1966
|
+
name: f.name,
|
|
1967
|
+
layout: {
|
|
1968
|
+
positions: { lg: { colSpan: f.layout?.colSpan ?? 12, order: f.layout?.order ?? 99 } },
|
|
1969
|
+
label: { visible: true },
|
|
1970
|
+
},
|
|
1971
|
+
});
|
|
1972
|
+
}
|
|
1973
|
+
return next;
|
|
1974
|
+
});
|
|
1975
|
+
}
|
|
1976
|
+
},
|
|
1977
|
+
};
|
|
1978
|
+
//#endregion
|
|
1979
|
+
|
|
1980
|
+
class AXPComputedPropertiesModule {
|
|
1981
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComputedPropertiesModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1982
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPComputedPropertiesModule }); }
|
|
1983
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComputedPropertiesModule, providers: [
|
|
1984
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: computedPropertiesPlugin },
|
|
1985
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: computedPropertiesMiddleware },
|
|
1986
|
+
] }); }
|
|
1987
|
+
}
|
|
1988
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPComputedPropertiesModule, decorators: [{
|
|
1989
|
+
type: NgModule,
|
|
1990
|
+
args: [{
|
|
1219
1991
|
providers: [
|
|
1220
|
-
{ provide:
|
|
1221
|
-
{ provide:
|
|
1222
|
-
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: lockGuardMiddleware },
|
|
1992
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: computedPropertiesPlugin },
|
|
1993
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: computedPropertiesMiddleware },
|
|
1223
1994
|
],
|
|
1224
1995
|
}]
|
|
1225
1996
|
}] });
|
|
@@ -1369,48 +2140,6 @@ const extraPropertiesPlugin = {
|
|
|
1369
2140
|
},
|
|
1370
2141
|
};
|
|
1371
2142
|
|
|
1372
|
-
const AXPWidgetsList = {
|
|
1373
|
-
Editors: {
|
|
1374
|
-
DocumentAttachment: 'document-attachment-editor',
|
|
1375
|
-
TagBox: 'tagable-editor',
|
|
1376
|
-
CheckBox: 'checkbox-editor',
|
|
1377
|
-
ColorBox: 'color-editor',
|
|
1378
|
-
DateTimeBox: 'date-time-editor',
|
|
1379
|
-
Direction: 'direction',
|
|
1380
|
-
LargeTextBox: 'large-text-editor',
|
|
1381
|
-
NumberBox: 'number-editor',
|
|
1382
|
-
UnitValueBox: 'number-unit-editor',
|
|
1383
|
-
PasswordBox: 'password-editor',
|
|
1384
|
-
QueryBuilder: 'query-builder-editor',
|
|
1385
|
-
RichText: 'rich-text-editor',
|
|
1386
|
-
SelectBox: 'select-editor',
|
|
1387
|
-
SelectionList: 'selection-list-editor',
|
|
1388
|
-
TextBox: 'text-editor',
|
|
1389
|
-
InlineDataTable: 'table-editor',
|
|
1390
|
-
ToggleSwitch: 'toggle-editor',
|
|
1391
|
-
FileTypeExtension: 'file-type-extension',
|
|
1392
|
-
MapBox: 'map',
|
|
1393
|
-
MediaGallery: 'gallery',
|
|
1394
|
-
SignatureBox: 'signature',
|
|
1395
|
-
LookupBox: 'lookup-editor',
|
|
1396
|
-
},
|
|
1397
|
-
Layouts: {
|
|
1398
|
-
BlockLayout: 'block-layout',
|
|
1399
|
-
RepeaterLayout: 'repeater-layout',
|
|
1400
|
-
TextBlockLayout: 'text-block-layout',
|
|
1401
|
-
FormField: 'form-field',
|
|
1402
|
-
},
|
|
1403
|
-
Actions: {
|
|
1404
|
-
ActionButton: 'button-action',
|
|
1405
|
-
},
|
|
1406
|
-
Advanced: {
|
|
1407
|
-
QRCode: 'qrcode',
|
|
1408
|
-
},
|
|
1409
|
-
Templates: {
|
|
1410
|
-
Designer: 'template-designer',
|
|
1411
|
-
},
|
|
1412
|
-
};
|
|
1413
|
-
|
|
1414
2143
|
const AXP_EXTRA_PROPERTY_TYPES_DEFAULT = [
|
|
1415
2144
|
{ id: AXPWidgetsList.Editors.TextBox, title: 'Text' },
|
|
1416
2145
|
{ id: AXPWidgetsList.Editors.CheckBox, title: 'Checkbox' },
|
|
@@ -1462,279 +2191,948 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1462
2191
|
}]
|
|
1463
2192
|
}] });
|
|
1464
2193
|
|
|
1465
|
-
const
|
|
1466
|
-
|
|
1467
|
-
|
|
1468
|
-
|
|
1469
|
-
|
|
1470
|
-
|
|
1471
|
-
|
|
1472
|
-
|
|
1473
|
-
|
|
1474
|
-
|
|
1475
|
-
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
|
|
1479
|
-
|
|
1480
|
-
|
|
1481
|
-
|
|
1482
|
-
const props = ctx.properties.list();
|
|
1483
|
-
if (!props.some((p) => p.name === propertyName)) {
|
|
1484
|
-
ctx.properties.add({
|
|
1485
|
-
name: propertyName,
|
|
1486
|
-
title: '@general:terms.category.plural',
|
|
1487
|
-
groupId: 'basic-info',
|
|
1488
|
-
schema: {
|
|
1489
|
-
dataType: 'string',
|
|
1490
|
-
interface: {
|
|
1491
|
-
type: AXPWidgetsList.Editors.LookupBox,
|
|
1492
|
-
options: {
|
|
1493
|
-
entity: `${moduleName}.${categoryEntityName}`,
|
|
1494
|
-
multiple: allowMultiple,
|
|
1495
|
-
expose: [
|
|
1496
|
-
{ source: 'id', target: 'categories.{id}' },
|
|
1497
|
-
{ source: 'title', target: 'categories.{title}' },
|
|
1498
|
-
],
|
|
1499
|
-
},
|
|
1500
|
-
},
|
|
1501
|
-
},
|
|
1502
|
-
});
|
|
1503
|
-
}
|
|
1504
|
-
// Ensure category sidebar/filter block
|
|
1505
|
-
ctx.category.update((cat) => {
|
|
1506
|
-
return {
|
|
1507
|
-
entity: `${moduleName}.${categoryEntityName}`,
|
|
1508
|
-
title: '@general:terms.category.plural',
|
|
1509
|
-
textField: 'title',
|
|
1510
|
-
valueField: 'id',
|
|
1511
|
-
applyConditions: [
|
|
1512
|
-
{
|
|
1513
|
-
name: propertyName,
|
|
1514
|
-
operator: { type: 'contains' },
|
|
1515
|
-
value: 'id',
|
|
1516
|
-
},
|
|
1517
|
-
],
|
|
1518
|
-
};
|
|
1519
|
-
});
|
|
1520
|
-
// Ensure layout includes property in create/modify/single
|
|
1521
|
-
const ensureLayoutProperty = (layout) => {
|
|
1522
|
-
layout.sections = layout.sections ?? [];
|
|
1523
|
-
if (!layout.sections.some((s) => s.id === 'basic-info')) {
|
|
1524
|
-
layout.sections.push({ id: 'basic-info' });
|
|
2194
|
+
const AXP_GLOBAL_SEARCH_CONFIG_TOKEN = new InjectionToken('AXP_GLOBAL_SEARCH_CONFIG_TOKEN');
|
|
2195
|
+
|
|
2196
|
+
class AXPGlobalSearchSlotComponent {
|
|
2197
|
+
constructor() {
|
|
2198
|
+
this.workflow = inject(AXPWorkflowService);
|
|
2199
|
+
}
|
|
2200
|
+
async startSearch() {
|
|
2201
|
+
await this.workflow.execute('global-search');
|
|
2202
|
+
}
|
|
2203
|
+
async handleKeyboardEvent(event) {
|
|
2204
|
+
if (event.ctrlKey) {
|
|
2205
|
+
switch (event.code) {
|
|
2206
|
+
case 'KeyK':
|
|
2207
|
+
event.preventDefault();
|
|
2208
|
+
event.stopPropagation();
|
|
2209
|
+
await this.startSearch();
|
|
2210
|
+
break;
|
|
1525
2211
|
}
|
|
1526
|
-
|
|
1527
|
-
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
2212
|
+
}
|
|
2213
|
+
}
|
|
2214
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchSlotComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
|
2215
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "20.1.6", type: AXPGlobalSearchSlotComponent, isStandalone: true, selector: "ng-component", host: { listeners: { "document:keydown": "handleKeyboardEvent($event)" } }, ngImport: i0, template: `
|
|
2216
|
+
<ax-button color="primary" class="ax-flex md:ax-hidden" (onClick)="startSearch()">
|
|
2217
|
+
<ax-icon class="fa-regular fa-search">
|
|
2218
|
+
</ax-icon>
|
|
2219
|
+
</ax-button>
|
|
2220
|
+
<div class="ax-bg-primary-200/15 ax-h-10 ax-w-72 ax-rounded-default ax-cursor-pointer ax-justify-between ax-hidden md:ax-flex ax-items-center ax-px-3 hover:ax-bg-primary-200/30 ax-text-primary-text" (click)="startSearch()" *translate="let t">
|
|
2221
|
+
<div class="ax-flex ax-items-center ax-gap-2">
|
|
2222
|
+
<i class="fa-light fa-search ax-text-xl"></i>
|
|
2223
|
+
<span>{{ t('search-placeholder',{scope:'global-search'}) | async}}</span>
|
|
2224
|
+
</div>
|
|
2225
|
+
<kbd class="ax-text-sm">Ctrl+K</kbd>
|
|
2226
|
+
</div>
|
|
2227
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i4.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }] }); }
|
|
2228
|
+
}
|
|
2229
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchSlotComponent, decorators: [{
|
|
2230
|
+
type: Component,
|
|
2231
|
+
args: [{
|
|
2232
|
+
template: `
|
|
2233
|
+
<ax-button color="primary" class="ax-flex md:ax-hidden" (onClick)="startSearch()">
|
|
2234
|
+
<ax-icon class="fa-regular fa-search">
|
|
2235
|
+
</ax-icon>
|
|
2236
|
+
</ax-button>
|
|
2237
|
+
<div class="ax-bg-primary-200/15 ax-h-10 ax-w-72 ax-rounded-default ax-cursor-pointer ax-justify-between ax-hidden md:ax-flex ax-items-center ax-px-3 hover:ax-bg-primary-200/30 ax-text-primary-text" (click)="startSearch()" *translate="let t">
|
|
2238
|
+
<div class="ax-flex ax-items-center ax-gap-2">
|
|
2239
|
+
<i class="fa-light fa-search ax-text-xl"></i>
|
|
2240
|
+
<span>{{ t('search-placeholder',{scope:'global-search'}) | async}}</span>
|
|
2241
|
+
</div>
|
|
2242
|
+
<kbd class="ax-text-sm">Ctrl+K</kbd>
|
|
2243
|
+
</div>
|
|
2244
|
+
`,
|
|
2245
|
+
imports: [CommonModule, AXButtonModule, AXDecoratorModule, AXTranslationModule, AXTextBoxModule]
|
|
2246
|
+
}]
|
|
2247
|
+
}], propDecorators: { handleKeyboardEvent: [{
|
|
2248
|
+
type: HostListener,
|
|
2249
|
+
args: ['document:keydown', ['$event']]
|
|
2250
|
+
}] } });
|
|
2251
|
+
|
|
2252
|
+
class AXPGlobalSearchStartAction extends AXPWorkflowAction {
|
|
2253
|
+
constructor() {
|
|
2254
|
+
super(...arguments);
|
|
2255
|
+
this.popupService = inject(AXPopupService);
|
|
2256
|
+
this.workflow = inject(AXPWorkflowService);
|
|
2257
|
+
this.config = inject(AXP_GLOBAL_SEARCH_CONFIG_TOKEN);
|
|
2258
|
+
}
|
|
2259
|
+
async execute(context) {
|
|
2260
|
+
const component = await this.config.window();
|
|
2261
|
+
const popup = await this.popupService.open(component, {
|
|
2262
|
+
title: 'Search...',
|
|
2263
|
+
size: 'fit',
|
|
2264
|
+
closeOnBackdropClick: true,
|
|
2265
|
+
data: {
|
|
2266
|
+
text: context.getVariable('text'),
|
|
2267
|
+
},
|
|
2268
|
+
header: false,
|
|
2269
|
+
});
|
|
2270
|
+
if (popup.data) {
|
|
2271
|
+
const result = popup.data;
|
|
2272
|
+
if (result && result.command) {
|
|
2273
|
+
this.workflow.execute(result.command?.name, result.command?.options);
|
|
1534
2274
|
}
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1538
|
-
|
|
1539
|
-
|
|
1540
|
-
|
|
1541
|
-
|
|
1542
|
-
|
|
1543
|
-
|
|
1544
|
-
|
|
1545
|
-
|
|
1546
|
-
|
|
2275
|
+
}
|
|
2276
|
+
}
|
|
2277
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchStartAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2278
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchStartAction }); }
|
|
2279
|
+
}
|
|
2280
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchStartAction, decorators: [{
|
|
2281
|
+
type: Injectable
|
|
2282
|
+
}] });
|
|
2283
|
+
const AXPGlobalSearchWorkflow = {
|
|
2284
|
+
startStepId: 'start',
|
|
2285
|
+
steps: {
|
|
2286
|
+
start: {
|
|
2287
|
+
action: 'AXPGlobalSearchStartAction',
|
|
2288
|
+
},
|
|
1547
2289
|
},
|
|
1548
2290
|
};
|
|
1549
2291
|
|
|
1550
|
-
class
|
|
1551
|
-
constructor() {
|
|
1552
|
-
this.injector = inject(Injector);
|
|
1553
|
-
}
|
|
1554
|
-
preload() {
|
|
1555
|
-
return [];
|
|
2292
|
+
class AXPGlobalSearchModule {
|
|
2293
|
+
constructor(appInitService, injector) {
|
|
1556
2294
|
}
|
|
1557
|
-
|
|
1558
|
-
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
name: entityName,
|
|
1565
|
-
parentKey: 'parentId',
|
|
1566
|
-
plugins: [
|
|
1567
|
-
// { name: 'history' },
|
|
1568
|
-
// { name: 'lock' },
|
|
1569
|
-
// { name: 'compare' },
|
|
1570
|
-
],
|
|
1571
|
-
source: '',
|
|
1572
|
-
title: '@general:terms.category.individual',
|
|
1573
|
-
formats: {
|
|
1574
|
-
individual: '@general:terms.category.individual',
|
|
1575
|
-
plural: '@general:terms.category.plural',
|
|
1576
|
-
searchResult: {
|
|
1577
|
-
title: '{{ title }}',
|
|
1578
|
-
description: '{{ module }}',
|
|
1579
|
-
},
|
|
2295
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchModule, deps: [{ token: i1$2.AXPAppStartUpService }, { token: i0.Injector }], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2296
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchModule, imports: [i2$1.AXPComponentSlotModule, i1.AXPWorkflowModule] }); }
|
|
2297
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchModule, providers: [
|
|
2298
|
+
{
|
|
2299
|
+
provide: AXP_GLOBAL_SEARCH_CONFIG_TOKEN,
|
|
2300
|
+
useValue: {
|
|
2301
|
+
window: () => import('./acorex-modules-common-search-popup.component-BSQyjDKA.mjs').then((c) => c.AXPGlobalSearchPopupComponent),
|
|
1580
2302
|
},
|
|
1581
|
-
|
|
1582
|
-
|
|
1583
|
-
|
|
1584
|
-
],
|
|
1585
|
-
properties: [
|
|
1586
|
-
{
|
|
1587
|
-
name: 'title',
|
|
1588
|
-
title: '@general:terms.title',
|
|
1589
|
-
groupId: 'basic-info',
|
|
1590
|
-
options: {
|
|
1591
|
-
sort: { enabled: true },
|
|
1592
|
-
filter: { advance: { enabled: true }, inline: { enabled: true } },
|
|
1593
|
-
},
|
|
1594
|
-
schema: { dataType: 'string', interface: { type: AXPWidgetsCatalog.text } },
|
|
1595
|
-
validations: [{ rule: 'required' }],
|
|
1596
|
-
},
|
|
1597
|
-
{
|
|
1598
|
-
name: 'parentId',
|
|
1599
|
-
title: '@general:terms.parent-id',
|
|
1600
|
-
groupId: 'basic-info',
|
|
1601
|
-
schema: {
|
|
1602
|
-
dataType: 'string',
|
|
1603
|
-
interface: {
|
|
1604
|
-
type: AXPWidgetsList.Editors.LookupBox,
|
|
1605
|
-
options: { entity: `${moduleName}.${entityName}` },
|
|
1606
|
-
},
|
|
1607
|
-
},
|
|
1608
|
-
},
|
|
2303
|
+
},
|
|
2304
|
+
], imports: [AXPComponentSlotModule.forChild({
|
|
2305
|
+
'root-header-start': [
|
|
1609
2306
|
{
|
|
1610
|
-
|
|
1611
|
-
|
|
1612
|
-
|
|
1613
|
-
schema: { dataType: 'string', interface: { type: AXPWidgetsCatalog.largeText } },
|
|
2307
|
+
priority: 0,
|
|
2308
|
+
name: 'search',
|
|
2309
|
+
component: AXPGlobalSearchSlotComponent,
|
|
1614
2310
|
},
|
|
1615
2311
|
],
|
|
1616
|
-
|
|
1617
|
-
|
|
1618
|
-
|
|
1619
|
-
|
|
1620
|
-
|
|
2312
|
+
}),
|
|
2313
|
+
//
|
|
2314
|
+
AXPWorkflowModule.forChild({
|
|
2315
|
+
actions: {
|
|
2316
|
+
AXPGlobalSearchStartAction
|
|
1621
2317
|
},
|
|
1622
|
-
|
|
1623
|
-
|
|
1624
|
-
list: {
|
|
1625
|
-
execute: async (e) => {
|
|
1626
|
-
const res = await dataService.query(e);
|
|
1627
|
-
// enrich hasChild for tree views if childCount is available
|
|
1628
|
-
return {
|
|
1629
|
-
items: res.items.map((item) => ({ ...item, hasChild: (item.childCount ?? 0) > 0 })),
|
|
1630
|
-
total: res.total,
|
|
1631
|
-
};
|
|
1632
|
-
},
|
|
1633
|
-
type: AXPEntityQueryType.List,
|
|
1634
|
-
},
|
|
2318
|
+
workflows: {
|
|
2319
|
+
'global-search': AXPGlobalSearchWorkflow,
|
|
1635
2320
|
},
|
|
1636
|
-
|
|
1637
|
-
|
|
1638
|
-
|
|
1639
|
-
|
|
1640
|
-
|
|
1641
|
-
|
|
1642
|
-
|
|
1643
|
-
|
|
1644
|
-
|
|
1645
|
-
|
|
1646
|
-
|
|
1647
|
-
|
|
1648
|
-
|
|
1649
|
-
{ name: 'title', layout: { positions: { lg: { colSpan: 12, order: 1 } } } },
|
|
1650
|
-
{ name: 'parentId', layout: { positions: { lg: { colSpan: 12, order: 2 } } } },
|
|
1651
|
-
{ name: 'description', layout: { positions: { lg: { colSpan: 12, order: 3 } } } },
|
|
2321
|
+
})] }); }
|
|
2322
|
+
}
|
|
2323
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPGlobalSearchModule, decorators: [{
|
|
2324
|
+
type: NgModule,
|
|
2325
|
+
args: [{
|
|
2326
|
+
imports: [
|
|
2327
|
+
AXPComponentSlotModule.forChild({
|
|
2328
|
+
'root-header-start': [
|
|
2329
|
+
{
|
|
2330
|
+
priority: 0,
|
|
2331
|
+
name: 'search',
|
|
2332
|
+
component: AXPGlobalSearchSlotComponent,
|
|
2333
|
+
},
|
|
1652
2334
|
],
|
|
2335
|
+
}),
|
|
2336
|
+
//
|
|
2337
|
+
AXPWorkflowModule.forChild({
|
|
2338
|
+
actions: {
|
|
2339
|
+
AXPGlobalSearchStartAction
|
|
2340
|
+
},
|
|
2341
|
+
workflows: {
|
|
2342
|
+
'global-search': AXPGlobalSearchWorkflow,
|
|
2343
|
+
},
|
|
2344
|
+
})
|
|
2345
|
+
],
|
|
2346
|
+
exports: [],
|
|
2347
|
+
declarations: [],
|
|
2348
|
+
providers: [
|
|
2349
|
+
{
|
|
2350
|
+
provide: AXP_GLOBAL_SEARCH_CONFIG_TOKEN,
|
|
2351
|
+
useValue: {
|
|
2352
|
+
window: () => import('./acorex-modules-common-search-popup.component-BSQyjDKA.mjs').then((c) => c.AXPGlobalSearchPopupComponent),
|
|
2353
|
+
},
|
|
1653
2354
|
},
|
|
1654
|
-
|
|
1655
|
-
|
|
1656
|
-
|
|
1657
|
-
|
|
1658
|
-
|
|
1659
|
-
|
|
1660
|
-
|
|
1661
|
-
|
|
1662
|
-
|
|
2355
|
+
]
|
|
2356
|
+
}]
|
|
2357
|
+
}], ctorParameters: () => [{ type: i1$2.AXPAppStartUpService }, { type: i0.Injector }] });
|
|
2358
|
+
|
|
2359
|
+
class AXPGlobalSearchViewModel {
|
|
2360
|
+
constructor() {
|
|
2361
|
+
this.settingKeys = {
|
|
2362
|
+
recent: "global-search:recents:items",
|
|
2363
|
+
pinned: "global-search:pinned:items"
|
|
2364
|
+
};
|
|
2365
|
+
this.searchService = inject(AXPSearchService);
|
|
2366
|
+
this.settingService = inject(AXPSettingService);
|
|
2367
|
+
this._text = signal(null, ...(ngDevMode ? [{ debugName: "_text" }] : []));
|
|
2368
|
+
this.text = this._text.asReadonly();
|
|
2369
|
+
this._results = signal([], ...(ngDevMode ? [{ debugName: "_results" }] : []));
|
|
2370
|
+
this.results = this._results.asReadonly();
|
|
2371
|
+
this._isBusy = signal(false, ...(ngDevMode ? [{ debugName: "_isBusy" }] : []));
|
|
2372
|
+
this.isBusy = this._isBusy.asReadonly();
|
|
2373
|
+
this.isEmpty = computed(() => this.text() && this.results().length == 0, ...(ngDevMode ? [{ debugName: "isEmpty" }] : []));
|
|
2374
|
+
this.isValid = computed(() => (this.text()?.length ?? 0) > 2, ...(ngDevMode ? [{ debugName: "isValid" }] : []));
|
|
2375
|
+
this.isStart = computed(() => !this.isEmpty() && this.results().length == 0, ...(ngDevMode ? [{ debugName: "isStart" }] : []));
|
|
2376
|
+
this.isWelcome = computed(() => this.isStart() && this.pinnedItems().length == 0 && this.recentItems().length == 0, ...(ngDevMode ? [{ debugName: "isWelcome" }] : []));
|
|
2377
|
+
this._recentItems = signal([], ...(ngDevMode ? [{ debugName: "_recentItems" }] : []));
|
|
2378
|
+
this._pinnedItems = signal([], ...(ngDevMode ? [{ debugName: "_pinnedItems" }] : []));
|
|
2379
|
+
this.pinnedItems = this._pinnedItems.asReadonly();
|
|
2380
|
+
this.recentItems = computed(() => this.getTopRecentItems(), ...(ngDevMode ? [{ debugName: "recentItems" }] : []));
|
|
2381
|
+
this.onItemSelected = new Subject();
|
|
2382
|
+
this.loadSettings();
|
|
2383
|
+
}
|
|
2384
|
+
async search(text) {
|
|
2385
|
+
this._isBusy.set(true);
|
|
2386
|
+
this._text.set(text);
|
|
2387
|
+
if (!this.isValid()) {
|
|
2388
|
+
this._results.set([]);
|
|
2389
|
+
}
|
|
2390
|
+
else {
|
|
2391
|
+
await new Promise((resolve) => setTimeout(resolve, 250));
|
|
2392
|
+
const results = await this.searchService.search(text);
|
|
2393
|
+
this._results.set(results);
|
|
2394
|
+
}
|
|
2395
|
+
this._isBusy.set(false);
|
|
2396
|
+
}
|
|
2397
|
+
async execute(item) {
|
|
2398
|
+
this.onItemSelected.next(item);
|
|
2399
|
+
await this.updateSelectionHistory(item);
|
|
2400
|
+
}
|
|
2401
|
+
async pin(item) {
|
|
2402
|
+
const currentPinned = this._pinnedItems();
|
|
2403
|
+
if (!currentPinned.some(i => i.id === item.id)) {
|
|
2404
|
+
this._pinnedItems.set([item, ...currentPinned].slice(0, 5));
|
|
2405
|
+
await this.saveSettings();
|
|
2406
|
+
}
|
|
2407
|
+
}
|
|
2408
|
+
async unpin(item) {
|
|
2409
|
+
const currentPinned = this._pinnedItems();
|
|
2410
|
+
this._pinnedItems.set(currentPinned.filter(i => i.id !== item.id));
|
|
2411
|
+
await this.saveSettings();
|
|
2412
|
+
}
|
|
2413
|
+
async togglePin(item) {
|
|
2414
|
+
if (this.isPinned(item)) {
|
|
2415
|
+
await this.unpin(item);
|
|
2416
|
+
}
|
|
2417
|
+
else {
|
|
2418
|
+
await this.pin(item);
|
|
2419
|
+
}
|
|
2420
|
+
}
|
|
2421
|
+
isPinned(item) {
|
|
2422
|
+
const currentPinned = this._pinnedItems();
|
|
2423
|
+
return currentPinned.some(i => i.id === item.id);
|
|
2424
|
+
}
|
|
2425
|
+
async updateSelectionHistory(item) {
|
|
2426
|
+
// Update recent selections
|
|
2427
|
+
const currentHistory = this._recentItems();
|
|
2428
|
+
const updatedHistory = [item, ...currentHistory.filter(i => i.id !== item.id)].slice(0, 5);
|
|
2429
|
+
this._recentItems.set(updatedHistory);
|
|
2430
|
+
// Save updated settings
|
|
2431
|
+
await this.saveSettings();
|
|
2432
|
+
}
|
|
2433
|
+
getTopRecentItems() {
|
|
2434
|
+
const pinnedIds = new Set(this._pinnedItems().map(item => item.id));
|
|
2435
|
+
return this._recentItems().filter(item => !pinnedIds.has(item.id)).slice(0, 5);
|
|
2436
|
+
}
|
|
2437
|
+
async clearRecentItems() {
|
|
2438
|
+
this._recentItems.set([]);
|
|
2439
|
+
await this.settingService.scope(AXPPlatformScope.User).set(this.settingKeys.recent, []);
|
|
2440
|
+
}
|
|
2441
|
+
async loadSettings() {
|
|
2442
|
+
// Load recent selections
|
|
2443
|
+
const recent = await this.settingService.get(this.settingKeys.recent);
|
|
2444
|
+
if (recent) {
|
|
2445
|
+
this._recentItems.set(recent.slice(0, 5));
|
|
2446
|
+
}
|
|
2447
|
+
// Load pinned items
|
|
2448
|
+
const pinned = await this.settingService.get(this.settingKeys.pinned);
|
|
2449
|
+
if (pinned) {
|
|
2450
|
+
this._pinnedItems.set(pinned.slice(0, 5));
|
|
2451
|
+
}
|
|
2452
|
+
}
|
|
2453
|
+
async saveSettings() {
|
|
2454
|
+
// Save recent selections
|
|
2455
|
+
await this.settingService.scope(AXPPlatformScope.User).set(this.settingKeys.recent, this._recentItems().slice(0, 5));
|
|
2456
|
+
// Save pinned items
|
|
2457
|
+
await this.settingService.scope(AXPPlatformScope.User).set(this.settingKeys.pinned, this._pinnedItems().slice(0, 5));
|
|
2458
|
+
}
|
|
2459
|
+
}
|
|
2460
|
+
|
|
2461
|
+
const lockGuardMiddleware = {
|
|
2462
|
+
target: { ops: ['update', 'delete'], order: 10 },
|
|
2463
|
+
execute: async (ctx, next) => {
|
|
2464
|
+
const lockService = inject(AXPLockService);
|
|
2465
|
+
const session = inject(AXPSessionService);
|
|
2466
|
+
const lock = await lockService.check({ refId: ctx.id, refType: ctx.entityName });
|
|
2467
|
+
if (lock) {
|
|
2468
|
+
const info = await lockService.getInfo({ refId: ctx.id, refType: ctx.entityName });
|
|
2469
|
+
if (info && session.user && info.lockedBy.id !== session.user.id) {
|
|
2470
|
+
throw new Error('This record is locked and cannot be edited.');
|
|
2471
|
+
}
|
|
2472
|
+
}
|
|
2473
|
+
await next();
|
|
2474
|
+
},
|
|
2475
|
+
};
|
|
2476
|
+
|
|
2477
|
+
class AXMLockPopupWorkflowAction extends AXPWorkflowAction {
|
|
2478
|
+
constructor() {
|
|
2479
|
+
super(...arguments);
|
|
2480
|
+
this.popupService = inject(AXPopupService);
|
|
2481
|
+
this.translationService = inject(AXTranslationService);
|
|
2482
|
+
}
|
|
2483
|
+
async execute(context) {
|
|
2484
|
+
const comp = (await Promise.resolve().then(function () { return index; })).AXPLockPopupComponent;
|
|
2485
|
+
const result = await this.popupService.open(comp, {
|
|
2486
|
+
title: await this.translationService.translateAsync('@lock-system:lock.dialog.title'),
|
|
2487
|
+
data: {
|
|
2488
|
+
refId: context.getVariable('options.refId'),
|
|
2489
|
+
refType: context.getVariable('options.refType'),
|
|
2490
|
+
},
|
|
2491
|
+
});
|
|
2492
|
+
if (result.data != null && result.data.isCanceled != null) {
|
|
2493
|
+
context.setOutput('isCanceled', result.data.isCanceled);
|
|
2494
|
+
if (!result.data.isCanceled) {
|
|
2495
|
+
context.setOutput('lockDuration', result.data.duration);
|
|
2496
|
+
context.setOutput('lockReason', result.data.reason);
|
|
2497
|
+
}
|
|
2498
|
+
}
|
|
2499
|
+
else {
|
|
2500
|
+
context.setOutput('isCanceled', true);
|
|
2501
|
+
}
|
|
2502
|
+
}
|
|
2503
|
+
}
|
|
2504
|
+
const AXMLockPopupWorkflow = {
|
|
2505
|
+
startStepId: 'lock-popup',
|
|
2506
|
+
steps: {
|
|
2507
|
+
'lock-popup': {
|
|
2508
|
+
action: 'AXMLockPopupWorkflowAction',
|
|
2509
|
+
nextSteps: [
|
|
2510
|
+
{
|
|
2511
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("isCanceled") == false' }],
|
|
2512
|
+
nextStepId: 'successToast',
|
|
2513
|
+
},
|
|
2514
|
+
],
|
|
2515
|
+
},
|
|
2516
|
+
successToast: {
|
|
2517
|
+
id: 'successToast',
|
|
2518
|
+
action: 'AXPToastAction',
|
|
2519
|
+
input: {
|
|
2520
|
+
color: 'success',
|
|
2521
|
+
title: 'workflow.entity-modified-title',
|
|
2522
|
+
content: 'workflow.entity-modified-body',
|
|
2523
|
+
},
|
|
2524
|
+
nextSteps: [
|
|
2525
|
+
{
|
|
2526
|
+
conditions: [],
|
|
2527
|
+
nextStepId: 'modifyConfirmed',
|
|
2528
|
+
},
|
|
2529
|
+
],
|
|
2530
|
+
},
|
|
2531
|
+
modifyConfirmed: {
|
|
2532
|
+
id: 'modifyConfirmed',
|
|
2533
|
+
action: 'AXPEntityModifyConfirmedAction',
|
|
2534
|
+
},
|
|
2535
|
+
},
|
|
2536
|
+
};
|
|
2537
|
+
|
|
2538
|
+
class AXMUnlockConfirmWorkflowAction extends AXPWorkflowAction {
|
|
2539
|
+
constructor() {
|
|
2540
|
+
super(...arguments);
|
|
2541
|
+
this.dialogService = inject(AXDialogService);
|
|
2542
|
+
this.translationService = inject(AXTranslationService);
|
|
2543
|
+
this.lockService = inject(AXPLockService);
|
|
2544
|
+
this.sessionService = inject(AXPSessionService);
|
|
2545
|
+
}
|
|
2546
|
+
async execute(context) {
|
|
2547
|
+
const refId = context.getVariable('options.refId');
|
|
2548
|
+
const refType = context.getVariable('options.refType');
|
|
2549
|
+
// Show confirmation dialog
|
|
2550
|
+
const dialogResult = await this.dialogService.confirm(await this.translationService.translateAsync('@lock-system:unlock.dialog.title'), await this.translationService.translateAsync('@lock-system:unlock.dialog.description'), 'warning', 'horizontal', false, 'cancel');
|
|
2551
|
+
if (dialogResult.result) {
|
|
2552
|
+
try {
|
|
2553
|
+
// Perform unlock
|
|
2554
|
+
await this.lockService.unlock({
|
|
2555
|
+
refId: refId,
|
|
2556
|
+
refType: refType,
|
|
2557
|
+
type: 'user',
|
|
2558
|
+
});
|
|
2559
|
+
context.setOutput('isCanceled', false);
|
|
2560
|
+
context.setOutput('unlocked', true);
|
|
2561
|
+
}
|
|
2562
|
+
catch (error) {
|
|
2563
|
+
console.error('Unlock failed:', error);
|
|
2564
|
+
// Show error dialog
|
|
2565
|
+
await this.dialogService.alert(await this.translationService.translateAsync('@lock-system:unlock.error.title'), await this.translationService.translateAsync('@lock-system:unlock.error.description'), 'danger');
|
|
2566
|
+
context.setOutput('isCanceled', true);
|
|
2567
|
+
context.setOutput('unlocked', false);
|
|
2568
|
+
}
|
|
2569
|
+
}
|
|
2570
|
+
else {
|
|
2571
|
+
context.setOutput('isCanceled', true);
|
|
2572
|
+
context.setOutput('unlocked', false);
|
|
2573
|
+
}
|
|
2574
|
+
}
|
|
2575
|
+
}
|
|
2576
|
+
const AXMUnlockConfirmWorkflow = {
|
|
2577
|
+
startStepId: 'unlock-confirm',
|
|
2578
|
+
steps: {
|
|
2579
|
+
'unlock-confirm': {
|
|
2580
|
+
action: 'AXMUnlockConfirmWorkflowAction',
|
|
2581
|
+
nextSteps: [
|
|
2582
|
+
{
|
|
2583
|
+
conditions: [{ type: 'SINGLE', expression: 'context.getOutput("unlocked") == true' }],
|
|
2584
|
+
nextStepId: 'successToast',
|
|
2585
|
+
},
|
|
2586
|
+
],
|
|
2587
|
+
},
|
|
2588
|
+
successToast: {
|
|
2589
|
+
id: 'successToast',
|
|
2590
|
+
action: 'AXPToastAction',
|
|
2591
|
+
input: {
|
|
2592
|
+
color: 'success',
|
|
2593
|
+
title: 'workflow.entity-modified-title',
|
|
2594
|
+
content: 'workflow.entity-modified-body',
|
|
2595
|
+
},
|
|
2596
|
+
nextSteps: [
|
|
2597
|
+
{
|
|
2598
|
+
conditions: [],
|
|
2599
|
+
nextStepId: 'modifyConfirmed',
|
|
2600
|
+
},
|
|
2601
|
+
],
|
|
2602
|
+
},
|
|
2603
|
+
modifyConfirmed: {
|
|
2604
|
+
id: 'modifyConfirmed',
|
|
2605
|
+
action: 'AXPEntityModifyConfirmedAction',
|
|
2606
|
+
},
|
|
2607
|
+
},
|
|
2608
|
+
};
|
|
2609
|
+
|
|
2610
|
+
class AXMLockEvaluatorScopeProvider {
|
|
2611
|
+
constructor() {
|
|
2612
|
+
this.lockService = inject(AXPLockService);
|
|
2613
|
+
}
|
|
2614
|
+
async provide(context) {
|
|
2615
|
+
context.addScope('lock', {
|
|
2616
|
+
check: async (refId, refType) => {
|
|
2617
|
+
const lock = await this.lockService.check({
|
|
2618
|
+
refId, refType
|
|
2619
|
+
});
|
|
2620
|
+
return lock;
|
|
2621
|
+
}
|
|
2622
|
+
});
|
|
2623
|
+
}
|
|
2624
|
+
}
|
|
2625
|
+
|
|
2626
|
+
const lockPlugin = {
|
|
2627
|
+
name: 'lock',
|
|
2628
|
+
order: 50,
|
|
2629
|
+
apply: (ctx) => {
|
|
2630
|
+
ensureListActions(ctx);
|
|
2631
|
+
ctx.interfaces.update((i) => {
|
|
2632
|
+
const actions = i.master.list.actions;
|
|
2633
|
+
if (!actions.some((a) => a.name === 'lock-entity')) {
|
|
2634
|
+
actions.push({
|
|
2635
|
+
title: '@lock-system:lock.title',
|
|
2636
|
+
name: 'lock-entity',
|
|
2637
|
+
command: {
|
|
2638
|
+
name: 'lock-popup',
|
|
2639
|
+
options: {
|
|
2640
|
+
refId: '{{ context.eval("id") }}',
|
|
2641
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
2642
|
+
},
|
|
2643
|
+
},
|
|
2644
|
+
priority: 'secondary',
|
|
2645
|
+
type: 'lock',
|
|
2646
|
+
scope: AXPEntityCommandScope.Individual,
|
|
2647
|
+
hidden: `{{ lock.check(context.eval("id"), "${ctx.entity.module}.${ctx.entity.name}") }}`,
|
|
2648
|
+
});
|
|
2649
|
+
}
|
|
2650
|
+
if (!actions.some((a) => a.name === 'unlock-entity')) {
|
|
2651
|
+
actions.push({
|
|
2652
|
+
title: '@lock-system:unlock.title',
|
|
2653
|
+
name: 'unlock-entity',
|
|
2654
|
+
command: {
|
|
2655
|
+
name: 'unlock-confirm',
|
|
2656
|
+
options: {
|
|
2657
|
+
refId: '{{ context.eval("id") }}',
|
|
2658
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
2659
|
+
},
|
|
2660
|
+
},
|
|
2661
|
+
priority: 'secondary',
|
|
2662
|
+
type: 'unlock',
|
|
2663
|
+
scope: AXPEntityCommandScope.Individual,
|
|
2664
|
+
hidden: `{{ (await lock.check(context.eval("id"), "${ctx.entity.module}.${ctx.entity.name}")) == false }}`,
|
|
2665
|
+
});
|
|
2666
|
+
}
|
|
2667
|
+
return i;
|
|
2668
|
+
});
|
|
2669
|
+
},
|
|
2670
|
+
};
|
|
2671
|
+
|
|
2672
|
+
class AXMLockSystemModule {
|
|
2673
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2674
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, imports: [i1.AXPWorkflowModule] }); }
|
|
2675
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, providers: [
|
|
2676
|
+
{ provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, multi: true, useClass: AXMLockEvaluatorScopeProvider },
|
|
2677
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: lockPlugin },
|
|
2678
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: lockGuardMiddleware },
|
|
2679
|
+
], imports: [AXPWorkflowModule.forChild({
|
|
2680
|
+
actions: {
|
|
2681
|
+
AXMLockPopupWorkflowAction,
|
|
2682
|
+
AXMUnlockConfirmWorkflowAction,
|
|
2683
|
+
},
|
|
2684
|
+
workflows: {
|
|
2685
|
+
'lock-popup': AXMLockPopupWorkflow,
|
|
2686
|
+
'unlock-confirm': AXMUnlockConfirmWorkflow,
|
|
2687
|
+
},
|
|
2688
|
+
})] }); }
|
|
2689
|
+
}
|
|
2690
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMLockSystemModule, decorators: [{
|
|
2691
|
+
type: NgModule,
|
|
2692
|
+
args: [{
|
|
2693
|
+
imports: [
|
|
2694
|
+
AXPWorkflowModule.forChild({
|
|
2695
|
+
actions: {
|
|
2696
|
+
AXMLockPopupWorkflowAction,
|
|
2697
|
+
AXMUnlockConfirmWorkflowAction,
|
|
2698
|
+
},
|
|
2699
|
+
workflows: {
|
|
2700
|
+
'lock-popup': AXMLockPopupWorkflow,
|
|
2701
|
+
'unlock-confirm': AXMUnlockConfirmWorkflow,
|
|
2702
|
+
},
|
|
2703
|
+
}),
|
|
2704
|
+
],
|
|
2705
|
+
providers: [
|
|
2706
|
+
{ provide: AXP_EXPRESSION_EVALUATOR_SCOPE_PROVIDER, multi: true, useClass: AXMLockEvaluatorScopeProvider },
|
|
2707
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: lockPlugin },
|
|
2708
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: lockGuardMiddleware },
|
|
2709
|
+
],
|
|
2710
|
+
}]
|
|
2711
|
+
}] });
|
|
2712
|
+
|
|
2713
|
+
class AXPDateTimeEvaluatorScopeProvider {
|
|
2714
|
+
constructor() {
|
|
2715
|
+
this.calendarService = inject(AXCalendarService);
|
|
2716
|
+
}
|
|
2717
|
+
async provide(context) {
|
|
2718
|
+
context.addScope('date', {
|
|
2719
|
+
today: () => {
|
|
2720
|
+
return this.calendarService.now();
|
|
2721
|
+
},
|
|
2722
|
+
tomorrow: () => {
|
|
2723
|
+
return this.calendarService.create(this.calendarService.now()).add('day', 1).startOf('day').date;
|
|
2724
|
+
},
|
|
2725
|
+
yesterday: () => {
|
|
2726
|
+
return this.calendarService.create(this.calendarService.now()).add('day', -1).startOf('day').date;
|
|
2727
|
+
},
|
|
2728
|
+
addDays: (date, days) => {
|
|
2729
|
+
return this.calendarService.create(date).add('day', days).date;
|
|
2730
|
+
},
|
|
2731
|
+
});
|
|
2732
|
+
}
|
|
2733
|
+
}
|
|
2734
|
+
|
|
2735
|
+
class AXPTranslateEvaluatorScopeProvider {
|
|
2736
|
+
constructor() {
|
|
2737
|
+
this.translateService = inject(AXTranslationService);
|
|
2738
|
+
}
|
|
2739
|
+
async provide(context) {
|
|
2740
|
+
context.addScope('translate', {
|
|
2741
|
+
resolve: async (text, options) => {
|
|
2742
|
+
return await this.translateService.translateAsync(text, options);
|
|
2743
|
+
},
|
|
2744
|
+
});
|
|
2745
|
+
}
|
|
2746
|
+
}
|
|
2747
|
+
|
|
2748
|
+
class AXMVersionHistoryPopupStartAction extends AXPWorkflowAction {
|
|
2749
|
+
constructor() {
|
|
2750
|
+
super(...arguments);
|
|
2751
|
+
this.popupService = inject(AXPopupService);
|
|
2752
|
+
this.translate = inject(AXTranslationService);
|
|
2753
|
+
}
|
|
2754
|
+
async execute(context) {
|
|
2755
|
+
const comp = (await import('./acorex-modules-common-timeline-version-history-popup.component-ByAc4Yp9.mjs')).AXMTimelineVersionHistoryPopupComponent;
|
|
2756
|
+
this.popupService.open(comp, {
|
|
2757
|
+
title: await this.translate.translateAsync('@activity-log:actions.view-history'),
|
|
2758
|
+
data: {
|
|
2759
|
+
refId: context.getVariable('options.refId'),
|
|
2760
|
+
refType: context.getVariable('options.refType'),
|
|
2761
|
+
fromDate: context.getVariable('options.fromDate'),
|
|
2762
|
+
toDate: context.getVariable('options.toDate'),
|
|
2763
|
+
limit: context.getVariable('options.limit'),
|
|
2764
|
+
offset: context.getVariable('options.offset'),
|
|
2765
|
+
},
|
|
2766
|
+
});
|
|
2767
|
+
}
|
|
2768
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMVersionHistoryPopupStartAction, deps: null, target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
2769
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMVersionHistoryPopupStartAction }); }
|
|
2770
|
+
}
|
|
2771
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMVersionHistoryPopupStartAction, decorators: [{
|
|
2772
|
+
type: Injectable
|
|
2773
|
+
}] });
|
|
2774
|
+
const AXMVersionHistoryPopupWorkflow = {
|
|
2775
|
+
startStepId: 'start',
|
|
2776
|
+
steps: {
|
|
2777
|
+
start: {
|
|
2778
|
+
action: 'show-version-history-popup-action',
|
|
2779
|
+
},
|
|
2780
|
+
},
|
|
2781
|
+
};
|
|
2782
|
+
|
|
2783
|
+
const historyLoggerMiddleware = {
|
|
2784
|
+
target: { ops: ['create', 'update', 'delete'], order: 80 },
|
|
2785
|
+
execute: async (ctx, next) => {
|
|
2786
|
+
const entityRegistry = inject(AXPEntityDefinitionRegistryService);
|
|
2787
|
+
const sessionService = inject(AXPSessionService);
|
|
2788
|
+
const backend = inject(AXP_ENTITY_STORAGE_BACKEND);
|
|
2789
|
+
// Capture previous for update/delete
|
|
2790
|
+
if (ctx.op === 'update' || ctx.op === 'delete') {
|
|
2791
|
+
try {
|
|
2792
|
+
ctx.previous = await ctx.backend.getOneRaw(ctx.entityName, ctx.id);
|
|
2793
|
+
}
|
|
2794
|
+
catch { /* ignore */ }
|
|
2795
|
+
}
|
|
2796
|
+
await next();
|
|
2797
|
+
// Build history entry
|
|
2798
|
+
const now = new Date();
|
|
2799
|
+
const [moduleName, entityModuleName] = ctx.entityName.split('.');
|
|
2800
|
+
const entityConfig = await entityRegistry.resolve(moduleName, entityModuleName);
|
|
2801
|
+
const actions = [];
|
|
2802
|
+
if (ctx.op === 'update' && ctx.previous && ctx.result) {
|
|
2803
|
+
const changes = detectEntityChanges(ctx.previous, ctx.result);
|
|
2804
|
+
// Build actions similar to old addToHistory mapping by widget type
|
|
2805
|
+
if (entityConfig) {
|
|
2806
|
+
for (const [key, value] of Object.entries(changes)) {
|
|
2807
|
+
const property = entityConfig.properties.find((p) => p.name === key);
|
|
2808
|
+
if (property && property.schema?.interface) {
|
|
2809
|
+
const widgetType = property.schema.interface.type;
|
|
2810
|
+
switch (widgetType) {
|
|
2811
|
+
case 'file-uploader':
|
|
2812
|
+
if (value.added?.length) {
|
|
2813
|
+
actions.push({
|
|
2814
|
+
type: AXPSystemActionType.Upload,
|
|
2815
|
+
description: `"${value.added?.map((item) => item.name).join(', ')}"`,
|
|
2816
|
+
});
|
|
2817
|
+
}
|
|
2818
|
+
if (value.removed?.length) {
|
|
2819
|
+
actions.push({
|
|
2820
|
+
type: AXPSystemActionType.Delete,
|
|
2821
|
+
description: `"${value.removed?.map((item) => item.name).join(', ')}"`,
|
|
2822
|
+
});
|
|
2823
|
+
}
|
|
2824
|
+
break;
|
|
2825
|
+
case 'large-text-editor':
|
|
2826
|
+
case 'rich-text-editor': {
|
|
2827
|
+
const safeValue = extractTextFromHtml(value.newValue);
|
|
2828
|
+
actions.push({
|
|
2829
|
+
type: AXPSystemActionType.Update,
|
|
2830
|
+
description: `${property.title} to "${safeValue.length > 100 ? safeValue.slice(0, 30) + '...' : safeValue}"`,
|
|
2831
|
+
});
|
|
2832
|
+
break;
|
|
2833
|
+
}
|
|
2834
|
+
case 'text-editor':
|
|
2835
|
+
actions.push({
|
|
2836
|
+
type: AXPSystemActionType.Update,
|
|
2837
|
+
description: `${property.title} to "${value.newValue.length > 100 ? value.newValue.slice(0, 30) + '...' : value.newValue}"`,
|
|
2838
|
+
});
|
|
2839
|
+
break;
|
|
2840
|
+
default:
|
|
2841
|
+
actions.push({ type: AXPSystemActionType.Update, description: `${property.title}` });
|
|
2842
|
+
}
|
|
2843
|
+
}
|
|
2844
|
+
}
|
|
2845
|
+
}
|
|
2846
|
+
// Expose raw changes to event middleware
|
|
2847
|
+
ctx.locals.set('changes', changes);
|
|
2848
|
+
}
|
|
2849
|
+
// Compute reference ID and final data per operation
|
|
2850
|
+
let referenceId;
|
|
2851
|
+
let finalData = undefined;
|
|
2852
|
+
if (ctx.op === 'create') {
|
|
2853
|
+
const createdId = String(ctx.result);
|
|
2854
|
+
const createdEntity = { ...ctx.data, id: createdId };
|
|
2855
|
+
referenceId = createdId;
|
|
2856
|
+
finalData = createdEntity;
|
|
2857
|
+
}
|
|
2858
|
+
else if (ctx.op === 'update') {
|
|
2859
|
+
referenceId = String(ctx.id);
|
|
2860
|
+
finalData = ctx.result;
|
|
2861
|
+
}
|
|
2862
|
+
else {
|
|
2863
|
+
// delete
|
|
2864
|
+
referenceId = String(ctx.id);
|
|
2865
|
+
finalData = ctx.previous;
|
|
2866
|
+
}
|
|
2867
|
+
const record = {
|
|
2868
|
+
id: AXPDataGenerator.uuid(),
|
|
2869
|
+
title: entityConfig?.title ?? now.toISOString(),
|
|
2870
|
+
date: now,
|
|
2871
|
+
user: {
|
|
2872
|
+
id: sessionService.user?.id ?? 'system',
|
|
2873
|
+
name: sessionService.user?.name ?? 'System',
|
|
2874
|
+
title: sessionService.user?.title ?? 'System',
|
|
2875
|
+
},
|
|
2876
|
+
reference: { id: referenceId, type: ctx.entityName },
|
|
2877
|
+
changeType: ctx.op === 'create'
|
|
2878
|
+
? AXPSystemActionType.Create
|
|
2879
|
+
: ctx.op === 'update'
|
|
2880
|
+
? AXPSystemActionType.Update
|
|
2881
|
+
: AXPSystemActionType.Delete,
|
|
2882
|
+
changes: actions,
|
|
2883
|
+
data: finalData,
|
|
2884
|
+
};
|
|
2885
|
+
// Persist via backend raw insert to avoid recursive middleware
|
|
2886
|
+
try {
|
|
2887
|
+
await backend.insertOne(`${ctx.entityName}-history`, { ...record, isCurrent: true });
|
|
2888
|
+
}
|
|
2889
|
+
catch (error) {
|
|
2890
|
+
console.error(error);
|
|
2891
|
+
// swallow errors to avoid breaking main flow
|
|
2892
|
+
}
|
|
2893
|
+
},
|
|
2894
|
+
};
|
|
2895
|
+
|
|
2896
|
+
const historyPlugin = {
|
|
2897
|
+
name: 'history',
|
|
2898
|
+
order: 50,
|
|
2899
|
+
apply: (ctx) => {
|
|
2900
|
+
ensureListActions(ctx);
|
|
2901
|
+
ctx.interfaces.update((i) => {
|
|
2902
|
+
const cmdName = 'show-version-history-popup';
|
|
2903
|
+
//
|
|
2904
|
+
const listActions = i.master.list.actions;
|
|
2905
|
+
if (!actionExists(listActions, cmdName)) {
|
|
2906
|
+
listActions.push({
|
|
2907
|
+
title: '@activity-log:actions.view-history',
|
|
2908
|
+
command: {
|
|
2909
|
+
name: cmdName,
|
|
2910
|
+
options: {
|
|
2911
|
+
refId: '{{ context.eval("id") }}',
|
|
2912
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1663
2913
|
},
|
|
1664
|
-
|
|
1665
|
-
|
|
1666
|
-
|
|
2914
|
+
},
|
|
2915
|
+
priority: 'secondary',
|
|
2916
|
+
type: 'version-history',
|
|
2917
|
+
scope: AXPEntityCommandScope.Individual,
|
|
2918
|
+
});
|
|
2919
|
+
}
|
|
2920
|
+
//
|
|
2921
|
+
const singleActions = i.master.single.actions;
|
|
2922
|
+
if (!actionExists(singleActions, cmdName)) {
|
|
2923
|
+
singleActions.push({
|
|
2924
|
+
title: '@activity-log:actions.view-history',
|
|
2925
|
+
command: {
|
|
2926
|
+
name: cmdName,
|
|
2927
|
+
options: {
|
|
2928
|
+
refId: '{{ context.eval("id") }}',
|
|
2929
|
+
refType: `${ctx.entity.module}.${ctx.entity.name}`,
|
|
1667
2930
|
},
|
|
1668
2931
|
},
|
|
1669
|
-
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1677
|
-
}
|
|
1678
|
-
|
|
1679
|
-
type: Injectable
|
|
1680
|
-
}] });
|
|
2932
|
+
priority: 'secondary',
|
|
2933
|
+
type: 'version-history',
|
|
2934
|
+
scope: AXPEntityCommandScope.Individual,
|
|
2935
|
+
});
|
|
2936
|
+
}
|
|
2937
|
+
//
|
|
2938
|
+
return i;
|
|
2939
|
+
});
|
|
2940
|
+
},
|
|
2941
|
+
};
|
|
1681
2942
|
|
|
1682
|
-
|
|
1683
|
-
|
|
1684
|
-
|
|
1685
|
-
|
|
1686
|
-
|
|
1687
|
-
|
|
1688
|
-
|
|
1689
|
-
|
|
1690
|
-
|
|
1691
|
-
|
|
1692
|
-
|
|
1693
|
-
|
|
1694
|
-
|
|
1695
|
-
|
|
1696
|
-
|
|
1697
|
-
|
|
1698
|
-
|
|
1699
|
-
|
|
2943
|
+
const comparePlugin = {
|
|
2944
|
+
name: 'compare',
|
|
2945
|
+
order: 50,
|
|
2946
|
+
apply: (ctx) => {
|
|
2947
|
+
ensureListActions(ctx);
|
|
2948
|
+
ctx.interfaces.update((i) => {
|
|
2949
|
+
const actions = i.master.list.actions;
|
|
2950
|
+
const cmdName = 'show-entity-records-compare';
|
|
2951
|
+
if (!actionExists(actions, cmdName)) {
|
|
2952
|
+
actions.push({
|
|
2953
|
+
title: '@activity-log:actions.compare-records',
|
|
2954
|
+
command: { name: cmdName },
|
|
2955
|
+
priority: 'secondary',
|
|
2956
|
+
type: 'compare',
|
|
2957
|
+
scope: AXPEntityCommandScope.Selected,
|
|
2958
|
+
});
|
|
2959
|
+
}
|
|
2960
|
+
return i;
|
|
2961
|
+
});
|
|
2962
|
+
},
|
|
2963
|
+
};
|
|
2964
|
+
|
|
2965
|
+
class AXPVersionHistoryModule {
|
|
2966
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
2967
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, imports: [i1.AXPWorkflowModule] }); }
|
|
2968
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, providers: [
|
|
2969
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: historyLoggerMiddleware },
|
|
2970
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: historyPlugin },
|
|
2971
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: comparePlugin },
|
|
2972
|
+
], imports: [AXPWorkflowModule.forChild({
|
|
2973
|
+
actions: {
|
|
2974
|
+
'show-version-history-popup-action': AXMVersionHistoryPopupStartAction,
|
|
1700
2975
|
},
|
|
1701
|
-
|
|
1702
|
-
|
|
1703
|
-
|
|
1704
|
-
|
|
1705
|
-
multi: true,
|
|
1706
|
-
},
|
|
1707
|
-
] }); }
|
|
2976
|
+
workflows: {
|
|
2977
|
+
'show-version-history-popup': AXMVersionHistoryPopupWorkflow,
|
|
2978
|
+
},
|
|
2979
|
+
})] }); }
|
|
1708
2980
|
}
|
|
1709
|
-
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type:
|
|
2981
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPVersionHistoryModule, decorators: [{
|
|
1710
2982
|
type: NgModule,
|
|
1711
2983
|
args: [{
|
|
1712
|
-
|
|
1713
|
-
{
|
|
1714
|
-
|
|
1715
|
-
|
|
1716
|
-
multi: true,
|
|
1717
|
-
useFactory: () => {
|
|
1718
|
-
const provider = {
|
|
1719
|
-
define: async (context) => {
|
|
1720
|
-
// Generate permissions for any entity that declared category extension
|
|
1721
|
-
// We can’t scan registry here reliably at bootstrap; rely on generic pattern per module via wildcard
|
|
1722
|
-
// Consumers can still override with module-level providers.
|
|
1723
|
-
// No-op here; permissions will be added when category entity is resolved via provideEntity elsewhere if needed.
|
|
1724
|
-
},
|
|
1725
|
-
};
|
|
1726
|
-
return provider;
|
|
2984
|
+
imports: [
|
|
2985
|
+
AXPWorkflowModule.forChild({
|
|
2986
|
+
actions: {
|
|
2987
|
+
'show-version-history-popup-action': AXMVersionHistoryPopupStartAction,
|
|
1727
2988
|
},
|
|
1728
|
-
|
|
1729
|
-
|
|
1730
|
-
|
|
1731
|
-
|
|
1732
|
-
|
|
1733
|
-
|
|
2989
|
+
workflows: {
|
|
2990
|
+
'show-version-history-popup': AXMVersionHistoryPopupWorkflow,
|
|
2991
|
+
},
|
|
2992
|
+
}),
|
|
2993
|
+
],
|
|
2994
|
+
exports: [],
|
|
2995
|
+
providers: [
|
|
2996
|
+
{ provide: AXP_ENTITY_STORAGE_MIDDLEWARE, multi: true, useValue: historyLoggerMiddleware },
|
|
2997
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: historyPlugin },
|
|
2998
|
+
{ provide: AXP_ENTITY_ACTION_PLUGIN, multi: true, useValue: comparePlugin },
|
|
1734
2999
|
],
|
|
1735
3000
|
}]
|
|
1736
3001
|
}] });
|
|
1737
3002
|
|
|
3003
|
+
const config = {
|
|
3004
|
+
i18n: 'common',
|
|
3005
|
+
};
|
|
3006
|
+
const RootConfig = {
|
|
3007
|
+
config,
|
|
3008
|
+
module: {
|
|
3009
|
+
module: 'common',
|
|
3010
|
+
name: 'Common',
|
|
3011
|
+
title: `t('module-name', {scope:"${config.i18n}"})`,
|
|
3012
|
+
icon: 'fa-light fa-file-invoice',
|
|
3013
|
+
},
|
|
3014
|
+
entities: {},
|
|
3015
|
+
};
|
|
3016
|
+
|
|
3017
|
+
class AXMMenuProvider {
|
|
3018
|
+
constructor() {
|
|
3019
|
+
this.sessionService = inject(AXPSessionService);
|
|
3020
|
+
this.homePageService = inject(AXPHomePageService);
|
|
3021
|
+
}
|
|
3022
|
+
async provide(context) {
|
|
3023
|
+
const scope = RootConfig.config.i18n;
|
|
3024
|
+
const module = RootConfig.module;
|
|
3025
|
+
const appName = this.sessionService.application?.name;
|
|
3026
|
+
const isAuthorized = await firstValueFrom(this.sessionService.isAuthorized$);
|
|
3027
|
+
if (!isAuthorized) {
|
|
3028
|
+
return;
|
|
3029
|
+
}
|
|
3030
|
+
//
|
|
3031
|
+
const homePagePath = this.homePageService.getCurrent().path;
|
|
3032
|
+
if (homePagePath) {
|
|
3033
|
+
context.addItems([
|
|
3034
|
+
{
|
|
3035
|
+
priority: -9,
|
|
3036
|
+
text: `t('home',{scope:'common'})`,
|
|
3037
|
+
path: homePagePath,
|
|
3038
|
+
icon: 'fa-light fa-grid-2',
|
|
3039
|
+
data: {
|
|
3040
|
+
//requiredPermission: '',
|
|
3041
|
+
},
|
|
3042
|
+
},
|
|
3043
|
+
]);
|
|
3044
|
+
}
|
|
3045
|
+
context.find('user-profile').addItems([
|
|
3046
|
+
{
|
|
3047
|
+
text: `t('user.title', {scope: "settings"})`,
|
|
3048
|
+
name: 'user-settings',
|
|
3049
|
+
icon: 'fa-light fa-gear',
|
|
3050
|
+
path: `/${this.sessionService.application?.name}/settings/user`,
|
|
3051
|
+
},
|
|
3052
|
+
]);
|
|
3053
|
+
context.addItems([
|
|
3054
|
+
{
|
|
3055
|
+
name: 'tenant-application-settings',
|
|
3056
|
+
priority: 10000000,
|
|
3057
|
+
text: `t('tenant.title', {scope: "settings"})`,
|
|
3058
|
+
type: 'menu',
|
|
3059
|
+
icon: 'fa-light fa-gear',
|
|
3060
|
+
path: `/${appName}/settings/tenant`,
|
|
3061
|
+
data: {
|
|
3062
|
+
requiredPermission: 'admin',
|
|
3063
|
+
},
|
|
3064
|
+
},
|
|
3065
|
+
]);
|
|
3066
|
+
}
|
|
3067
|
+
}
|
|
3068
|
+
|
|
3069
|
+
class AXMPermissionDefinitionProvider {
|
|
3070
|
+
async define(context) {
|
|
3071
|
+
// context.addPermissions([
|
|
3072
|
+
// {
|
|
3073
|
+
// name: 'view_templates',
|
|
3074
|
+
// title: 'Permission to view templates',
|
|
3075
|
+
// isArchived: false,
|
|
3076
|
+
// },
|
|
3077
|
+
// ]);
|
|
3078
|
+
}
|
|
3079
|
+
}
|
|
3080
|
+
|
|
3081
|
+
class AXMSearchCommandProvider extends AXPSearchCommandProvider {
|
|
3082
|
+
constructor() {
|
|
3083
|
+
super(...arguments);
|
|
3084
|
+
this.commands = [
|
|
3085
|
+
// {
|
|
3086
|
+
// group: 'command',
|
|
3087
|
+
// title: 'New Form Template',
|
|
3088
|
+
// icon: RootConfig.entities.template.icon,
|
|
3089
|
+
// description: 'Create a new form template for designing reusable forms.', // Added description
|
|
3090
|
+
// commands: {
|
|
3091
|
+
// 'create-entity': {
|
|
3092
|
+
// entity: `${RootConfig.module.name}.${RootConfig.entities.template.name}`,
|
|
3093
|
+
// },
|
|
3094
|
+
// },
|
|
3095
|
+
// }
|
|
3096
|
+
];
|
|
3097
|
+
}
|
|
3098
|
+
}
|
|
3099
|
+
|
|
3100
|
+
class AXMSettingProvider {
|
|
3101
|
+
constructor(injector) {
|
|
3102
|
+
this.injector = injector;
|
|
3103
|
+
this.translateService = this.injector.get(AXTranslationService);
|
|
3104
|
+
}
|
|
3105
|
+
async provide(context) {
|
|
3106
|
+
const trans = async (key) => await this.translateService.translateAsync(`settings.${key}`, { scope: 'general' });
|
|
3107
|
+
// Find the 'General Settings' group
|
|
3108
|
+
const group = context.group('general');
|
|
3109
|
+
if (!group) {
|
|
3110
|
+
return;
|
|
3111
|
+
}
|
|
3112
|
+
// Add the 'Release Notes' setting
|
|
3113
|
+
// group.addSection('lock-system', await trans('general.lock-system.lock.title'), await trans('general.lock-system.lock.description')).addSetting({
|
|
3114
|
+
// key: AXMLockSystemSettings.LockSystem,
|
|
3115
|
+
// title: await trans('general.lock-system.lock.title'),
|
|
3116
|
+
// scope: AXPPlatformScope.Tenant,
|
|
3117
|
+
// isInherited: true,
|
|
3118
|
+
// defaultValue: false,
|
|
3119
|
+
// valueTransforms: objectKeyValueTransforms('id'),
|
|
3120
|
+
// widget: {
|
|
3121
|
+
// type: AXPWidgetsCatalog.toggle,
|
|
3122
|
+
// options: {
|
|
3123
|
+
// label: null,
|
|
3124
|
+
// }
|
|
3125
|
+
// },
|
|
3126
|
+
// description: await trans('general.lock-system.lock.description'),
|
|
3127
|
+
// })
|
|
3128
|
+
}
|
|
3129
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMSettingProvider, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
3130
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMSettingProvider }); }
|
|
3131
|
+
}
|
|
3132
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMSettingProvider, decorators: [{
|
|
3133
|
+
type: Injectable
|
|
3134
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
3135
|
+
|
|
1738
3136
|
class AXMCommonModule {
|
|
1739
3137
|
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCommonModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1740
3138
|
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "20.1.6", ngImport: i0, type: AXMCommonModule, imports: [AXMLockSystemModule,
|
|
@@ -1743,6 +3141,9 @@ class AXMCommonModule {
|
|
|
1743
3141
|
AXPGlobalSearchModule,
|
|
1744
3142
|
AXPWidgetsModule,
|
|
1745
3143
|
AXPVersionHistoryModule,
|
|
3144
|
+
AXPComputedPropertiesModule,
|
|
3145
|
+
AXPClonePluginModule,
|
|
3146
|
+
AXPArchivePluginModule,
|
|
1746
3147
|
AXPCompareModule] }); }
|
|
1747
3148
|
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCommonModule, providers: [
|
|
1748
3149
|
{
|
|
@@ -1781,6 +3182,9 @@ class AXMCommonModule {
|
|
|
1781
3182
|
AXPGlobalSearchModule,
|
|
1782
3183
|
AXPWidgetsModule,
|
|
1783
3184
|
AXPVersionHistoryModule,
|
|
3185
|
+
AXPComputedPropertiesModule,
|
|
3186
|
+
AXPClonePluginModule,
|
|
3187
|
+
AXPArchivePluginModule,
|
|
1784
3188
|
AXPCompareModule] }); }
|
|
1785
3189
|
}
|
|
1786
3190
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXMCommonModule, decorators: [{
|
|
@@ -1793,6 +3197,9 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImpor
|
|
|
1793
3197
|
AXPGlobalSearchModule,
|
|
1794
3198
|
AXPWidgetsModule,
|
|
1795
3199
|
AXPVersionHistoryModule,
|
|
3200
|
+
AXPComputedPropertiesModule,
|
|
3201
|
+
AXPClonePluginModule,
|
|
3202
|
+
AXPArchivePluginModule,
|
|
1796
3203
|
AXPCompareModule,
|
|
1797
3204
|
],
|
|
1798
3205
|
exports: [],
|
|
@@ -1922,7 +3329,7 @@ class AXPLockPopupComponent extends AXBasePageComponent {
|
|
|
1922
3329
|
// Angular
|
|
1923
3330
|
CommonModule }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i1$3.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1$3.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type:
|
|
1924
3331
|
// ACoreX
|
|
1925
|
-
AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i4$1.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i4$1.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "directive", type: i4$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i5.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i6.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed"] }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i7.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i4.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
3332
|
+
AXButtonModule }, { kind: "component", type: i2.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "iconOnly", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i1$1.AXDecoratorClearButtonComponent, selector: "ax-clear-button", inputs: ["icon"] }, { kind: "component", type: i1$1.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXFormModule }, { kind: "component", type: i4$1.AXFormFieldComponent, selector: "ax-form-field", inputs: ["labelMode"] }, { kind: "component", type: i4$1.AXFormComponent, selector: "ax-form", inputs: ["labelMode", "look", "messageStyle", "updateOn"], outputs: ["onValidate", "updateOnChange"] }, { kind: "directive", type: i4$1.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXLabelModule }, { kind: "component", type: i5.AXLabelComponent, selector: "ax-label", inputs: ["required", "for"], outputs: ["requiredChange"] }, { kind: "ngmodule", type: AXSelectBoxModule }, { kind: "component", type: i6.AXSelectBoxComponent, selector: "ax-select-box", inputs: ["disabled", "readonly", "tabIndex", "placeholder", "minValue", "maxValue", "value", "state", "name", "id", "type", "look", "multiple", "valueField", "textField", "disabledField", "textTemplate", "selectedItems", "isItemTruncated", "showItemTooltip", "dataSource", "minRecordsForSearch", "caption", "itemTemplate", "selectedTemplate", "emptyTemplate", "loadingTemplate", "dropdownWidth", "searchBoxAutoFocus"], outputs: ["valueChange", "stateChange", "onValueChanged", "onBlur", "onFocus", "readonlyChange", "disabledChange", "onOpened", "onClosed", "onItemSelected", "onItemClick"] }, { kind: "ngmodule", type: AXTextAreaModule }, { kind: "component", type: i7.AXTextAreaComponent, selector: "ax-text-area", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "placeholder", "maxLength", "look", "rows", "allowResize", "showCounter", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress"] }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i4.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXValidationModule }, { kind: "pipe", type: i3.AsyncPipe, name: "async" }], encapsulation: i0.ViewEncapsulation.None }); }
|
|
1926
3333
|
}
|
|
1927
3334
|
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "20.1.6", ngImport: i0, type: AXPLockPopupComponent, decorators: [{
|
|
1928
3335
|
type: Component,
|