@acorex/modules 19.2.6 → 19.2.7
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/application-management/lib/layouts/module-entity-detail-view/module-entity-detail-view.component.d.ts +2 -2
- package/fesm2022/{acorex-modules-auth-acorex-modules-auth-D75igkfc.mjs → acorex-modules-auth-acorex-modules-auth-HwJJs-3A.mjs} +12 -12
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-HwJJs-3A.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-app-chooser.component-BZb8n5Ag.mjs → acorex-modules-auth-app-chooser.component-BvxMkXPp.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-app-chooser.component-BZb8n5Ag.mjs.map → acorex-modules-auth-app-chooser.component-BvxMkXPp.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-login.module-DAtJYcHZ.mjs → acorex-modules-auth-login.module-CDvLUxls.mjs} +4 -4
- package/fesm2022/{acorex-modules-auth-login.module-DAtJYcHZ.mjs.map → acorex-modules-auth-login.module-CDvLUxls.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth-master.layout-CnKBnl8W.mjs +23 -0
- package/fesm2022/acorex-modules-auth-master.layout-CnKBnl8W.mjs.map +1 -0
- package/fesm2022/{acorex-modules-auth-password.component-20Ofs9FL.mjs → acorex-modules-auth-password.component-1FnIjiZ8.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-20Ofs9FL.mjs.map → acorex-modules-auth-password.component-1FnIjiZ8.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-password.component-CRvI9sIa.mjs → acorex-modules-auth-password.component-C16jeHuJ.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-password.component-CRvI9sIa.mjs.map → acorex-modules-auth-password.component-C16jeHuJ.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-routes-BDED-qaZ.mjs → acorex-modules-auth-routes-ZDDUhAWd.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-routes-BDED-qaZ.mjs.map → acorex-modules-auth-routes-ZDDUhAWd.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-setting.provider-GJeEbIRd.mjs → acorex-modules-auth-setting.provider-DDl3OHw6.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-setting.provider-GJeEbIRd.mjs.map → acorex-modules-auth-setting.provider-DDl3OHw6.mjs.map} +1 -1
- package/fesm2022/{acorex-modules-auth-two-factor.module-B0C2aBWh.mjs → acorex-modules-auth-two-factor.module-C32MVGby.mjs} +2 -2
- package/fesm2022/{acorex-modules-auth-two-factor.module-B0C2aBWh.mjs.map → acorex-modules-auth-two-factor.module-C32MVGby.mjs.map} +1 -1
- package/fesm2022/acorex-modules-auth.mjs +1 -1
- package/fesm2022/acorex-modules-form-template-management-acorex-modules-form-template-management-DGGKoVbL.mjs +908 -0
- package/fesm2022/acorex-modules-form-template-management-acorex-modules-form-template-management-DGGKoVbL.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-category.entity-BcfMw_wb.mjs → acorex-modules-form-template-management-category.entity-B1X2QyYV.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-category.entity-BcfMw_wb.mjs.map → acorex-modules-form-template-management-category.entity-B1X2QyYV.mjs.map} +1 -1
- package/fesm2022/acorex-modules-form-template-management-designer.page-BLbPLLdP.mjs.map +1 -1
- package/fesm2022/{acorex-modules-form-template-management-setting.provider-ceq0ZtxA.mjs → acorex-modules-form-template-management-setting.provider-D-HyCbH7.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-setting.provider-ceq0ZtxA.mjs.map → acorex-modules-form-template-management-setting.provider-D-HyCbH7.mjs.map} +1 -1
- package/fesm2022/acorex-modules-form-template-management-template-picker.component-xiRKc4FF.mjs.map +1 -1
- package/fesm2022/{acorex-modules-form-template-management-template-widget-edit.component-CVyFN7D9.mjs → acorex-modules-form-template-management-template-widget-edit.component-CyZLM6M9.mjs} +2 -2
- package/fesm2022/acorex-modules-form-template-management-template-widget-edit.component-CyZLM6M9.mjs.map +1 -0
- package/fesm2022/{acorex-modules-form-template-management-template.entity-BpApQcvG.mjs → acorex-modules-form-template-management-template.entity-DXIhxJeU.mjs} +2 -2
- package/fesm2022/{acorex-modules-form-template-management-template.entity-BpApQcvG.mjs.map → acorex-modules-form-template-management-template.entity-DXIhxJeU.mjs.map} +1 -1
- package/fesm2022/acorex-modules-form-template-management.mjs +1 -907
- package/fesm2022/acorex-modules-form-template-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-notification-management.mjs +49 -66
- package/fesm2022/acorex-modules-notification-management.mjs.map +1 -1
- package/fesm2022/acorex-modules-organization-management-add-item.component-D0tN7Se4.mjs +83 -0
- package/fesm2022/acorex-modules-organization-management-add-item.component-D0tN7Se4.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-branch.entity-kuZxLStS.mjs → acorex-modules-organization-management-branch.entity-CbmnpHl2.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-branch.entity-CbmnpHl2.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-chart.entity-BqUE8fbV.mjs → acorex-modules-organization-management-chart.entity-Bk4WgsYr.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-chart.entity-Bk4WgsYr.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-company.entity-DJt8tCqO.mjs → acorex-modules-organization-management-company.entity-d7GaCVei.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-company.entity-d7GaCVei.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-department.entity-C1PxLx6p.mjs → acorex-modules-organization-management-department.entity-Dl7y4Rva.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-department.entity-Dl7y4Rva.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-division.entity-DHVnrP38.mjs → acorex-modules-organization-management-division.entity-Ckmu2Tj9.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-division.entity-Ckmu2Tj9.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-employee.entity-D4BSxGAW.mjs → acorex-modules-organization-management-employee.entity-PwlBjkYo.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-employee.entity-PwlBjkYo.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-employment-type.entity-Cgbezwio.mjs → acorex-modules-organization-management-employment-type.entity-9aOaYT_-.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-employment-type.entity-9aOaYT_-.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-org-chart-configuration.page-DEFgztyn.mjs → acorex-modules-organization-management-org-chart-configuration.page-BzjTyYyS.mjs} +6 -6
- package/fesm2022/acorex-modules-organization-management-org-chart-configuration.page-BzjTyYyS.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-org-chart-configuration.service-D-LkPUIw.mjs → acorex-modules-organization-management-org-chart-configuration.service-DObuNZKQ.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-org-chart-configuration.service-DObuNZKQ.mjs.map +1 -0
- package/fesm2022/acorex-modules-organization-management-org-chart.page-Cz4ENQRa.mjs +868 -0
- package/fesm2022/acorex-modules-organization-management-org-chart.page-Cz4ENQRa.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-position.entity-Bbb5KAkm.mjs → acorex-modules-organization-management-position.entity-DDkiBefn.mjs} +2 -2
- package/fesm2022/acorex-modules-organization-management-position.entity-DDkiBefn.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-setting.keys-CF6Giykz.mjs → acorex-modules-organization-management-setting.keys-CF6Giykz.mjs} +1 -1
- package/fesm2022/acorex-modules-organization-management-setting.keys-CF6Giykz.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment-setting.provider-nKs53GcA.mjs → acorex-modules-organization-management-setting.provider-eLv_qnmE.mjs} +3 -3
- package/fesm2022/acorex-modules-organization-management-setting.provider-eLv_qnmE.mjs.map +1 -0
- package/fesm2022/{acorex-modules-organization-managment.mjs → acorex-modules-organization-management.mjs} +66 -22
- package/fesm2022/acorex-modules-organization-management.mjs.map +1 -0
- package/fesm2022/acorex-modules-platform-management.mjs +1443 -155
- package/fesm2022/acorex-modules-platform-management.mjs.map +1 -1
- package/form-template-management/index.d.ts +0 -1
- package/form-template-management/lib/features/designer/index.d.ts +5 -0
- package/form-template-management/lib/{services → features/designer}/template.provider.d.ts +1 -1
- package/form-template-management/lib/features/index.d.ts +1 -0
- package/notification-management/lib/entities/channel/channel.types.d.ts +3 -1
- package/organization-management/README.md +3 -0
- package/organization-management/index.d.ts +4 -0
- package/{organization-managment → organization-management}/lib/entities/chart/chart.types.d.ts +10 -5
- package/organization-management/lib/features/index.d.ts +1 -0
- package/organization-management/lib/features/organization-chart/add-item/add-item.component.d.ts +21 -0
- package/organization-management/lib/features/organization-chart/index.d.ts +1 -0
- package/{organization-managment → organization-management}/lib/features/organization-chart/org-chart-configuration.page.d.ts +2 -2
- package/{organization-managment → organization-management}/lib/features/organization-chart/org-chart-configuration.service.d.ts +6 -5
- package/organization-management/lib/features/organization-chart/org-chart-print.service.d.ts +45 -0
- package/{organization-managment → organization-management}/lib/features/organization-chart/org-chart.page.d.ts +78 -7
- package/organization-management/lib/features/organization-chart/org-chart.service.d.ts +63 -0
- package/organization-management/lib/features/organization-chart/org-chart.type.d.ts +46 -0
- package/{organization-managment/lib/organization-managment.module.d.ts → organization-management/lib/organization-management.module.d.ts} +4 -4
- package/package.json +8 -8
- package/platform-management/lib/const.d.ts +12 -0
- package/platform-management/lib/entities/app-term/components/notify-app/notify-app.component.d.ts +1 -2
- package/platform-management/lib/entities/data-source/coulmn-def.widget.d.ts +56 -0
- package/platform-management/lib/entities/data-source/data-source.entity.d.ts +3 -0
- package/platform-management/lib/entities/data-source/data-source.service.d.ts +10 -0
- package/platform-management/lib/entities/data-source/data-source.types.d.ts +7 -0
- package/platform-management/lib/entities/data-source/datasource-provider.dynamic.d.ts +6 -0
- package/platform-management/lib/entities/data-source/index.d.ts +3 -0
- package/platform-management/lib/entities/index.d.ts +2 -0
- package/platform-management/lib/entities/promotion/components/index.d.ts +1 -0
- package/{notification-management/lib → platform-management/lib/entities/promotion}/components/promotion-slot/promotion-slot.component.d.ts +5 -3
- package/platform-management/lib/entities/promotion/index.d.ts +4 -0
- package/platform-management/lib/entities/promotion/promotion.entity.d.ts +3 -0
- package/platform-management/lib/entities/promotion/promotion.service.d.ts +10 -0
- package/platform-management/lib/entities/promotion/promotion.types.d.ts +15 -0
- package/platform-management/lib/platform-management.module.d.ts +2 -1
- package/fesm2022/acorex-modules-auth-acorex-modules-auth-D75igkfc.mjs.map +0 -1
- package/fesm2022/acorex-modules-auth-master.layout-qeAQTygT.mjs +0 -23
- package/fesm2022/acorex-modules-auth-master.layout-qeAQTygT.mjs.map +0 -1
- package/fesm2022/acorex-modules-form-template-management-template-widget-edit.component-CVyFN7D9.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-branch.entity-kuZxLStS.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-chart.entity-BqUE8fbV.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-company.entity-DJt8tCqO.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-department.entity-C1PxLx6p.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-division.entity-DHVnrP38.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-employee.entity-D4BSxGAW.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-employment-type.entity-Cgbezwio.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-org-chart-configuration.page-DEFgztyn.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-org-chart-configuration.service-D-LkPUIw.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-org-chart.page-B3aaLlm2.mjs +0 -597
- package/fesm2022/acorex-modules-organization-managment-org-chart.page-B3aaLlm2.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-position.entity-Bbb5KAkm.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-setting.keys-CF6Giykz.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment-setting.provider-nKs53GcA.mjs.map +0 -1
- package/fesm2022/acorex-modules-organization-managment.mjs.map +0 -1
- package/organization-managment/README.md +0 -3
- package/organization-managment/index.d.ts +0 -3
- package/organization-managment/lib/features/organization-chart/org-chart-print.service.d.ts +0 -22
- package/organization-managment/lib/features/organization-chart/org-chart.service.d.ts +0 -19
- package/organization-managment/lib/features/organization-chart/org-chart.type.d.ts +0 -25
- /package/form-template-management/lib/{services → features/designer}/designer-connector.service.d.ts +0 -0
- /package/form-template-management/lib/{pages → features}/designer/designer.page.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template/index.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template/template-widget-designer.component.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template/template-widget-edit.component.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template/template-widget-view.component.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template/template-widget.config.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template-designer/index.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template-designer/template-designer-widget-view.component.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template-designer/template-designer-widget.config.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template-picker/template-picker.component.d.ts +0 -0
- /package/form-template-management/lib/{components → features/designer}/widgets/template-picker/template.provider.d.ts +0 -0
- /package/form-template-management/lib/{workflows → features/designer/workflows}/create-template.workflow.d.ts +0 -0
- /package/form-template-management/lib/{workflows → features/designer/workflows}/design-template.workflow.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/const.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/branch/branch.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/branch/branch.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/branch/branch.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/branch/branch.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/branch/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/chart/chart.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/chart/chart.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/chart/chart.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/chart/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/company/company.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/company/company.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/company/company.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/company/company.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/company/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/department/department.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/department/department.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/department/department.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/department/department.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/department/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/division/division.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/division/division.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/division/division.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/division/division.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/division/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employee/employee.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employee/employee.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employee/employee.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employee/employee.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employee/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employment-type/employment-type.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employment-type/employment-type.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employment-type/employment-type.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employment-type/employment-type.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/employment-type/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/position/index.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/position/position.entity.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/position/position.module.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/position/position.service.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entities/position/position.types.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/entity.provider.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/menu.provider.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/setting.keys.d.ts +0 -0
- /package/{organization-managment → organization-management}/lib/setting.provider.d.ts +0 -0
@@ -0,0 +1,868 @@
|
|
1
|
+
import { AXPanViewDirective } from '@acorex/cdk/pan-view';
|
2
|
+
import { AXBadgeModule } from '@acorex/components/badge';
|
3
|
+
import * as i6 from '@acorex/components/breadcrumbs';
|
4
|
+
import { AXBreadcrumbsModule } from '@acorex/components/breadcrumbs';
|
5
|
+
import * as i3 from '@acorex/components/button';
|
6
|
+
import { AXButtonModule } from '@acorex/components/button';
|
7
|
+
import * as i5 from '@acorex/components/decorators';
|
8
|
+
import { AXDecoratorModule } from '@acorex/components/decorators';
|
9
|
+
import { AXDropdownButtonModule } from '@acorex/components/dropdown-button';
|
10
|
+
import { AXLoadingModule } from '@acorex/components/loading';
|
11
|
+
import * as i2 from '@acorex/components/menu';
|
12
|
+
import { AXContextMenuComponent, AXMenuModule } from '@acorex/components/menu';
|
13
|
+
import * as i4 from '@acorex/core/translation';
|
14
|
+
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
15
|
+
import { AXPSimplePageLayout } from '@acorex/platform/themes/default';
|
16
|
+
import { AXPLayoutThemeService, AXPThemeLayoutBlockComponent, AXPThemeLayoutHeaderTemplateComponent, AXPThemeLayoutActionsComponent, AXPThemeLayoutPageSecondaryActionsComponent, AXPThemeLayoutPagePrimaryActionsComponent, AXPThemeLayoutFooterComponent } from '@acorex/platform/themes/shared';
|
17
|
+
import * as i1 from '@angular/common';
|
18
|
+
import { CommonModule } from '@angular/common';
|
19
|
+
import * as i0 from '@angular/core';
|
20
|
+
import { inject, Injectable, signal, viewChild, NgZone, ViewContainerRef, afterNextRender, Component, ChangeDetectionStrategy, ViewEncapsulation } from '@angular/core';
|
21
|
+
import { RouterModule } from '@angular/router';
|
22
|
+
import get from 'lodash-es/get';
|
23
|
+
import { AXMOrganizationManagementDepartmentEntityService, AXMOrganizationManagementDivisionEntityService, AXMOrganizationManagementBranchEntityService, AXMOrganizationManagementEmployeeEntityService, AXMOrganizationManagementPositionEntityService, AXMOrganizationManagementChartEntityService, AXMOrganizationNodeType, AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS, RootConfig, AXMOrganizationNodeTypeCategory } from './acorex-modules-organization-management.mjs';
|
24
|
+
import { A as AXMOrgChartConfigService } from './acorex-modules-organization-management-org-chart-configuration.service-DObuNZKQ.mjs';
|
25
|
+
import { AXLoadingDialogService } from '@acorex/components/loading-dialog';
|
26
|
+
import { AXPExportService, AXPDataGenerator } from '@acorex/platform/common';
|
27
|
+
import { AXPSessionService } from '@acorex/platform/auth';
|
28
|
+
import { cloneDeep } from 'lodash-es';
|
29
|
+
import { AXPopupService } from '@acorex/components/popup';
|
30
|
+
import set from 'lodash-es/set';
|
31
|
+
|
32
|
+
/**
|
33
|
+
* Service for printing organization charts.
|
34
|
+
*/
|
35
|
+
class AXMOrgChartPrintService {
|
36
|
+
constructor() {
|
37
|
+
this.loadingDialog = inject(AXLoadingDialogService);
|
38
|
+
this.exportService = inject(AXPExportService);
|
39
|
+
this.translationService = inject(AXTranslationService);
|
40
|
+
}
|
41
|
+
/**
|
42
|
+
* Prints the organization chart.
|
43
|
+
* @param element - The HTMLElement representing the chart to be printed.
|
44
|
+
* @returns A promise that resolves when the print process is complete.
|
45
|
+
*/
|
46
|
+
async printChart(element) {
|
47
|
+
const d = this.loadingDialog.show({
|
48
|
+
title: 'Printing Organization Chart...',
|
49
|
+
mode: 'determinate',
|
50
|
+
progressColor: 'primary',
|
51
|
+
progressValue: 0,
|
52
|
+
status: '0/10',
|
53
|
+
text: 'Initializing print process...',
|
54
|
+
buttons: [
|
55
|
+
{
|
56
|
+
text: 'Cancel',
|
57
|
+
color: 'danger',
|
58
|
+
onClick: () => {
|
59
|
+
d.close();
|
60
|
+
},
|
61
|
+
},
|
62
|
+
],
|
63
|
+
});
|
64
|
+
try {
|
65
|
+
await this.HandleStep(d, await this.translateStatements('preparing-document'), 10, '1/10');
|
66
|
+
const chartElement = element;
|
67
|
+
const { originalStyles, modifiedStyles } = this.expandChart(chartElement);
|
68
|
+
await this.HandleStep(d, await this.translateStatements('rendering-chart-image'), 25, '2.5/10');
|
69
|
+
const canvasBlob = await this.exportService.generateBlobFromElement(chartElement, {
|
70
|
+
popup: true,
|
71
|
+
filter: (node) => {
|
72
|
+
if (node instanceof Element && node.classList.contains('--toggle')) {
|
73
|
+
return false;
|
74
|
+
}
|
75
|
+
return true;
|
76
|
+
},
|
77
|
+
bgcolor: 'transparent',
|
78
|
+
scale: 2,
|
79
|
+
quality: 1,
|
80
|
+
height: Number.parseInt(modifiedStyles.modifiedHeight),
|
81
|
+
width: Number.parseInt(modifiedStyles.modifiedWidth),
|
82
|
+
});
|
83
|
+
await this.HandleStep(d, await this.translateStatements('finalizing-image-processing'), 50, '5/10');
|
84
|
+
this.restoreChartStyles(chartElement, originalStyles);
|
85
|
+
await this.HandleStep(d, await this.translateStatements('downloading-image'), 75, '7.5/10');
|
86
|
+
this.exportService.download(canvasBlob, 'org-chart.png');
|
87
|
+
await this.HandleStep(d, await this.translateStatements('process-complete'), 100, '10/10');
|
88
|
+
setTimeout(() => d.close(), 1500);
|
89
|
+
}
|
90
|
+
catch (err) {
|
91
|
+
console.error('Error capturing chart:', err);
|
92
|
+
await this.HandleStep(d, await this.translateStatements('failed-to-generate-chart-image'), 100, 'Error', 'danger');
|
93
|
+
d.close();
|
94
|
+
}
|
95
|
+
}
|
96
|
+
/**
|
97
|
+
* Expands the chart temporarily to capture the full view.
|
98
|
+
* @param chartElement - The HTMLElement representing the chart.
|
99
|
+
* @returns An object containing the original and modified styles of the chart.
|
100
|
+
*/
|
101
|
+
expandChart(chartElement) {
|
102
|
+
const originalStyles = {
|
103
|
+
originalOverflow: chartElement.style.overflow,
|
104
|
+
originalWidth: chartElement.style.width,
|
105
|
+
originalHeight: chartElement.style.height,
|
106
|
+
};
|
107
|
+
const modifiedStyles = {
|
108
|
+
modifiedOverflow: 'visible',
|
109
|
+
modifiedWidth: `${chartElement.scrollWidth}px`,
|
110
|
+
modifiedHeight: `${chartElement.scrollHeight}px`,
|
111
|
+
};
|
112
|
+
chartElement.style.overflow = modifiedStyles.modifiedOverflow;
|
113
|
+
chartElement.style.width = modifiedStyles.modifiedWidth;
|
114
|
+
chartElement.style.height = modifiedStyles.modifiedHeight;
|
115
|
+
return { originalStyles, modifiedStyles };
|
116
|
+
}
|
117
|
+
/**
|
118
|
+
* Restores chart styles after capturing.
|
119
|
+
* @param chartElement - The HTMLElement representing the chart.
|
120
|
+
* @param originalStyles - The original styles to be restored.
|
121
|
+
*/
|
122
|
+
restoreChartStyles(chartElement, originalStyles) {
|
123
|
+
chartElement.style.overflow = originalStyles.originalOverflow;
|
124
|
+
chartElement.style.width = originalStyles.originalWidth;
|
125
|
+
chartElement.style.height = originalStyles.originalHeight;
|
126
|
+
}
|
127
|
+
/**
|
128
|
+
* Handles updating the progress dialog step.
|
129
|
+
* @param dialog - The dialog reference.
|
130
|
+
* @param text - The text to display in the dialog.
|
131
|
+
* @param progress - The progress value to set.
|
132
|
+
* @param status - The status to display.
|
133
|
+
* @param color - The color of the progress bar.
|
134
|
+
* @returns A promise that resolves when the dialog is updated.
|
135
|
+
*/
|
136
|
+
async HandleStep(dialog, text, progress, status, color = 'primary') {
|
137
|
+
return new Promise((resolve) => {
|
138
|
+
dialog.setProgressColor(color);
|
139
|
+
dialog.setProgressText(text);
|
140
|
+
dialog.setProgressValue(progress);
|
141
|
+
dialog.setProgressStatus(status);
|
142
|
+
resolve();
|
143
|
+
});
|
144
|
+
}
|
145
|
+
/**
|
146
|
+
* Translates a statement using the translation service.
|
147
|
+
* @param key - The translation key.
|
148
|
+
* @returns A promise that resolves to the translated string.
|
149
|
+
*/
|
150
|
+
async translateStatements(key) {
|
151
|
+
return (await this.translationService.translateAsync(key, { scope: 'organization-management' })) + '...';
|
152
|
+
}
|
153
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartPrintService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
154
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartPrintService }); }
|
155
|
+
}
|
156
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartPrintService, decorators: [{
|
157
|
+
type: Injectable
|
158
|
+
}] });
|
159
|
+
|
160
|
+
class AXMOrgChartService {
|
161
|
+
constructor() {
|
162
|
+
this.departmentService = inject(AXMOrganizationManagementDepartmentEntityService);
|
163
|
+
this.divisionService = inject(AXMOrganizationManagementDivisionEntityService);
|
164
|
+
this.branchService = inject(AXMOrganizationManagementBranchEntityService);
|
165
|
+
this.employmentService = inject(AXMOrganizationManagementEmployeeEntityService);
|
166
|
+
this.positionService = inject(AXMOrganizationManagementPositionEntityService);
|
167
|
+
this.chartService = inject(AXMOrganizationManagementChartEntityService);
|
168
|
+
this.sessionService = inject(AXPSessionService);
|
169
|
+
this.configService = inject(AXMOrgChartConfigService);
|
170
|
+
this.popupService = inject(AXPopupService);
|
171
|
+
this.layoutService = inject(AXPLayoutThemeService);
|
172
|
+
this._rootNode = signal({ id: AXPDataGenerator.uuid(), title: "Company" });
|
173
|
+
this.rootNode = this._rootNode.asReadonly();
|
174
|
+
// The clipboard holds the node being cut or copied.
|
175
|
+
this.clipboard = signal(null);
|
176
|
+
}
|
177
|
+
//#region Load/Save
|
178
|
+
async load() {
|
179
|
+
const first = (await this.chartService.query({
|
180
|
+
skip: 0,
|
181
|
+
take: 1,
|
182
|
+
sort: [
|
183
|
+
{ field: 'version', dir: 'desc' }
|
184
|
+
]
|
185
|
+
})).items[0];
|
186
|
+
//
|
187
|
+
if (first) {
|
188
|
+
const data = first.data;
|
189
|
+
this._rootNode.set(data);
|
190
|
+
}
|
191
|
+
else {
|
192
|
+
await this.createNew();
|
193
|
+
await this.load();
|
194
|
+
}
|
195
|
+
}
|
196
|
+
async createNew() {
|
197
|
+
const tenant = this.sessionService.tenant;
|
198
|
+
const record = {
|
199
|
+
id: AXPDataGenerator.uuid(),
|
200
|
+
createAt: new Date(),
|
201
|
+
updateAt: new Date(),
|
202
|
+
version: '0.0.0',
|
203
|
+
data: {
|
204
|
+
id: AXPDataGenerator.uuid(),
|
205
|
+
title: tenant.name,
|
206
|
+
type: AXMOrganizationNodeType.Company,
|
207
|
+
entity: {
|
208
|
+
id: tenant.id,
|
209
|
+
source: 'tenant',
|
210
|
+
},
|
211
|
+
children: []
|
212
|
+
},
|
213
|
+
};
|
214
|
+
await this.chartService.insertOne({ data: record.data, version: record.version });
|
215
|
+
}
|
216
|
+
async save() {
|
217
|
+
const first = (await this.chartService.query()).items[0];
|
218
|
+
await this.chartService.updateOne(first.id, { version: first.version, data: this._rootNode(), updateAt: new Date() });
|
219
|
+
}
|
220
|
+
//#endregion
|
221
|
+
//#region Context Menu
|
222
|
+
async getAllowedAddMenuItems(node) {
|
223
|
+
const allowedCategories = await this.getAllowedChildCategoriesForParent(node);
|
224
|
+
const allowedMenuItems = [];
|
225
|
+
// Group items by category for visual breaks.
|
226
|
+
const groupedMenuItems = {
|
227
|
+
Company: [],
|
228
|
+
Location: [],
|
229
|
+
BusinessUnit: [],
|
230
|
+
Role: [],
|
231
|
+
Employee: []
|
232
|
+
};
|
233
|
+
Object.entries(AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS).forEach(([entitySource, config]) => {
|
234
|
+
if (allowedCategories.includes(config.category)) {
|
235
|
+
groupedMenuItems[config.category].push({
|
236
|
+
name: 'add',
|
237
|
+
text: `${config.title}`,
|
238
|
+
icon: config.icon,
|
239
|
+
data: {
|
240
|
+
node,
|
241
|
+
config,
|
242
|
+
source: entitySource
|
243
|
+
},
|
244
|
+
});
|
245
|
+
}
|
246
|
+
});
|
247
|
+
Object.values(groupedMenuItems).forEach(group => {
|
248
|
+
if (group.length > 0) {
|
249
|
+
allowedMenuItems.push(...group);
|
250
|
+
group[group.length - 1].break = true;
|
251
|
+
}
|
252
|
+
});
|
253
|
+
if (allowedMenuItems.length > 0) {
|
254
|
+
allowedMenuItems[allowedMenuItems.length - 1].break = false;
|
255
|
+
}
|
256
|
+
return allowedMenuItems;
|
257
|
+
}
|
258
|
+
//#endregion
|
259
|
+
//#region Check Permission
|
260
|
+
async getAllowedChildCategoriesForParent(parent) {
|
261
|
+
await this.configService.load();
|
262
|
+
const types = this.configService.types; // e.g. ['Company', 'Location', 'BusinessUnit', 'Role', 'Employee']
|
263
|
+
const currentType = get(parent, 'category');
|
264
|
+
if (!parent || !currentType) {
|
265
|
+
return [];
|
266
|
+
}
|
267
|
+
const allowedCategories = new Set();
|
268
|
+
Object.entries(AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS).forEach(([entitySource, config]) => {
|
269
|
+
if (this.configService.isAllowed(currentType, config.category) && types.includes(config.category)) {
|
270
|
+
allowedCategories.add(config.category);
|
271
|
+
}
|
272
|
+
});
|
273
|
+
return Array.from(allowedCategories);
|
274
|
+
}
|
275
|
+
//#endregion
|
276
|
+
//#region Remove/Cut/Copy/Past
|
277
|
+
async removeNode(id) {
|
278
|
+
this._rootNode.update((node) => this.removeNodeRecursively(node, id));
|
279
|
+
await this.save();
|
280
|
+
}
|
281
|
+
removeNodeRecursively(node, id) {
|
282
|
+
// If the node itself is the one to be deleted, return null
|
283
|
+
if (node.id === id) {
|
284
|
+
return null;
|
285
|
+
}
|
286
|
+
// Otherwise, recursively check children
|
287
|
+
if (node.children) {
|
288
|
+
node.children = node.children.filter(child => child.id !== id)
|
289
|
+
.map(child => {
|
290
|
+
return { ...child, children: this.removeNodeRecursively(child, id)?.children };
|
291
|
+
});
|
292
|
+
}
|
293
|
+
return node;
|
294
|
+
}
|
295
|
+
isPasteAvailable() {
|
296
|
+
return this.clipboard() != null && this.clipboard()?.node != null;
|
297
|
+
}
|
298
|
+
async allowPaste(target) {
|
299
|
+
if (!this.isPasteAvailable()) {
|
300
|
+
return false;
|
301
|
+
}
|
302
|
+
const allowedCategories = await this.getAllowedChildCategoriesForParent(target);
|
303
|
+
// Compare using the clipboard node's category.
|
304
|
+
return allowedCategories.includes(get(this.clipboard()?.node, 'category'));
|
305
|
+
}
|
306
|
+
/**
|
307
|
+
* Cuts the node with the given id.
|
308
|
+
* The node is removed from the tree and stored in the clipboard.
|
309
|
+
* Cutting the root node is not allowed.
|
310
|
+
*/
|
311
|
+
async cutNode(id) {
|
312
|
+
const tree = this._rootNode();
|
313
|
+
if (tree.id === id) {
|
314
|
+
throw new Error("Cannot cut the root node.");
|
315
|
+
}
|
316
|
+
const result = this.findNodeAndParent(tree, id);
|
317
|
+
if (!result) {
|
318
|
+
throw new Error("Node not found.");
|
319
|
+
}
|
320
|
+
// Set the clipboard signal with mode 'cut'
|
321
|
+
this.clipboard.set({ mode: 'cut', node: result.node });
|
322
|
+
// Remove the node from the tree.
|
323
|
+
const newTree = this.removeNodeRecursively(tree, id);
|
324
|
+
this._rootNode.set(newTree);
|
325
|
+
await this.save();
|
326
|
+
}
|
327
|
+
/**
|
328
|
+
* Copies the node with the given id.
|
329
|
+
* A deep clone of the node is stored in the clipboard.
|
330
|
+
*/
|
331
|
+
copyNode(id) {
|
332
|
+
const tree = this._rootNode();
|
333
|
+
const result = this.findNodeAndParent(tree, id);
|
334
|
+
if (!result) {
|
335
|
+
throw new Error("Node not found.");
|
336
|
+
}
|
337
|
+
// Use lodash's cloneDeep to create a deep clone.
|
338
|
+
const copiedNode = cloneDeep(result.node);
|
339
|
+
this.clipboard.set({ mode: 'copy', node: copiedNode });
|
340
|
+
}
|
341
|
+
/**
|
342
|
+
* Pastes the node in the clipboard as a child of the node with the given parentId.
|
343
|
+
* For a cut, the node is moved; for a copy, new IDs are generated so the pasted node is unique.
|
344
|
+
*/
|
345
|
+
async pasteNode(parentId) {
|
346
|
+
const clipboardValue = this.clipboard();
|
347
|
+
if (!clipboardValue) {
|
348
|
+
throw new Error("Clipboard is empty.");
|
349
|
+
}
|
350
|
+
const tree = this._rootNode();
|
351
|
+
const parentResult = this.findNodeAndParent(tree, parentId);
|
352
|
+
if (!parentResult) {
|
353
|
+
throw new Error("Parent node not found.");
|
354
|
+
}
|
355
|
+
let nodeToPaste;
|
356
|
+
if (clipboardValue.mode === 'cut') {
|
357
|
+
nodeToPaste = clipboardValue.node;
|
358
|
+
// Clear the clipboard after pasting.
|
359
|
+
this.clipboard.set(null);
|
360
|
+
}
|
361
|
+
else {
|
362
|
+
nodeToPaste = this.cloneNodeWithNewIds(clipboardValue.node);
|
363
|
+
}
|
364
|
+
const newTree = this.insertNodeRecursively(tree, parentId, nodeToPaste);
|
365
|
+
this._rootNode.set(newTree);
|
366
|
+
await this.save();
|
367
|
+
}
|
368
|
+
/**
|
369
|
+
* Recursively searches the tree for the node with the given id,
|
370
|
+
* returning both the node and its parent.
|
371
|
+
*/
|
372
|
+
findNodeAndParent(node, id, parent = null) {
|
373
|
+
if (node.id === id) {
|
374
|
+
return { node, parent };
|
375
|
+
}
|
376
|
+
if (node.children) {
|
377
|
+
for (const child of node.children) {
|
378
|
+
const result = this.findNodeAndParent(child, id, node);
|
379
|
+
if (result) {
|
380
|
+
return result;
|
381
|
+
}
|
382
|
+
}
|
383
|
+
}
|
384
|
+
return null;
|
385
|
+
}
|
386
|
+
/**
|
387
|
+
* Clones a node recursively and generates new IDs for the node and its children.
|
388
|
+
*/
|
389
|
+
cloneNodeWithNewIds(node) {
|
390
|
+
// First, clone the node using lodash.
|
391
|
+
const newNode = cloneDeep(node);
|
392
|
+
// Then, assign new IDs recursively.
|
393
|
+
this.assignNewIds(newNode);
|
394
|
+
return newNode;
|
395
|
+
}
|
396
|
+
/**
|
397
|
+
* Recursively assigns new unique IDs to the given node and its children.
|
398
|
+
*/
|
399
|
+
assignNewIds(node) {
|
400
|
+
node.id = AXPDataGenerator.uuid();
|
401
|
+
if (node.children) {
|
402
|
+
node.children.forEach(child => this.assignNewIds(child));
|
403
|
+
}
|
404
|
+
}
|
405
|
+
/**
|
406
|
+
* Recursively traverses the tree to insert newNode as a child of the node with parentId.
|
407
|
+
*/
|
408
|
+
insertNodeRecursively(node, parentId, newNode) {
|
409
|
+
if (node.id === parentId) {
|
410
|
+
const newChildren = node.children ? [...node.children, newNode] : [newNode];
|
411
|
+
return { ...node, children: newChildren };
|
412
|
+
}
|
413
|
+
if (node.children) {
|
414
|
+
return {
|
415
|
+
...node,
|
416
|
+
children: node.children.map(child => this.insertNodeRecursively(child, parentId, newNode))
|
417
|
+
};
|
418
|
+
}
|
419
|
+
return node;
|
420
|
+
}
|
421
|
+
//#endregion
|
422
|
+
//#region Add Node
|
423
|
+
async addNode(data) {
|
424
|
+
console.log(data);
|
425
|
+
this.layoutService.setNavigationLoading(true);
|
426
|
+
const comp = (await import('./acorex-modules-organization-management-add-item.component-D0tN7Se4.mjs')).AddItemComponent;
|
427
|
+
const node = get(data, 'node');
|
428
|
+
const type = get(data, 'config.type');
|
429
|
+
const source = get(data, 'source');
|
430
|
+
let query;
|
431
|
+
switch (type) {
|
432
|
+
case AXMOrganizationNodeType.Department:
|
433
|
+
query = this.departmentService.query.bind(this.departmentService);
|
434
|
+
break;
|
435
|
+
case AXMOrganizationNodeType.Division:
|
436
|
+
query = this.divisionService.query.bind(this.divisionService);
|
437
|
+
break;
|
438
|
+
case AXMOrganizationNodeType.Branch:
|
439
|
+
query = this.branchService.query.bind(this.branchService);
|
440
|
+
break;
|
441
|
+
case AXMOrganizationNodeType.Position:
|
442
|
+
query = this.positionService.query.bind(this.positionService);
|
443
|
+
break;
|
444
|
+
case AXMOrganizationNodeType.Employee:
|
445
|
+
query = this.employmentService.query.bind(this.employmentService);
|
446
|
+
break;
|
447
|
+
default:
|
448
|
+
break;
|
449
|
+
}
|
450
|
+
const result = await this.popupService.open(comp, {
|
451
|
+
title: `Add ${get(data, 'config.title')}`,
|
452
|
+
size: 'md',
|
453
|
+
data: {
|
454
|
+
config: {
|
455
|
+
valueField: 'id',
|
456
|
+
textField: 'title',
|
457
|
+
query: query
|
458
|
+
}
|
459
|
+
}
|
460
|
+
});
|
461
|
+
const newNode = {
|
462
|
+
id: AXPDataGenerator.uuid(),
|
463
|
+
title: result.data.title,
|
464
|
+
description: result.data.description,
|
465
|
+
subtitle: result.data.subtitle,
|
466
|
+
type: type,
|
467
|
+
parentId: node.id,
|
468
|
+
entity: {
|
469
|
+
id: result.data.id,
|
470
|
+
source: source
|
471
|
+
}
|
472
|
+
};
|
473
|
+
const tree = this._rootNode();
|
474
|
+
const newTree = this.insertNodeRecursively(tree, node.id, newNode);
|
475
|
+
this._rootNode.set(newTree);
|
476
|
+
await this.save();
|
477
|
+
this.layoutService.setNavigationLoading(false);
|
478
|
+
return result.data != null;
|
479
|
+
}
|
480
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
481
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartService }); }
|
482
|
+
}
|
483
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartService, decorators: [{
|
484
|
+
type: Injectable
|
485
|
+
}] });
|
486
|
+
|
487
|
+
/**
|
488
|
+
* Component for displaying and interacting with an organizational chart.
|
489
|
+
*/
|
490
|
+
class AXMOrgChartPage {
|
491
|
+
constructor() {
|
492
|
+
this.layout = inject(AXPLayoutThemeService);
|
493
|
+
this.rootConfig = RootConfig;
|
494
|
+
this.nodeTemplate = viewChild.required('nodeTemplate');
|
495
|
+
this.treeContainer = viewChild.required('chart');
|
496
|
+
this.parent = viewChild.required('parent');
|
497
|
+
this.contextMenu = viewChild(AXContextMenuComponent);
|
498
|
+
this.panView = viewChild(AXPanViewDirective);
|
499
|
+
this.ngzone = inject(NgZone);
|
500
|
+
this.viewContainerRef = inject(ViewContainerRef);
|
501
|
+
this.chartPrintService = inject(AXMOrgChartPrintService);
|
502
|
+
this.chartService = inject(AXMOrgChartService);
|
503
|
+
this.NODE_STROKE_COLOR = 'rgba(var(--ax-sys-color-primary-400))';
|
504
|
+
this.LINK_STROKE_WIDTH = 1;
|
505
|
+
this.NodeTypes = AXMOrganizationNodeTypeCategory;
|
506
|
+
this.isFullscreen = signal(false);
|
507
|
+
this.panX = signal(0);
|
508
|
+
this.panY = signal(0);
|
509
|
+
this.panZoomLevel = signal(100);
|
510
|
+
this.isChartRendered = false;
|
511
|
+
this.nodeTypes = Object.entries(AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS).map(c => ({
|
512
|
+
title: c[1].title,
|
513
|
+
color: c[1].color,
|
514
|
+
icon: c[1].icon,
|
515
|
+
category: c[1].category
|
516
|
+
}));
|
517
|
+
this.#initialize = afterNextRender(async () => {
|
518
|
+
this.d3 = await import('d3');
|
519
|
+
await this.chartService.load();
|
520
|
+
await this.refreshChart();
|
521
|
+
});
|
522
|
+
}
|
523
|
+
#initialize;
|
524
|
+
/**
|
525
|
+
* Zooms in the chart.
|
526
|
+
*/
|
527
|
+
zoomIn() {
|
528
|
+
this.panZoomLevel.update((prev) => prev + 5);
|
529
|
+
}
|
530
|
+
/**
|
531
|
+
* Zooms out the chart.
|
532
|
+
*/
|
533
|
+
zoomOut() {
|
534
|
+
this.panZoomLevel.update((prev) => prev - 5);
|
535
|
+
}
|
536
|
+
/**
|
537
|
+
* Resets the zoom level and pan position of the chart.
|
538
|
+
*/
|
539
|
+
zoomReset() {
|
540
|
+
this.panView()?.resetPosition();
|
541
|
+
}
|
542
|
+
/**
|
543
|
+
* Toggles fullscreen mode for the chart.
|
544
|
+
*/
|
545
|
+
toggleFullscreen() {
|
546
|
+
if (this.isFullscreen()) {
|
547
|
+
document.exitFullscreen();
|
548
|
+
this.isFullscreen.set(false);
|
549
|
+
}
|
550
|
+
else {
|
551
|
+
this.parent().nativeElement.requestFullscreen();
|
552
|
+
this.isFullscreen.set(true);
|
553
|
+
}
|
554
|
+
document.querySelector(`foreignObject[node="node-${this.chartService.rootNode().id}"]`)?.scrollIntoView({
|
555
|
+
behavior: 'smooth',
|
556
|
+
block: 'start',
|
557
|
+
inline: 'center',
|
558
|
+
});
|
559
|
+
}
|
560
|
+
/**
|
561
|
+
* Calculates the maximum depth of the organizational chart.
|
562
|
+
* @param node - The root node of the chart.
|
563
|
+
* @returns The maximum depth of the chart.
|
564
|
+
*/
|
565
|
+
calculateMaxDepth(node) {
|
566
|
+
if (!node.children || node.children.length === 0 || node.isExpanded === false) {
|
567
|
+
return 1;
|
568
|
+
}
|
569
|
+
return 1 + Math.max(...node.children.map((child) => this.calculateMaxDepth(child)));
|
570
|
+
}
|
571
|
+
/**
|
572
|
+
* Calculates the maximum breadth of the organizational chart.
|
573
|
+
* @param node - The root node of the chart.
|
574
|
+
* @returns The maximum breadth of the chart.
|
575
|
+
*/
|
576
|
+
calculateMaxBreadth(node) {
|
577
|
+
if (!node.children || node.children.length === 0 || node.isExpanded === false) {
|
578
|
+
return 1;
|
579
|
+
}
|
580
|
+
return node.children.reduce((acc, child) => acc + this.calculateMaxBreadth(child), 0);
|
581
|
+
}
|
582
|
+
/**
|
583
|
+
* Creates and renders the organizational chart.
|
584
|
+
* @param el - The container element for the chart.
|
585
|
+
* @param data - The root node of the organizational chart.
|
586
|
+
*/
|
587
|
+
createChart(el, data) {
|
588
|
+
if (!this.d3) {
|
589
|
+
return;
|
590
|
+
}
|
591
|
+
this.ngzone.runOutsideAngular(() => {
|
592
|
+
const NODE_WIDTH_BASE = 260;
|
593
|
+
const NODE_HEIGHT_BASE = 180;
|
594
|
+
const HORIZONTAL_SPACING = 20;
|
595
|
+
const VERTICAL_SPACING = 40;
|
596
|
+
this.clearChart(el);
|
597
|
+
const newSvg = this.d3.select(el).append('svg');
|
598
|
+
const root = this.d3.hierarchy(data);
|
599
|
+
root.descendants().forEach((node) => {
|
600
|
+
if (node.data.isExpanded === false) {
|
601
|
+
node.children = undefined;
|
602
|
+
}
|
603
|
+
});
|
604
|
+
const treeLayout = this.d3
|
605
|
+
.tree()
|
606
|
+
.nodeSize([NODE_WIDTH_BASE + HORIZONTAL_SPACING, NODE_HEIGHT_BASE + VERTICAL_SPACING]);
|
607
|
+
treeLayout(root);
|
608
|
+
let minX = Infinity, maxX = -Infinity, minY = Infinity, maxY = -Infinity;
|
609
|
+
root.descendants().forEach((d) => {
|
610
|
+
if (d.x < minX)
|
611
|
+
minX = d.x;
|
612
|
+
if (d.x > maxX)
|
613
|
+
maxX = d.x;
|
614
|
+
if (d.y < minY)
|
615
|
+
minY = d.y;
|
616
|
+
if (d.y > maxY)
|
617
|
+
maxY = d.y;
|
618
|
+
});
|
619
|
+
const CONTAINER_WIDTH = maxX - minX + NODE_WIDTH_BASE + 2 * HORIZONTAL_SPACING;
|
620
|
+
const CONTAINER_HEIGHT = maxY - minY + NODE_HEIGHT_BASE + 2 * VERTICAL_SPACING;
|
621
|
+
newSvg.attr('width', CONTAINER_WIDTH).attr('height', CONTAINER_HEIGHT);
|
622
|
+
const g = newSvg
|
623
|
+
.append('g')
|
624
|
+
.attr('transform', `translate(${-minX + NODE_WIDTH_BASE / 2 + HORIZONTAL_SPACING / 2}, ${-minY + NODE_HEIGHT_BASE / 2 + VERTICAL_SPACING / 2})`);
|
625
|
+
const link = g
|
626
|
+
.selectAll('.link')
|
627
|
+
.data(root.links())
|
628
|
+
.enter()
|
629
|
+
.append('path')
|
630
|
+
.attr('class', 'link')
|
631
|
+
.attr('d', (d) => {
|
632
|
+
const source = d.source;
|
633
|
+
const target = d.target;
|
634
|
+
return `M${source.x},${source.y}V${(source.y + target.y) / 2}H${target.x}V${target.y - 10}`;
|
635
|
+
})
|
636
|
+
.attr('fill', 'none')
|
637
|
+
.attr('stroke', this.NODE_STROKE_COLOR)
|
638
|
+
.attr('stroke-width', this.LINK_STROKE_WIDTH)
|
639
|
+
.attr('from', (d) => `node-${d.source.data.id}`)
|
640
|
+
.attr('to', (d) => `node-${d.target.data.id}`);
|
641
|
+
const node = g
|
642
|
+
.selectAll('.axp-chart-node')
|
643
|
+
.data(root.descendants())
|
644
|
+
.enter()
|
645
|
+
.append('foreignObject')
|
646
|
+
.attr('class', 'axp-chart-node')
|
647
|
+
.attr('node', (d) => `node-${d.data.id}`)
|
648
|
+
.attr('x', (d) => d.x - NODE_WIDTH_BASE / 2)
|
649
|
+
.attr('y', (d) => d.y - NODE_HEIGHT_BASE / 2 + 10)
|
650
|
+
.attr('width', NODE_WIDTH_BASE)
|
651
|
+
.attr('height', NODE_HEIGHT_BASE)
|
652
|
+
.each((d) => this.renderNodeTemplate(d.data, d.x, d.y));
|
653
|
+
this.contextMenu()?.refresh();
|
654
|
+
});
|
655
|
+
if (!this.isChartRendered) {
|
656
|
+
// document.querySelector(`foreignObject[node="node-${data.id}"] .--heading-container`)?.scrollIntoView({
|
657
|
+
// behavior: 'smooth',
|
658
|
+
// block: 'center',
|
659
|
+
// inline: 'center',
|
660
|
+
// });
|
661
|
+
this.isChartRendered = true;
|
662
|
+
this.panView()?.resetPosition();
|
663
|
+
}
|
664
|
+
}
|
665
|
+
/**
|
666
|
+
* Renders the node template for a given organizational node.
|
667
|
+
* @param data - The node data.
|
668
|
+
* @param x - The x-coordinate of the node.
|
669
|
+
* @param y - The y-coordinate of the node.
|
670
|
+
*/
|
671
|
+
renderNodeTemplate(data, x, y) {
|
672
|
+
// Find the key that matches the node type
|
673
|
+
const entityKey = Object.keys(AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS).find(key => {
|
674
|
+
const keyName = key.split('.').pop(); // Get the last part after splitting by '.'
|
675
|
+
return keyName === data.type; // Compare with data.type
|
676
|
+
});
|
677
|
+
if (entityKey) {
|
678
|
+
const categoryMapping = AXM_ORG_CHART_NODE_TYPE_ENTITY_MAPPINGS[entityKey];
|
679
|
+
// Add the category to the data object
|
680
|
+
set(data, 'category', categoryMapping.category);
|
681
|
+
}
|
682
|
+
const viewRef = this.viewContainerRef.createEmbeddedView(this.nodeTemplate(), {
|
683
|
+
$implicit: data,
|
684
|
+
});
|
685
|
+
const nodeElement = this.d3.select(this.treeContainer().nativeElement).select(`[node="node-${data.id}"]`);
|
686
|
+
const element = nodeElement.node();
|
687
|
+
if (element) {
|
688
|
+
element.appendChild(viewRef.rootNodes[0]);
|
689
|
+
}
|
690
|
+
}
|
691
|
+
/**
|
692
|
+
* Toggles the expansion state of a node.
|
693
|
+
* @param data - The node data.
|
694
|
+
* @param el - The HTML element representing the node.
|
695
|
+
*/
|
696
|
+
toggleNode(data, el) {
|
697
|
+
data.isExpanded = data.isExpanded === undefined ? false : !data.isExpanded;
|
698
|
+
this.createChart(this.treeContainer().nativeElement, this.chartService.rootNode());
|
699
|
+
// el.scrollIntoView({
|
700
|
+
// behavior: 'smooth',
|
701
|
+
// });
|
702
|
+
}
|
703
|
+
/**
|
704
|
+
* Clears the chart from the container element.
|
705
|
+
* @param el - The container element.
|
706
|
+
*/
|
707
|
+
clearChart(el) {
|
708
|
+
if (this.d3) {
|
709
|
+
this.d3.select(el).select('svg').remove();
|
710
|
+
this.viewContainerRef.clear();
|
711
|
+
}
|
712
|
+
}
|
713
|
+
async refreshChart() {
|
714
|
+
if (this.d3) {
|
715
|
+
this.createChart(this.treeContainer().nativeElement, this.chartService.rootNode());
|
716
|
+
}
|
717
|
+
}
|
718
|
+
//#region Context Menu
|
719
|
+
async handleContextMenuOnOpening(e) {
|
720
|
+
const node = get(e.targetElement, '__data__.data');
|
721
|
+
const allowedAddItems = await this.chartService.getAllowedAddMenuItems(node);
|
722
|
+
const allowDelete = node.type != AXMOrganizationNodeType.Company;
|
723
|
+
const isPasteAvailable = await this.chartService.isPasteAvailable();
|
724
|
+
const allowPaste = await this.chartService.allowPaste(node);
|
725
|
+
//
|
726
|
+
if (allowedAddItems.length) {
|
727
|
+
e.items.push({
|
728
|
+
text: 'Add New',
|
729
|
+
icon: 'fa-light fa-plus',
|
730
|
+
items: allowedAddItems,
|
731
|
+
break: allowDelete,
|
732
|
+
});
|
733
|
+
}
|
734
|
+
//
|
735
|
+
if (allowDelete) {
|
736
|
+
e.items.push({
|
737
|
+
name: 'cut',
|
738
|
+
text: 'Cut',
|
739
|
+
icon: 'fa-light fa-cut',
|
740
|
+
data: node
|
741
|
+
});
|
742
|
+
e.items.push({
|
743
|
+
name: 'copy',
|
744
|
+
text: 'Copy',
|
745
|
+
icon: 'fa-light fa-copy',
|
746
|
+
data: node,
|
747
|
+
break: !isPasteAvailable
|
748
|
+
});
|
749
|
+
}
|
750
|
+
if (isPasteAvailable) {
|
751
|
+
e.items.push({
|
752
|
+
name: 'paste',
|
753
|
+
text: 'Paste',
|
754
|
+
icon: 'fa-light fa-paste',
|
755
|
+
data: node,
|
756
|
+
break: true,
|
757
|
+
disabled: !allowPaste
|
758
|
+
});
|
759
|
+
}
|
760
|
+
//
|
761
|
+
if (allowDelete) {
|
762
|
+
e.items.push({
|
763
|
+
name: 'remove',
|
764
|
+
text: 'Remove',
|
765
|
+
color: 'danger',
|
766
|
+
icon: 'fa-light fa-trash-can',
|
767
|
+
data: node,
|
768
|
+
});
|
769
|
+
}
|
770
|
+
//
|
771
|
+
if (e.items.length == 0) {
|
772
|
+
e.canceled = true;
|
773
|
+
}
|
774
|
+
}
|
775
|
+
async handleContextMenuItemClick(e) {
|
776
|
+
//
|
777
|
+
if (e.item.name == 'add') {
|
778
|
+
if (await this.chartService.addNode(e.item.data)) {
|
779
|
+
await this.refreshChart();
|
780
|
+
}
|
781
|
+
}
|
782
|
+
//
|
783
|
+
else if (e.item.name == 'remove') {
|
784
|
+
await this.chartService.removeNode(e.item.data.id);
|
785
|
+
await this.refreshChart();
|
786
|
+
}
|
787
|
+
//
|
788
|
+
else if (e.item.name == 'copy') {
|
789
|
+
await this.chartService.copyNode(e.item.data.id);
|
790
|
+
}
|
791
|
+
else if (e.item.name == 'cut') {
|
792
|
+
await this.chartService.cutNode(e.item.data.id);
|
793
|
+
await this.refreshChart();
|
794
|
+
}
|
795
|
+
else if (e.item.name == 'paste') {
|
796
|
+
await this.chartService.pasteNode(e.item.data.id);
|
797
|
+
await this.refreshChart();
|
798
|
+
}
|
799
|
+
}
|
800
|
+
//#endregion
|
801
|
+
/**
|
802
|
+
* Prints the organizational chart.
|
803
|
+
*/
|
804
|
+
async printChart() {
|
805
|
+
let [panX, panY, panZoomLevel] = [this.panX(), this.panY(), this.panZoomLevel()];
|
806
|
+
this.panX.set(0), this.panY.set(0), this.panZoomLevel.set(100);
|
807
|
+
await this.chartPrintService.printChart(this.treeContainer().nativeElement);
|
808
|
+
this.panX.set(panX), this.panY.set(panY), this.panZoomLevel.set(panZoomLevel);
|
809
|
+
}
|
810
|
+
/**
|
811
|
+
* Gets the node colors based on the provided color.
|
812
|
+
* @param color - The color to use for the node.
|
813
|
+
* @returns An object containing the node's background, text, and border colors.
|
814
|
+
*/
|
815
|
+
getNodeColors(color) {
|
816
|
+
if (color.includes('surface')) {
|
817
|
+
return {
|
818
|
+
'--node-bg-color': `var(--ax-sys-color-${color})`,
|
819
|
+
'--node-text-color': `var(--ax-sys-color-on-${color})`,
|
820
|
+
'--node-border-color': `var(--ax-sys-color-border-${color})`,
|
821
|
+
};
|
822
|
+
}
|
823
|
+
return {
|
824
|
+
'--node-bg-color': `var(--ax-sys-color-${color}-surface)`,
|
825
|
+
'--node-text-color': `var(--ax-sys-color-on-${color}-surface)`,
|
826
|
+
'--node-border-color': `var(--ax-sys-color-border-${color}-surface)`,
|
827
|
+
};
|
828
|
+
}
|
829
|
+
updateVar(oldValue, newValue) {
|
830
|
+
oldValue.cat = newValue;
|
831
|
+
}
|
832
|
+
ngOnDestroy() {
|
833
|
+
this.clearChart(this.treeContainer().nativeElement);
|
834
|
+
}
|
835
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartPage, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
|
836
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXMOrgChartPage, isStandalone: true, selector: "ng-component", providers: [AXMOrgChartConfigService, AXMOrgChartService, AXMOrgChartPrintService], viewQueries: [{ propertyName: "nodeTemplate", first: true, predicate: ["nodeTemplate"], descendants: true, isSignal: true }, { propertyName: "treeContainer", first: true, predicate: ["chart"], descendants: true, isSignal: true }, { propertyName: "parent", first: true, predicate: ["parent"], descendants: true, isSignal: true }, { propertyName: "contextMenu", first: true, predicate: AXContextMenuComponent, descendants: true, isSignal: true }, { propertyName: "panView", first: true, predicate: AXPanViewDirective, descendants: true, isSignal: true }], ngImport: i0, template: "<axp-layout-simple-page *translate=\"let t\">\n <axp-layout-header>\n <axp-layout-title> {{t(rootConfig.entities.chart.title) | async}} </axp-layout-title>\n\n <axp-layout-description> Clear and dynamic view of your organization's structure </axp-layout-description>\n\n <axp-layout-actions>\n <axp-layout-actions-primary> </axp-layout-actions-primary>\n\n <axp-layout-actions-secondary>\n <ax-button-item [text]=\"(t('print') | async)!\" (onClick)=\"printChart()\">\n <ax-prefix>\n <ax-icon [icon]=\"'fa-solid fa-print'\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </axp-layout-actions-secondary>\n </axp-layout-actions>\n\n <axp-layout-breadcrumbs>\n <ax-breadcrumbs [class.ax-hidden]=\"layout.isSmall()\">\n <ng-template #divider>\n <i class=\"fa-regular fa-slash-forward\"></i>\n </ng-template>\n <ax-breadcrumbs-item> {{(t('home') | async)}} </ax-breadcrumbs-item>\n <ax-breadcrumbs-item> Organization </ax-breadcrumbs-item>\n </ax-breadcrumbs>\n </axp-layout-breadcrumbs>\n </axp-layout-header>\n\n <axp-layout-content class=\"ax-overflow-hidden\">\n <div class=\"ax-h-[calc(100vh-290px)]\" #parent id=\"parent\">\n <div #chart axPanView [(panX)]=\"panX\" [(panY)]=\"panY\" [(zoom)]=\"panZoomLevel\" [fitContent]=\"true\"\n wrapperClasses=\"h\" class=\"ax-light\"></div>\n <ax-context-menu [target]=\"'.axp-chart-node'\" [orientation]=\"'vertical'\" [closeOn]=\"'leave'\"\n (onItemClick)=\"handleContextMenuItemClick($event)\" (onOpening)=\"handleContextMenuOnOpening($event)\">\n </ax-context-menu>\n </div>\n </axp-layout-content>\n <axp-layout-footer>\n <axp-layout-prefix>\n <div class=\"ax-flex ax-gap-1 ax-light ax-flex-wrap ax-justify-center\">\n @let v = {cat:'Company'};\n @for (item of nodeTypes; track $index) {\n <div class=\"axp-node-hint\" [style]=\"getNodeColors(item.color)\" [class.ax-ms-4]=\"v.cat!=item.category\">\n <div class=\"--badge\">\n </div>\n {{item.title}}\n </div>\n {{updateVar(v,item.category)}}\n }\n </div>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <div class=\"ax-flex ax-gap-2 \">\n <ax-button (onClick)=\"zoomOut()\">\n <ax-icon class=\"fa-solid fa-minus\"> </ax-icon>\n </ax-button>\n <ax-button [text]=\"panZoomLevel()\" (onClick)=\"zoomReset()\"></ax-button>\n <ax-button (onClick)=\"zoomIn()\">\n <ax-icon class=\"fa-solid fa-add\"> </ax-icon>\n </ax-button>\n <ax-button (onClick)=\"toggleFullscreen()\">\n <ax-icon>\n <i class=\"fa-solid\" [class]=\"isFullscreen()? 'fa-compress' : 'fa-expand'\"></i>\n </ax-icon>\n </ax-button>\n </div>\n </axp-layout-suffix>\n </axp-layout-footer>\n</axp-layout-simple-page>\n\n<ng-template #nodeTemplate let-data>\n <div>\n @switch (data.category) {\n <!-- Company -->\n @case (NodeTypes.Company) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'primary' }\"></ng-container>\n }\n <!-- Location -->\n @case (NodeTypes.Location) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent1' }\"></ng-container>\n }\n <!-- BusinessUnit -->\n @case (NodeTypes.BusinessUnit) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent2' }\"></ng-container>\n }\n <!-- Role -->\n @case (NodeTypes.Role) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent3' }\"></ng-container>\n }\n <!-- Employee -->\n @case (NodeTypes.Employee) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'surface' }\"></ng-container>\n }\n }\n </div>\n</ng-template>\n\n<!----------------------------------- General Node Template ----------------------------------->\n<ng-template #generalTemplate let-data=\"data\" let-color=\"color\">\n <div #node class=\"--node-container\" [style]=\"getNodeColors(color)\">\n <div class=\"--container\">\n <div class=\"--heading-container\">\n <div class=\"--content\">\n <div class=\"--icon\">\n <i class=\"fa-light fa-xl fa-fw\" [class]=\"data.icon\"></i>\n </div>\n <div class=\"--titles\">\n <span class=\"--title\">{{data.title}}</span>\n <span class=\"--sub-title\">{{data.subtitle}}</span>\n </div>\n @if(data?.children?.length){\n <div class=\"--badge\">\n <span>{{data?.children?.length ?? 0}}</span>\n </div>\n }\n </div>\n </div>\n <div class=\"--body-container\">\n <div class=\"--description\" [class.ax-pb-3]=\"data.children && data.children.length > 0\">\n {{data.description}}\n </div>\n </div>\n @if(data.children && data.children.length > 0){\n <div class=\"--toggle\">\n <ax-button class=\"ax-xs ax-rounded-sm\" (onClick)=\"toggleNode(data,node)\">\n <ax-icon icon=\"fa-solid\" [class]=\"data.isExpanded === false ? 'fa-chevron-down' : 'fa-chevron-up'\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</ng-template>", styles: [".axp-node-hint{display:flex;align-items:center;justify-content:center;gap:.25rem;font-size:.75rem;line-height:1rem}.axp-node-hint>div.--badge{background-color:rgba(var(--node-bg-color));color:rgba(var(--node-text-color));display:flex;width:.75rem;height:.75rem;align-items:center;justify-content:center;border-radius:.125rem}.axp-chart-node{display:flex;align-items:center;justify-content:center}.axp-chart-node .--node-container{position:relative;cursor:pointer;--node-bg-color: var(--ax-sys-color-primary-surface);--node-text-color: var(--ax-sys-color-on-primary-surface);--node-border-color: var(--ax-sys-color-border-primary-surface)}.axp-chart-node .--node-container .--container{display:flex;max-height:100%;width:100%;flex-direction:column;overflow:hidden;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);border-color:rgba(var(--node-border-color))}.axp-chart-node .--node-container .--container .--heading-container{background-color:rgba(var(--node-bg-color));color:rgba(var(--node-text-color));width:100%;padding:.5rem .75rem}.axp-chart-node .--node-container .--container .--heading-container .--content{display:flex;width:100%;align-items:center;justify-content:center;gap:.5rem;overflow:hidden}.axp-chart-node .--node-container .--container .--heading-container .--content .--icon{background-color:color-mix(in srgb,rgba(var(--node-bg-color),1) 85%,black);display:flex;width:2.75rem;height:2.75rem;flex:none;align-items:center;justify-content:center;border-radius:.5rem}.axp-chart-node .--node-container .--container .--heading-container .--content .--badge{background-color:color-mix(in srgb,rgba(var(--node-bg-color),1) 85%,black);display:flex;width:1.5rem;height:1.5rem;flex:none;align-items:center;justify-content:center;border-radius:.375rem;line-height:1}.axp-chart-node .--node-container .--container .--heading-container .--content .--badge>span{font-size:.75rem;line-height:1rem}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles{display:flex;width:100%;flex:1 1 0%;flex-direction:column;gap:.25rem;overflow:hidden}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles .--title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.125rem;line-height:1.75rem;font-weight:600;line-height:1}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles .--sub-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.75rem;line-height:1rem;opacity:.85}.axp-chart-node .--node-container .--container .--body-container{width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:.5rem .75rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.axp-chart-node .--node-container .--container .--body-container .--description{text-align:center;font-size:.875rem;line-height:1rem;opacity:.85}.axp-chart-node .--node-container .--container .--toggle{position:absolute;left:0;right:0;bottom:-.75rem;display:flex;width:100%;-webkit-user-select:none;-moz-user-select:-moz-none;user-select:none;align-items:center;justify-content:center}#parent:fullscreen{background-color:rgba(var(--axp-brand-color))}\n"], dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "pipe", type: i1.AsyncPipe, name: "async" }, { kind: "ngmodule", type: RouterModule }, { kind: "component", type: AXPSimplePageLayout, selector: "axp-layout-simple-page" }, { kind: "component", type: AXPThemeLayoutBlockComponent, selector: " axp-layout-content, axp-layout-header-container, axp-layout-side-container, axp-layout-sections, axp-layout-section-container, axp-layout-body, axp-layout-prefix, axp-layout-suffix, axp-layout-title, axp-layout-nav-button, axp-layout-description, axp-layout-toolbar, axp-layout-title-bar, axp-layout-breadcrumbs, axp-layout-list-action, " }, { kind: "component", type: AXPThemeLayoutHeaderTemplateComponent, selector: "axp-layout-header" }, { kind: "component", type: AXPThemeLayoutActionsComponent, selector: "axp-layout-actions" }, { kind: "component", type: AXPThemeLayoutPageSecondaryActionsComponent, selector: "axp-layout-actions-secondary" }, { kind: "component", type: AXPThemeLayoutPagePrimaryActionsComponent, selector: "axp-layout-actions-primary" }, { kind: "component", type: AXPThemeLayoutFooterComponent, selector: "axp-layout-footer" }, { kind: "ngmodule", type: AXMenuModule }, { kind: "component", type: i2.AXContextMenuComponent, selector: "ax-context-menu", inputs: ["orientation", "openOn", "closeOn", "items", "target"], outputs: ["onItemClick", "onOpening"] }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i3.AXButtonComponent, selector: "ax-button", inputs: ["disabled", "size", "tabIndex", "color", "look", "text", "toggleable", "selected", "type", "loadingText"], outputs: ["onBlur", "onFocus", "onClick", "selectedChange", "toggleableChange", "lookChange", "colorChange", "disabledChange", "loadingTextChange"] }, { kind: "component", type: i3.AXButtonItemComponent, selector: "ax-button-item", inputs: ["color", "disabled", "text", "selected", "divided", "data", "name"], outputs: ["onClick", "onFocus", "onBlur", "disabledChange"] }, { kind: "ngmodule", type: AXDropdownButtonModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "directive", type: i4.AXTranslatorDirective, selector: "[translate]" }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i5.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i5.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: "directive", type: AXPanViewDirective, selector: "[axPanView]", inputs: ["zoomStep", "minZoom", "maxZoom", "fitContent", "disablePan", "disableZoom", "wrapperClasses", "panX", "panY", "zoom"], outputs: ["panXChange", "panYChange", "zoomChange", "positionChange"], exportAs: ["axPanView"] }, { kind: "ngmodule", type: AXLoadingModule }, { kind: "ngmodule", type: AXBreadcrumbsModule }, { kind: "component", type: i6.AXBreadCrumbsComponent, selector: "ax-breadcrumbs" }, { kind: "component", type: i6.AXBreadCrumbsItemComponent, selector: "ax-breadcrumbs-item", inputs: ["disabled", "active"] }, { kind: "ngmodule", type: AXBadgeModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush, encapsulation: i0.ViewEncapsulation.None }); }
|
837
|
+
}
|
838
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXMOrgChartPage, decorators: [{
|
839
|
+
type: Component,
|
840
|
+
args: [{ imports: [
|
841
|
+
CommonModule,
|
842
|
+
RouterModule,
|
843
|
+
AXPSimplePageLayout,
|
844
|
+
AXPThemeLayoutBlockComponent,
|
845
|
+
AXPThemeLayoutHeaderTemplateComponent,
|
846
|
+
AXPThemeLayoutActionsComponent,
|
847
|
+
AXPThemeLayoutPageSecondaryActionsComponent,
|
848
|
+
AXPThemeLayoutPagePrimaryActionsComponent,
|
849
|
+
AXPThemeLayoutFooterComponent,
|
850
|
+
AXMenuModule,
|
851
|
+
AXButtonModule,
|
852
|
+
AXDropdownButtonModule,
|
853
|
+
AXTranslationModule,
|
854
|
+
AXDecoratorModule,
|
855
|
+
AXPanViewDirective,
|
856
|
+
AXLoadingModule,
|
857
|
+
AXBreadcrumbsModule,
|
858
|
+
AXBadgeModule,
|
859
|
+
], changeDetection: ChangeDetectionStrategy.OnPush, encapsulation: ViewEncapsulation.None, providers: [AXMOrgChartConfigService, AXMOrgChartService, AXMOrgChartPrintService], template: "<axp-layout-simple-page *translate=\"let t\">\n <axp-layout-header>\n <axp-layout-title> {{t(rootConfig.entities.chart.title) | async}} </axp-layout-title>\n\n <axp-layout-description> Clear and dynamic view of your organization's structure </axp-layout-description>\n\n <axp-layout-actions>\n <axp-layout-actions-primary> </axp-layout-actions-primary>\n\n <axp-layout-actions-secondary>\n <ax-button-item [text]=\"(t('print') | async)!\" (onClick)=\"printChart()\">\n <ax-prefix>\n <ax-icon [icon]=\"'fa-solid fa-print'\"> </ax-icon>\n </ax-prefix>\n </ax-button-item>\n </axp-layout-actions-secondary>\n </axp-layout-actions>\n\n <axp-layout-breadcrumbs>\n <ax-breadcrumbs [class.ax-hidden]=\"layout.isSmall()\">\n <ng-template #divider>\n <i class=\"fa-regular fa-slash-forward\"></i>\n </ng-template>\n <ax-breadcrumbs-item> {{(t('home') | async)}} </ax-breadcrumbs-item>\n <ax-breadcrumbs-item> Organization </ax-breadcrumbs-item>\n </ax-breadcrumbs>\n </axp-layout-breadcrumbs>\n </axp-layout-header>\n\n <axp-layout-content class=\"ax-overflow-hidden\">\n <div class=\"ax-h-[calc(100vh-290px)]\" #parent id=\"parent\">\n <div #chart axPanView [(panX)]=\"panX\" [(panY)]=\"panY\" [(zoom)]=\"panZoomLevel\" [fitContent]=\"true\"\n wrapperClasses=\"h\" class=\"ax-light\"></div>\n <ax-context-menu [target]=\"'.axp-chart-node'\" [orientation]=\"'vertical'\" [closeOn]=\"'leave'\"\n (onItemClick)=\"handleContextMenuItemClick($event)\" (onOpening)=\"handleContextMenuOnOpening($event)\">\n </ax-context-menu>\n </div>\n </axp-layout-content>\n <axp-layout-footer>\n <axp-layout-prefix>\n <div class=\"ax-flex ax-gap-1 ax-light ax-flex-wrap ax-justify-center\">\n @let v = {cat:'Company'};\n @for (item of nodeTypes; track $index) {\n <div class=\"axp-node-hint\" [style]=\"getNodeColors(item.color)\" [class.ax-ms-4]=\"v.cat!=item.category\">\n <div class=\"--badge\">\n </div>\n {{item.title}}\n </div>\n {{updateVar(v,item.category)}}\n }\n </div>\n </axp-layout-prefix>\n <axp-layout-suffix>\n <div class=\"ax-flex ax-gap-2 \">\n <ax-button (onClick)=\"zoomOut()\">\n <ax-icon class=\"fa-solid fa-minus\"> </ax-icon>\n </ax-button>\n <ax-button [text]=\"panZoomLevel()\" (onClick)=\"zoomReset()\"></ax-button>\n <ax-button (onClick)=\"zoomIn()\">\n <ax-icon class=\"fa-solid fa-add\"> </ax-icon>\n </ax-button>\n <ax-button (onClick)=\"toggleFullscreen()\">\n <ax-icon>\n <i class=\"fa-solid\" [class]=\"isFullscreen()? 'fa-compress' : 'fa-expand'\"></i>\n </ax-icon>\n </ax-button>\n </div>\n </axp-layout-suffix>\n </axp-layout-footer>\n</axp-layout-simple-page>\n\n<ng-template #nodeTemplate let-data>\n <div>\n @switch (data.category) {\n <!-- Company -->\n @case (NodeTypes.Company) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'primary' }\"></ng-container>\n }\n <!-- Location -->\n @case (NodeTypes.Location) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent1' }\"></ng-container>\n }\n <!-- BusinessUnit -->\n @case (NodeTypes.BusinessUnit) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent2' }\"></ng-container>\n }\n <!-- Role -->\n @case (NodeTypes.Role) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'accent3' }\"></ng-container>\n }\n <!-- Employee -->\n @case (NodeTypes.Employee) {\n <ng-container *ngTemplateOutlet=\"generalTemplate; context: { data,color:'surface' }\"></ng-container>\n }\n }\n </div>\n</ng-template>\n\n<!----------------------------------- General Node Template ----------------------------------->\n<ng-template #generalTemplate let-data=\"data\" let-color=\"color\">\n <div #node class=\"--node-container\" [style]=\"getNodeColors(color)\">\n <div class=\"--container\">\n <div class=\"--heading-container\">\n <div class=\"--content\">\n <div class=\"--icon\">\n <i class=\"fa-light fa-xl fa-fw\" [class]=\"data.icon\"></i>\n </div>\n <div class=\"--titles\">\n <span class=\"--title\">{{data.title}}</span>\n <span class=\"--sub-title\">{{data.subtitle}}</span>\n </div>\n @if(data?.children?.length){\n <div class=\"--badge\">\n <span>{{data?.children?.length ?? 0}}</span>\n </div>\n }\n </div>\n </div>\n <div class=\"--body-container\">\n <div class=\"--description\" [class.ax-pb-3]=\"data.children && data.children.length > 0\">\n {{data.description}}\n </div>\n </div>\n @if(data.children && data.children.length > 0){\n <div class=\"--toggle\">\n <ax-button class=\"ax-xs ax-rounded-sm\" (onClick)=\"toggleNode(data,node)\">\n <ax-icon icon=\"fa-solid\" [class]=\"data.isExpanded === false ? 'fa-chevron-down' : 'fa-chevron-up'\"></ax-icon>\n </ax-button>\n </div>\n }\n </div>\n </div>\n</ng-template>", styles: [".axp-node-hint{display:flex;align-items:center;justify-content:center;gap:.25rem;font-size:.75rem;line-height:1rem}.axp-node-hint>div.--badge{background-color:rgba(var(--node-bg-color));color:rgba(var(--node-text-color));display:flex;width:.75rem;height:.75rem;align-items:center;justify-content:center;border-radius:.125rem}.axp-chart-node{display:flex;align-items:center;justify-content:center}.axp-chart-node .--node-container{position:relative;cursor:pointer;--node-bg-color: var(--ax-sys-color-primary-surface);--node-text-color: var(--ax-sys-color-on-primary-surface);--node-border-color: var(--ax-sys-color-border-primary-surface)}.axp-chart-node .--node-container .--container{display:flex;max-height:100%;width:100%;flex-direction:column;overflow:hidden;border-radius:.375rem;border-width:1px;--tw-shadow: 0 4px 6px -1px rgb(0 0 0 / .1), 0 2px 4px -2px rgb(0 0 0 / .1);--tw-shadow-colored: 0 4px 6px -1px var(--tw-shadow-color), 0 2px 4px -2px var(--tw-shadow-color);box-shadow:var(--tw-ring-offset-shadow, 0 0 #0000),var(--tw-ring-shadow, 0 0 #0000),var(--tw-shadow);border-color:rgba(var(--node-border-color))}.axp-chart-node .--node-container .--container .--heading-container{background-color:rgba(var(--node-bg-color));color:rgba(var(--node-text-color));width:100%;padding:.5rem .75rem}.axp-chart-node .--node-container .--container .--heading-container .--content{display:flex;width:100%;align-items:center;justify-content:center;gap:.5rem;overflow:hidden}.axp-chart-node .--node-container .--container .--heading-container .--content .--icon{background-color:color-mix(in srgb,rgba(var(--node-bg-color),1) 85%,black);display:flex;width:2.75rem;height:2.75rem;flex:none;align-items:center;justify-content:center;border-radius:.5rem}.axp-chart-node .--node-container .--container .--heading-container .--content .--badge{background-color:color-mix(in srgb,rgba(var(--node-bg-color),1) 85%,black);display:flex;width:1.5rem;height:1.5rem;flex:none;align-items:center;justify-content:center;border-radius:.375rem;line-height:1}.axp-chart-node .--node-container .--container .--heading-container .--content .--badge>span{font-size:.75rem;line-height:1rem}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles{display:flex;width:100%;flex:1 1 0%;flex-direction:column;gap:.25rem;overflow:hidden}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles .--title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:1.125rem;line-height:1.75rem;font-weight:600;line-height:1}.axp-chart-node .--node-container .--container .--heading-container .--content .--titles .--sub-title{overflow:hidden;text-overflow:ellipsis;white-space:nowrap;font-size:.75rem;line-height:1rem;opacity:.85}.axp-chart-node .--node-container .--container .--body-container{width:100%;--tw-bg-opacity: 1;background-color:rgba(var(--ax-sys-color-lightest-surface),var(--tw-bg-opacity, 1));padding:.5rem .75rem;--tw-text-opacity: 1;color:rgba(var(--ax-sys-color-on-lightest-surface),var(--tw-text-opacity, 1))}.axp-chart-node .--node-container .--container .--body-container .--description{text-align:center;font-size:.875rem;line-height:1rem;opacity:.85}.axp-chart-node .--node-container .--container .--toggle{position:absolute;left:0;right:0;bottom:-.75rem;display:flex;width:100%;-webkit-user-select:none;-moz-user-select:-moz-none;user-select:none;align-items:center;justify-content:center}#parent:fullscreen{background-color:rgba(var(--axp-brand-color))}\n"] }]
|
860
|
+
}] });
|
861
|
+
|
862
|
+
var orgChart_page = /*#__PURE__*/Object.freeze({
|
863
|
+
__proto__: null,
|
864
|
+
AXMOrgChartPage: AXMOrgChartPage
|
865
|
+
});
|
866
|
+
|
867
|
+
export { AXMOrgChartService as A, orgChart_page as o };
|
868
|
+
//# sourceMappingURL=acorex-modules-organization-management-org-chart.page-Cz4ENQRa.mjs.map
|