@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.
Files changed (60) hide show
  1. package/fesm2022/acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs +164 -0
  2. package/fesm2022/acorex-platform-module-location-management-client-assign-existing-location-to-party.command-DmpN-yas.mjs.map +1 -0
  3. package/fesm2022/acorex-platform-module-location-management-client-contracts.mjs +2694 -0
  4. package/fesm2022/acorex-platform-module-location-management-client-contracts.mjs.map +1 -0
  5. package/fesm2022/acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs +201 -0
  6. package/fesm2022/acorex-platform-module-location-management-client-create-location-with-assignment.command-D6VXtZRf.mjs.map +1 -0
  7. package/fesm2022/acorex-platform-module-location-management-client.mjs +1955 -0
  8. package/fesm2022/acorex-platform-module-location-management-client.mjs.map +1 -0
  9. package/package.json +21 -5
  10. package/types/acorex-platform-module-location-management-client-contracts.d.ts +274 -0
  11. package/types/acorex-platform-module-location-management-client.d.ts +53 -0
  12. package/contracts/datasource.keys.d.ts +0 -6
  13. package/contracts/datasource.keys.js +0 -8
  14. package/contracts/entities/geographic-region/geographic-region.entity.d.ts +0 -2
  15. package/contracts/entities/geographic-region/geographic-region.entity.js +0 -725
  16. package/contracts/entities/geographic-region/geographic-region.types.d.ts +0 -27
  17. package/contracts/entities/geographic-region/geographic-region.types.js +0 -1
  18. package/contracts/entities/geographic-region/index.d.ts +0 -2
  19. package/contracts/entities/geographic-region/index.js +0 -2
  20. package/contracts/entities/index.d.ts +0 -5
  21. package/contracts/entities/index.js +0 -5
  22. package/contracts/entities/location/index.d.ts +0 -2
  23. package/contracts/entities/location/index.js +0 -2
  24. package/contracts/entities/location/location.entity.d.ts +0 -2
  25. package/contracts/entities/location/location.entity.js +0 -1075
  26. package/contracts/entities/location/location.types.d.ts +0 -30
  27. package/contracts/entities/location/location.types.js +0 -1
  28. package/contracts/entities/location-assignment/index.d.ts +0 -2
  29. package/contracts/entities/location-assignment/index.js +0 -2
  30. package/contracts/entities/location-assignment/location-assignment.entity.d.ts +0 -2
  31. package/contracts/entities/location-assignment/location-assignment.entity.js +0 -194
  32. package/contracts/entities/location-assignment/location-assignment.types.d.ts +0 -35
  33. package/contracts/entities/location-assignment/location-assignment.types.js +0 -2
  34. package/contracts/entities/location-role/index.d.ts +0 -2
  35. package/contracts/entities/location-role/index.js +0 -2
  36. package/contracts/entities/location-role/location-role.entity.d.ts +0 -2
  37. package/contracts/entities/location-role/location-role.entity.js +0 -143
  38. package/contracts/entities/location-role/location-role.types.d.ts +0 -6
  39. package/contracts/entities/location-role/location-role.types.js +0 -1
  40. package/contracts/entities/location-type/index.d.ts +0 -2
  41. package/contracts/entities/location-type/index.js +0 -2
  42. package/contracts/entities/location-type/location-type.entity.d.ts +0 -2
  43. package/contracts/entities/location-type/location-type.entity.js +0 -237
  44. package/contracts/entities/location-type/location-type.types.d.ts +0 -8
  45. package/contracts/entities/location-type/location-type.types.js +0 -1
  46. package/contracts/features.keys.d.ts +0 -1
  47. package/contracts/features.keys.js +0 -2
  48. package/contracts/index.d.ts +0 -8
  49. package/contracts/index.js +0 -10
  50. package/contracts/location-assignment.actions.d.ts +0 -8
  51. package/contracts/location-assignment.actions.js +0 -73
  52. package/contracts/location-assignment.utils.d.ts +0 -53
  53. package/contracts/location-assignment.utils.js +0 -145
  54. package/contracts/menu.keys.d.ts +0 -8
  55. package/contracts/menu.keys.js +0 -8
  56. package/contracts/package.json +0 -5
  57. package/contracts/permission.keys.d.ts +0 -33
  58. package/contracts/permission.keys.js +0 -42
  59. package/contracts/root-config.d.ts +0 -42
  60. 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