@acorex-platform/module-location-management-client 0.0.15 → 0.0.18
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/fesm2022/acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs +164 -0
- package/fesm2022/acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-location-management-client-contracts.mjs +2694 -0
- package/fesm2022/acorex-platform-module-location-management-client-contracts.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs +201 -0
- package/fesm2022/acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs.map +1 -0
- package/fesm2022/acorex-platform-module-location-management-client.mjs +1955 -0
- package/fesm2022/acorex-platform-module-location-management-client.mjs.map +1 -0
- package/package.json +21 -5
- package/types/acorex-platform-module-location-management-client-contracts.d.ts +274 -0
- package/types/acorex-platform-module-location-management-client.d.ts +53 -0
- package/contracts/datasource.keys.d.ts +0 -6
- package/contracts/datasource.keys.js +0 -8
- package/contracts/entities/geographic-region/geographic-region.entity.d.ts +0 -2
- package/contracts/entities/geographic-region/geographic-region.entity.js +0 -725
- package/contracts/entities/geographic-region/geographic-region.types.d.ts +0 -27
- package/contracts/entities/geographic-region/geographic-region.types.js +0 -1
- package/contracts/entities/geographic-region/index.d.ts +0 -2
- package/contracts/entities/geographic-region/index.js +0 -2
- package/contracts/entities/index.d.ts +0 -5
- package/contracts/entities/index.js +0 -5
- package/contracts/entities/location/index.d.ts +0 -2
- package/contracts/entities/location/index.js +0 -2
- package/contracts/entities/location/location.entity.d.ts +0 -2
- package/contracts/entities/location/location.entity.js +0 -1075
- package/contracts/entities/location/location.types.d.ts +0 -30
- package/contracts/entities/location/location.types.js +0 -1
- package/contracts/entities/location-assignment/index.d.ts +0 -2
- package/contracts/entities/location-assignment/index.js +0 -2
- package/contracts/entities/location-assignment/location-assignment.entity.d.ts +0 -2
- package/contracts/entities/location-assignment/location-assignment.entity.js +0 -194
- package/contracts/entities/location-assignment/location-assignment.types.d.ts +0 -35
- package/contracts/entities/location-assignment/location-assignment.types.js +0 -2
- package/contracts/entities/location-role/index.d.ts +0 -2
- package/contracts/entities/location-role/index.js +0 -2
- package/contracts/entities/location-role/location-role.entity.d.ts +0 -2
- package/contracts/entities/location-role/location-role.entity.js +0 -143
- package/contracts/entities/location-role/location-role.types.d.ts +0 -6
- package/contracts/entities/location-role/location-role.types.js +0 -1
- package/contracts/entities/location-type/index.d.ts +0 -2
- package/contracts/entities/location-type/index.js +0 -2
- package/contracts/entities/location-type/location-type.entity.d.ts +0 -2
- package/contracts/entities/location-type/location-type.entity.js +0 -237
- package/contracts/entities/location-type/location-type.types.d.ts +0 -8
- package/contracts/entities/location-type/location-type.types.js +0 -1
- package/contracts/features.keys.d.ts +0 -1
- package/contracts/features.keys.js +0 -2
- package/contracts/index.d.ts +0 -8
- package/contracts/index.js +0 -10
- package/contracts/location-assignment.actions.d.ts +0 -8
- package/contracts/location-assignment.actions.js +0 -73
- package/contracts/location-assignment.utils.d.ts +0 -53
- package/contracts/location-assignment.utils.js +0 -145
- package/contracts/menu.keys.d.ts +0 -8
- package/contracts/menu.keys.js +0 -8
- package/contracts/package.json +0 -5
- package/contracts/permission.keys.d.ts +0 -33
- package/contracts/permission.keys.js +0 -42
- package/contracts/root-config.d.ts +0 -42
- package/contracts/root-config.js +0 -43
|
@@ -0,0 +1,1955 @@
|
|
|
1
|
+
import * as i0 from '@angular/core';
|
|
2
|
+
import { Injectable, inject, signal, effect, computed, HostBinding, ChangeDetectionStrategy, Component, NgModule } from '@angular/core';
|
|
3
|
+
import { AXP_MODULE_MANIFEST_PROVIDER, AXP_FEATURE_DEFINITION_PROVIDER, AXP_DATASOURCE_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/core';
|
|
4
|
+
import { AXPEntityService, AXP_ENTITY_STORAGE_BACKEND, AXP_ENTITY_DEFINITION_LOADER, AXP_ENTITY_STORAGE_MIDDLEWARE } from '@acorex-platform/framework-client/layout/entity';
|
|
5
|
+
import { RootConfig, AXMLocationManagementPermissionsKeys, AXPLocationManagementMenuKeys, AXMLocationManagementDataSourceKeys, buildLocationAssignmentLocationSnapshot, buildLocationAssignmentPersonSnapshot } from '@acorex-platform/module-location-management-client/contracts';
|
|
6
|
+
import { AXPSearchCommandProvider, createEntityCommandOptions, AXPSettingsService, AXPClipBoardService, AXP_MENU_PROVIDER, AXP_SETTING_DEFINITION_PROVIDER, AXP_SEARCH_PROVIDER } from '@acorex-platform/framework-client/common';
|
|
7
|
+
import { AXP_PERMISSION_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/auth';
|
|
8
|
+
import { AXP_WIDGETS_EDITOR_SUB_COMPOSITE, AXP_WIDGETS_EDITOR_CATEGORY, AXPValueWidgetComponent, AXPColumnWidgetComponent, AXPWidgetCoreModule, AXP_WIDGET_DEFINITION_PROVIDER } from '@acorex-platform/framework-client/layout/widget-core';
|
|
9
|
+
import * as i1 from '@angular/common';
|
|
10
|
+
import { CommonModule } from '@angular/common';
|
|
11
|
+
import { provideCommandSetups } from '@acorex-platform/framework-client/runtime';
|
|
12
|
+
import { AXTranslationService, AXTranslationModule } from '@acorex/core/translation';
|
|
13
|
+
import { AXPCommonMenuKeys } from '@acorex-platform/module-common-client/contracts';
|
|
14
|
+
import { AXPWidgetsCatalog, AXPPlatformScope, formatAddressData, extractValue } from '@acorex-platform/framework-shared/core';
|
|
15
|
+
import { AXDataSource } from '@acorex/cdk/common';
|
|
16
|
+
import { get, set, defaultTo, isEmpty, isEqual, isNil, isNull } from 'lodash';
|
|
17
|
+
import { createSelectProperty, createBooleanProperty, AXPWidgetGroupEnum } from '@acorex-platform/framework-shared/widget-core';
|
|
18
|
+
import { AXP_NAME_PROPERTY, AXP_DATA_PATH_PROPERTY, AXP_DISABLED_PROPERTY, AXP_HAS_LABEL_PROPERTY, AXP_PLACEHOLDER_PROPERTY, AXP_BEHAVIOR_PROPERTY_GROUP } from '@acorex-platform/framework-client/layout/widgets';
|
|
19
|
+
import * as i6 from '@acorex/components/button';
|
|
20
|
+
import { AXButtonModule } from '@acorex/components/button';
|
|
21
|
+
import * as i4 from '@acorex/components/decorators';
|
|
22
|
+
import { AXDecoratorModule } from '@acorex/components/decorators';
|
|
23
|
+
import * as i3 from '@acorex/components/form';
|
|
24
|
+
import { AXFormModule } from '@acorex/components/form';
|
|
25
|
+
import * as i5 from '@acorex/components/text-box';
|
|
26
|
+
import { AXTextBoxModule } from '@acorex/components/text-box';
|
|
27
|
+
import { AXValidationModule } from '@acorex/core/validation';
|
|
28
|
+
import { AXPLayoutBuilderService, AXPLayoutRendererComponent } from '@acorex-platform/framework-client/layout/builder';
|
|
29
|
+
import * as i2 from '@angular/forms';
|
|
30
|
+
import { FormsModule } from '@angular/forms';
|
|
31
|
+
import * as i7 from '@acorex/components/accordion';
|
|
32
|
+
import { AXAccordionModule } from '@acorex/components/accordion';
|
|
33
|
+
import * as i1$1 from '@acorex/components/badge';
|
|
34
|
+
import { AXBadgeModule } from '@acorex/components/badge';
|
|
35
|
+
|
|
36
|
+
//#region ---- Imports ----
|
|
37
|
+
//#endregion
|
|
38
|
+
//#region ---- Manifest Definition ----
|
|
39
|
+
/**
|
|
40
|
+
* Location Management Module Manifest.
|
|
41
|
+
* Defines module metadata, features, and provider references.
|
|
42
|
+
*/
|
|
43
|
+
const LocationManagementManifest = {
|
|
44
|
+
name: RootConfig.module.name,
|
|
45
|
+
version: '1.0.0',
|
|
46
|
+
title: RootConfig.module.title,
|
|
47
|
+
icon: RootConfig.module.icon,
|
|
48
|
+
i18n: RootConfig.config.i18n,
|
|
49
|
+
required: true,
|
|
50
|
+
// Module dependencies (optional)
|
|
51
|
+
};
|
|
52
|
+
//#endregion
|
|
53
|
+
|
|
54
|
+
class AXMLocationManagementPermissionDefinitionProvider {
|
|
55
|
+
constructor(injector) {
|
|
56
|
+
this.injector = injector;
|
|
57
|
+
this.translateService = this.injector.get(AXTranslationService);
|
|
58
|
+
}
|
|
59
|
+
async define(context) {
|
|
60
|
+
const keys = AXMLocationManagementPermissionsKeys.LocationManagement;
|
|
61
|
+
const moduleTitle = await this.translateService.translateAsync('@location-management:module.permissions.title');
|
|
62
|
+
const moduleDescription = await this.translateService.translateAsync('@location-management:module.permissions.description');
|
|
63
|
+
context.addGroup(RootConfig.module.name, moduleTitle, moduleDescription)
|
|
64
|
+
// Locations Management
|
|
65
|
+
.addPermission(keys.Locations.Management, await this.translateService.translateAsync('@location-management:locations.permissions.locations.title'), await this.translateService.translateAsync('@location-management:locations.permissions.locations.description'))
|
|
66
|
+
.addChild(keys.Locations.View, await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.view.title'), await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.view.description'))
|
|
67
|
+
.addChild(keys.Locations.Create, await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.create.title'), await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.create.description'))
|
|
68
|
+
.addChild(keys.Locations.Edit, await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.edit.title'), await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.edit.description'))
|
|
69
|
+
.addChild(keys.Locations.Delete, await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.delete.title'), await this.translateService.translateAsync('@location-management:locations.permissions.locations.actions.delete.description'))
|
|
70
|
+
.endPermission()
|
|
71
|
+
// Location Types Management
|
|
72
|
+
.addPermission(keys.LocationTypes.Management, await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.title'), await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.description'))
|
|
73
|
+
.addChild(keys.LocationTypes.View, await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.view.title'), await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.view.description'))
|
|
74
|
+
.addChild(keys.LocationTypes.Create, await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.create.title'), await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.create.description'))
|
|
75
|
+
.addChild(keys.LocationTypes.Edit, await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.edit.title'), await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.edit.description'))
|
|
76
|
+
.addChild(keys.LocationTypes.Delete, await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.delete.title'), await this.translateService.translateAsync('@location-management:location-types.permissions.location-types.actions.delete.description'))
|
|
77
|
+
.endPermission()
|
|
78
|
+
// Location Roles Management
|
|
79
|
+
.addPermission(keys.LocationRoles.Management, await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.title'), await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.description'))
|
|
80
|
+
.addChild(keys.LocationRoles.View, await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.view.title'), await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.view.description'))
|
|
81
|
+
.addChild(keys.LocationRoles.Create, await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.create.title'), await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.create.description'))
|
|
82
|
+
.addChild(keys.LocationRoles.Edit, await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.edit.title'), await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.edit.description'))
|
|
83
|
+
.addChild(keys.LocationRoles.Delete, await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.delete.title'), await this.translateService.translateAsync('@location-management:location-roles.permissions.location-roles.actions.delete.description'))
|
|
84
|
+
.endPermission()
|
|
85
|
+
// Geographic Regions Management
|
|
86
|
+
.addPermission(keys.GeographicRegions.Management, await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.title'), await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.description'))
|
|
87
|
+
.addChild(keys.GeographicRegions.View, await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.view.title'), await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.view.description'))
|
|
88
|
+
.addChild(keys.GeographicRegions.Create, await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.create.title'), await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.create.description'))
|
|
89
|
+
.addChild(keys.GeographicRegions.Edit, await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.edit.title'), await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.edit.description'))
|
|
90
|
+
.addChild(keys.GeographicRegions.Delete, await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.delete.title'), await this.translateService.translateAsync('@location-management:geographic-regions.permissions.geographic-regions.actions.delete.description'))
|
|
91
|
+
.endPermission()
|
|
92
|
+
.endGroup();
|
|
93
|
+
}
|
|
94
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementPermissionDefinitionProvider, deps: [{ token: i0.Injector }], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
95
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementPermissionDefinitionProvider }); }
|
|
96
|
+
}
|
|
97
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementPermissionDefinitionProvider, decorators: [{
|
|
98
|
+
type: Injectable
|
|
99
|
+
}], ctorParameters: () => [{ type: i0.Injector }] });
|
|
100
|
+
|
|
101
|
+
//#region ---- Imports ----
|
|
102
|
+
//#endregion
|
|
103
|
+
//#region ---- Menu Provider ----
|
|
104
|
+
class AXMLocationManagementMenuProvider {
|
|
105
|
+
constructor() {
|
|
106
|
+
this.entityService = inject(AXPEntityService);
|
|
107
|
+
}
|
|
108
|
+
async provide(context) {
|
|
109
|
+
const module = RootConfig.module;
|
|
110
|
+
// Ensure Contacts root menu exists before adding items (avoids dependency on provider order)
|
|
111
|
+
const contactsMenu = context.find(AXPCommonMenuKeys.Contacts);
|
|
112
|
+
if (!contactsMenu.exists) {
|
|
113
|
+
context.addItems([
|
|
114
|
+
{
|
|
115
|
+
name: AXPCommonMenuKeys.Contacts,
|
|
116
|
+
priority: 8010,
|
|
117
|
+
text: '@general:menus.contacts.title',
|
|
118
|
+
icon: 'fa-light fa-address-book',
|
|
119
|
+
type: 'menu',
|
|
120
|
+
children: [],
|
|
121
|
+
},
|
|
122
|
+
]);
|
|
123
|
+
}
|
|
124
|
+
// Add Locations entity list under Contact root menu
|
|
125
|
+
context.find(AXPCommonMenuKeys.Contacts).addItems([
|
|
126
|
+
{
|
|
127
|
+
name: AXPLocationManagementMenuKeys.Locations,
|
|
128
|
+
text: RootConfig.entities.location.titlePlural,
|
|
129
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.location.name),
|
|
130
|
+
icon: RootConfig.entities.location.icon,
|
|
131
|
+
priority: 40,
|
|
132
|
+
policy: {
|
|
133
|
+
features: [module.name],
|
|
134
|
+
permissions: [AXMLocationManagementPermissionsKeys.LocationManagement.Locations.View],
|
|
135
|
+
},
|
|
136
|
+
},
|
|
137
|
+
]);
|
|
138
|
+
// Add LocationTypes and GeographicRegions under Configuration/Region
|
|
139
|
+
context.find(AXPCommonMenuKeys.Region).addItems([
|
|
140
|
+
{
|
|
141
|
+
name: AXPLocationManagementMenuKeys.LocationTypes,
|
|
142
|
+
text: '@location-management:location-types.menus.location-types.title',
|
|
143
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.locationType.name),
|
|
144
|
+
icon: RootConfig.entities.locationType.icon,
|
|
145
|
+
priority: 1,
|
|
146
|
+
policy: {
|
|
147
|
+
features: [module.name],
|
|
148
|
+
permissions: [AXMLocationManagementPermissionsKeys.LocationManagement.LocationTypes.View],
|
|
149
|
+
},
|
|
150
|
+
},
|
|
151
|
+
{
|
|
152
|
+
name: AXPLocationManagementMenuKeys.LocationRoles,
|
|
153
|
+
text: '@location-management:location-roles.menus.location-roles.title',
|
|
154
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.locationRole.name),
|
|
155
|
+
icon: RootConfig.entities.locationRole.icon,
|
|
156
|
+
priority: 2,
|
|
157
|
+
policy: {
|
|
158
|
+
features: [module.name],
|
|
159
|
+
permissions: [AXMLocationManagementPermissionsKeys.LocationManagement.LocationRoles.View],
|
|
160
|
+
},
|
|
161
|
+
},
|
|
162
|
+
{
|
|
163
|
+
name: AXPLocationManagementMenuKeys.GeographicRegions,
|
|
164
|
+
text: '@location-management:geographic-regions.menus.geographic-regions.title',
|
|
165
|
+
path: this.entityService.createPath(module.name, RootConfig.entities.geographicRegion.name),
|
|
166
|
+
icon: RootConfig.entities.geographicRegion.icon,
|
|
167
|
+
priority: 3,
|
|
168
|
+
policy: {
|
|
169
|
+
features: [module.name],
|
|
170
|
+
permissions: [AXMLocationManagementPermissionsKeys.LocationManagement.GeographicRegions.View],
|
|
171
|
+
},
|
|
172
|
+
},
|
|
173
|
+
]);
|
|
174
|
+
}
|
|
175
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementMenuProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
176
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementMenuProvider }); }
|
|
177
|
+
}
|
|
178
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementMenuProvider, decorators: [{
|
|
179
|
+
type: Injectable
|
|
180
|
+
}] });
|
|
181
|
+
|
|
182
|
+
class AXMLocationManagementEntityProvider {
|
|
183
|
+
preload() {
|
|
184
|
+
const module = RootConfig.module.name;
|
|
185
|
+
return Array.from(Object.values(RootConfig.entities)).map((entity) => ({
|
|
186
|
+
module: module,
|
|
187
|
+
entity: entity.name,
|
|
188
|
+
}));
|
|
189
|
+
}
|
|
190
|
+
async get(moduleName, entityName) {
|
|
191
|
+
if (moduleName == RootConfig.module.name) {
|
|
192
|
+
switch (entityName) {
|
|
193
|
+
case RootConfig.entities.location.name:
|
|
194
|
+
return (await import('@acorex-platform/module-location-management-client/contracts')).locationFactory();
|
|
195
|
+
case RootConfig.entities.locationType.name:
|
|
196
|
+
return (await import('@acorex-platform/module-location-management-client/contracts')).locationTypeFactory();
|
|
197
|
+
case RootConfig.entities.locationRole.name:
|
|
198
|
+
return (await import('@acorex-platform/module-location-management-client/contracts')).locationRoleFactory();
|
|
199
|
+
case RootConfig.entities.geographicRegion.name:
|
|
200
|
+
return (await import('@acorex-platform/module-location-management-client/contracts')).geographicRegionFactory();
|
|
201
|
+
case RootConfig.entities.locationAssignment.name:
|
|
202
|
+
return (await import('@acorex-platform/module-location-management-client/contracts')).locationAssignmentFactory();
|
|
203
|
+
}
|
|
204
|
+
}
|
|
205
|
+
return null;
|
|
206
|
+
}
|
|
207
|
+
async list() {
|
|
208
|
+
const m = RootConfig.module.name;
|
|
209
|
+
return Promise.resolve(Object.values(RootConfig.entities).map((e) => ({ name: e.name, module: m })));
|
|
210
|
+
}
|
|
211
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementEntityProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
212
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementEntityProvider }); }
|
|
213
|
+
}
|
|
214
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementEntityProvider, decorators: [{
|
|
215
|
+
type: Injectable
|
|
216
|
+
}] });
|
|
217
|
+
|
|
218
|
+
class AXMSettingProvider {
|
|
219
|
+
async provide(context) {
|
|
220
|
+
// context
|
|
221
|
+
// // Add Form Template Group
|
|
222
|
+
// .addGroup('form-template', 'Form Template', 'Settings related to form templates.', RootConfig.module.icon)
|
|
223
|
+
// // Start Interface Section
|
|
224
|
+
// .addSection('interface', 'UI Interface', 'Customize the user interface for forms.')
|
|
225
|
+
// .addSetting({
|
|
226
|
+
// key: 'history-panel',
|
|
227
|
+
// title: 'Show History Panel',
|
|
228
|
+
// scope: 'U',
|
|
229
|
+
// isInherited: true,
|
|
230
|
+
// defaultValue: false,
|
|
231
|
+
// widget: {
|
|
232
|
+
// type: AXPWidgetsCatalog.toggle,
|
|
233
|
+
// },
|
|
234
|
+
// description: 'Enable or disable the history panel for forms.',
|
|
235
|
+
// validationRules: [
|
|
236
|
+
// {
|
|
237
|
+
// rule: 'required',
|
|
238
|
+
// },
|
|
239
|
+
// ],
|
|
240
|
+
// })
|
|
241
|
+
// .endSection()
|
|
242
|
+
// .endGroup();
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
class AXMSearchCommandProvider extends AXPSearchCommandProvider {
|
|
247
|
+
constructor() {
|
|
248
|
+
super(...arguments);
|
|
249
|
+
this.commands = [
|
|
250
|
+
{
|
|
251
|
+
id: 'create-location-role',
|
|
252
|
+
group: 'command',
|
|
253
|
+
title: RootConfig.entities.locationRole.title,
|
|
254
|
+
icon: RootConfig.entities.locationRole.icon,
|
|
255
|
+
description: RootConfig.entities.locationRole.titlePlural,
|
|
256
|
+
command: {
|
|
257
|
+
name: 'Entity:Create',
|
|
258
|
+
options: createEntityCommandOptions(`${RootConfig.module.name}.${RootConfig.entities.locationRole.name}`, {
|
|
259
|
+
name: RootConfig.entities.locationRole.name,
|
|
260
|
+
module: RootConfig.module.name,
|
|
261
|
+
title: RootConfig.entities.locationRole.title,
|
|
262
|
+
}),
|
|
263
|
+
},
|
|
264
|
+
},
|
|
265
|
+
{
|
|
266
|
+
id: 'create-location-type',
|
|
267
|
+
group: 'command',
|
|
268
|
+
title: RootConfig.entities.locationType.title,
|
|
269
|
+
icon: RootConfig.entities.locationType.icon,
|
|
270
|
+
description: RootConfig.entities.locationType.titlePlural,
|
|
271
|
+
command: {
|
|
272
|
+
name: 'Entity:Create',
|
|
273
|
+
options: createEntityCommandOptions(`${RootConfig.module.name}.${RootConfig.entities.locationType.name}`, {
|
|
274
|
+
name: RootConfig.entities.locationType.name,
|
|
275
|
+
module: RootConfig.module.name,
|
|
276
|
+
title: RootConfig.entities.locationType.title,
|
|
277
|
+
}),
|
|
278
|
+
},
|
|
279
|
+
},
|
|
280
|
+
{
|
|
281
|
+
id: 'create-geographic-region',
|
|
282
|
+
group: 'command',
|
|
283
|
+
title: RootConfig.entities.geographicRegion.title,
|
|
284
|
+
icon: RootConfig.entities.geographicRegion.icon,
|
|
285
|
+
description: RootConfig.entities.geographicRegion.titlePlural,
|
|
286
|
+
command: {
|
|
287
|
+
name: 'Entity:Create',
|
|
288
|
+
options: createEntityCommandOptions(`${RootConfig.module.name}.${RootConfig.entities.geographicRegion.name}`, {
|
|
289
|
+
name: RootConfig.entities.geographicRegion.name,
|
|
290
|
+
module: RootConfig.module.name,
|
|
291
|
+
title: RootConfig.entities.geographicRegion.title,
|
|
292
|
+
}),
|
|
293
|
+
},
|
|
294
|
+
},
|
|
295
|
+
];
|
|
296
|
+
}
|
|
297
|
+
}
|
|
298
|
+
|
|
299
|
+
//#region ---- Imports ----
|
|
300
|
+
//#endregion
|
|
301
|
+
//#region ---- Feature Definition Provider ----
|
|
302
|
+
/**
|
|
303
|
+
* Location Management Feature Definition Provider.
|
|
304
|
+
* Provides feature definitions for the Location Management module.
|
|
305
|
+
*/
|
|
306
|
+
class AXMLocationManagementFeatureDefinitionProvider {
|
|
307
|
+
async provide(context) {
|
|
308
|
+
// Management feature removed - module name is used directly as feature key
|
|
309
|
+
}
|
|
310
|
+
}
|
|
311
|
+
//#endregion
|
|
312
|
+
|
|
313
|
+
class AXMGeographicRegionDataSourceDefinition {
|
|
314
|
+
constructor() {
|
|
315
|
+
this.entityService = inject(AXPEntityService);
|
|
316
|
+
this.geographicRegionService = this.entityService
|
|
317
|
+
.withEntity(RootConfig.module.name, RootConfig.entities.geographicRegion.name)
|
|
318
|
+
.data();
|
|
319
|
+
//#region ---- Country ----
|
|
320
|
+
this.countries = {
|
|
321
|
+
name: AXMLocationManagementDataSourceKeys.Countries,
|
|
322
|
+
title: 'Countries',
|
|
323
|
+
columns: [
|
|
324
|
+
{
|
|
325
|
+
name: 'code',
|
|
326
|
+
title: 'Code',
|
|
327
|
+
type: 'string',
|
|
328
|
+
datatype: 'string',
|
|
329
|
+
},
|
|
330
|
+
{
|
|
331
|
+
name: 'title',
|
|
332
|
+
title: 'Title',
|
|
333
|
+
type: 'string',
|
|
334
|
+
datatype: 'string',
|
|
335
|
+
},
|
|
336
|
+
],
|
|
337
|
+
filters: [],
|
|
338
|
+
textField: { name: 'title', title: 'Title' },
|
|
339
|
+
valueField: { name: 'id', title: 'Id' },
|
|
340
|
+
samples: [
|
|
341
|
+
{ id: 'US', title: 'United States' },
|
|
342
|
+
{ id: 'CA', title: 'Canada' },
|
|
343
|
+
{ id: 'GB', title: 'United Kingdom' },
|
|
344
|
+
{ id: 'AU', title: 'Australia' },
|
|
345
|
+
{ id: 'NZ', title: 'New Zealand' },
|
|
346
|
+
{ id: 'ZA', title: 'South Africa' },
|
|
347
|
+
{ id: 'IN', title: 'India' },
|
|
348
|
+
],
|
|
349
|
+
source: () => {
|
|
350
|
+
return new AXDataSource({
|
|
351
|
+
pageSize: 50,
|
|
352
|
+
key: 'id',
|
|
353
|
+
load: async (e) => {
|
|
354
|
+
const result = await this.geographicRegionService.query({
|
|
355
|
+
...e,
|
|
356
|
+
filter: { field: 'type.code', operator: { type: 'equal' }, value: 'country' },
|
|
357
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
358
|
+
});
|
|
359
|
+
return {
|
|
360
|
+
items: result.items,
|
|
361
|
+
total: result.total,
|
|
362
|
+
};
|
|
363
|
+
},
|
|
364
|
+
byKey: async (key) => {
|
|
365
|
+
const item = await this.geographicRegionService.byKey(key);
|
|
366
|
+
return item;
|
|
367
|
+
},
|
|
368
|
+
});
|
|
369
|
+
},
|
|
370
|
+
};
|
|
371
|
+
//#endregion
|
|
372
|
+
//#region ---- Provinces (States) ----
|
|
373
|
+
this.provinces = {
|
|
374
|
+
name: AXMLocationManagementDataSourceKeys.Provinces,
|
|
375
|
+
title: 'Provinces',
|
|
376
|
+
columns: [
|
|
377
|
+
{
|
|
378
|
+
name: 'code',
|
|
379
|
+
title: 'Code',
|
|
380
|
+
type: 'string',
|
|
381
|
+
datatype: 'string',
|
|
382
|
+
},
|
|
383
|
+
{
|
|
384
|
+
name: 'title',
|
|
385
|
+
title: 'Title',
|
|
386
|
+
type: 'string',
|
|
387
|
+
datatype: 'string',
|
|
388
|
+
},
|
|
389
|
+
],
|
|
390
|
+
filters: [
|
|
391
|
+
{
|
|
392
|
+
field: 'parentId',
|
|
393
|
+
title: 'Country',
|
|
394
|
+
operator: { type: 'equal' },
|
|
395
|
+
widget: {
|
|
396
|
+
type: AXPWidgetsCatalog.selectFilter,
|
|
397
|
+
options: {
|
|
398
|
+
dataSource: AXMLocationManagementDataSourceKeys.Countries,
|
|
399
|
+
valueField: 'id',
|
|
400
|
+
textField: 'title',
|
|
401
|
+
},
|
|
402
|
+
},
|
|
403
|
+
filterType: { advance: true, inline: true },
|
|
404
|
+
},
|
|
405
|
+
],
|
|
406
|
+
textField: { name: 'title', title: 'Title' },
|
|
407
|
+
valueField: { name: 'id', title: 'Id' },
|
|
408
|
+
source: () => {
|
|
409
|
+
return new AXDataSource({
|
|
410
|
+
pageSize: 50,
|
|
411
|
+
key: 'id',
|
|
412
|
+
load: async (e) => {
|
|
413
|
+
console.log('[provinces datasource] load query:', { filter: e?.filter, take: e?.take, skip: e?.skip });
|
|
414
|
+
const typeFilter = { field: 'type.code', operator: { type: 'equal' }, value: 'state' };
|
|
415
|
+
const extraFilters = e?.filter?.filters ?? (e?.filter ? [e.filter] : []);
|
|
416
|
+
const filter = extraFilters.length > 0
|
|
417
|
+
? { logic: 'and', filters: [typeFilter, ...extraFilters] }
|
|
418
|
+
: typeFilter;
|
|
419
|
+
console.log('[provinces datasource] extraFilters:', extraFilters, 'final filter:', filter);
|
|
420
|
+
const result = await this.geographicRegionService.query({
|
|
421
|
+
...e,
|
|
422
|
+
filter,
|
|
423
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
424
|
+
});
|
|
425
|
+
console.log('[provinces datasource] result:', result.items?.length, result.total);
|
|
426
|
+
return {
|
|
427
|
+
items: result.items,
|
|
428
|
+
total: result.total,
|
|
429
|
+
};
|
|
430
|
+
},
|
|
431
|
+
byKey: async (key) => {
|
|
432
|
+
const item = await this.geographicRegionService.byKey(key);
|
|
433
|
+
return item;
|
|
434
|
+
},
|
|
435
|
+
});
|
|
436
|
+
},
|
|
437
|
+
};
|
|
438
|
+
//#endregion
|
|
439
|
+
//#region ---- Cities ----
|
|
440
|
+
this.cities = {
|
|
441
|
+
name: AXMLocationManagementDataSourceKeys.Cities,
|
|
442
|
+
title: 'Cities',
|
|
443
|
+
columns: [
|
|
444
|
+
{
|
|
445
|
+
name: 'code',
|
|
446
|
+
title: 'Code',
|
|
447
|
+
type: 'string',
|
|
448
|
+
datatype: 'string',
|
|
449
|
+
},
|
|
450
|
+
{
|
|
451
|
+
name: 'title',
|
|
452
|
+
title: 'Title',
|
|
453
|
+
type: 'string',
|
|
454
|
+
datatype: 'string',
|
|
455
|
+
},
|
|
456
|
+
],
|
|
457
|
+
filters: [
|
|
458
|
+
{
|
|
459
|
+
field: 'parentId',
|
|
460
|
+
title: 'Province',
|
|
461
|
+
operator: { type: 'equal' },
|
|
462
|
+
widget: {
|
|
463
|
+
type: AXPWidgetsCatalog.selectFilter,
|
|
464
|
+
options: {
|
|
465
|
+
dataSource: AXMLocationManagementDataSourceKeys.Provinces,
|
|
466
|
+
valueField: 'id',
|
|
467
|
+
textField: 'title',
|
|
468
|
+
},
|
|
469
|
+
},
|
|
470
|
+
filterType: { advance: true, inline: true },
|
|
471
|
+
},
|
|
472
|
+
],
|
|
473
|
+
textField: { name: 'title', title: 'Title' },
|
|
474
|
+
valueField: { name: 'id', title: 'Id' },
|
|
475
|
+
source: () => {
|
|
476
|
+
return new AXDataSource({
|
|
477
|
+
pageSize: 50,
|
|
478
|
+
key: 'id',
|
|
479
|
+
load: async (e) => {
|
|
480
|
+
console.log('[cities datasource] load query:', { filter: e?.filter, take: e?.take, skip: e?.skip });
|
|
481
|
+
const typeFilter = { field: 'type.code', operator: { type: 'equal' }, value: 'city' };
|
|
482
|
+
const extraFilters = e?.filter?.filters ?? (e?.filter ? [e.filter] : []);
|
|
483
|
+
const filter = extraFilters.length > 0
|
|
484
|
+
? { logic: 'and', filters: [typeFilter, ...extraFilters] }
|
|
485
|
+
: typeFilter;
|
|
486
|
+
console.log('[cities datasource] extraFilters:', extraFilters, 'final filter:', filter);
|
|
487
|
+
const result = await this.geographicRegionService.query({
|
|
488
|
+
...e,
|
|
489
|
+
filter,
|
|
490
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
491
|
+
});
|
|
492
|
+
console.log('[cities datasource] result:', result.items?.length, result.total);
|
|
493
|
+
return {
|
|
494
|
+
items: result.items,
|
|
495
|
+
total: result.total,
|
|
496
|
+
};
|
|
497
|
+
},
|
|
498
|
+
byKey: async (key) => {
|
|
499
|
+
const item = await this.geographicRegionService.byKey(key);
|
|
500
|
+
return item;
|
|
501
|
+
},
|
|
502
|
+
});
|
|
503
|
+
},
|
|
504
|
+
};
|
|
505
|
+
}
|
|
506
|
+
//#endregion
|
|
507
|
+
async items() {
|
|
508
|
+
return [this.countries, this.provinces, this.cities];
|
|
509
|
+
}
|
|
510
|
+
}
|
|
511
|
+
|
|
512
|
+
//#region ---- LocationAssignment nested hydration ----
|
|
513
|
+
const LOCATION_ASSIGNMENT_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.locationAssignment.name}`;
|
|
514
|
+
const LOCATION_ENTITY = `${RootConfig.module.name}.${RootConfig.entities.location.name}`;
|
|
515
|
+
const PERSON_ENTITY = 'PersonCore.Person';
|
|
516
|
+
/**
|
|
517
|
+
* Hydrates nested `location` and `person` on LocationAssignment rows so consumers
|
|
518
|
+
* (e.g. party location lists) receive computed fields such as `fullAddress` and `fullName`.
|
|
519
|
+
*/
|
|
520
|
+
const locationAssignmentLocationHydrateMiddleware = {
|
|
521
|
+
target: { ops: ['getOne', 'getAll', 'query'], order: 13 },
|
|
522
|
+
execute: async (ctx, next) => {
|
|
523
|
+
const backend = inject(AXP_ENTITY_STORAGE_BACKEND);
|
|
524
|
+
await next();
|
|
525
|
+
if (ctx.entityName !== LOCATION_ASSIGNMENT_ENTITY) {
|
|
526
|
+
return;
|
|
527
|
+
}
|
|
528
|
+
try {
|
|
529
|
+
const rows = Array.isArray(ctx.result)
|
|
530
|
+
? ctx.result
|
|
531
|
+
: Array.isArray(ctx.result?.items)
|
|
532
|
+
? (ctx.result.items ?? [])
|
|
533
|
+
: ctx.result
|
|
534
|
+
? [ctx.result]
|
|
535
|
+
: [];
|
|
536
|
+
if (!rows.length) {
|
|
537
|
+
return;
|
|
538
|
+
}
|
|
539
|
+
const locationIds = Array.from(new Set(rows.map((row) => get(row, 'locationId')).filter((id) => id != null)));
|
|
540
|
+
const personIds = Array.from(new Set(rows.map((row) => get(row, 'personId')).filter((id) => id != null)));
|
|
541
|
+
const locationMap = new Map();
|
|
542
|
+
if (locationIds.length) {
|
|
543
|
+
const locationResponse = await backend.query(LOCATION_ENTITY, {
|
|
544
|
+
skip: 0,
|
|
545
|
+
take: locationIds.length,
|
|
546
|
+
filter: { field: 'id', operator: { type: 'in' }, value: locationIds },
|
|
547
|
+
});
|
|
548
|
+
for (const item of locationResponse?.items ?? []) {
|
|
549
|
+
const record = item;
|
|
550
|
+
locationMap.set(get(record, 'id'), record);
|
|
551
|
+
}
|
|
552
|
+
}
|
|
553
|
+
const personMap = new Map();
|
|
554
|
+
if (personIds.length) {
|
|
555
|
+
const personResponse = await backend.query(PERSON_ENTITY, {
|
|
556
|
+
skip: 0,
|
|
557
|
+
take: personIds.length,
|
|
558
|
+
filter: { field: 'id', operator: { type: 'in' }, value: personIds },
|
|
559
|
+
});
|
|
560
|
+
for (const item of personResponse?.items ?? []) {
|
|
561
|
+
const record = item;
|
|
562
|
+
personMap.set(get(record, 'id'), record);
|
|
563
|
+
}
|
|
564
|
+
}
|
|
565
|
+
for (const row of rows) {
|
|
566
|
+
const locationId = get(row, 'locationId');
|
|
567
|
+
if (locationId != null) {
|
|
568
|
+
const location = locationMap.get(locationId);
|
|
569
|
+
if (location) {
|
|
570
|
+
set(row, 'location', buildLocationAssignmentLocationSnapshot(location, locationId));
|
|
571
|
+
}
|
|
572
|
+
}
|
|
573
|
+
const personId = get(row, 'personId');
|
|
574
|
+
if (personId != null) {
|
|
575
|
+
const person = personMap.get(personId);
|
|
576
|
+
if (person) {
|
|
577
|
+
set(row, 'person', buildLocationAssignmentPersonSnapshot(person, personId));
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
}
|
|
581
|
+
}
|
|
582
|
+
catch {
|
|
583
|
+
// swallow to avoid breaking main flow
|
|
584
|
+
}
|
|
585
|
+
},
|
|
586
|
+
};
|
|
587
|
+
//#endregion
|
|
588
|
+
|
|
589
|
+
const AXPAddressWidget = {
|
|
590
|
+
name: 'address-editor',
|
|
591
|
+
title: '@platform-layout-widgets:widgets.address-editor.title',
|
|
592
|
+
description: '@platform-layout-widgets:widgets.address-editor.description',
|
|
593
|
+
categories: AXP_WIDGETS_EDITOR_CATEGORY,
|
|
594
|
+
subCategory: AXP_WIDGETS_EDITOR_SUB_COMPOSITE,
|
|
595
|
+
groups: [AXPWidgetGroupEnum.FormElement],
|
|
596
|
+
icon: 'fa-light fa-location-dot',
|
|
597
|
+
defaultFilterWidgetName: 'string-filter',
|
|
598
|
+
type: 'editor',
|
|
599
|
+
properties: [
|
|
600
|
+
AXP_NAME_PROPERTY,
|
|
601
|
+
AXP_DATA_PATH_PROPERTY,
|
|
602
|
+
createSelectProperty({
|
|
603
|
+
name: 'mode',
|
|
604
|
+
title: 'Mode',
|
|
605
|
+
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
|
606
|
+
dataSource: [
|
|
607
|
+
{ id: 'simple', title: 'Single line' },
|
|
608
|
+
{ id: 'popup', title: 'Popup editor' },
|
|
609
|
+
{ id: 'expandable', title: 'Expandable panel' },
|
|
610
|
+
],
|
|
611
|
+
defaultValue: { id: 'simple', title: 'Single line' },
|
|
612
|
+
path: 'options.mode',
|
|
613
|
+
}),
|
|
614
|
+
createBooleanProperty({
|
|
615
|
+
name: 'hasLabel',
|
|
616
|
+
title: 'Has Label',
|
|
617
|
+
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
|
618
|
+
defaultValue: false,
|
|
619
|
+
path: 'options.hasLabel',
|
|
620
|
+
}),
|
|
621
|
+
createBooleanProperty({
|
|
622
|
+
name: 'hasMap',
|
|
623
|
+
title: 'Has Map',
|
|
624
|
+
group: AXP_BEHAVIOR_PROPERTY_GROUP,
|
|
625
|
+
defaultValue: true,
|
|
626
|
+
path: 'options.hasMap',
|
|
627
|
+
}),
|
|
628
|
+
AXP_DISABLED_PROPERTY,
|
|
629
|
+
AXP_HAS_LABEL_PROPERTY,
|
|
630
|
+
AXP_PLACEHOLDER_PROPERTY,
|
|
631
|
+
],
|
|
632
|
+
components: {
|
|
633
|
+
view: {
|
|
634
|
+
component: () => Promise.resolve().then(function () { return addressWidgetView_component; }).then((c) => c.AXPAddressWidgetViewComponent),
|
|
635
|
+
},
|
|
636
|
+
edit: {
|
|
637
|
+
component: () => Promise.resolve().then(function () { return addressWidgetEdit_component; }).then((c) => c.AXPAddressWidgetEditComponent),
|
|
638
|
+
},
|
|
639
|
+
column: {
|
|
640
|
+
component: () => Promise.resolve().then(function () { return addressWidgetColumn_component; }).then((c) => c.AXPAddressWidgetColumnComponent),
|
|
641
|
+
},
|
|
642
|
+
designer: {
|
|
643
|
+
component: () => Promise.resolve().then(function () { return addressWidgetEdit_component; }).then((c) => c.AXPAddressWidgetEditComponent),
|
|
644
|
+
},
|
|
645
|
+
},
|
|
646
|
+
};
|
|
647
|
+
|
|
648
|
+
//#endregion
|
|
649
|
+
|
|
650
|
+
const TENANT_ORGANIZATION_ADDRESS_SETTINGS = {
|
|
651
|
+
street1: 'OrganizationManagement:Setting:Organization.Street1',
|
|
652
|
+
street2: 'OrganizationManagement:Setting:Organization.Street2',
|
|
653
|
+
countryId: 'OrganizationManagement:Setting:Organization.CountryId',
|
|
654
|
+
stateId: 'OrganizationManagement:Setting:Organization.StateId',
|
|
655
|
+
cityId: 'OrganizationManagement:Setting:Organization.CityId',
|
|
656
|
+
postalCode: 'OrganizationManagement:Setting:Organization.PostalCode',
|
|
657
|
+
};
|
|
658
|
+
const GEOGRAPHIC_REGION_ENTITY = 'LocationManagement.GeographicRegion';
|
|
659
|
+
//#region ---- Service ----
|
|
660
|
+
class AXPAddressWidgetService {
|
|
661
|
+
constructor() {
|
|
662
|
+
//#region ---- Services & Dependencies ----
|
|
663
|
+
this.layoutBuilder = inject(AXPLayoutBuilderService);
|
|
664
|
+
this.translationService = inject(AXTranslationService);
|
|
665
|
+
this.settingsService = inject(AXPSettingsService);
|
|
666
|
+
this.entityService = inject(AXPEntityService);
|
|
667
|
+
this.geographicDefaultsCache = null;
|
|
668
|
+
this.geographicTitleCache = new Map();
|
|
669
|
+
this.settingsService.onChanged.subscribe((event) => {
|
|
670
|
+
const settingKeys = Object.values(TENANT_ORGANIZATION_ADDRESS_SETTINGS);
|
|
671
|
+
if (event.keys.some((key) => settingKeys.includes(key))) {
|
|
672
|
+
this.invalidateGeographicDefaultsCache();
|
|
673
|
+
}
|
|
674
|
+
});
|
|
675
|
+
}
|
|
676
|
+
//#endregion
|
|
677
|
+
//#region ---- Shared address form layout (dialog + inline renderer) ----
|
|
678
|
+
/**
|
|
679
|
+
* Builds the address form content (street1, street2, country, state, city, postalCode, label, map).
|
|
680
|
+
* Used by both the dialog and the expandable inline layout via create().flex().build().
|
|
681
|
+
*/
|
|
682
|
+
buildAddressFormContent(flex, options) {
|
|
683
|
+
const { hasLabel, labelEntity, hasMap, addressData } = options;
|
|
684
|
+
const showLabel = !!hasLabel && !!labelEntity;
|
|
685
|
+
flex.mode('edit').setDirection('column').setGap('12px');
|
|
686
|
+
//#region ---- Row 1: label + show map ----
|
|
687
|
+
if (showLabel || hasMap) {
|
|
688
|
+
flex.grid((metaRow) => {
|
|
689
|
+
metaRow.setColumns(12).setGap('12px');
|
|
690
|
+
if (showLabel) {
|
|
691
|
+
metaRow.formField('@location-management:locations.entities.location.fields.label', (field) => {
|
|
692
|
+
field.path('labelId');
|
|
693
|
+
field.layout(3);
|
|
694
|
+
field.customWidget('lookup-editor', {
|
|
695
|
+
entity: labelEntity,
|
|
696
|
+
look: 'select',
|
|
697
|
+
textField: 'title',
|
|
698
|
+
valueField: 'id',
|
|
699
|
+
hasClearButton: true,
|
|
700
|
+
allowCreate: 'quick',
|
|
701
|
+
create: {
|
|
702
|
+
enable: true,
|
|
703
|
+
},
|
|
704
|
+
expose: [
|
|
705
|
+
{ source: 'id', target: 'label.id' },
|
|
706
|
+
{ source: 'title', target: 'label.title' },
|
|
707
|
+
],
|
|
708
|
+
validations: [{ rule: 'required', message: '@general:validation.messages.required' }],
|
|
709
|
+
});
|
|
710
|
+
});
|
|
711
|
+
}
|
|
712
|
+
if (hasMap) {
|
|
713
|
+
metaRow.formField('@location-management:locations.entities.location.fields.show-map', (field) => {
|
|
714
|
+
field.path('showMap');
|
|
715
|
+
field.layout(3);
|
|
716
|
+
field.toggleSwitch({
|
|
717
|
+
defaultValue: !!(addressData?.coordinates),
|
|
718
|
+
});
|
|
719
|
+
});
|
|
720
|
+
}
|
|
721
|
+
});
|
|
722
|
+
}
|
|
723
|
+
//#endregion
|
|
724
|
+
//#region ---- Row 2: street address + address line 2 ----
|
|
725
|
+
flex.grid((streetRow) => {
|
|
726
|
+
streetRow.setColumns(12).setGap('12px');
|
|
727
|
+
streetRow
|
|
728
|
+
.formField('@location-management:locations.entities.location.fields.street1', (field) => {
|
|
729
|
+
field.path('street1');
|
|
730
|
+
field.layout(6);
|
|
731
|
+
field.textBox({
|
|
732
|
+
validations: [{ rule: 'required', message: '@general:validation.messages.required' }],
|
|
733
|
+
});
|
|
734
|
+
})
|
|
735
|
+
.formField('@location-management:locations.entities.location.fields.street2', (field) => {
|
|
736
|
+
field.path('street2');
|
|
737
|
+
field.layout(6);
|
|
738
|
+
field.textBox({});
|
|
739
|
+
});
|
|
740
|
+
});
|
|
741
|
+
//#endregion
|
|
742
|
+
//#region ---- Row 3: postal code + country + state + city ----
|
|
743
|
+
flex.grid((geoRow) => {
|
|
744
|
+
geoRow.setColumns(12).setGap('12px');
|
|
745
|
+
geoRow
|
|
746
|
+
.formField('@location-management:locations.entities.location.fields.postal-code', (field) => {
|
|
747
|
+
field.path('postalCode');
|
|
748
|
+
field.layout(3);
|
|
749
|
+
field.textBox({ placeholder: 'Enter postal code' });
|
|
750
|
+
})
|
|
751
|
+
.formField('@location-management:locations.entities.location.fields.country', (field) => {
|
|
752
|
+
field.path('countryId');
|
|
753
|
+
field.layout(3);
|
|
754
|
+
field.customWidget('lookup-editor', {
|
|
755
|
+
entity: 'LocationManagement.GeographicRegion',
|
|
756
|
+
look: 'select',
|
|
757
|
+
textField: 'title',
|
|
758
|
+
valueField: 'id',
|
|
759
|
+
hasClearButton: true,
|
|
760
|
+
allowCreate: 'quick',
|
|
761
|
+
create: {
|
|
762
|
+
enable: true,
|
|
763
|
+
},
|
|
764
|
+
expose: [
|
|
765
|
+
{ source: 'id', target: 'country.id' },
|
|
766
|
+
{ source: 'title', target: 'country.title' },
|
|
767
|
+
],
|
|
768
|
+
filter: {
|
|
769
|
+
logic: 'and',
|
|
770
|
+
filters: [{ field: 'type.code', operator: { type: 'equal' }, value: 'country' }],
|
|
771
|
+
},
|
|
772
|
+
});
|
|
773
|
+
})
|
|
774
|
+
.formField('@location-management:locations.entities.location.fields.state', (field) => {
|
|
775
|
+
field.path('stateId');
|
|
776
|
+
field.layout(3);
|
|
777
|
+
field.customWidget('lookup-editor', {
|
|
778
|
+
entity: 'LocationManagement.GeographicRegion',
|
|
779
|
+
look: 'select',
|
|
780
|
+
textField: 'title',
|
|
781
|
+
valueField: 'id',
|
|
782
|
+
hasClearButton: true,
|
|
783
|
+
allowCreate: 'quick',
|
|
784
|
+
disabled: '{{ !context.eval("countryId") }}',
|
|
785
|
+
create: {
|
|
786
|
+
enable: true,
|
|
787
|
+
context: {
|
|
788
|
+
parentId: '{{ context.eval("countryId") }}',
|
|
789
|
+
type: { code: 'state' },
|
|
790
|
+
},
|
|
791
|
+
},
|
|
792
|
+
expose: [
|
|
793
|
+
{ source: 'id', target: 'state.id' },
|
|
794
|
+
{ source: 'title', target: 'state.title' },
|
|
795
|
+
],
|
|
796
|
+
filter: {
|
|
797
|
+
logic: 'and',
|
|
798
|
+
filters: [
|
|
799
|
+
{ field: 'parentId', operator: { type: 'equal' }, value: '{{ context.eval("countryId") }}' },
|
|
800
|
+
{ field: 'type.code', operator: { type: 'equal' }, value: 'state' },
|
|
801
|
+
],
|
|
802
|
+
},
|
|
803
|
+
triggers: [
|
|
804
|
+
{
|
|
805
|
+
event: "{{ events.context('countryId') }}",
|
|
806
|
+
action: "{{ widget.setValue(null); context.set('state.title', null); context.set('cityId', null); context.set('city.id', null); context.set('city.title', null); widget.refresh(); }}",
|
|
807
|
+
},
|
|
808
|
+
],
|
|
809
|
+
});
|
|
810
|
+
})
|
|
811
|
+
.formField('@location-management:locations.entities.location.fields.city', (field) => {
|
|
812
|
+
field.path('cityId');
|
|
813
|
+
field.layout(3);
|
|
814
|
+
field.customWidget('lookup-editor', {
|
|
815
|
+
entity: 'LocationManagement.GeographicRegion',
|
|
816
|
+
look: 'select',
|
|
817
|
+
textField: 'title',
|
|
818
|
+
valueField: 'id',
|
|
819
|
+
hasClearButton: true,
|
|
820
|
+
allowCreate: 'quick',
|
|
821
|
+
disabled: '{{ !context.eval("stateId") }}',
|
|
822
|
+
create: {
|
|
823
|
+
enable: true,
|
|
824
|
+
context: {
|
|
825
|
+
parentId: '{{ context.eval("stateId") }}',
|
|
826
|
+
type: { code: 'city' },
|
|
827
|
+
},
|
|
828
|
+
},
|
|
829
|
+
expose: [
|
|
830
|
+
{ source: 'id', target: 'city.id' },
|
|
831
|
+
{ source: 'title', target: 'city.title' },
|
|
832
|
+
],
|
|
833
|
+
filter: {
|
|
834
|
+
logic: 'and',
|
|
835
|
+
filters: [
|
|
836
|
+
{ field: 'parentId', operator: { type: 'equal' }, value: '{{ context.eval("stateId") }}' },
|
|
837
|
+
{ field: 'type.code', operator: { type: 'equal' }, value: 'city' },
|
|
838
|
+
],
|
|
839
|
+
},
|
|
840
|
+
triggers: [
|
|
841
|
+
{
|
|
842
|
+
event: "{{ events.context('stateId') }}",
|
|
843
|
+
action: "{{ widget.setValue(null); context.set('city.title', null); widget.refresh(); }}",
|
|
844
|
+
},
|
|
845
|
+
{
|
|
846
|
+
event: "{{ events.context('countryId') }}",
|
|
847
|
+
action: "{{ widget.setValue(null); context.set('city.title', null); widget.refresh(); }}",
|
|
848
|
+
},
|
|
849
|
+
],
|
|
850
|
+
});
|
|
851
|
+
});
|
|
852
|
+
});
|
|
853
|
+
//#endregion
|
|
854
|
+
//#region ---- Map picker (when show map is enabled) ----
|
|
855
|
+
if (hasMap) {
|
|
856
|
+
flex.grid((mapRow) => {
|
|
857
|
+
mapRow.setColumns(12).setGap('12px');
|
|
858
|
+
mapRow.formField('@location-management:locations.entities.location.fields.coordinates', (field) => {
|
|
859
|
+
field.path('coordinates');
|
|
860
|
+
field.layout(12);
|
|
861
|
+
field.visible('{{ context.eval("showMap") }}');
|
|
862
|
+
field.customWidget('map', { hasDraw: true, maxPolygon: 0 });
|
|
863
|
+
});
|
|
864
|
+
});
|
|
865
|
+
}
|
|
866
|
+
//#endregion
|
|
867
|
+
}
|
|
868
|
+
/**
|
|
869
|
+
* Returns the address form layout node using layoutBuilder.create().flex().build() for use in axp-layout-renderer.
|
|
870
|
+
*/
|
|
871
|
+
getAddressFormLayout(options) {
|
|
872
|
+
return this.layoutBuilder
|
|
873
|
+
.create()
|
|
874
|
+
.flex((flex) => this.buildAddressFormContent(flex, options))
|
|
875
|
+
.build();
|
|
876
|
+
}
|
|
877
|
+
//#endregion
|
|
878
|
+
//#region ---- Geographic Defaults Methods ----
|
|
879
|
+
/** Loads geographic defaults from tenant organization address settings. */
|
|
880
|
+
async getGeographicDefaults() {
|
|
881
|
+
if (!this.geographicDefaultsCache) {
|
|
882
|
+
this.geographicDefaultsCache = this.loadGeographicDefaultsFromSettings();
|
|
883
|
+
}
|
|
884
|
+
return this.geographicDefaultsCache;
|
|
885
|
+
}
|
|
886
|
+
async loadGeographicDefaultsFromSettings() {
|
|
887
|
+
const tenantScope = this.settingsService.scope(AXPPlatformScope.Tenant);
|
|
888
|
+
const [countryId, stateId, cityId, street1, street2, postalCode] = await Promise.all([
|
|
889
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.countryId),
|
|
890
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.stateId),
|
|
891
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.cityId),
|
|
892
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.street1),
|
|
893
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.street2),
|
|
894
|
+
tenantScope.get(TENANT_ORGANIZATION_ADDRESS_SETTINGS.postalCode),
|
|
895
|
+
]);
|
|
896
|
+
const resolvedCountry = this.resolveSettingLookupSnapshot(countryId);
|
|
897
|
+
const resolvedState = this.resolveSettingLookupSnapshot(stateId);
|
|
898
|
+
const resolvedCity = this.resolveSettingLookupSnapshot(cityId);
|
|
899
|
+
const resolvedStreet1 = defaultTo(street1, '').trim();
|
|
900
|
+
const resolvedStreet2 = defaultTo(street2, '').trim();
|
|
901
|
+
const resolvedPostalCode = defaultTo(postalCode, '').trim();
|
|
902
|
+
if (isEmpty(resolvedCountry?.id) &&
|
|
903
|
+
isEmpty(resolvedState?.id) &&
|
|
904
|
+
isEmpty(resolvedCity?.id) &&
|
|
905
|
+
isEmpty(resolvedStreet1) &&
|
|
906
|
+
isEmpty(resolvedStreet2) &&
|
|
907
|
+
isEmpty(resolvedPostalCode)) {
|
|
908
|
+
return null;
|
|
909
|
+
}
|
|
910
|
+
return {
|
|
911
|
+
street1: resolvedStreet1 || undefined,
|
|
912
|
+
street2: resolvedStreet2 || undefined,
|
|
913
|
+
postalCode: resolvedPostalCode || undefined,
|
|
914
|
+
countryId: resolvedCountry?.id,
|
|
915
|
+
stateId: resolvedState?.id,
|
|
916
|
+
cityId: resolvedCity?.id,
|
|
917
|
+
country: resolvedCountry,
|
|
918
|
+
state: resolvedState,
|
|
919
|
+
city: resolvedCity,
|
|
920
|
+
};
|
|
921
|
+
}
|
|
922
|
+
/** Clears cached defaults (e.g. after tenant settings change). */
|
|
923
|
+
invalidateGeographicDefaultsCache() {
|
|
924
|
+
this.geographicDefaultsCache = null;
|
|
925
|
+
}
|
|
926
|
+
/**
|
|
927
|
+
* Applies tenant/platform geographic defaults to empty address fields only.
|
|
928
|
+
* Returns whether any field was updated.
|
|
929
|
+
*/
|
|
930
|
+
async applyGeographicDefaultsIfNeeded(value, options) {
|
|
931
|
+
if (options?.enabled === false) {
|
|
932
|
+
return { value, applied: false };
|
|
933
|
+
}
|
|
934
|
+
const defaults = await this.getGeographicDefaults();
|
|
935
|
+
if (!defaults) {
|
|
936
|
+
return { value, applied: false };
|
|
937
|
+
}
|
|
938
|
+
const merged = this.mergeGeographicDefaults(value, defaults);
|
|
939
|
+
const enriched = await this.enrichGeographicLookupTitles(merged);
|
|
940
|
+
const applied = !isEqual(this.snapshotGeographicFields(value), this.snapshotGeographicFields(enriched));
|
|
941
|
+
return { value: enriched, applied };
|
|
942
|
+
}
|
|
943
|
+
/** Merges defaults into empty country/state/city (and optional street/postal) fields. */
|
|
944
|
+
mergeGeographicDefaults(value, defaults) {
|
|
945
|
+
const result = { ...value };
|
|
946
|
+
if (this.isLookupEmpty(result.country) && defaults.country?.id) {
|
|
947
|
+
result.country = defaults.country;
|
|
948
|
+
}
|
|
949
|
+
if (this.isLookupEmpty(result.state) && defaults.state?.id) {
|
|
950
|
+
result.state = defaults.state;
|
|
951
|
+
}
|
|
952
|
+
if (this.isLookupEmpty(result.city) && defaults.city?.id) {
|
|
953
|
+
result.city = defaults.city;
|
|
954
|
+
}
|
|
955
|
+
if (!result.street1?.trim() && defaults.street1?.trim()) {
|
|
956
|
+
result.street1 = defaults.street1;
|
|
957
|
+
}
|
|
958
|
+
if (!result.street2?.trim() && defaults.street2?.trim()) {
|
|
959
|
+
result.street2 = defaults.street2;
|
|
960
|
+
}
|
|
961
|
+
if (!result.postalCode?.trim() && defaults.postalCode?.trim()) {
|
|
962
|
+
result.postalCode = defaults.postalCode;
|
|
963
|
+
}
|
|
964
|
+
return result;
|
|
965
|
+
}
|
|
966
|
+
/** Ensures country/state/city snapshots include titles required for formatted address text. */
|
|
967
|
+
async enrichGeographicLookupTitles(value) {
|
|
968
|
+
const [country, state, city] = await Promise.all([
|
|
969
|
+
this.enrichLookupField(value.country),
|
|
970
|
+
this.enrichLookupField(value.state),
|
|
971
|
+
this.enrichLookupField(value.city),
|
|
972
|
+
]);
|
|
973
|
+
if (country === value.country && state === value.state && city === value.city) {
|
|
974
|
+
return value;
|
|
975
|
+
}
|
|
976
|
+
return { ...value, country, state, city };
|
|
977
|
+
}
|
|
978
|
+
//#endregion
|
|
979
|
+
//#region ---- Geographic Cascade Methods ----
|
|
980
|
+
/**
|
|
981
|
+
* Builds layout context with flat lookup ids (countryId/stateId/cityId/labelId) required for cascade triggers.
|
|
982
|
+
* Same pattern as LocationManagement.Location entity fields.
|
|
983
|
+
*/
|
|
984
|
+
buildAddressFormContext(addressData, options) {
|
|
985
|
+
return {
|
|
986
|
+
...addressData,
|
|
987
|
+
countryId: addressData.country?.id,
|
|
988
|
+
stateId: addressData.state?.id,
|
|
989
|
+
cityId: addressData.city?.id,
|
|
990
|
+
labelId: addressData.label?.id,
|
|
991
|
+
showMap: (options?.hasMap ?? false) && !!addressData.coordinates,
|
|
992
|
+
};
|
|
993
|
+
}
|
|
994
|
+
/**
|
|
995
|
+
* Clears dependent geographic fields when a parent selection changes.
|
|
996
|
+
* Mirrors Location entity cascade: state depends on country, city depends on state.
|
|
997
|
+
*/
|
|
998
|
+
applyGeographicCascade(previous, next) {
|
|
999
|
+
const result = { ...next };
|
|
1000
|
+
const previousCountryId = previous.countryId ?? previous.country?.id;
|
|
1001
|
+
const nextCountryId = result.countryId ?? result.country?.id;
|
|
1002
|
+
const previousStateId = previous.stateId ?? previous.state?.id;
|
|
1003
|
+
const nextStateId = result.stateId ?? result.state?.id;
|
|
1004
|
+
if (previousCountryId !== nextCountryId) {
|
|
1005
|
+
result.state = undefined;
|
|
1006
|
+
result.city = undefined;
|
|
1007
|
+
result.stateId = undefined;
|
|
1008
|
+
result.cityId = undefined;
|
|
1009
|
+
}
|
|
1010
|
+
else if (previousStateId !== nextStateId) {
|
|
1011
|
+
result.city = undefined;
|
|
1012
|
+
result.cityId = undefined;
|
|
1013
|
+
}
|
|
1014
|
+
return result;
|
|
1015
|
+
}
|
|
1016
|
+
//#endregion
|
|
1017
|
+
//#region ---- Address Formatting Methods ----
|
|
1018
|
+
/**
|
|
1019
|
+
* Formats address data into full address string
|
|
1020
|
+
* Format: [street1], [street2], [country] - [state], [city], [postalCode]
|
|
1021
|
+
* Uses titles from exposed fields, excludes coordinates
|
|
1022
|
+
*/
|
|
1023
|
+
formatAddress(data) {
|
|
1024
|
+
return formatAddressData(data);
|
|
1025
|
+
}
|
|
1026
|
+
/**
|
|
1027
|
+
* Collapse header parts: label title (semibold in template) + full address.
|
|
1028
|
+
*/
|
|
1029
|
+
async resolveCollapsibleHeader(value, options) {
|
|
1030
|
+
const enriched = await this.enrichGeographicLookupTitles(value);
|
|
1031
|
+
const full = (enriched.full?.trim() || this.formatAddress(enriched)).trim();
|
|
1032
|
+
const addressText = full !== '' ? full : options.placeholder;
|
|
1033
|
+
const labelText = enriched.label?.title?.trim() || null;
|
|
1034
|
+
return { labelText, addressText };
|
|
1035
|
+
}
|
|
1036
|
+
//#endregion
|
|
1037
|
+
//#region ---- Dialog & UI Methods ----
|
|
1038
|
+
/**
|
|
1039
|
+
* Shows address details popup dialog using the shared address form layout.
|
|
1040
|
+
*/
|
|
1041
|
+
async showAddressDetailsPopup(addressData, options = {}) {
|
|
1042
|
+
const { hasMap = true, hasLabel, labelEntity, useGeographicDefaults = true } = options;
|
|
1043
|
+
const { value: addressWithDefaults } = await this.applyGeographicDefaultsIfNeeded(addressData, {
|
|
1044
|
+
enabled: useGeographicDefaults,
|
|
1045
|
+
});
|
|
1046
|
+
const initialContext = this.buildAddressFormContext(addressWithDefaults, { hasMap });
|
|
1047
|
+
const dialogTitle = await this.translationService.translateAsync('@general:terms.common.address');
|
|
1048
|
+
const ref = await this.layoutBuilder
|
|
1049
|
+
.create()
|
|
1050
|
+
.dialog((dialog) => {
|
|
1051
|
+
dialog
|
|
1052
|
+
.setTitle(dialogTitle)
|
|
1053
|
+
.setSize('lg')
|
|
1054
|
+
.setContext(initialContext)
|
|
1055
|
+
.content((layoutBuilder) => {
|
|
1056
|
+
layoutBuilder.flex((flex) => this.buildAddressFormContent(flex, {
|
|
1057
|
+
hasLabel,
|
|
1058
|
+
labelEntity,
|
|
1059
|
+
hasMap,
|
|
1060
|
+
addressData: addressWithDefaults,
|
|
1061
|
+
}));
|
|
1062
|
+
})
|
|
1063
|
+
.setActions((actions) => {
|
|
1064
|
+
actions.cancel('@general:actions.cancel.title').submit('@general:actions.apply.title');
|
|
1065
|
+
});
|
|
1066
|
+
})
|
|
1067
|
+
.show();
|
|
1068
|
+
if (ref.action() === 'cancel') {
|
|
1069
|
+
ref.close();
|
|
1070
|
+
return null;
|
|
1071
|
+
}
|
|
1072
|
+
const result = this.applyGeographicCascade(initialContext, this.normalizeAddressData(ref.context()));
|
|
1073
|
+
ref.close();
|
|
1074
|
+
return result;
|
|
1075
|
+
}
|
|
1076
|
+
//#endregion
|
|
1077
|
+
//#region ---- Data Normalization Methods ----
|
|
1078
|
+
/**
|
|
1079
|
+
* Normalizes address data from various input formats
|
|
1080
|
+
*/
|
|
1081
|
+
normalizeAddressData(value) {
|
|
1082
|
+
if (typeof value === 'object' && value !== null) {
|
|
1083
|
+
const contextValue = value;
|
|
1084
|
+
return {
|
|
1085
|
+
street1: contextValue.street1 ?? '',
|
|
1086
|
+
street2: contextValue.street2,
|
|
1087
|
+
country: contextValue.country,
|
|
1088
|
+
state: contextValue.state,
|
|
1089
|
+
city: contextValue.city,
|
|
1090
|
+
postalCode: contextValue.postalCode,
|
|
1091
|
+
coordinates: contextValue.coordinates,
|
|
1092
|
+
full: contextValue.full ?? this.formatAddress(contextValue),
|
|
1093
|
+
label: this.resolveLabel(contextValue),
|
|
1094
|
+
};
|
|
1095
|
+
}
|
|
1096
|
+
// Simple string format
|
|
1097
|
+
return {
|
|
1098
|
+
street1: '',
|
|
1099
|
+
street2: '',
|
|
1100
|
+
country: undefined,
|
|
1101
|
+
state: undefined,
|
|
1102
|
+
city: undefined,
|
|
1103
|
+
postalCode: '',
|
|
1104
|
+
coordinates: undefined,
|
|
1105
|
+
full: value?.toString() || '',
|
|
1106
|
+
label: undefined,
|
|
1107
|
+
};
|
|
1108
|
+
}
|
|
1109
|
+
/** Resolves persisted label snapshot from lookup expose or transient labelId. */
|
|
1110
|
+
resolveLabel(value) {
|
|
1111
|
+
const exposed = value.label;
|
|
1112
|
+
if (exposed?.id) {
|
|
1113
|
+
return { id: exposed.id, title: exposed.title };
|
|
1114
|
+
}
|
|
1115
|
+
if (value.labelId) {
|
|
1116
|
+
return { id: value.labelId, title: exposed?.title };
|
|
1117
|
+
}
|
|
1118
|
+
return undefined;
|
|
1119
|
+
}
|
|
1120
|
+
isLookupEmpty(value) {
|
|
1121
|
+
return isNil(value?.id) || value.id === '';
|
|
1122
|
+
}
|
|
1123
|
+
snapshotGeographicFields(value) {
|
|
1124
|
+
return {
|
|
1125
|
+
street1: value.street1,
|
|
1126
|
+
street2: value.street2,
|
|
1127
|
+
postalCode: value.postalCode,
|
|
1128
|
+
country: value.country,
|
|
1129
|
+
state: value.state,
|
|
1130
|
+
city: value.city,
|
|
1131
|
+
};
|
|
1132
|
+
}
|
|
1133
|
+
resolveSettingLookupSnapshot(value) {
|
|
1134
|
+
if (isNil(value) || value === '') {
|
|
1135
|
+
return undefined;
|
|
1136
|
+
}
|
|
1137
|
+
if (typeof value === 'object') {
|
|
1138
|
+
const record = value;
|
|
1139
|
+
const id = extractValue(record.id ?? value);
|
|
1140
|
+
const title = extractValue(record.title);
|
|
1141
|
+
if (!id?.trim()) {
|
|
1142
|
+
return undefined;
|
|
1143
|
+
}
|
|
1144
|
+
return {
|
|
1145
|
+
id: id.trim(),
|
|
1146
|
+
title: title?.trim() || undefined,
|
|
1147
|
+
};
|
|
1148
|
+
}
|
|
1149
|
+
const id = extractValue(value);
|
|
1150
|
+
return id?.trim() ? { id: id.trim() } : undefined;
|
|
1151
|
+
}
|
|
1152
|
+
async enrichLookupField(field) {
|
|
1153
|
+
if (!field?.id || field.title?.trim()) {
|
|
1154
|
+
return field;
|
|
1155
|
+
}
|
|
1156
|
+
const title = await this.resolveGeographicRegionTitle(field.id);
|
|
1157
|
+
return title ? { id: field.id, title } : field;
|
|
1158
|
+
}
|
|
1159
|
+
async resolveGeographicRegionTitle(id) {
|
|
1160
|
+
if (this.geographicTitleCache.has(id)) {
|
|
1161
|
+
const cached = this.geographicTitleCache.get(id);
|
|
1162
|
+
return cached || undefined;
|
|
1163
|
+
}
|
|
1164
|
+
try {
|
|
1165
|
+
const row = await this.entityService.withEntity(GEOGRAPHIC_REGION_ENTITY).data().byKey(id);
|
|
1166
|
+
const title = extractValue(get(row, 'title'));
|
|
1167
|
+
const normalized = title?.trim() ?? '';
|
|
1168
|
+
this.geographicTitleCache.set(id, normalized);
|
|
1169
|
+
return normalized || undefined;
|
|
1170
|
+
}
|
|
1171
|
+
catch {
|
|
1172
|
+
this.geographicTitleCache.set(id, '');
|
|
1173
|
+
return undefined;
|
|
1174
|
+
}
|
|
1175
|
+
}
|
|
1176
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1177
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetService, providedIn: 'root' }); }
|
|
1178
|
+
}
|
|
1179
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetService, decorators: [{
|
|
1180
|
+
type: Injectable,
|
|
1181
|
+
args: [{ providedIn: 'root' }]
|
|
1182
|
+
}], ctorParameters: () => [] });
|
|
1183
|
+
|
|
1184
|
+
class AXPAddressWidgetEditComponent extends AXPValueWidgetComponent {
|
|
1185
|
+
constructor() {
|
|
1186
|
+
super(...arguments);
|
|
1187
|
+
this.addressService = inject(AXPAddressWidgetService);
|
|
1188
|
+
/** Collapsible mode: true = panel collapsed (only full address visible), false = expanded (edit button visible) */
|
|
1189
|
+
this.collapsibleCollapsed = signal(true, ...(ngDevMode ? [{ debugName: "collapsibleCollapsed" }] : /* istanbul ignore next */ []));
|
|
1190
|
+
this.collapsibleHeaderLabel = signal(null, ...(ngDevMode ? [{ debugName: "collapsibleHeaderLabel" }] : /* istanbul ignore next */ []));
|
|
1191
|
+
this.collapsibleHeaderAddress = signal('', ...(ngDevMode ? [{ debugName: "collapsibleHeaderAddress" }] : /* istanbul ignore next */ []));
|
|
1192
|
+
/** Bumped on parent discard so the nested layout renderer remounts with reverted context. */
|
|
1193
|
+
this.layoutRendererGeneration = signal(0, ...(ngDevMode ? [{ debugName: "layoutRendererGeneration" }] : /* istanbul ignore next */ []));
|
|
1194
|
+
this.parentContextWasRestored = false;
|
|
1195
|
+
this.geographicDefaultsInitialized = false;
|
|
1196
|
+
this.suppressContextSync = false;
|
|
1197
|
+
/** Blocks ax-collapse from auto-collapsing while a new empty row is opening. */
|
|
1198
|
+
this.blockAutoCollapseUntil = 0;
|
|
1199
|
+
/** Expand new repeater rows so users can enter values without clicking the header again. */
|
|
1200
|
+
this.#expandEmptyAddressEffect = effect(() => {
|
|
1201
|
+
if (this.addressMode() !== 'expandable') {
|
|
1202
|
+
return;
|
|
1203
|
+
}
|
|
1204
|
+
if (this.shouldKeepExpandedForEntry(this.valueAsObject())) {
|
|
1205
|
+
this.collapsibleCollapsed.set(false);
|
|
1206
|
+
this.blockAutoCollapseUntil = Date.now() + 300;
|
|
1207
|
+
}
|
|
1208
|
+
}, ...(ngDevMode ? [{ debugName: "#expandEmptyAddressEffect" }] : /* istanbul ignore next */ []));
|
|
1209
|
+
this.#resetNestedFormOnDiscard = effect(() => {
|
|
1210
|
+
if (this.addressMode() !== 'expandable') {
|
|
1211
|
+
return;
|
|
1212
|
+
}
|
|
1213
|
+
const isRestored = this.contextService.changeEvent().state === 'restored';
|
|
1214
|
+
if (isRestored && !this.parentContextWasRestored) {
|
|
1215
|
+
this.layoutRendererGeneration.update((generation) => generation + 1);
|
|
1216
|
+
}
|
|
1217
|
+
this.parentContextWasRestored = isRestored;
|
|
1218
|
+
}, ...(ngDevMode ? [{ debugName: "#resetNestedFormOnDiscard" }] : /* istanbul ignore next */ []));
|
|
1219
|
+
this.#collapsibleHeaderEffect = effect(() => {
|
|
1220
|
+
const value = this.valueAsObject();
|
|
1221
|
+
this.formattedAddress();
|
|
1222
|
+
const placeholder = this.placeholder();
|
|
1223
|
+
void this.addressService
|
|
1224
|
+
.resolveCollapsibleHeader(value, { placeholder })
|
|
1225
|
+
.then((header) => {
|
|
1226
|
+
this.collapsibleHeaderLabel.set(header.labelText);
|
|
1227
|
+
this.collapsibleHeaderAddress.set(header.addressText);
|
|
1228
|
+
});
|
|
1229
|
+
}, ...(ngDevMode ? [{ debugName: "#collapsibleHeaderEffect" }] : /* istanbul ignore next */ []));
|
|
1230
|
+
this.#applyGeographicDefaultsEffect = effect(() => {
|
|
1231
|
+
if (!this.useGeographicDefaults() || this.geographicDefaultsInitialized) {
|
|
1232
|
+
return;
|
|
1233
|
+
}
|
|
1234
|
+
const value = this.valueAsObject();
|
|
1235
|
+
void this.addressService
|
|
1236
|
+
.applyGeographicDefaultsIfNeeded(value, { enabled: true })
|
|
1237
|
+
.then(({ value: merged, applied }) => {
|
|
1238
|
+
this.geographicDefaultsInitialized = true;
|
|
1239
|
+
if (!applied) {
|
|
1240
|
+
return;
|
|
1241
|
+
}
|
|
1242
|
+
const normalized = this.addressService.normalizeAddressData(merged);
|
|
1243
|
+
normalized.full = this.addressService.formatAddress(normalized);
|
|
1244
|
+
this.commitAddressValue(normalized);
|
|
1245
|
+
});
|
|
1246
|
+
}, ...(ngDevMode ? [{ debugName: "#applyGeographicDefaultsEffect" }] : /* istanbul ignore next */ []));
|
|
1247
|
+
this.addressMode = computed(() => extractValue(this.options()['mode']) || 'simple', ...(ngDevMode ? [{ debugName: "addressMode" }] : /* istanbul ignore next */ []));
|
|
1248
|
+
this.placeholder = computed(() => this.options()['placeholder'] || 'Enter address...', ...(ngDevMode ? [{ debugName: "placeholder" }] : /* istanbul ignore next */ []));
|
|
1249
|
+
this.labelEntity = computed(() => this.options()['labelEntity'], ...(ngDevMode ? [{ debugName: "labelEntity" }] : /* istanbul ignore next */ []));
|
|
1250
|
+
this.useGeographicDefaults = computed(() => this.options()['useGeographicDefaults'] ?? true, ...(ngDevMode ? [{ debugName: "useGeographicDefaults" }] : /* istanbul ignore next */ []));
|
|
1251
|
+
this.disabled = computed(() => this.options()['disabled'] ?? false, ...(ngDevMode ? [{ debugName: "disabled" }] : /* istanbul ignore next */ []));
|
|
1252
|
+
this.hasLabel = computed(() => this.options()['hasLabel'] ?? false, ...(ngDevMode ? [{ debugName: "hasLabel" }] : /* istanbul ignore next */ []));
|
|
1253
|
+
this.hasMap = computed(() => this.options()['hasMap'] ?? true, ...(ngDevMode ? [{ debugName: "hasMap" }] : /* istanbul ignore next */ []));
|
|
1254
|
+
this.format = computed(() => {
|
|
1255
|
+
if (this.hasLabel() ||
|
|
1256
|
+
this.addressMode() === 'popup' ||
|
|
1257
|
+
this.addressMode() === 'expandable') {
|
|
1258
|
+
return 'object';
|
|
1259
|
+
}
|
|
1260
|
+
return 'string';
|
|
1261
|
+
}, ...(ngDevMode ? [{ debugName: "format" }] : /* istanbul ignore next */ []));
|
|
1262
|
+
this.valueAsObject = computed(() => this.toObject(this.getValue()), ...(ngDevMode ? [{ debugName: "valueAsObject" }] : /* istanbul ignore next */ []));
|
|
1263
|
+
this.formattedAddress = computed(() => {
|
|
1264
|
+
const value = this.valueAsObject();
|
|
1265
|
+
return value.full || this.addressService.formatAddress(value);
|
|
1266
|
+
}, ...(ngDevMode ? [{ debugName: "formattedAddress" }] : /* istanbul ignore next */ []));
|
|
1267
|
+
/** Layout node from create().flex().build() for inline renderer (expandable mode). */
|
|
1268
|
+
this.addressFormLayout = computed(() => this.addressService.getAddressFormLayout({
|
|
1269
|
+
hasLabel: this.hasLabel(),
|
|
1270
|
+
labelEntity: this.labelEntity(),
|
|
1271
|
+
hasMap: this.hasMap(),
|
|
1272
|
+
}), ...(ngDevMode ? [{ debugName: "addressFormLayout" }] : /* istanbul ignore next */ []));
|
|
1273
|
+
/** Context for inline address form (expandable); includes showMap for map toggle. */
|
|
1274
|
+
this.collapsibleFormContext = computed(() => this.addressService.buildAddressFormContext(this.valueAsObject(), {
|
|
1275
|
+
hasMap: this.hasMap(),
|
|
1276
|
+
}), ...(ngDevMode ? [{ debugName: "collapsibleFormContext" }] : /* istanbul ignore next */ []));
|
|
1277
|
+
}
|
|
1278
|
+
/** Expand new repeater rows so users can enter values without clicking the header again. */
|
|
1279
|
+
#expandEmptyAddressEffect;
|
|
1280
|
+
#resetNestedFormOnDiscard;
|
|
1281
|
+
#collapsibleHeaderEffect;
|
|
1282
|
+
#applyGeographicDefaultsEffect;
|
|
1283
|
+
onCollapsibleFormContextChange(ctx) {
|
|
1284
|
+
if (ctx == null || this.suppressContextSync) {
|
|
1285
|
+
return;
|
|
1286
|
+
}
|
|
1287
|
+
const previous = this.addressService.buildAddressFormContext(this.valueAsObject(), {
|
|
1288
|
+
hasMap: this.hasMap(),
|
|
1289
|
+
});
|
|
1290
|
+
void (async () => {
|
|
1291
|
+
const normalized = this.addressService.normalizeAddressData(this.addressService.applyGeographicCascade(previous, ctx));
|
|
1292
|
+
const enriched = await this.addressService.enrichGeographicLookupTitles(normalized);
|
|
1293
|
+
enriched.full = this.addressService.formatAddress(enriched);
|
|
1294
|
+
if (isEqual(enriched, this.valueAsObject())) {
|
|
1295
|
+
return;
|
|
1296
|
+
}
|
|
1297
|
+
this.commitAddressValue(enriched);
|
|
1298
|
+
})();
|
|
1299
|
+
}
|
|
1300
|
+
onCollapsedChange(collapsed) {
|
|
1301
|
+
if (collapsed &&
|
|
1302
|
+
(Date.now() < this.blockAutoCollapseUntil ||
|
|
1303
|
+
this.shouldKeepExpandedForEntry(this.valueAsObject()))) {
|
|
1304
|
+
return;
|
|
1305
|
+
}
|
|
1306
|
+
this.collapsibleCollapsed.set(collapsed);
|
|
1307
|
+
}
|
|
1308
|
+
async handleValueChange(e) {
|
|
1309
|
+
const { name, value, isUserInteraction } = e;
|
|
1310
|
+
if (isUserInteraction) {
|
|
1311
|
+
const newValues = { ...this.valueAsObject(), [name]: value };
|
|
1312
|
+
this.setValue(this.setFormattedValue(newValues));
|
|
1313
|
+
}
|
|
1314
|
+
}
|
|
1315
|
+
async showDetailsPopup() {
|
|
1316
|
+
const currentValue = this.valueAsObject();
|
|
1317
|
+
const result = await this.addressService.showAddressDetailsPopup(currentValue, {
|
|
1318
|
+
hasMap: this.hasMap(),
|
|
1319
|
+
hasLabel: this.hasLabel(),
|
|
1320
|
+
labelEntity: this.labelEntity(),
|
|
1321
|
+
useGeographicDefaults: this.useGeographicDefaults(),
|
|
1322
|
+
});
|
|
1323
|
+
if (result) {
|
|
1324
|
+
result.full = this.addressService.formatAddress(result);
|
|
1325
|
+
this.setValue(this.setFormattedValue(result));
|
|
1326
|
+
}
|
|
1327
|
+
}
|
|
1328
|
+
generateClasses(element) {
|
|
1329
|
+
const isValue = element === 'value';
|
|
1330
|
+
const hasLabel = this.hasLabel();
|
|
1331
|
+
const baseClass = 'col-span-12';
|
|
1332
|
+
if (!hasLabel) {
|
|
1333
|
+
return baseClass;
|
|
1334
|
+
}
|
|
1335
|
+
return {
|
|
1336
|
+
[baseClass]: true,
|
|
1337
|
+
'lg:col-span-7': isValue,
|
|
1338
|
+
'lg:col-span-5': !isValue,
|
|
1339
|
+
};
|
|
1340
|
+
}
|
|
1341
|
+
commitAddressValue(value) {
|
|
1342
|
+
this.suppressContextSync = true;
|
|
1343
|
+
if (this.shouldKeepExpandedForEntry(value)) {
|
|
1344
|
+
this.blockAutoCollapseUntil = Date.now() + 300;
|
|
1345
|
+
this.collapsibleCollapsed.set(false);
|
|
1346
|
+
}
|
|
1347
|
+
this.setValue(this.setFormattedValue(value));
|
|
1348
|
+
window.setTimeout(() => {
|
|
1349
|
+
this.suppressContextSync = false;
|
|
1350
|
+
}, 50);
|
|
1351
|
+
}
|
|
1352
|
+
/** True while the row has no user-entered content (ignores geographic defaults). */
|
|
1353
|
+
shouldKeepExpandedForEntry(value) {
|
|
1354
|
+
return (!value.street1?.trim() &&
|
|
1355
|
+
!value.street2?.trim() &&
|
|
1356
|
+
!value.postalCode?.trim() &&
|
|
1357
|
+
!value.label?.id);
|
|
1358
|
+
}
|
|
1359
|
+
toObject(item) {
|
|
1360
|
+
return this.addressService.normalizeAddressData(item);
|
|
1361
|
+
}
|
|
1362
|
+
setFormattedValue(item) {
|
|
1363
|
+
if (this.format() === 'string') {
|
|
1364
|
+
return item.full;
|
|
1365
|
+
}
|
|
1366
|
+
return item;
|
|
1367
|
+
}
|
|
1368
|
+
get __class() {
|
|
1369
|
+
return 'block flex-1';
|
|
1370
|
+
}
|
|
1371
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetEditComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1372
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPAddressWidgetEditComponent, isStandalone: true, selector: "axp-address-widget-edit", host: { properties: { "class": "this.__class" } }, usesInheritance: true, ngImport: i0, template: `
|
|
1373
|
+
@if (addressMode() === 'simple') {
|
|
1374
|
+
<div class="grid grid-cols-12 gap-4 auto-cols-max">
|
|
1375
|
+
<ax-text-box
|
|
1376
|
+
[ngModel]="valueAsObject().full"
|
|
1377
|
+
(onValueChanged)="handleValueChange($event)"
|
|
1378
|
+
type="text"
|
|
1379
|
+
name="full"
|
|
1380
|
+
[placeholder]="placeholder()"
|
|
1381
|
+
[ngClass]="generateClasses('value')"
|
|
1382
|
+
[disabled]="disabled()"
|
|
1383
|
+
>
|
|
1384
|
+
@for (validation of validationRules(); track $index) {
|
|
1385
|
+
<ax-validation-rule
|
|
1386
|
+
[rule]="validation.rule"
|
|
1387
|
+
[message]="validation.options?.message"
|
|
1388
|
+
[options]="validation.options"
|
|
1389
|
+
></ax-validation-rule>
|
|
1390
|
+
}
|
|
1391
|
+
</ax-text-box>
|
|
1392
|
+
</div>
|
|
1393
|
+
} @else if (addressMode() === 'expandable') {
|
|
1394
|
+
<div class="w-full">
|
|
1395
|
+
<ax-accordion-group>
|
|
1396
|
+
<ax-accordion-item
|
|
1397
|
+
[headerTemplate]="collapseHeaderTemplate"
|
|
1398
|
+
[isCollapsed]="collapsibleCollapsed()"
|
|
1399
|
+
(isCollapsedChange)="onCollapsedChange($event)"
|
|
1400
|
+
>
|
|
1401
|
+
<div class="pt-1">
|
|
1402
|
+
@for (formKey of [layoutRendererGeneration()]; track formKey) {
|
|
1403
|
+
<axp-layout-renderer
|
|
1404
|
+
[layout]="addressFormLayout()"
|
|
1405
|
+
[context]="collapsibleFormContext()"
|
|
1406
|
+
(contextChange)="onCollapsibleFormContextChange($event)"
|
|
1407
|
+
/>
|
|
1408
|
+
}
|
|
1409
|
+
</div>
|
|
1410
|
+
</ax-accordion-item>
|
|
1411
|
+
</ax-accordion-group>
|
|
1412
|
+
</div>
|
|
1413
|
+
|
|
1414
|
+
<ng-template #collapseHeaderTemplate>
|
|
1415
|
+
<div class="ax-accordion-header-container">
|
|
1416
|
+
<div class="ax-accordion-header-start">
|
|
1417
|
+
<span
|
|
1418
|
+
class="ax-accordion-header-icon fa-light fa-map-marker-alt"
|
|
1419
|
+
></span>
|
|
1420
|
+
<span>
|
|
1421
|
+
@if (collapsibleHeaderLabel()) {
|
|
1422
|
+
<span class="font-semibold">{{
|
|
1423
|
+
collapsibleHeaderLabel()
|
|
1424
|
+
}}</span>
|
|
1425
|
+
@if (collapsibleHeaderAddress()) {
|
|
1426
|
+
<span> · {{ collapsibleHeaderAddress() }}</span>
|
|
1427
|
+
}
|
|
1428
|
+
} @else {
|
|
1429
|
+
{{ collapsibleHeaderAddress() }}
|
|
1430
|
+
}
|
|
1431
|
+
</span>
|
|
1432
|
+
</div>
|
|
1433
|
+
<div class="ax-accordion-header-end">
|
|
1434
|
+
<span
|
|
1435
|
+
class="ax-icon ax-icon-chevron-left ax-accordion-arrow"
|
|
1436
|
+
[class]="collapsibleCollapsed() ? '-rotation-90' : 'rotation-90'"
|
|
1437
|
+
></span>
|
|
1438
|
+
</div>
|
|
1439
|
+
</div>
|
|
1440
|
+
</ng-template>
|
|
1441
|
+
} @else {
|
|
1442
|
+
<div class="grid grid-cols-12 gap-4 auto-cols-max">
|
|
1443
|
+
<div class="flex items-center gap-2 col-span-12">
|
|
1444
|
+
<ax-text-box
|
|
1445
|
+
[ngModel]="formattedAddress()"
|
|
1446
|
+
type="text"
|
|
1447
|
+
[readonly]="true"
|
|
1448
|
+
[placeholder]="placeholder()"
|
|
1449
|
+
class="flex-1"
|
|
1450
|
+
[disabled]="disabled()"
|
|
1451
|
+
>
|
|
1452
|
+
<ax-prefix>
|
|
1453
|
+
<ax-icon icon="fa-light fa-map-marker-alt" />
|
|
1454
|
+
</ax-prefix>
|
|
1455
|
+
<ax-suffix>
|
|
1456
|
+
<ax-button
|
|
1457
|
+
look="flat"
|
|
1458
|
+
size="sm"
|
|
1459
|
+
[disabled]="disabled()"
|
|
1460
|
+
(onClick)="showDetailsPopup()"
|
|
1461
|
+
>
|
|
1462
|
+
<ax-icon icon="fa-light fa-cog" />
|
|
1463
|
+
</ax-button>
|
|
1464
|
+
</ax-suffix>
|
|
1465
|
+
</ax-text-box>
|
|
1466
|
+
</div>
|
|
1467
|
+
</div>
|
|
1468
|
+
}
|
|
1469
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: CommonModule }, { kind: "directive", type: i1.NgClass, selector: "[ngClass]", inputs: ["class", "ngClass"] }, { kind: "ngmodule", type: FormsModule }, { kind: "directive", type: i2.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i2.NgModel, selector: "[ngModel]:not([formControlName]):not([formControl])", inputs: ["name", "disabled", "ngModel", "ngModelOptions"], outputs: ["ngModelChange"], exportAs: ["ngModel"] }, { kind: "ngmodule", type: AXFormModule }, { kind: "directive", type: i3.AXValidationRuleDirective, selector: "ax-validation-rule", inputs: ["rule", "options", "message", "disabled"] }, { kind: "ngmodule", type: AXDecoratorModule }, { kind: "component", type: i4.AXDecoratorIconComponent, selector: "ax-icon", inputs: ["icon"] }, { kind: "component", type: i4.AXDecoratorGenericComponent, selector: "ax-footer, ax-header, ax-content, ax-divider, ax-form-hint, ax-prefix, ax-suffix, ax-text, ax-title, ax-subtitle, ax-placeholder, ax-overlay" }, { kind: "ngmodule", type: AXTextBoxModule }, { kind: "component", type: i5.AXTextBoxComponent, selector: "ax-text-box", inputs: ["disabled", "tabIndex", "readonly", "value", "state", "name", "id", "placeholder", "maxLength", "allowNull", "type", "autoComplete", "look", "maskPattern", "customTokens", "class"], outputs: ["onBlur", "onFocus", "valueChange", "stateChange", "onValueChanged", "readonlyChange", "disabledChange", "onKeyDown", "onKeyUp", "onKeyPress", "onMaskChanged"] }, { kind: "ngmodule", type: AXValidationModule }, { kind: "ngmodule", type: AXTranslationModule }, { kind: "ngmodule", type: AXButtonModule }, { kind: "component", type: i6.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: AXAccordionModule }, { kind: "component", type: i7.AXAccordionItemComponent, selector: "ax-accordion-item", inputs: ["isCollapsed", "icon", "textdecoration", "caption", "isLoading", "headerTemplate", "look", "disabled"], outputs: ["isCollapsedChange", "isLoadingChange", "onClick"] }, { kind: "component", type: i7.AXAccordionGroupComponent, selector: "ax-accordion-group", inputs: ["accordion", "activeIndex", "look", "collapsedOnItemClick"], outputs: ["activeIndexChange"] }, { kind: "component", type: AXPLayoutRendererComponent, selector: "axp-layout-renderer", inputs: ["layout", "context", "look", "mode"], outputs: ["contextChange", "contextInitiated", "validityChange"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1470
|
+
}
|
|
1471
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetEditComponent, decorators: [{
|
|
1472
|
+
type: Component,
|
|
1473
|
+
args: [{
|
|
1474
|
+
selector: 'axp-address-widget-edit',
|
|
1475
|
+
template: `
|
|
1476
|
+
@if (addressMode() === 'simple') {
|
|
1477
|
+
<div class="grid grid-cols-12 gap-4 auto-cols-max">
|
|
1478
|
+
<ax-text-box
|
|
1479
|
+
[ngModel]="valueAsObject().full"
|
|
1480
|
+
(onValueChanged)="handleValueChange($event)"
|
|
1481
|
+
type="text"
|
|
1482
|
+
name="full"
|
|
1483
|
+
[placeholder]="placeholder()"
|
|
1484
|
+
[ngClass]="generateClasses('value')"
|
|
1485
|
+
[disabled]="disabled()"
|
|
1486
|
+
>
|
|
1487
|
+
@for (validation of validationRules(); track $index) {
|
|
1488
|
+
<ax-validation-rule
|
|
1489
|
+
[rule]="validation.rule"
|
|
1490
|
+
[message]="validation.options?.message"
|
|
1491
|
+
[options]="validation.options"
|
|
1492
|
+
></ax-validation-rule>
|
|
1493
|
+
}
|
|
1494
|
+
</ax-text-box>
|
|
1495
|
+
</div>
|
|
1496
|
+
} @else if (addressMode() === 'expandable') {
|
|
1497
|
+
<div class="w-full">
|
|
1498
|
+
<ax-accordion-group>
|
|
1499
|
+
<ax-accordion-item
|
|
1500
|
+
[headerTemplate]="collapseHeaderTemplate"
|
|
1501
|
+
[isCollapsed]="collapsibleCollapsed()"
|
|
1502
|
+
(isCollapsedChange)="onCollapsedChange($event)"
|
|
1503
|
+
>
|
|
1504
|
+
<div class="pt-1">
|
|
1505
|
+
@for (formKey of [layoutRendererGeneration()]; track formKey) {
|
|
1506
|
+
<axp-layout-renderer
|
|
1507
|
+
[layout]="addressFormLayout()"
|
|
1508
|
+
[context]="collapsibleFormContext()"
|
|
1509
|
+
(contextChange)="onCollapsibleFormContextChange($event)"
|
|
1510
|
+
/>
|
|
1511
|
+
}
|
|
1512
|
+
</div>
|
|
1513
|
+
</ax-accordion-item>
|
|
1514
|
+
</ax-accordion-group>
|
|
1515
|
+
</div>
|
|
1516
|
+
|
|
1517
|
+
<ng-template #collapseHeaderTemplate>
|
|
1518
|
+
<div class="ax-accordion-header-container">
|
|
1519
|
+
<div class="ax-accordion-header-start">
|
|
1520
|
+
<span
|
|
1521
|
+
class="ax-accordion-header-icon fa-light fa-map-marker-alt"
|
|
1522
|
+
></span>
|
|
1523
|
+
<span>
|
|
1524
|
+
@if (collapsibleHeaderLabel()) {
|
|
1525
|
+
<span class="font-semibold">{{
|
|
1526
|
+
collapsibleHeaderLabel()
|
|
1527
|
+
}}</span>
|
|
1528
|
+
@if (collapsibleHeaderAddress()) {
|
|
1529
|
+
<span> · {{ collapsibleHeaderAddress() }}</span>
|
|
1530
|
+
}
|
|
1531
|
+
} @else {
|
|
1532
|
+
{{ collapsibleHeaderAddress() }}
|
|
1533
|
+
}
|
|
1534
|
+
</span>
|
|
1535
|
+
</div>
|
|
1536
|
+
<div class="ax-accordion-header-end">
|
|
1537
|
+
<span
|
|
1538
|
+
class="ax-icon ax-icon-chevron-left ax-accordion-arrow"
|
|
1539
|
+
[class]="collapsibleCollapsed() ? '-rotation-90' : 'rotation-90'"
|
|
1540
|
+
></span>
|
|
1541
|
+
</div>
|
|
1542
|
+
</div>
|
|
1543
|
+
</ng-template>
|
|
1544
|
+
} @else {
|
|
1545
|
+
<div class="grid grid-cols-12 gap-4 auto-cols-max">
|
|
1546
|
+
<div class="flex items-center gap-2 col-span-12">
|
|
1547
|
+
<ax-text-box
|
|
1548
|
+
[ngModel]="formattedAddress()"
|
|
1549
|
+
type="text"
|
|
1550
|
+
[readonly]="true"
|
|
1551
|
+
[placeholder]="placeholder()"
|
|
1552
|
+
class="flex-1"
|
|
1553
|
+
[disabled]="disabled()"
|
|
1554
|
+
>
|
|
1555
|
+
<ax-prefix>
|
|
1556
|
+
<ax-icon icon="fa-light fa-map-marker-alt" />
|
|
1557
|
+
</ax-prefix>
|
|
1558
|
+
<ax-suffix>
|
|
1559
|
+
<ax-button
|
|
1560
|
+
look="flat"
|
|
1561
|
+
size="sm"
|
|
1562
|
+
[disabled]="disabled()"
|
|
1563
|
+
(onClick)="showDetailsPopup()"
|
|
1564
|
+
>
|
|
1565
|
+
<ax-icon icon="fa-light fa-cog" />
|
|
1566
|
+
</ax-button>
|
|
1567
|
+
</ax-suffix>
|
|
1568
|
+
</ax-text-box>
|
|
1569
|
+
</div>
|
|
1570
|
+
</div>
|
|
1571
|
+
}
|
|
1572
|
+
`,
|
|
1573
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1574
|
+
imports: [
|
|
1575
|
+
CommonModule,
|
|
1576
|
+
FormsModule,
|
|
1577
|
+
AXFormModule,
|
|
1578
|
+
AXDecoratorModule,
|
|
1579
|
+
AXTextBoxModule,
|
|
1580
|
+
AXValidationModule,
|
|
1581
|
+
AXTranslationModule,
|
|
1582
|
+
AXButtonModule,
|
|
1583
|
+
AXAccordionModule,
|
|
1584
|
+
AXPLayoutRendererComponent,
|
|
1585
|
+
],
|
|
1586
|
+
}]
|
|
1587
|
+
}], propDecorators: { __class: [{
|
|
1588
|
+
type: HostBinding,
|
|
1589
|
+
args: ['class']
|
|
1590
|
+
}] } });
|
|
1591
|
+
|
|
1592
|
+
var addressWidgetEdit_component = /*#__PURE__*/Object.freeze({
|
|
1593
|
+
__proto__: null,
|
|
1594
|
+
AXPAddressWidgetEditComponent: AXPAddressWidgetEditComponent
|
|
1595
|
+
});
|
|
1596
|
+
|
|
1597
|
+
class AXPAddressWidgetViewComponent extends AXPValueWidgetComponent {
|
|
1598
|
+
constructor() {
|
|
1599
|
+
super(...arguments);
|
|
1600
|
+
this.addressService = inject(AXPAddressWidgetService);
|
|
1601
|
+
this.hasLabel = computed(() => this.options()['hasLabel'] ?? false, ...(ngDevMode ? [{ debugName: "hasLabel" }] : /* istanbul ignore next */ []));
|
|
1602
|
+
this.internalValue = computed(() => this.addressService.normalizeAddressData(this.getValue()), ...(ngDevMode ? [{ debugName: "internalValue" }] : /* istanbul ignore next */ []));
|
|
1603
|
+
this.labelText = computed(() => this.internalValue().label?.title?.trim() ?? '', ...(ngDevMode ? [{ debugName: "labelText" }] : /* istanbul ignore next */ []));
|
|
1604
|
+
this.formattedAddress = computed(() => {
|
|
1605
|
+
const value = this.internalValue();
|
|
1606
|
+
return value.full || this.addressService.formatAddress(value);
|
|
1607
|
+
}, ...(ngDevMode ? [{ debugName: "formattedAddress" }] : /* istanbul ignore next */ []));
|
|
1608
|
+
this.hasValue = computed(() => {
|
|
1609
|
+
const rawValue = this.getValue();
|
|
1610
|
+
if (isNull(rawValue))
|
|
1611
|
+
return false;
|
|
1612
|
+
const value = this.addressService.normalizeAddressData(rawValue);
|
|
1613
|
+
return !isEmpty(value.full);
|
|
1614
|
+
}, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
1615
|
+
}
|
|
1616
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetViewComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1617
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPAddressWidgetViewComponent, isStandalone: true, selector: "axp-address-widget-view", usesInheritance: true, ngImport: i0, template: `
|
|
1618
|
+
@if (hasValue()) {
|
|
1619
|
+
<div class="flex gap-2 items-center">
|
|
1620
|
+
<div class="flex gap-2 group items-center justify-center truncate">
|
|
1621
|
+
<span class="truncate">{{ formattedAddress() }}</span>
|
|
1622
|
+
</div>
|
|
1623
|
+
@if (hasLabel() && labelText()) {
|
|
1624
|
+
<div><ax-badge color="primary" [look]="'twotone'" [text]="labelText()"></ax-badge></div>
|
|
1625
|
+
}
|
|
1626
|
+
</div>
|
|
1627
|
+
} @else {
|
|
1628
|
+
<span class="text-muted">---</span>
|
|
1629
|
+
}
|
|
1630
|
+
`, isInline: true, dependencies: [{ kind: "ngmodule", type: FormsModule }, { kind: "ngmodule", type: AXBadgeModule }, { kind: "component", type: i1$1.AXBadgeComponent, selector: "ax-badge", inputs: ["color", "look", "text"] }, { kind: "ngmodule", type: AXDecoratorModule }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1631
|
+
}
|
|
1632
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetViewComponent, decorators: [{
|
|
1633
|
+
type: Component,
|
|
1634
|
+
args: [{
|
|
1635
|
+
selector: 'axp-address-widget-view',
|
|
1636
|
+
template: `
|
|
1637
|
+
@if (hasValue()) {
|
|
1638
|
+
<div class="flex gap-2 items-center">
|
|
1639
|
+
<div class="flex gap-2 group items-center justify-center truncate">
|
|
1640
|
+
<span class="truncate">{{ formattedAddress() }}</span>
|
|
1641
|
+
</div>
|
|
1642
|
+
@if (hasLabel() && labelText()) {
|
|
1643
|
+
<div><ax-badge color="primary" [look]="'twotone'" [text]="labelText()"></ax-badge></div>
|
|
1644
|
+
}
|
|
1645
|
+
</div>
|
|
1646
|
+
} @else {
|
|
1647
|
+
<span class="text-muted">---</span>
|
|
1648
|
+
}
|
|
1649
|
+
`,
|
|
1650
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1651
|
+
imports: [FormsModule, AXBadgeModule, AXDecoratorModule],
|
|
1652
|
+
}]
|
|
1653
|
+
}] });
|
|
1654
|
+
|
|
1655
|
+
var addressWidgetView_component = /*#__PURE__*/Object.freeze({
|
|
1656
|
+
__proto__: null,
|
|
1657
|
+
AXPAddressWidgetViewComponent: AXPAddressWidgetViewComponent
|
|
1658
|
+
});
|
|
1659
|
+
|
|
1660
|
+
class AXPAddressWidgetColumnComponent extends AXPColumnWidgetComponent {
|
|
1661
|
+
constructor() {
|
|
1662
|
+
super(...arguments);
|
|
1663
|
+
this.clipboard = inject(AXPClipBoardService);
|
|
1664
|
+
this.addressService = inject(AXPAddressWidgetService);
|
|
1665
|
+
this.normalizedValue = computed(() => {
|
|
1666
|
+
const raw = this.rawValue;
|
|
1667
|
+
if (!raw)
|
|
1668
|
+
return null;
|
|
1669
|
+
return this.addressService.normalizeAddressData(raw);
|
|
1670
|
+
}, ...(ngDevMode ? [{ debugName: "normalizedValue" }] : /* istanbul ignore next */ []));
|
|
1671
|
+
this.formattedAddress = computed(() => {
|
|
1672
|
+
const value = this.normalizedValue();
|
|
1673
|
+
if (!value)
|
|
1674
|
+
return '';
|
|
1675
|
+
return value.full || this.addressService.formatAddress(value);
|
|
1676
|
+
}, ...(ngDevMode ? [{ debugName: "formattedAddress" }] : /* istanbul ignore next */ []));
|
|
1677
|
+
this.hasValue = computed(() => {
|
|
1678
|
+
const value = this.normalizedValue();
|
|
1679
|
+
if (!value)
|
|
1680
|
+
return false;
|
|
1681
|
+
return !isEmpty(value.full);
|
|
1682
|
+
}, ...(ngDevMode ? [{ debugName: "hasValue" }] : /* istanbul ignore next */ []));
|
|
1683
|
+
}
|
|
1684
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetColumnComponent, deps: null, target: i0.ɵɵFactoryTarget.Component }); }
|
|
1685
|
+
static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.2.9", type: AXPAddressWidgetColumnComponent, isStandalone: true, selector: "axp-address-widget-column", inputs: { rawValue: "rawValue", rowData: "rowData" }, usesInheritance: true, ngImport: i0, template: `
|
|
1686
|
+
@if (hasValue()) {
|
|
1687
|
+
<div class="flex justify-start items-center gap-2 group w-fit">
|
|
1688
|
+
<span class="truncate" [title]="formattedAddress()">{{ formattedAddress() }}</span>
|
|
1689
|
+
<i
|
|
1690
|
+
(click)="clipboard.copy('Address', formattedAddress())"
|
|
1691
|
+
class="fa-solid fa-copy text-neutral-400 dark:hover:text-neutral-100 hover:text-neutral-900 group-hover:visible invisible"
|
|
1692
|
+
></i>
|
|
1693
|
+
</div>
|
|
1694
|
+
} @else {
|
|
1695
|
+
<span class="text-muted">---</span>
|
|
1696
|
+
}
|
|
1697
|
+
`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
|
|
1698
|
+
}
|
|
1699
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXPAddressWidgetColumnComponent, decorators: [{
|
|
1700
|
+
type: Component,
|
|
1701
|
+
args: [{
|
|
1702
|
+
selector: 'axp-address-widget-column',
|
|
1703
|
+
template: `
|
|
1704
|
+
@if (hasValue()) {
|
|
1705
|
+
<div class="flex justify-start items-center gap-2 group w-fit">
|
|
1706
|
+
<span class="truncate" [title]="formattedAddress()">{{ formattedAddress() }}</span>
|
|
1707
|
+
<i
|
|
1708
|
+
(click)="clipboard.copy('Address', formattedAddress())"
|
|
1709
|
+
class="fa-solid fa-copy text-neutral-400 dark:hover:text-neutral-100 hover:text-neutral-900 group-hover:visible invisible"
|
|
1710
|
+
></i>
|
|
1711
|
+
</div>
|
|
1712
|
+
} @else {
|
|
1713
|
+
<span class="text-muted">---</span>
|
|
1714
|
+
}
|
|
1715
|
+
`,
|
|
1716
|
+
changeDetection: ChangeDetectionStrategy.OnPush,
|
|
1717
|
+
inputs: ['rawValue', 'rowData'],
|
|
1718
|
+
}]
|
|
1719
|
+
}] });
|
|
1720
|
+
|
|
1721
|
+
var addressWidgetColumn_component = /*#__PURE__*/Object.freeze({
|
|
1722
|
+
__proto__: null,
|
|
1723
|
+
AXPAddressWidgetColumnComponent: AXPAddressWidgetColumnComponent
|
|
1724
|
+
});
|
|
1725
|
+
|
|
1726
|
+
//#endregion
|
|
1727
|
+
//#region ---- Location Management Widgets Provider ----
|
|
1728
|
+
const LOCATION_WIDGETS = [AXPAddressWidget];
|
|
1729
|
+
/**
|
|
1730
|
+
* Provider for location-management widgets (Address editor).
|
|
1731
|
+
* The address widget lives here because its service depends on `@acorex-platform/framework-client/layout/entity`,
|
|
1732
|
+
* which would otherwise create a circular dependency with `@acorex-platform/framework-client/layout/widgets`.
|
|
1733
|
+
*/
|
|
1734
|
+
class AXMLocationManagementWidgetsProvider {
|
|
1735
|
+
getWidgets() {
|
|
1736
|
+
return LOCATION_WIDGETS;
|
|
1737
|
+
}
|
|
1738
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementWidgetsProvider, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1739
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementWidgetsProvider }); }
|
|
1740
|
+
}
|
|
1741
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementWidgetsProvider, decorators: [{
|
|
1742
|
+
type: Injectable
|
|
1743
|
+
}] });
|
|
1744
|
+
|
|
1745
|
+
class AXMLocationManagementModule {
|
|
1746
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementModule, deps: [], target: i0.ɵɵFactoryTarget.NgModule }); }
|
|
1747
|
+
static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementModule, imports: [CommonModule,
|
|
1748
|
+
AXPWidgetCoreModule] }); }
|
|
1749
|
+
static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementModule, providers: [
|
|
1750
|
+
// Module Manifest Provider
|
|
1751
|
+
{
|
|
1752
|
+
provide: AXP_MODULE_MANIFEST_PROVIDER,
|
|
1753
|
+
useValue: LocationManagementManifest,
|
|
1754
|
+
multi: true,
|
|
1755
|
+
},
|
|
1756
|
+
// Provider references (now using tokens)
|
|
1757
|
+
{
|
|
1758
|
+
provide: AXP_PERMISSION_DEFINITION_PROVIDER,
|
|
1759
|
+
useClass: AXMLocationManagementPermissionDefinitionProvider,
|
|
1760
|
+
multi: true,
|
|
1761
|
+
},
|
|
1762
|
+
{
|
|
1763
|
+
provide: AXP_MENU_PROVIDER,
|
|
1764
|
+
useClass: AXMLocationManagementMenuProvider,
|
|
1765
|
+
multi: true,
|
|
1766
|
+
},
|
|
1767
|
+
{
|
|
1768
|
+
provide: AXP_ENTITY_DEFINITION_LOADER,
|
|
1769
|
+
useClass: AXMLocationManagementEntityProvider,
|
|
1770
|
+
multi: true,
|
|
1771
|
+
},
|
|
1772
|
+
{
|
|
1773
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
1774
|
+
multi: true,
|
|
1775
|
+
useValue: locationAssignmentLocationHydrateMiddleware,
|
|
1776
|
+
},
|
|
1777
|
+
{
|
|
1778
|
+
provide: AXP_SETTING_DEFINITION_PROVIDER,
|
|
1779
|
+
useClass: AXMSettingProvider,
|
|
1780
|
+
multi: true,
|
|
1781
|
+
},
|
|
1782
|
+
{
|
|
1783
|
+
provide: AXP_SEARCH_PROVIDER,
|
|
1784
|
+
useClass: AXMSearchCommandProvider,
|
|
1785
|
+
multi: true,
|
|
1786
|
+
},
|
|
1787
|
+
{
|
|
1788
|
+
provide: AXP_FEATURE_DEFINITION_PROVIDER,
|
|
1789
|
+
useClass: AXMLocationManagementFeatureDefinitionProvider,
|
|
1790
|
+
multi: true,
|
|
1791
|
+
},
|
|
1792
|
+
{
|
|
1793
|
+
provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
|
|
1794
|
+
useClass: AXMGeographicRegionDataSourceDefinition,
|
|
1795
|
+
multi: true,
|
|
1796
|
+
},
|
|
1797
|
+
{
|
|
1798
|
+
provide: AXP_WIDGET_DEFINITION_PROVIDER,
|
|
1799
|
+
useClass: AXMLocationManagementWidgetsProvider,
|
|
1800
|
+
multi: true,
|
|
1801
|
+
},
|
|
1802
|
+
provideCommandSetups([
|
|
1803
|
+
{
|
|
1804
|
+
key: `${RootConfig.module.name}.${RootConfig.entities.locationAssignment.name}:AssignExistingLocation`,
|
|
1805
|
+
command: () => import('./acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs').then((c) => c.AXMLocationAssignmentAssignExistingLocationCommand),
|
|
1806
|
+
},
|
|
1807
|
+
{
|
|
1808
|
+
key: `${RootConfig.module.name}.${RootConfig.entities.locationAssignment.name}:CreateWithNewLocation`,
|
|
1809
|
+
command: () => import('./acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs').then((c) => c.AXMLocationAssignmentCreateWithNewLocationCommand),
|
|
1810
|
+
},
|
|
1811
|
+
]),
|
|
1812
|
+
], imports: [CommonModule,
|
|
1813
|
+
AXPWidgetCoreModule] }); }
|
|
1814
|
+
}
|
|
1815
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementModule, decorators: [{
|
|
1816
|
+
type: NgModule,
|
|
1817
|
+
args: [{
|
|
1818
|
+
imports: [
|
|
1819
|
+
CommonModule,
|
|
1820
|
+
AXPWidgetCoreModule,
|
|
1821
|
+
],
|
|
1822
|
+
exports: [],
|
|
1823
|
+
declarations: [],
|
|
1824
|
+
providers: [
|
|
1825
|
+
// Module Manifest Provider
|
|
1826
|
+
{
|
|
1827
|
+
provide: AXP_MODULE_MANIFEST_PROVIDER,
|
|
1828
|
+
useValue: LocationManagementManifest,
|
|
1829
|
+
multi: true,
|
|
1830
|
+
},
|
|
1831
|
+
// Provider references (now using tokens)
|
|
1832
|
+
{
|
|
1833
|
+
provide: AXP_PERMISSION_DEFINITION_PROVIDER,
|
|
1834
|
+
useClass: AXMLocationManagementPermissionDefinitionProvider,
|
|
1835
|
+
multi: true,
|
|
1836
|
+
},
|
|
1837
|
+
{
|
|
1838
|
+
provide: AXP_MENU_PROVIDER,
|
|
1839
|
+
useClass: AXMLocationManagementMenuProvider,
|
|
1840
|
+
multi: true,
|
|
1841
|
+
},
|
|
1842
|
+
{
|
|
1843
|
+
provide: AXP_ENTITY_DEFINITION_LOADER,
|
|
1844
|
+
useClass: AXMLocationManagementEntityProvider,
|
|
1845
|
+
multi: true,
|
|
1846
|
+
},
|
|
1847
|
+
{
|
|
1848
|
+
provide: AXP_ENTITY_STORAGE_MIDDLEWARE,
|
|
1849
|
+
multi: true,
|
|
1850
|
+
useValue: locationAssignmentLocationHydrateMiddleware,
|
|
1851
|
+
},
|
|
1852
|
+
{
|
|
1853
|
+
provide: AXP_SETTING_DEFINITION_PROVIDER,
|
|
1854
|
+
useClass: AXMSettingProvider,
|
|
1855
|
+
multi: true,
|
|
1856
|
+
},
|
|
1857
|
+
{
|
|
1858
|
+
provide: AXP_SEARCH_PROVIDER,
|
|
1859
|
+
useClass: AXMSearchCommandProvider,
|
|
1860
|
+
multi: true,
|
|
1861
|
+
},
|
|
1862
|
+
{
|
|
1863
|
+
provide: AXP_FEATURE_DEFINITION_PROVIDER,
|
|
1864
|
+
useClass: AXMLocationManagementFeatureDefinitionProvider,
|
|
1865
|
+
multi: true,
|
|
1866
|
+
},
|
|
1867
|
+
{
|
|
1868
|
+
provide: AXP_DATASOURCE_DEFINITION_PROVIDER,
|
|
1869
|
+
useClass: AXMGeographicRegionDataSourceDefinition,
|
|
1870
|
+
multi: true,
|
|
1871
|
+
},
|
|
1872
|
+
{
|
|
1873
|
+
provide: AXP_WIDGET_DEFINITION_PROVIDER,
|
|
1874
|
+
useClass: AXMLocationManagementWidgetsProvider,
|
|
1875
|
+
multi: true,
|
|
1876
|
+
},
|
|
1877
|
+
provideCommandSetups([
|
|
1878
|
+
{
|
|
1879
|
+
key: `${RootConfig.module.name}.${RootConfig.entities.locationAssignment.name}:AssignExistingLocation`,
|
|
1880
|
+
command: () => import('./acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs').then((c) => c.AXMLocationAssignmentAssignExistingLocationCommand),
|
|
1881
|
+
},
|
|
1882
|
+
{
|
|
1883
|
+
key: `${RootConfig.module.name}.${RootConfig.entities.locationAssignment.name}:CreateWithNewLocation`,
|
|
1884
|
+
command: () => import('./acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs').then((c) => c.AXMLocationAssignmentCreateWithNewLocationCommand),
|
|
1885
|
+
},
|
|
1886
|
+
]),
|
|
1887
|
+
]
|
|
1888
|
+
}]
|
|
1889
|
+
}] });
|
|
1890
|
+
|
|
1891
|
+
class AXMLocationManagementService {
|
|
1892
|
+
constructor() {
|
|
1893
|
+
this.entityService = inject(AXPEntityService);
|
|
1894
|
+
this.geographicRegionDataAccessor = this.entityService
|
|
1895
|
+
.withEntity(RootConfig.module.name, RootConfig.entities.geographicRegion.name)
|
|
1896
|
+
.data();
|
|
1897
|
+
}
|
|
1898
|
+
async getCountries() {
|
|
1899
|
+
const result = await this.geographicRegionDataAccessor.query({
|
|
1900
|
+
skip: 0,
|
|
1901
|
+
take: 1000,
|
|
1902
|
+
filter: { field: 'type', operator: { type: 'equal' }, value: 'country' },
|
|
1903
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
1904
|
+
});
|
|
1905
|
+
return result.items.map((m) => ({
|
|
1906
|
+
code: m.code,
|
|
1907
|
+
title: m.title,
|
|
1908
|
+
id: m.id,
|
|
1909
|
+
timezone: m.timezone,
|
|
1910
|
+
}));
|
|
1911
|
+
}
|
|
1912
|
+
async getProvinces(countryId) {
|
|
1913
|
+
const result = await this.geographicRegionDataAccessor.query({
|
|
1914
|
+
skip: 0,
|
|
1915
|
+
take: 1000,
|
|
1916
|
+
filter: { field: 'type', operator: { type: 'equal' }, value: 'state' },
|
|
1917
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
1918
|
+
});
|
|
1919
|
+
return result.items.map((m) => ({
|
|
1920
|
+
code: m.code,
|
|
1921
|
+
title: m.title,
|
|
1922
|
+
id: m.id,
|
|
1923
|
+
timezone: m.timezone,
|
|
1924
|
+
}));
|
|
1925
|
+
}
|
|
1926
|
+
async getCities(filter) {
|
|
1927
|
+
const result = await this.geographicRegionDataAccessor.query({
|
|
1928
|
+
skip: 0,
|
|
1929
|
+
take: 1000,
|
|
1930
|
+
filter: { field: 'type', operator: { type: 'equal' }, value: 'city' },
|
|
1931
|
+
sort: [{ field: 'title', dir: 'asc' }],
|
|
1932
|
+
});
|
|
1933
|
+
return result.items.map((m) => ({
|
|
1934
|
+
code: m.code,
|
|
1935
|
+
title: m.title,
|
|
1936
|
+
id: m.id,
|
|
1937
|
+
timezone: m.timezone,
|
|
1938
|
+
}));
|
|
1939
|
+
}
|
|
1940
|
+
static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
|
|
1941
|
+
static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementService, providedIn: 'root' }); }
|
|
1942
|
+
}
|
|
1943
|
+
i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.2.9", ngImport: i0, type: AXMLocationManagementService, decorators: [{
|
|
1944
|
+
type: Injectable,
|
|
1945
|
+
args: [{
|
|
1946
|
+
providedIn: 'root'
|
|
1947
|
+
}]
|
|
1948
|
+
}] });
|
|
1949
|
+
|
|
1950
|
+
/**
|
|
1951
|
+
* Generated bundle index. Do not edit.
|
|
1952
|
+
*/
|
|
1953
|
+
|
|
1954
|
+
export { AXMLocationManagementEntityProvider, AXMLocationManagementMenuProvider, AXMLocationManagementModule, AXMLocationManagementService, AXMSearchCommandProvider, AXMSettingProvider };
|
|
1955
|
+
//# sourceMappingURL=acorex-platform-module-location-management-client.mjs.map
|