@acorex/platform 19.1.3 → 19.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (157) hide show
  1. package/common/index.d.ts +1 -0
  2. package/common/lib/app/application.types.d.ts +2 -2
  3. package/common/lib/file-storage/file-storage.service.d.ts +13 -0
  4. package/common/lib/file-storage/file-storage.types.d.ts +143 -0
  5. package/common/lib/file-storage/index.d.ts +2 -0
  6. package/common/lib/filters/filters.types.d.ts +2 -1
  7. package/common/lib/settings/setting-definition.provider.d.ts +12 -5
  8. package/common/lib/settings/setting.builder.d.ts +4 -3
  9. package/common/lib/settings/settings.provider.d.ts +2 -7
  10. package/common/lib/settings/settings.service.d.ts +19 -7
  11. package/common/lib/settings/settings.types.d.ts +15 -2
  12. package/common/lib/workflows/common.workflow.d.ts +11 -0
  13. package/core/utils/highlighter.d.ts +1 -1
  14. package/fesm2022/acorex-platform-common.mjs +194 -74
  15. package/fesm2022/acorex-platform-common.mjs.map +1 -1
  16. package/fesm2022/acorex-platform-core.mjs +2 -2
  17. package/fesm2022/acorex-platform-core.mjs.map +1 -1
  18. package/fesm2022/acorex-platform-layout-builder.mjs +290 -456
  19. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  20. package/fesm2022/acorex-platform-layout-designer.mjs +13 -13
  21. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  22. package/fesm2022/acorex-platform-layout-entity.mjs +595 -584
  23. package/fesm2022/acorex-platform-layout-entity.mjs.map +1 -1
  24. package/fesm2022/acorex-platform-layout-filters.mjs +82 -6
  25. package/fesm2022/acorex-platform-layout-filters.mjs.map +1 -1
  26. package/fesm2022/acorex-platform-layout-setting.mjs +73 -91
  27. package/fesm2022/acorex-platform-layout-setting.mjs.map +1 -1
  28. package/fesm2022/acorex-platform-layouts.mjs +3 -4
  29. package/fesm2022/acorex-platform-layouts.mjs.map +1 -1
  30. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-K9B_-q_K.mjs +108 -0
  31. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-K9B_-q_K.mjs.map +1 -0
  32. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-xlBBA76O.mjs +369 -0
  33. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-xlBBA76O.mjs.map +1 -0
  34. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Cd2gxLZt.mjs +87 -0
  35. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-Cd2gxLZt.mjs.map +1 -0
  36. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-6sZdw013.mjs +130 -0
  37. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-6sZdw013.mjs.map +1 -0
  38. package/fesm2022/acorex-platform-themes-default-setting-page.component-BYpCgHZb.mjs +74 -0
  39. package/fesm2022/acorex-platform-themes-default-setting-page.component-BYpCgHZb.mjs.map +1 -0
  40. package/fesm2022/acorex-platform-themes-default-setting-view.component-CdmIphX1.mjs +73 -0
  41. package/fesm2022/acorex-platform-themes-default-setting-view.component-CdmIphX1.mjs.map +1 -0
  42. package/fesm2022/acorex-platform-themes-default.mjs +20 -20
  43. package/fesm2022/acorex-platform-themes-default.mjs.map +1 -1
  44. package/fesm2022/acorex-platform-themes-shared.mjs +288 -81
  45. package/fesm2022/acorex-platform-themes-shared.mjs.map +1 -1
  46. package/fesm2022/{acorex-platform-widgets-checkbox-widget-column.component-05nKV-UV.mjs → acorex-platform-widgets-checkbox-widget-column.component-jeZBOEhl.mjs} +18 -14
  47. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-jeZBOEhl.mjs.map +1 -0
  48. package/fesm2022/{acorex-platform-widgets-checkbox-widget-designer.component-B_Gec5Qf.mjs → acorex-platform-widgets-checkbox-widget-designer.component-D8KErkus.mjs} +3 -3
  49. package/fesm2022/{acorex-platform-widgets-checkbox-widget-designer.component-B_Gec5Qf.mjs.map → acorex-platform-widgets-checkbox-widget-designer.component-D8KErkus.mjs.map} +1 -1
  50. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-DU1niJES.mjs +64 -0
  51. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-DU1niJES.mjs.map +1 -0
  52. package/fesm2022/acorex-platform-widgets.mjs +2306 -549
  53. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  54. package/fesm2022/acorex-platform-workflow.mjs +9 -3
  55. package/fesm2022/acorex-platform-workflow.mjs.map +1 -1
  56. package/layout/builder/lib/builder/builder.module.d.ts +10 -10
  57. package/layout/builder/lib/builder/builder.service.d.ts +9 -10
  58. package/layout/builder/lib/builder/context-store.service.d.ts +33 -0
  59. package/layout/builder/lib/builder/index.d.ts +4 -2
  60. package/layout/builder/lib/builder/widget-catalog.d.ts +1 -1
  61. package/layout/builder/lib/builder/widget-container.component.d.ts +34 -9
  62. package/layout/builder/lib/builder/widget-groups.d.ts +1 -0
  63. package/layout/builder/lib/builder/widget-map.d.ts +48 -0
  64. package/layout/builder/lib/builder/widget-placeholder.component.d.ts +5 -0
  65. package/layout/builder/lib/builder/{widget-renderer.component.directive.d.ts → widget-renderer.directive.d.ts} +27 -1
  66. package/layout/builder/lib/builder/widget-status.types.d.ts +14 -0
  67. package/layout/builder/lib/builder/widget.types.d.ts +45 -55
  68. package/layout/designer/lib/preview/preview-viewer.component.d.ts +2 -2
  69. package/layout/designer/lib/property-viewer/widget-property-viewer.component.d.ts +2 -2
  70. package/layout/entity/lib/entity-master-list.viewmodel.d.ts +7 -2
  71. package/layout/entity/lib/widgets/lookup-widget/lookup-widget-edit.component.d.ts +0 -1
  72. package/layout/filters/lib/filters.viewmodel.d.ts +13 -3
  73. package/layout/setting/lib/convert-setting-data.d.ts +0 -20
  74. package/layout/setting/lib/setting.viewmodel.d.ts +65 -4
  75. package/layouts/lib/admin/entity-layout/entity-details-view/entity-details-view.component.d.ts +15 -5
  76. package/package.json +9 -9
  77. package/themes/default/lib/layouts/base/simple-page/simple-page.layout.d.ts +15 -5
  78. package/themes/default/lib/layouts/entity-layouts/entity-detail-list-view/entity-detail-list-view.component.d.ts +15 -5
  79. package/themes/default/lib/layouts/entity-layouts/entity-master-create-view/entity-master-create-view.component.d.ts +2 -1
  80. package/themes/default/lib/layouts/entity-layouts/entity-master-list-view/entity-master-list-view.component.d.ts +17 -6
  81. package/themes/default/lib/layouts/entity-layouts/entity-master-list-view/list-view-option-filters/list-view-option-filters.component.d.ts +6 -3
  82. package/themes/default/lib/layouts/entity-layouts/entity-master-modify-view/entity-master-modify-view.component.d.ts +2 -1
  83. package/themes/default/lib/layouts/entity-layouts/entity-master-single-view/entity-master-single-view.component.d.ts +15 -5
  84. package/themes/default/lib/layouts/filters-layout/simple-filter-builder/filters-view.component.d.ts +6 -5
  85. package/themes/default/lib/layouts/root-layout/components/header/header.component.d.ts +15 -5
  86. package/themes/default/lib/layouts/root-layout/root-layout.component.d.ts +15 -5
  87. package/themes/default/lib/layouts/setting-layout/setting-page/setting-page.component.d.ts +0 -47
  88. package/themes/default/lib/layouts/setting-layout/setting-view/setting-view.component.d.ts +19 -5
  89. package/themes/shared/index.d.ts +3 -1
  90. package/themes/shared/lib/components/theme-slot.component.d.ts +23 -13
  91. package/themes/shared/lib/palette.provider.d.ts +9 -0
  92. package/themes/shared/lib/setting.keys.d.ts +7 -2
  93. package/themes/shared/lib/setting.provider.d.ts +1 -0
  94. package/themes/shared/lib/shared.module.d.ts +2 -1
  95. package/themes/shared/lib/{services/theme.service.d.ts → theme.service.d.ts} +16 -24
  96. package/themes/shared/lib/theme.types.d.ts +25 -0
  97. package/themes/shared/lib/widgets/theme-color-selection/index.d.ts +2 -0
  98. package/themes/shared/lib/widgets/theme-color-selection/theme-color-selection-widget-edit.component.d.ts +6 -0
  99. package/themes/shared/lib/widgets/theme-color-selection/theme-color-selection-widget.config.d.ts +7 -0
  100. package/widgets/lib/properties/layout.props.d.ts +1 -0
  101. package/widgets/lib/widgets/advance/avatar/avatar-widget-column.component.d.ts +6 -0
  102. package/widgets/lib/widgets/advance/avatar/avatar-widget-designer.component.d.ts +6 -0
  103. package/widgets/lib/widgets/advance/avatar/avatar-widget-edit.component.d.ts +18 -0
  104. package/widgets/lib/widgets/advance/avatar/avatar-widget-print.component.d.ts +6 -0
  105. package/widgets/lib/widgets/advance/avatar/avatar-widget-view.component.d.ts +6 -0
  106. package/widgets/lib/widgets/advance/avatar/avatar-widget.config.d.ts +7 -0
  107. package/widgets/lib/widgets/advance/avatar/index.d.ts +6 -0
  108. package/widgets/lib/widgets/advance/map/map-box-widget-edit.component.d.ts +9 -5
  109. package/widgets/lib/widgets/advance/map/map-box-widget-view.component.d.ts +6 -4
  110. package/widgets/lib/widgets/editors/number/number-box-widget-edit.component.d.ts +1 -7
  111. package/widgets/lib/widgets/editors/select/select-box-widget-edit.component.d.ts +1 -1
  112. package/widgets/lib/widgets/editors/toggle/toggle-widget-edit.component.d.ts +0 -2
  113. package/widgets/lib/widgets/filters/boolean-filter/boolean-filter-widget-edit.component.d.ts +18 -0
  114. package/widgets/lib/widgets/filters/boolean-filter/boolean-filter-widget.config.d.ts +7 -0
  115. package/widgets/lib/widgets/filters/boolean-filter/index.d.ts +2 -0
  116. package/widgets/lib/widgets/filters/date-time-filter/date-time-filter-widget-edit.component.d.ts +20 -0
  117. package/widgets/lib/widgets/filters/date-time-filter/date-time-filter-widget.config.d.ts +7 -0
  118. package/widgets/lib/widgets/filters/date-time-filter/index.d.ts +2 -0
  119. package/widgets/lib/widgets/filters/number-filter/index.d.ts +2 -0
  120. package/widgets/lib/widgets/filters/number-filter/number-filter-widget-edit.component.d.ts +12 -0
  121. package/widgets/lib/widgets/filters/number-filter/number-filter-widget.config.d.ts +7 -0
  122. package/widgets/lib/widgets/filters/operations/operations.component.d.ts +9 -0
  123. package/widgets/lib/widgets/filters/select-filter/index.d.ts +2 -0
  124. package/widgets/lib/widgets/filters/select-filter/select-filter-widget-edit.component.d.ts +16 -0
  125. package/widgets/lib/widgets/filters/select-filter/select-filter-widget.config.d.ts +7 -0
  126. package/widgets/lib/widgets/filters/string-filter/index.d.ts +2 -0
  127. package/widgets/lib/widgets/filters/string-filter/string-filter-widget-edit.component.d.ts +12 -0
  128. package/widgets/lib/widgets/filters/string-filter/string-filter-widget.config.d.ts +7 -0
  129. package/widgets/lib/widgets/index.d.ts +5 -1
  130. package/widgets/lib/widgets/property-editors/border/border-widget-editor.component.d.ts +29 -7
  131. package/widgets/lib/widgets/property-editors/border/index.d.ts +0 -1
  132. package/widgets/lib/widgets/property-editors/flex-options/flex-options-widget-editor.component.d.ts +36 -0
  133. package/widgets/lib/widgets/property-editors/flex-options/flex-options-widget.config.d.ts +7 -0
  134. package/widgets/lib/widgets/property-editors/flex-options/flex-options-widget.type.d.ts +18 -0
  135. package/widgets/lib/widgets/property-editors/flex-options/index.d.ts +3 -0
  136. package/widgets/lib/widgets/property-editors/property-editor-helper.d.ts +82 -0
  137. package/widgets/lib/widgets/property-editors/property-editor.type.d.ts +35 -0
  138. package/widgets/lib/widgets/property-editors/spacing/index.d.ts +0 -1
  139. package/widgets/lib/widgets/property-editors/spacing/spacing-widget-editor.component.d.ts +11 -9
  140. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CSyR4pYp.mjs +0 -108
  141. package/fesm2022/acorex-platform-themes-default-entity-master-create-view.component-CSyR4pYp.mjs.map +0 -1
  142. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-xHWp2Lk-.mjs +0 -368
  143. package/fesm2022/acorex-platform-themes-default-entity-master-list-view.component-xHWp2Lk-.mjs.map +0 -1
  144. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-n7mYNduJ.mjs +0 -87
  145. package/fesm2022/acorex-platform-themes-default-entity-master-modify-view.component-n7mYNduJ.mjs.map +0 -1
  146. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DjyYU0Gy.mjs +0 -130
  147. package/fesm2022/acorex-platform-themes-default-entity-master-single-view.component-DjyYU0Gy.mjs.map +0 -1
  148. package/fesm2022/acorex-platform-themes-default-setting-page.component-6Dd8MGqr.mjs +0 -78
  149. package/fesm2022/acorex-platform-themes-default-setting-page.component-6Dd8MGqr.mjs.map +0 -1
  150. package/fesm2022/acorex-platform-themes-default-setting-view.component-BgiMClew.mjs +0 -58
  151. package/fesm2022/acorex-platform-themes-default-setting-view.component-BgiMClew.mjs.map +0 -1
  152. package/fesm2022/acorex-platform-widgets-checkbox-widget-column.component-05nKV-UV.mjs.map +0 -1
  153. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-BkWcZ4K9.mjs +0 -72
  154. package/fesm2022/acorex-platform-widgets-checkbox-widget-view.component-BkWcZ4K9.mjs.map +0 -1
  155. package/layout/builder/lib/builder/widget-renderer.component.d.ts +0 -48
  156. package/widgets/lib/widgets/property-editors/border/border-widget-type.d.ts +0 -18
  157. package/widgets/lib/widgets/property-editors/spacing/spacing-widget-type.d.ts +0 -16
@@ -1,16 +1,40 @@
1
- import * as i3 from '@acorex/components/skeleton';
1
+ import * as i1$1 from '@acorex/components/skeleton';
2
2
  import { AXSkeletonModule } from '@acorex/components/skeleton';
3
- import * as i2 from '@angular/cdk/portal';
4
- import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
3
+ import { PortalModule } from '@angular/cdk/portal';
5
4
  import * as i1 from '@angular/common';
6
5
  import { CommonModule } from '@angular/common';
7
6
  import * as i0 from '@angular/core';
8
- import { signal, Injectable, InjectionToken, inject, ElementRef, afterNextRender, computed, effect, Injector, Component, ChangeDetectionStrategy, Input, EventEmitter, model, Output, ChangeDetectorRef, ViewChild, input, ViewContainerRef, Directive, NgModule, Optional, Inject } from '@angular/core';
9
- import { AXUnsubscriber } from '@acorex/core/utils';
10
- import { set, get, isEqual, clone, merge, isNil, cloneDeep, isUndefined, sum } from 'lodash-es';
11
- import { Subject, filter } from 'rxjs';
12
- import { convertArrayToDataSource, AXDataSource } from '@acorex/components/common';
7
+ import { signal, computed, Injectable, InjectionToken, inject, ElementRef, effect, Injector, ChangeDetectorRef, Component, ChangeDetectionStrategy, Input, ViewChild, EventEmitter, Output, input, ViewContainerRef, Directive, NgModule, Optional, Inject } from '@angular/core';
13
8
  import { AXDataTableColumnComponent, AXBaseDataTable } from '@acorex/components/data-table';
9
+ import { set, merge, cloneDeep, get, isEqual, isNil, isUndefined, sum } from 'lodash-es';
10
+ import { Subject, BehaviorSubject, filter } from 'rxjs';
11
+ import { convertArrayToDataSource, AXDataSource } from '@acorex/components/common';
12
+ import { signalStore, withState, withComputed, withMethods, patchState } from '@ngrx/signals';
13
+ import { AXUnsubscriber } from '@acorex/core/utils';
14
+
15
+ var AXPPageStatus;
16
+ (function (AXPPageStatus) {
17
+ // Rendering statuses
18
+ AXPPageStatus["Rendering"] = "rendering";
19
+ AXPPageStatus["Rendered"] = "rendered";
20
+ // Processing statuses
21
+ AXPPageStatus["Processing"] = "processing";
22
+ // Submission statuses
23
+ AXPPageStatus["Submitting"] = "submitting";
24
+ AXPPageStatus["Submitted"] = "submitted";
25
+ // Error handling
26
+ AXPPageStatus["Error"] = "error";
27
+ })(AXPPageStatus || (AXPPageStatus = {}));
28
+ var AXPWidgetStatus;
29
+ (function (AXPWidgetStatus) {
30
+ // Rendering statuses
31
+ AXPWidgetStatus["Rendering"] = "rendering";
32
+ AXPWidgetStatus["Rendered"] = "rendered";
33
+ // Processing statuses
34
+ AXPWidgetStatus["Processing"] = "processing";
35
+ // Error handling
36
+ AXPWidgetStatus["Error"] = "error";
37
+ })(AXPWidgetStatus || (AXPWidgetStatus = {}));
14
38
 
15
39
  class AXPLayoutElement {
16
40
  api() {
@@ -19,15 +43,15 @@ class AXPLayoutElement {
19
43
  }
20
44
  class AXPLayoutBuilderService {
21
45
  constructor() {
22
- this.context$ = signal({});
23
46
  this.variables$ = signal({});
24
47
  this.functions$ = signal({});
25
- this.onChanged = new Subject();
26
48
  this.onRefresh = new Subject();
27
- this.debouncers = {};
28
- this.debouncerSubscriptions = {};
29
49
  this.widgets = new Map();
30
- this.context = this.context$.asReadonly();
50
+ this.status$ = signal(AXPPageStatus.Rendering);
51
+ this.status = this.status$.asReadonly();
52
+ this.isBusy = computed(() => {
53
+ return [AXPPageStatus.Processing, AXPPageStatus.Submitting, AXPPageStatus.Rendering].includes(this.status());
54
+ });
31
55
  }
32
56
  get variables() {
33
57
  return this.variables$();
@@ -35,15 +59,36 @@ class AXPLayoutBuilderService {
35
59
  get functions() {
36
60
  return this.functions$();
37
61
  }
38
- initial(value) {
39
- this.context$.set(value);
40
- this.refresh();
62
+ updateStatus() {
63
+ this.status$.update(() => this.detectStatus());
64
+ }
65
+ detectStatus() {
66
+ const statuses = Array.from(this.widgets.values()).map(c => c.status());
67
+ // Rendering statuses
68
+ if (statuses.some((status) => status === AXPWidgetStatus.Rendering)) {
69
+ return AXPPageStatus.Rendering;
70
+ }
71
+ if (statuses.every((status) => status === AXPWidgetStatus.Rendered)) {
72
+ return AXPPageStatus.Rendered;
73
+ }
74
+ // Processing statuses
75
+ if (statuses.some((status) => status === AXPWidgetStatus.Processing)) {
76
+ return AXPPageStatus.Processing;
77
+ }
78
+ // Error handling
79
+ if (statuses.some((status) => status === AXPWidgetStatus.Error)) {
80
+ return AXPPageStatus.Error;
81
+ }
82
+ return AXPPageStatus.Rendered; // Default to Loaded when all widgets are in a completed state
41
83
  }
42
84
  refresh() {
43
85
  setTimeout(() => {
44
86
  this.onRefresh.next();
45
87
  }, 0);
46
88
  }
89
+ setStatus(status) {
90
+ this.status$.set(status);
91
+ }
47
92
  setVariables(...args) {
48
93
  if (args.length == 0)
49
94
  return;
@@ -62,57 +107,13 @@ class AXPLayoutBuilderService {
62
107
  this.functions$.update((v) => set(v, args[0], args[1]));
63
108
  }
64
109
  }
65
- setValue(path, value, init = false) {
66
- const oldValue = get(this.context$(), path);
67
- if (isEqual(oldValue, value)) {
68
- return;
69
- }
70
- // if (!this.debouncers[path]) {
71
- // // Create a new Subject for debouncing if it doesn't exist
72
- // this.debouncers[path] = new Subject<{ path: string; value: any; init: boolean }>();
73
- // // Subscribe to the subject with debounceTime
74
- // this.debouncerSubscriptions[path] = this.debouncers[path].pipe(debounceTime(150)).subscribe(({ value, init }) => {
75
- // // Only emit onChanged event after debounce time
76
- // this.onChanged.next({
77
- // oldValue: oldValue,
78
- // newValue: value,
79
- // data: this.context(),
80
- // path,
81
- // init,
82
- // });
83
- // });
84
- // }
85
- // Update context immediately
86
- this.context$.update((ctx) => set(clone(ctx), path, value));
87
- //
88
- this.onChanged.next({
89
- oldValue: oldValue,
90
- newValue: value,
91
- data: this.context(),
92
- path,
93
- init,
94
- });
95
- // Emit value through the debouncer subject
96
- //this.debouncers[path].next({ path, value, init });
97
- }
98
- getValue(path) {
99
- return get(this.context(), path);
100
- }
101
110
  registerWidget(id, widget) {
102
111
  this.widgets.set(id, widget);
103
112
  }
104
113
  getWidget(id) {
105
114
  return this.widgets.get(id);
106
115
  }
107
- unsubscribeDebouncers() {
108
- Object.keys(this.debouncerSubscriptions).forEach((path) => {
109
- this.debouncerSubscriptions[path].unsubscribe();
110
- delete this.debouncerSubscriptions[path]; // Clean up the reference
111
- delete this.debouncers[path]; // Also clean up the debouncer subject
112
- });
113
- }
114
116
  ngOnDestroy() {
115
- this.unsubscribeDebouncers();
116
117
  }
117
118
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderService, deps: [], target: i0.ɵɵFactoryTarget.Injectable }); }
118
119
  static { this.ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderService }); }
@@ -154,6 +155,101 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
154
155
  }]
155
156
  }] });
156
157
 
158
+ class AXPLayoutContextChangeEvent {
159
+ }
160
+ const AXPLayoutBuilderContextStore = signalStore(
161
+ // Initial State
162
+ withState(() => ({
163
+ data: {}, // Shared context data
164
+ state: 'initiated', // Current state
165
+ initialSnapshot: {}, // Snapshot of the first initialized state
166
+ previousSnapshot: {}, // Snapshot of the previous state
167
+ lastChange: {
168
+ state: 'initiated',
169
+ }, // Last change event
170
+ })),
171
+ // Computed Signals
172
+ withComputed(({ data, state, lastChange, initialSnapshot, previousSnapshot }) => ({
173
+ isChanged: computed(() => state() === 'changed'),
174
+ isReset: computed(() => state() === 'restored'),
175
+ isInitiated: computed(() => state() === 'initiated'),
176
+ isEmpty: computed(() => Object.keys(data()).length === 0),
177
+ snapshot: computed(() => cloneDeep(data())), // Current data snapshot
178
+ initial: computed(() => cloneDeep(initialSnapshot())), // Initial snapshot
179
+ previous: computed(() => cloneDeep(previousSnapshot())), // Previous snapshot
180
+ changeEvent: computed(() => lastChange()), // Reactive last change event
181
+ })),
182
+ // Methods for State Management
183
+ withMethods((store) => ({
184
+ // Update a specific value
185
+ update(path, value) {
186
+ const currentData = cloneDeep(store.data());
187
+ const oldValue = get(currentData, path);
188
+ // Skip if the value hasn't changed
189
+ if (isEqual(oldValue, value)) {
190
+ return;
191
+ }
192
+ // Update the value and prepare the change event
193
+ const updatedData = set(currentData, path, value);
194
+ const changeEvent = {
195
+ oldValue,
196
+ newValue: value,
197
+ path,
198
+ state: 'changed',
199
+ data: updatedData,
200
+ };
201
+ // Patch the state
202
+ patchState(store, {
203
+ previousSnapshot: store.snapshot(), // Save the previous state
204
+ data: updatedData,
205
+ state: 'changed',
206
+ lastChange: changeEvent,
207
+ });
208
+ },
209
+ // Reset to the initial state
210
+ reset() {
211
+ const initialData = store.initial();
212
+ const changeEvent = {
213
+ oldValue: cloneDeep(store.data()), // Current data becomes old value
214
+ newValue: cloneDeep(initialData), // Reset to the initial state
215
+ path: '',
216
+ state: 'restored',
217
+ data: initialData,
218
+ };
219
+ patchState(store, {
220
+ previousSnapshot: store.snapshot(), // Save the previous state
221
+ data: initialData,
222
+ state: 'restored',
223
+ lastChange: changeEvent,
224
+ });
225
+ },
226
+ // Initialize the state
227
+ set(initialData) {
228
+ const currentData = store.data();
229
+ if (isEqual(currentData, initialData)) {
230
+ return; // Skip if the current state matches the initial state
231
+ }
232
+ const changeEvent = {
233
+ oldValue: null,
234
+ newValue: cloneDeep(initialData),
235
+ path: '',
236
+ state: 'initiated',
237
+ data: initialData,
238
+ };
239
+ patchState(store, {
240
+ initialSnapshot: cloneDeep(initialData), // Save the initial state
241
+ previousSnapshot: store.snapshot(), // Save the current state as the previous
242
+ data: initialData,
243
+ state: 'initiated',
244
+ lastChange: changeEvent,
245
+ });
246
+ },
247
+ // Get a specific value
248
+ getValue(path) {
249
+ return get(store.data(), path);
250
+ },
251
+ })));
252
+
157
253
  const AXP_WIDGET_DATASOURCE_PROVIDER = new InjectionToken('AXP_WIDGET_DATASOURCE_PROVIDER');
158
254
  class AXPWidgetDataSourceProviderService {
159
255
  constructor() {
@@ -217,6 +313,15 @@ const AXPWidgetsCatalog = {
217
313
  cronJob: 'cron-job',
218
314
  spacing: 'spacing',
219
315
  border: 'border',
316
+ avatar: 'avatar',
317
+ stringFilter: 'string-filter',
318
+ themeColorSelection: 'theme-color-selection',
319
+ numberFilter: 'number-filter',
320
+ dateTimeFilter: 'datetime-filter',
321
+ booleanFilter: 'boolean-filter',
322
+ lookupFilter: 'lookup-filter',
323
+ flexOptions: 'flex-options',
324
+ selectFilter: 'select-filter',
220
325
  };
221
326
 
222
327
  function objectKeyValueTransforms(keyName) {
@@ -230,7 +335,7 @@ function objectKeyValueTransforms(keyName) {
230
335
  if (isNil(value))
231
336
  return undefined;
232
337
  return typeof value == 'object' ? value[keyName] : value;
233
- }
338
+ },
234
339
  };
235
340
  }
236
341
  function cloneProperty(property, values) {
@@ -310,22 +415,18 @@ class AXPWidgetComponent extends AXPLayoutElement {
310
415
  this.children = this._children.asReadonly();
311
416
  this._options = signal(this.token.options ?? {});
312
417
  this.options = this._options.asReadonly();
313
- this.contextService = inject(AXPLayoutBuilderService);
314
- this.onReady = new Subject();
315
- this.isRendered = false;
418
+ this.layoutService = inject(AXPLayoutBuilderService);
419
+ this.contextService = inject(AXPLayoutBuilderContextStore);
316
420
  this._isValueWidget = false;
317
421
  this.isValueWidget = () => this._isValueWidget;
318
- this.fullPath = signal(null);
319
- this.nextRender = afterNextRender(() => {
320
- //
321
- if (!this.isRendered) {
322
- this.detectFullPath();
323
- //
324
- this.onReady.next();
325
- //
326
- this.isRendered = true;
327
- }
422
+ this._status = signal(AXPWidgetStatus.Rendering);
423
+ this.status = this._status.asReadonly();
424
+ this.onStatusChanged = new BehaviorSubject(this._status());
425
+ this.#statusEffect = effect(() => {
426
+ this.onStatusChanged.next(this.status());
328
427
  });
428
+ this.isBusy = computed(() => [AXPWidgetStatus.Rendering, AXPWidgetStatus.Processing].includes(this.status()));
429
+ this.fullPath = signal(null);
329
430
  this.getValue = computed(() => {
330
431
  return this.fullPath() ? this.extractValue(this.fullPath()) : null;
331
432
  });
@@ -333,33 +434,32 @@ class AXPWidgetComponent extends AXPLayoutElement {
333
434
  get id() {
334
435
  return this._id;
335
436
  }
437
+ #statusEffect;
336
438
  outputs() {
337
439
  return [];
338
440
  }
339
441
  ngOnInit() {
340
- this.initRender();
341
- }
342
- initRender() {
343
442
  this._isValueWidget = this.config.properties?.some((c) => c.name == 'path') ?? false;
344
443
  if (this.isValueWidget()) {
345
444
  this.detectFullPath();
346
445
  if (!isNil(this.defaultValue) && isNil(this.getValue())) {
347
- this.setValue(this.defaultValue, true);
446
+ this.setValue(this.defaultValue);
348
447
  }
349
448
  }
350
449
  //
351
450
  if (get(this.node, '__meta__.added')) {
352
451
  this.onAdded();
353
452
  }
453
+ this.setStatus(AXPWidgetStatus.Rendered);
354
454
  }
355
455
  extractValue(path) {
356
- const rawValue = get(this.contextService.context(), path);
456
+ const rawValue = this.contextService.getValue(path);
357
457
  if (this.node.valueTransforms?.getter) {
358
458
  return this.node.valueTransforms?.getter(rawValue);
359
459
  }
360
460
  return rawValue;
361
461
  }
362
- setValue(value, init = false) {
462
+ setValue(value) {
363
463
  if (this.node.valueTransforms?.setter) {
364
464
  value = this.node.valueTransforms?.setter(value);
365
465
  }
@@ -372,9 +472,12 @@ class AXPWidgetComponent extends AXPLayoutElement {
372
472
  return;
373
473
  }
374
474
  if (this.fullPath()) {
375
- this.contextService.setValue(this.fullPath(), value, init);
475
+ this.contextService.update(this.fullPath(), value);
376
476
  }
377
- this.onValueChanged(oldValue, value, init);
477
+ }
478
+ setStatus(status) {
479
+ this._status.set(status);
480
+ this.layoutService.updateStatus();
378
481
  }
379
482
  setOptions(values) {
380
483
  this._options.set({ ...this.options(), ...values });
@@ -397,7 +500,6 @@ class AXPWidgetComponent extends AXPLayoutElement {
397
500
  setChildren(children) {
398
501
  this._children.set([...children]);
399
502
  }
400
- onValueChanged(oldValue, newValue, init = false) { }
401
503
  onAdded() { }
402
504
  detectFullPath() {
403
505
  const sections = [];
@@ -427,7 +529,7 @@ class AXPWidgetComponent extends AXPLayoutElement {
427
529
  this.fullPath.set(sections.reverse().join('.'));
428
530
  this._id = this.name || this.parent ? ids.reverse().join('_') : null;
429
531
  if (this._id) {
430
- this.contextService.registerWidget(this._id, this);
532
+ this.layoutService.registerWidget(this._id, this);
431
533
  }
432
534
  }
433
535
  handleValueChanged(e) {
@@ -508,358 +610,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
508
610
  type: Injectable
509
611
  }] });
510
612
 
511
- class AXPWidgetRendererComponent {
512
- get node() {
513
- return this._node;
514
- }
515
- set node(v) {
516
- this._node = v;
517
- this.loadComponent();
518
- }
519
- get mode() {
520
- return this._mode;
521
- }
522
- set mode(v) {
523
- this._mode = v;
524
- }
525
- constructor() {
526
- this._mode = 'edit';
527
- this.mergedOptions = signal({});
528
- this.injector = inject(Injector);
529
- this.builderService = inject(AXPLayoutBuilderService);
530
- this.widgetRegistery = inject(AXPWidgetRegistryService);
531
- this.unsubscriber = inject(AXUnsubscriber);
532
- this.isLoading = signal(true);
533
- this.expressionCache = new Map();
534
- this.expressionEvaluators = new Map();
535
- this.scope = null;
536
- this.builderService.onChanged.pipe(this.unsubscriber.takeUntilDestroy).subscribe(async (e) => {
537
- if ((await this.updateOptionsBasedOnContext()) > 0) {
538
- this.applyOptions();
539
- }
540
- if (this.checkFormulaForUpdate(this.node.formula, e.path)) {
541
- await this.updateValueBasedOnFormula();
542
- }
543
- });
544
- }
545
- async loadComponent() {
546
- this.isLoading.set(true);
547
- const widget = this.widgetRegistery.resolve(this.node.type);
548
- //
549
- const props = widget?.components[this.mode]?.properties
550
- ?.filter((c) => c.schema.defaultValue != null)
551
- .map((c) => ({ [c.name]: c.schema.defaultValue }))
552
- .reduce((acc, curr) => {
553
- return { ...acc, ...curr };
554
- }, {});
555
- //
556
- this.mergedOptions.set(merge(props, this.node.options) || {});
557
- this.preprocessAndInitialOptions(cloneDeep(this.node.options));
558
- await this.updateOptionsBasedOnContext();
559
- const tokenValue = {
560
- node: this.node,
561
- options: this.mergedOptions(),
562
- config: widget,
563
- };
564
- const token = Injector.create({
565
- parent: this.injector,
566
- providers: [
567
- {
568
- provide: AXP_WIDGET_TOKEN,
569
- useValue: tokenValue,
570
- },
571
- ],
572
- });
573
- var com = await widget?.components[this.mode]?.component();
574
- this.portal = new ComponentPortal(com, null, token);
575
- this.isLoading.set(false);
576
- }
577
- async handleAttached(portalOutletRef) {
578
- portalOutletRef = portalOutletRef;
579
- this.instance = portalOutletRef.instance;
580
- this.instance.parent = this.parentNode;
581
- this.instance.index = this.index;
582
- this.instance.mode = this.mode;
583
- await this.updateValueBasedOnFormula();
584
- await this.assignTriggers();
585
- }
586
- applyOptions() {
587
- if (!this.instance)
588
- return;
589
- this.instance.setOptions(this.mergedOptions());
590
- }
591
- checkFormulaForUpdate(formula, path) {
592
- if (formula) {
593
- const regex = /context\.eval\('([^']+)'\)/g;
594
- const matches = formula.match(regex);
595
- const nodes = matches ? matches.map((match) => match.match(/'([^']+)'/)[1]) : [];
596
- return nodes.includes(path);
597
- }
598
- else
599
- return false;
600
- }
601
- preprocessAndInitialOptions(obj, pathPrefix = '') {
602
- if (!obj)
603
- return;
604
- Object.entries(obj).forEach(([key, value]) => {
605
- const currentPath = pathPrefix ? `${pathPrefix}.${key}` : key;
606
- if (typeof value === 'string' && value.includes('{{')) {
607
- // Cache dynamic expression for later evaluation
608
- this.expressionEvaluators.set(currentPath, () => this.evaluateExpression(value));
609
- }
610
- else if (typeof value === 'object' &&
611
- value !== null &&
612
- (value.constructor === Object || Array.isArray(value))) {
613
- // Recursively handle nested objects
614
- this.preprocessAndInitialOptions(value, currentPath);
615
- }
616
- else {
617
- // Apply static values directly
618
- this.mergedOptions.update((currentOptions) => {
619
- return set(currentOptions, currentPath, value);
620
- });
621
- }
622
- });
623
- }
624
- async updateOptionsBasedOnContext() {
625
- const updates = [];
626
- for (let [path, evaluator] of this.expressionEvaluators) {
627
- const newValue = await evaluator();
628
- updates.push({ path, newValue });
629
- }
630
- // Apply updates to mergedOptions
631
- if (updates.length > 0) {
632
- this.mergedOptions.update((o) => {
633
- const updatedOptions = { ...o };
634
- updates.forEach(({ path, newValue }) => {
635
- // Set the new value in the updatedOptions object by path
636
- set(updatedOptions, path, newValue); // Assuming 'set' can handle paths like 'property.subproperty'
637
- });
638
- return updatedOptions;
639
- });
640
- }
641
- return updates.length;
642
- }
643
- async updateValueBasedOnFormula() {
644
- if (this.node.formula) {
645
- const value = await this.evaluateExpression(this.node.formula);
646
- this.instance.setValue(value);
647
- }
648
- }
649
- async evaluateExpression(templateExpression) {
650
- try {
651
- // Check cache first, but cache the function for evaluation, not the evaluated value
652
- if (!this.expressionCache.has(templateExpression)) {
653
- const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
654
- if (!expressionMatch) {
655
- throw Error(`No valid expression found in "${templateExpression}"`);
656
- }
657
- const expression = expressionMatch[1];
658
- // Cache the evaluation function instead of the result
659
- const scope = this.getGlobalScope();
660
- const evaluationFunction = async () => {
661
- const sandbox = new Function('scope', `with (scope) { return (async function() { return ${expression}; })(); }`);
662
- return await sandbox(scope);
663
- };
664
- this.expressionCache.set(templateExpression, evaluationFunction);
665
- }
666
- // Retrieve the function from the cache and call it to evaluate the expression
667
- const evaluate = this.expressionCache.get(templateExpression);
668
- if (evaluate) {
669
- const result = await evaluate();
670
- return result;
671
- }
672
- else {
673
- throw Error(`Failed to retrieve evaluation function for expression: "${templateExpression}"`);
674
- }
675
- }
676
- catch (error) {
677
- console.error('Error evaluating expression:', error);
678
- return false;
679
- }
680
- }
681
- getGlobalScope() {
682
- if (this.scope)
683
- return this.scope;
684
- this.scope = {};
685
- set(this.scope, 'context', this.getContextScope());
686
- set(this.scope, 'events', this.getEventScope());
687
- set(this.scope, 'widget', this.getWidgetScope());
688
- set(this.scope, 'methods', this.getFunctionScope());
689
- set(this.scope, 'vars', this.getVariablesScope());
690
- return this.scope;
691
- }
692
- getContextScope() {
693
- const scope = {};
694
- set(scope, 'eval', (path) => this.builderService.getValue(path));
695
- return scope;
696
- }
697
- getEventScope() {
698
- const scope = {};
699
- set(scope, 'context', (path) => this.builderService.onChanged.pipe(filter((c) => c.path == path)));
700
- set(scope, 'from', (event) => get(this.instance.api(), event));
701
- return scope;
702
- }
703
- getWidgetScope() {
704
- const scope = {};
705
- set(scope, 'call', (name, ...args) => {
706
- this.instance.call(name, ...args);
707
- });
708
- set(scope, 'find', (id) => {
709
- return this.builderService.getWidget(id)?.api();
710
- });
711
- return scope;
712
- }
713
- getFunctionScope() {
714
- const scope = {};
715
- set(scope, 'sum', (values) => {
716
- return sum(values);
717
- });
718
- Object.entries(this.builderService.functions).forEach((i) => {
719
- set(scope, i[0], (...args) => {
720
- return i[1](...args);
721
- });
722
- });
723
- return scope;
724
- }
725
- getVariablesScope() {
726
- const scope = {};
727
- set(scope, 'eval', (path) => get(this.builderService.variables, path));
728
- return scope;
729
- }
730
- async assignTriggers() {
731
- this.node.triggers?.forEach((t) => {
732
- const event = this.evaluateTrigger(t.event);
733
- event?.pipe(this.unsubscriber.takeUntilDestroy).subscribe((c) => {
734
- this.evaluateAction(t.action);
735
- });
736
- });
737
- }
738
- evaluateTrigger(templateExpression) {
739
- try {
740
- const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
741
- if (!expressionMatch) {
742
- throw Error(`No valid expression found in "${templateExpression}"`);
743
- }
744
- const expression = expressionMatch[1];
745
- // Cache the evaluation function instead of the result
746
- const scope = this.getGlobalScope();
747
- const sandbox = new Function('scope', `with (scope) { return ( function() { return ${expression}; })(); }`);
748
- return sandbox(scope);
749
- }
750
- catch (error) {
751
- console.error('Error evaluating expression:', error);
752
- return null;
753
- }
754
- }
755
- evaluateAction(templateExpression) {
756
- try {
757
- const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
758
- if (!expressionMatch) {
759
- throw Error(`No valid expression found in "${templateExpression}"`);
760
- }
761
- const expression = expressionMatch[1];
762
- // Cache the evaluation function instead of the result
763
- const scope = this.getGlobalScope();
764
- const sandbox = new Function('scope', `with (scope) { ${expression} }`);
765
- sandbox(scope);
766
- }
767
- catch (error) {
768
- console.error('Error evaluating expression:', error);
769
- }
770
- }
771
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetRendererComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
772
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "19.0.3", type: AXPWidgetRendererComponent, isStandalone: false, selector: "axp-widget-renderer", inputs: { node: "node", mode: "mode", parentNode: "parentNode", index: "index" }, providers: [
773
- {
774
- provide: AXUnsubscriber,
775
- },
776
- ], ngImport: i0, template: `
777
- @if(mergedOptions().isVisible!=false) { @if(isLoading()){
778
- <ax-skeleton [animated]="true" class="ax-w-full lg:ax-w-[50%] ax-h-8 ax-rounded"></ax-skeleton>
779
- } @else {
780
- <ng-container *ngTemplateOutlet="tt"></ng-container>
781
- } }
782
- <ng-template #tt>
783
- <ng-template [cdkPortalOutlet]="portal" (attached)="handleAttached($event)"></ng-template>
784
- </ng-template>
785
- `, isInline: true, dependencies: [{ kind: "directive", type: i1.NgTemplateOutlet, selector: "[ngTemplateOutlet]", inputs: ["ngTemplateOutletContext", "ngTemplateOutlet", "ngTemplateOutletInjector"] }, { kind: "directive", type: i2.CdkPortalOutlet, selector: "[cdkPortalOutlet]", inputs: ["cdkPortalOutlet"], outputs: ["attached"], exportAs: ["cdkPortalOutlet"] }, { kind: "component", type: i3.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
786
- }
787
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetRendererComponent, decorators: [{
788
- type: Component,
789
- args: [{
790
- selector: 'axp-widget-renderer',
791
- template: `
792
- @if(mergedOptions().isVisible!=false) { @if(isLoading()){
793
- <ax-skeleton [animated]="true" class="ax-w-full lg:ax-w-[50%] ax-h-8 ax-rounded"></ax-skeleton>
794
- } @else {
795
- <ng-container *ngTemplateOutlet="tt"></ng-container>
796
- } }
797
- <ng-template #tt>
798
- <ng-template [cdkPortalOutlet]="portal" (attached)="handleAttached($event)"></ng-template>
799
- </ng-template>
800
- `,
801
- changeDetection: ChangeDetectionStrategy.OnPush,
802
- providers: [
803
- {
804
- provide: AXUnsubscriber,
805
- },
806
- ],
807
- standalone: false
808
- }]
809
- }], ctorParameters: () => [], propDecorators: { node: [{
810
- type: Input,
811
- args: [{ required: true }]
812
- }], mode: [{
813
- type: Input
814
- }], parentNode: [{
815
- type: Input
816
- }], index: [{
817
- type: Input
818
- }] } });
819
-
820
- class AXPWidgetContainerComponent {
821
- constructor() {
822
- this.onChanged = new EventEmitter();
823
- this.context = model({});
824
- this.unsubscriber = inject(AXUnsubscriber);
825
- this.builderService = inject(AXPLayoutBuilderService);
826
- this.ef = effect(() => {
827
- this.builderService.initial(this.context());
828
- });
829
- }
830
- set variables(v) {
831
- this.builderService.setVariables(v);
832
- }
833
- set functions(v) {
834
- this.builderService.setFunctions(v);
835
- }
836
- ngOnInit() {
837
- this.builderService.onChanged.pipe(this.unsubscriber.takeUntilDestroy).subscribe((e) => {
838
- this.context.set(e.data);
839
- this.onChanged.emit(e);
840
- });
841
- }
842
- static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
843
- static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.1.0", version: "19.0.3", type: AXPWidgetContainerComponent, isStandalone: false, selector: "axp-widgets-container", inputs: { context: { classPropertyName: "context", publicName: "context", isSignal: true, isRequired: false, transformFunction: null }, variables: { classPropertyName: "variables", publicName: "variables", isSignal: false, isRequired: false, transformFunction: null }, functions: { classPropertyName: "functions", publicName: "functions", isSignal: false, isRequired: false, transformFunction: null } }, outputs: { onChanged: "onChanged", context: "contextChange" }, host: { styleAttribute: "display: contents;" }, providers: [AXPLayoutBuilderService, AXUnsubscriber], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
844
- }
845
- i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetContainerComponent, decorators: [{
846
- type: Component,
847
- args: [{
848
- selector: 'axp-widgets-container',
849
- template: `<ng-content></ng-content>`,
850
- changeDetection: ChangeDetectionStrategy.OnPush,
851
- host: { style: 'display: contents;' },
852
- providers: [AXPLayoutBuilderService, AXUnsubscriber],
853
- standalone: false
854
- }]
855
- }], propDecorators: { onChanged: [{
856
- type: Output
857
- }], variables: [{
858
- type: Input
859
- }], functions: [{
860
- type: Input
861
- }] } });
862
-
863
613
  class AXPWidgetColumnRendererComponent extends AXDataTableColumnComponent {
864
614
  constructor() {
865
615
  super(...arguments);
@@ -1027,6 +777,69 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
1027
777
  args: ['header']
1028
778
  }] } });
1029
779
 
780
+ class AXPWidgetContainerComponent {
781
+ set context(value) {
782
+ this.contextService.set(value);
783
+ }
784
+ set functions(v) {
785
+ this.builderService.setFunctions(v);
786
+ }
787
+ constructor() {
788
+ this.contextService = inject(AXPLayoutBuilderContextStore);
789
+ this.builderService = inject(AXPLayoutBuilderService);
790
+ this.onContextChanged = new EventEmitter();
791
+ this.status = computed(() => {
792
+ return this.builderService.status();
793
+ });
794
+ this.isBusy = computed(() => {
795
+ return this.builderService.isBusy();
796
+ });
797
+ effect(() => {
798
+ if (this.contextService.isChanged()) {
799
+ this.onContextChanged.emit(this.contextService.changeEvent());
800
+ }
801
+ });
802
+ }
803
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetContainerComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
804
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPWidgetContainerComponent, isStandalone: false, selector: "axp-widgets-container", inputs: { context: "context", functions: "functions" }, outputs: { onContextChanged: "onContextChanged" }, host: { styleAttribute: "display: contents;" }, providers: [AXPLayoutBuilderService, AXPLayoutBuilderContextStore], ngImport: i0, template: `<ng-content></ng-content>`, isInline: true, changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
805
+ }
806
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetContainerComponent, decorators: [{
807
+ type: Component,
808
+ args: [{
809
+ selector: 'axp-widgets-container',
810
+ template: `<ng-content></ng-content>`,
811
+ changeDetection: ChangeDetectionStrategy.OnPush,
812
+ host: { style: 'display: contents;' },
813
+ providers: [AXPLayoutBuilderService, AXPLayoutBuilderContextStore],
814
+ standalone: false,
815
+ }]
816
+ }], ctorParameters: () => [], propDecorators: { onContextChanged: [{
817
+ type: Output
818
+ }], context: [{
819
+ type: Input
820
+ }], functions: [{
821
+ type: Input
822
+ }] } });
823
+
824
+ class AXPWidgetPlaceholderComponent {
825
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetPlaceholderComponent, deps: [], target: i0.ɵɵFactoryTarget.Component }); }
826
+ static { this.ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "14.0.0", version: "19.0.3", type: AXPWidgetPlaceholderComponent, isStandalone: true, selector: "axp-widget-placeholder", ngImport: i0, template: `<div>
827
+ <ax-skeleton class="ax-w-full ax-h-10 ax-rounded-md"></ax-skeleton>
828
+ </div>`, isInline: true, dependencies: [{ kind: "ngmodule", type: AXSkeletonModule }, { kind: "component", type: i1$1.AXSkeletonComponent, selector: "ax-skeleton", inputs: ["animated"] }], changeDetection: i0.ChangeDetectionStrategy.OnPush }); }
829
+ }
830
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPWidgetPlaceholderComponent, decorators: [{
831
+ type: Component,
832
+ args: [{
833
+ selector: 'axp-widget-placeholder',
834
+ template: `<div>
835
+ <ax-skeleton class="ax-w-full ax-h-10 ax-rounded-md"></ax-skeleton>
836
+ </div>`,
837
+ changeDetection: ChangeDetectionStrategy.OnPush,
838
+ imports: [AXSkeletonModule],
839
+ standalone: true,
840
+ }]
841
+ }] });
842
+
1030
843
  class AXPWidgetRendererDirective {
1031
844
  constructor() {
1032
845
  this.parentNode = input();
@@ -1038,6 +851,7 @@ class AXPWidgetRendererDirective {
1038
851
  this.mergedOptions = signal({});
1039
852
  this.injector = inject(Injector);
1040
853
  this.builderService = inject(AXPLayoutBuilderService);
854
+ this.contextService = inject(AXPLayoutBuilderContextStore);
1041
855
  this.widgetRegistery = inject(AXPWidgetRegistryService);
1042
856
  this.unsubscriber = inject(AXUnsubscriber);
1043
857
  this.viewContainerRef = inject(ViewContainerRef);
@@ -1045,13 +859,19 @@ class AXPWidgetRendererDirective {
1045
859
  this.expressionCache = new Map();
1046
860
  this.expressionEvaluators = new Map();
1047
861
  this.scope = null;
1048
- this.builderService.onChanged.pipe(this.unsubscriber.takeUntilDestroy).subscribe(async (e) => {
862
+ this.onContextChanged = new Subject();
863
+ effect(async () => {
864
+ const changed = this.contextService.changeEvent();
1049
865
  if ((await this.updateOptionsBasedOnContext()) > 0) {
1050
866
  this.applyOptions();
1051
867
  }
1052
- if (this.checkFormulaForUpdate(this.node().formula, e.path)) {
868
+ if (this.checkFormulaForUpdate(this.node().formula, changed.path)) {
1053
869
  await this.updateValueBasedOnFormula();
1054
870
  }
871
+ //
872
+ if (changed.path) {
873
+ this.onContextChanged.next({ path: changed.path });
874
+ }
1055
875
  });
1056
876
  this.builderService.onRefresh.pipe(this.unsubscriber.takeUntilDestroy).subscribe(async () => {
1057
877
  if ((await this.updateOptionsBasedOnContext()) > 0) {
@@ -1099,7 +919,7 @@ class AXPWidgetRendererDirective {
1099
919
  return { ...acc, ...curr };
1100
920
  }, {});
1101
921
  //
1102
- this.mergedOptions.set(merge(props, this.node().options) || {});
922
+ this.mergedOptions.set(merge(props, widget?.options, this.node().options) || {});
1103
923
  this.preprocessAndInitialOptions(cloneDeep(this.node().options));
1104
924
  await this.updateOptionsBasedOnContext();
1105
925
  //
@@ -1120,16 +940,22 @@ class AXPWidgetRendererDirective {
1120
940
  ],
1121
941
  });
1122
942
  //
943
+ const loadingRef = this.viewContainerRef.createComponent(AXPWidgetPlaceholderComponent);
944
+ //
1123
945
  const com = await widget?.components[this.mode()]?.component();
1124
946
  this.componentRef = this.viewContainerRef.createComponent(com, { injector: token });
1125
947
  this.instance = this.componentRef.instance;
948
+ this.instance.setStatus(AXPWidgetStatus.Rendering);
1126
949
  this.instance.parent = this.parentNode();
1127
950
  this.instance.index = this.index();
1128
951
  this.instance.mode = this.mode();
952
+ this.instance.setStatus(AXPWidgetStatus.Rendered);
1129
953
  await this.updateValueBasedOnFormula();
1130
954
  await this.assignTriggers();
1131
955
  //
956
+ loadingRef.destroy();
1132
957
  this.isLoading.set(false);
958
+ //
1133
959
  }
1134
960
  applyOptions() {
1135
961
  if (!this.instance)
@@ -1242,15 +1068,15 @@ class AXPWidgetRendererDirective {
1242
1068
  }
1243
1069
  getContextScope() {
1244
1070
  const scope = {};
1245
- set(scope, 'eval', (path) => this.builderService.getValue(path));
1071
+ set(scope, 'eval', (path) => this.contextService.getValue(path));
1246
1072
  set(scope, 'set', (path, value) => {
1247
- this.builderService.setValue(path, value);
1073
+ this.contextService.update(path, value);
1248
1074
  });
1249
1075
  return scope;
1250
1076
  }
1251
1077
  getEventScope() {
1252
1078
  const scope = {};
1253
- set(scope, 'context', (path) => this.builderService.onChanged.pipe(filter((c) => c.path == path)));
1079
+ set(scope, 'context', (path) => this.onContextChanged.pipe(filter((c) => c.path == path)));
1254
1080
  set(scope, 'from', (event) => get(this.instance.api(), event));
1255
1081
  return scope;
1256
1082
  }
@@ -1345,11 +1171,11 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImpor
1345
1171
  provide: AXUnsubscriber,
1346
1172
  },
1347
1173
  ],
1348
- standalone: false
1174
+ standalone: false,
1349
1175
  }]
1350
1176
  }], ctorParameters: () => [] });
1351
1177
 
1352
- const COMPONENTS = [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective];
1178
+ const COMPONENTS = [AXPWidgetContainerComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective];
1353
1179
  class AXPLayoutBuilderModule {
1354
1180
  static forRoot(config) {
1355
1181
  return {
@@ -1357,13 +1183,14 @@ class AXPLayoutBuilderModule {
1357
1183
  providers: [
1358
1184
  {
1359
1185
  provide: 'AXPLayoutBuilderModuleFactory',
1360
- useFactory: (registry) => () => {
1361
- config?.widgets?.forEach(w => registry.register(w));
1186
+ useFactory: (registry) => async () => {
1187
+ await Promise.all(config?.widgets?.map((w) => Promise.resolve(registry.register(w))) || []);
1188
+ await Promise.all(config?.extendedWidgets?.map((ew) => Promise.resolve(registry.extend(ew.parentName, ew.widget))) || []);
1362
1189
  },
1363
1190
  deps: [AXPWidgetRegistryService],
1364
- multi: true
1191
+ multi: true,
1365
1192
  },
1366
- ]
1193
+ ],
1367
1194
  };
1368
1195
  }
1369
1196
  static forChild(config) {
@@ -1372,25 +1199,26 @@ class AXPLayoutBuilderModule {
1372
1199
  providers: [
1373
1200
  {
1374
1201
  provide: 'AXPLayoutBuilderModuleFactory',
1375
- useFactory: (registry) => () => {
1376
- config?.widgets?.forEach(w => registry.register(w));
1202
+ useFactory: (registry) => async () => {
1203
+ await Promise.all(config?.widgets?.map((w) => Promise.resolve(registry.register(w))) || []);
1204
+ await Promise.all(config?.extendedWidgets?.map((ew) => Promise.resolve(registry.extend(ew.parentName, ew.widget))) || []);
1377
1205
  },
1378
1206
  deps: [AXPWidgetRegistryService],
1379
- multi: true
1380
- }
1381
- ]
1207
+ multi: true,
1208
+ },
1209
+ ],
1382
1210
  };
1383
1211
  }
1384
1212
  /**
1385
1213
  * @ignore
1386
1214
  */
1387
1215
  constructor(instances) {
1388
- instances?.forEach(f => {
1216
+ instances?.forEach((f) => {
1389
1217
  f();
1390
1218
  });
1391
1219
  }
1392
1220
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderModule, deps: [{ token: 'AXPLayoutBuilderModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
1393
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderModule, declarations: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective], imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule], exports: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective] }); }
1221
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderModule, declarations: [AXPWidgetContainerComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective], imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule], exports: [AXPWidgetContainerComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective] }); }
1394
1222
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderModule, imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule] }); }
1395
1223
  }
1396
1224
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "19.0.3", ngImport: i0, type: AXPLayoutBuilderModule, decorators: [{
@@ -1427,16 +1255,22 @@ const AXP_WIDGETS_ADVANCE_GROUP = {
1427
1255
  order: 4,
1428
1256
  title: 'Advance',
1429
1257
  };
1258
+ const AXP_WIDGETS_FILTER_GROUP = {
1259
+ name: 'filter',
1260
+ order: 5,
1261
+ title: 'Filters',
1262
+ };
1430
1263
  const AXP_WIDGETS_GROUPS = [
1431
1264
  AXP_WIDGETS_EDITOR_GROUP,
1432
1265
  AXP_WIDGETS_ACTION_GROUP,
1433
1266
  AXP_WIDGETS_LAYOUT_GROUP,
1434
1267
  AXP_WIDGETS_ADVANCE_GROUP,
1268
+ AXP_WIDGETS_FILTER_GROUP,
1435
1269
  ];
1436
1270
 
1437
1271
  /**
1438
1272
  * Generated bundle index. Do not edit.
1439
1273
  */
1440
1274
 
1441
- export { AXPColumnWidgetComponent, AXPDataListWidgetComponent, AXPLayoutBuilderModule, AXPLayoutBuilderService, AXPLayoutElement, AXPWidgetColumnRendererComponent, AXPWidgetComponent, AXPWidgetContainerComponent, AXPWidgetDataSourceProviderService, AXPWidgetRegistryService, AXPWidgetRendererComponent, AXPWidgetRendererDirective, AXPWidgetsCatalog, AXP_WIDGETS_ACTION_GROUP, AXP_WIDGETS_ADVANCE_GROUP, AXP_WIDGETS_EDITOR_GROUP, AXP_WIDGETS_GROUPS, AXP_WIDGETS_LAYOUT_GROUP, AXP_WIDGET_COLUMN_TOKEN, AXP_WIDGET_DATASOURCE_PROVIDER, AXP_WIDGET_TOKEN, cloneProperty, createBooleanProperty, createSelectProperty, createStringProperty, objectKeyValueTransforms };
1275
+ export { AXPColumnWidgetComponent, AXPDataListWidgetComponent, AXPLayoutBuilderContextStore, AXPLayoutBuilderModule, AXPLayoutBuilderService, AXPLayoutContextChangeEvent, AXPLayoutElement, AXPPageStatus, AXPWidgetColumnRendererComponent, AXPWidgetComponent, AXPWidgetContainerComponent, AXPWidgetDataSourceProviderService, AXPWidgetRegistryService, AXPWidgetRendererDirective, AXPWidgetStatus, AXPWidgetsCatalog, AXP_WIDGETS_ACTION_GROUP, AXP_WIDGETS_ADVANCE_GROUP, AXP_WIDGETS_EDITOR_GROUP, AXP_WIDGETS_FILTER_GROUP, AXP_WIDGETS_GROUPS, AXP_WIDGETS_LAYOUT_GROUP, AXP_WIDGET_COLUMN_TOKEN, AXP_WIDGET_DATASOURCE_PROVIDER, AXP_WIDGET_TOKEN, cloneProperty, createBooleanProperty, createSelectProperty, createStringProperty, objectKeyValueTransforms };
1442
1276
  //# sourceMappingURL=acorex-platform-layout-builder.mjs.map