@acorex/platform 18.1.0 → 18.1.1

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 (50) hide show
  1. package/esm2022/layout/builder/lib/builder/builder.module.mjs +4 -3
  2. package/esm2022/layout/builder/lib/builder/index.mjs +2 -1
  3. package/esm2022/layout/builder/lib/builder/widget-renderer.component.directive.mjs +280 -0
  4. package/esm2022/layout/designer/lib/designer/components/board/board.component.mjs +3 -3
  5. package/esm2022/layout/designer/lib/designer/components/header-menu/header-menu.component.mjs +3 -3
  6. package/esm2022/layout/designer/lib/designer/designer.component.mjs +9 -5
  7. package/esm2022/layout/designer/lib/designer/shared/designer.service.mjs +21 -21
  8. package/esm2022/layout/designer/lib/designer/shared/designer.typs.mjs +6 -2
  9. package/esm2022/themes/default/lib/layouts/entity-layouts/entity-master-single-view/overview/entity-single-overview.component.mjs +3 -3
  10. package/esm2022/widgets/lib/widgets/actions/button/button-widget-designer.component.mjs +3 -3
  11. package/esm2022/widgets/lib/widgets/actions/button/button-widget-view.component.mjs +3 -3
  12. package/esm2022/widgets/lib/widgets/advance/map/map-box-widget-view.component.mjs +3 -3
  13. package/esm2022/widgets/lib/widgets/editors/contact/contact-widget-edit.component.mjs +9 -9
  14. package/esm2022/widgets/lib/widgets/editors/contact/contact-widget-view.component.mjs +6 -6
  15. package/esm2022/widgets/lib/widgets/editors/rich-text/rich-text-widget-view.component.mjs +5 -3
  16. package/esm2022/widgets/lib/widgets/editors/select/select-box-widget-column.component.mjs +36 -6
  17. package/esm2022/widgets/lib/widgets/editors/selection-list/selection-list-widget-column.component.mjs +2 -1
  18. package/esm2022/widgets/lib/widgets/layout/block/block-widget-view.component.mjs +4 -4
  19. package/esm2022/widgets/lib/widgets/layout/form-field/form-field-widget-view.component.mjs +28 -16
  20. package/esm2022/widgets/lib/widgets/layout/grid/grid-widget-designer.component.mjs +37 -31
  21. package/esm2022/widgets/lib/widgets/layout/grid/grid-widget-view.component.mjs +27 -6
  22. package/esm2022/widgets/lib/widgets/layout/grid-item/grid-item-widget-designer.component.mjs +32 -26
  23. package/esm2022/widgets/lib/widgets/layout/grid-item/grid-item-widget-view.component.mjs +82 -8
  24. package/esm2022/widgets/lib/widgets/layout/grid-row/grid-row-widget-view.component.mjs +27 -6
  25. package/esm2022/widgets/lib/widgets/layout/page/page-widget-view.component.mjs +6 -4
  26. package/fesm2022/acorex-platform-layout-builder.mjs +276 -4
  27. package/fesm2022/acorex-platform-layout-builder.mjs.map +1 -1
  28. package/fesm2022/acorex-platform-layout-designer.mjs +36 -28
  29. package/fesm2022/acorex-platform-layout-designer.mjs.map +1 -1
  30. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-CGhOE3jO.mjs → acorex-platform-themes-default-entity-master-single-view.component-B9lGgO_u.mjs} +3 -3
  31. package/fesm2022/{acorex-platform-themes-default-entity-master-single-view.component-CGhOE3jO.mjs.map → acorex-platform-themes-default-entity-master-single-view.component-B9lGgO_u.mjs.map} +1 -1
  32. package/fesm2022/acorex-platform-themes-default.mjs +2 -2
  33. package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-COvuxaTt.mjs → acorex-platform-widgets-button-widget-designer.component-Oxpdaz9P.mjs} +3 -3
  34. package/fesm2022/{acorex-platform-widgets-button-widget-designer.component-COvuxaTt.mjs.map → acorex-platform-widgets-button-widget-designer.component-Oxpdaz9P.mjs.map} +1 -1
  35. package/fesm2022/acorex-platform-widgets.mjs +277 -107
  36. package/fesm2022/acorex-platform-widgets.mjs.map +1 -1
  37. package/layout/builder/lib/builder/builder.module.d.ts +5 -4
  38. package/layout/builder/lib/builder/index.d.ts +1 -0
  39. package/layout/builder/lib/builder/widget-renderer.component.directive.d.ts +42 -0
  40. package/layout/designer/lib/designer/designer.component.d.ts +1 -0
  41. package/layout/designer/lib/designer/shared/designer.service.d.ts +2 -1
  42. package/layout/designer/lib/designer/shared/designer.typs.d.ts +15 -0
  43. package/package.json +7 -7
  44. package/widgets/lib/widgets/actions/button/button-widget-designer.component.d.ts +1 -1
  45. package/widgets/lib/widgets/actions/button/button-widget-view.component.d.ts +1 -1
  46. package/widgets/lib/widgets/editors/select/select-box-widget-column.component.d.ts +5 -0
  47. package/widgets/lib/widgets/layout/form-field/form-field-widget-view.component.d.ts +2 -1
  48. package/widgets/lib/widgets/layout/grid/grid-widget-view.component.d.ts +3 -0
  49. package/widgets/lib/widgets/layout/grid-item/grid-item-widget-view.component.d.ts +11 -2
  50. package/widgets/lib/widgets/layout/grid-row/grid-row-widget-view.component.d.ts +3 -0
@@ -5,7 +5,7 @@ import { ComponentPortal, PortalModule } from '@angular/cdk/portal';
5
5
  import * as i1 from '@angular/common';
6
6
  import { CommonModule } from '@angular/common';
7
7
  import * as i0 from '@angular/core';
8
- import { signal, Injectable, InjectionToken, inject, ElementRef, computed, afterNextRender, Injector, Component, ChangeDetectionStrategy, Input, EventEmitter, model, effect, Output, ChangeDetectorRef, ViewChild, NgModule, Optional, Inject } from '@angular/core';
8
+ import { signal, Injectable, InjectionToken, inject, ElementRef, computed, afterNextRender, Injector, Component, ChangeDetectionStrategy, Input, EventEmitter, model, effect, Output, ChangeDetectorRef, ViewChild, input, ViewContainerRef, Directive, NgModule, Optional, Inject } from '@angular/core';
9
9
  import { AXUnsubscriber } from '@acorex/core/utils';
10
10
  import { set, get, isEqual, clone, merge, cloneDeep, isUndefined, sum } from 'lodash-es';
11
11
  import { Subject, debounceTime, filter } from 'rxjs';
@@ -741,7 +741,279 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImpor
741
741
  args: ['header']
742
742
  }] } });
743
743
 
744
- const COMPONENTS = [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent];
744
+ class AXPWidgetRendererDirective {
745
+ constructor() {
746
+ this.parentNode = input();
747
+ this.index = input();
748
+ this.mode = input.required();
749
+ this.node = input.required();
750
+ this.mergedOptions = signal({});
751
+ this.injector = inject(Injector);
752
+ this.builderService = inject(AXPLayoutBuilderService);
753
+ this.widgetRegistery = inject(AXPWidgetRegistryService);
754
+ this.unsubscriber = inject(AXUnsubscriber);
755
+ this.viewContainerRef = inject(ViewContainerRef);
756
+ this.isLoading = signal(true);
757
+ this.expressionCache = new Map();
758
+ this.expressionEvaluators = new Map();
759
+ this.scope = null;
760
+ this.builderService.onChanged.pipe(this.unsubscriber.takeUntilDestroy).subscribe(async (e) => {
761
+ if ((await this.updateOptionsBasedOnContext()) > 0) {
762
+ this.applyOptions();
763
+ }
764
+ if (this.checkFormulaForUpdate(this.node().formula, e.path)) {
765
+ await this.updateValueBasedOnFormula();
766
+ }
767
+ });
768
+ //
769
+ effect(async () => {
770
+ await this.loadComponent();
771
+ }, { allowSignalWrites: true });
772
+ }
773
+ async loadComponent() {
774
+ this.isLoading.set(true);
775
+ this.viewContainerRef.clear();
776
+ const widget = this.widgetRegistery.resolve(this.node().type);
777
+ //
778
+ const props = widget?.components[this.mode()]?.properties
779
+ ?.filter((c) => c.schema.defaultValue)
780
+ .map((c) => ({ [c.name]: c.schema.defaultValue }))
781
+ .reduce((acc, curr) => {
782
+ return { ...acc, ...curr };
783
+ }, {});
784
+ //
785
+ this.mergedOptions.set(merge(props, this.node().options) || {});
786
+ this.preprocessAndInitialOptions(cloneDeep(this.node().options));
787
+ await this.updateOptionsBasedOnContext();
788
+ //
789
+ const tokenValue = {
790
+ node: this.node(),
791
+ options: this.mergedOptions(),
792
+ config: widget,
793
+ };
794
+ const token = Injector.create({
795
+ parent: this.injector,
796
+ providers: [
797
+ {
798
+ provide: AXP_WIDGET_TOKEN,
799
+ useValue: tokenValue,
800
+ },
801
+ ],
802
+ });
803
+ //
804
+ var com = await widget?.components[this.mode()]?.component();
805
+ this.instance = this.viewContainerRef.createComponent(com, { injector: token }).instance;
806
+ this.instance.parent = this.parentNode();
807
+ this.instance.index = this.index();
808
+ this.instance.mode = this.mode();
809
+ await this.updateValueBasedOnFormula();
810
+ await this.assignTriggers();
811
+ //
812
+ this.isLoading.set(false);
813
+ }
814
+ applyOptions() {
815
+ if (!this.instance)
816
+ return;
817
+ this.instance.setOptions(this.mergedOptions());
818
+ }
819
+ checkFormulaForUpdate(formula, path) {
820
+ if (formula) {
821
+ const regex = /context\.eval\('([^']+)'\)/g;
822
+ const matches = formula.match(regex);
823
+ const nodes = matches ? matches.map((match) => match.match(/'([^']+)'/)[1]) : [];
824
+ return nodes.includes(path);
825
+ }
826
+ else
827
+ return false;
828
+ }
829
+ preprocessAndInitialOptions(obj, pathPrefix = '') {
830
+ if (!obj)
831
+ return;
832
+ Object.entries(obj).forEach(([key, value]) => {
833
+ const currentPath = pathPrefix ? `${pathPrefix}.${key}` : key;
834
+ if (typeof value === 'string' && value.includes('{{')) {
835
+ // Cache dynamic expression for later evaluation
836
+ this.expressionEvaluators.set(currentPath, () => this.evaluateExpression(value));
837
+ }
838
+ else if (typeof value === 'object' && value !== null && (value.constructor === Object || Array.isArray(value))) {
839
+ // Recursively handle nested objects
840
+ this.preprocessAndInitialOptions(value, currentPath);
841
+ }
842
+ else {
843
+ // Apply static values directly
844
+ this.mergedOptions.update((currentOptions) => {
845
+ return set(currentOptions, currentPath, value);
846
+ });
847
+ }
848
+ });
849
+ }
850
+ async updateOptionsBasedOnContext() {
851
+ const updates = [];
852
+ for (let [path, evaluator] of this.expressionEvaluators) {
853
+ const newValue = await evaluator();
854
+ updates.push({ path, newValue });
855
+ }
856
+ // Apply updates to mergedOptions
857
+ if (updates.length > 0) {
858
+ this.mergedOptions.update((o) => {
859
+ const updatedOptions = { ...o };
860
+ updates.forEach(({ path, newValue }) => {
861
+ // Set the new value in the updatedOptions object by path
862
+ set(updatedOptions, path, newValue); // Assuming 'set' can handle paths like 'property.subproperty'
863
+ });
864
+ return updatedOptions;
865
+ });
866
+ }
867
+ return updates.length;
868
+ }
869
+ async updateValueBasedOnFormula() {
870
+ if (this.node().formula) {
871
+ const value = await this.evaluateExpression(this.node().formula);
872
+ this.instance.setValue(value);
873
+ }
874
+ }
875
+ async evaluateExpression(templateExpression) {
876
+ try {
877
+ // Check cache first, but cache the function for evaluation, not the evaluated value
878
+ if (!this.expressionCache.has(templateExpression)) {
879
+ const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
880
+ if (!expressionMatch) {
881
+ throw Error(`No valid expression found in "${templateExpression}"`);
882
+ }
883
+ const expression = expressionMatch[1];
884
+ // Cache the evaluation function instead of the result
885
+ const scope = this.getGlobalScope();
886
+ const evaluationFunction = async () => {
887
+ const sandbox = new Function('scope', `with (scope) { return (async function() { return ${expression}; })(); }`);
888
+ return await sandbox(scope);
889
+ };
890
+ this.expressionCache.set(templateExpression, evaluationFunction);
891
+ }
892
+ // Retrieve the function from the cache and call it to evaluate the expression
893
+ const evaluate = this.expressionCache.get(templateExpression);
894
+ if (evaluate) {
895
+ const result = await evaluate();
896
+ return result;
897
+ }
898
+ else {
899
+ throw Error(`Failed to retrieve evaluation function for expression: "${templateExpression}"`);
900
+ }
901
+ }
902
+ catch (error) {
903
+ console.error('Error evaluating expression:', error);
904
+ return false;
905
+ }
906
+ }
907
+ getGlobalScope() {
908
+ if (this.scope)
909
+ return this.scope;
910
+ this.scope = {};
911
+ set(this.scope, 'context', this.getContextScope());
912
+ set(this.scope, 'events', this.getEventScope());
913
+ set(this.scope, 'widget', this.getWidgetScope());
914
+ set(this.scope, 'methods', this.getFunctionScope());
915
+ set(this.scope, 'vars', this.getVariablesScope());
916
+ return this.scope;
917
+ }
918
+ getContextScope() {
919
+ const scope = {};
920
+ set(scope, 'eval', (path) => this.builderService.getValue(path));
921
+ return scope;
922
+ }
923
+ getEventScope() {
924
+ const scope = {};
925
+ set(scope, 'context', (path) => this.builderService.onChanged.pipe(filter((c) => c.path == path)));
926
+ set(scope, 'from', (event) => get(this.instance.api(), event));
927
+ return scope;
928
+ }
929
+ getWidgetScope() {
930
+ const scope = {};
931
+ set(scope, 'call', (name, ...args) => {
932
+ this.instance.call(name, ...args);
933
+ });
934
+ set(scope, 'find', (id) => {
935
+ return this.builderService.getWidget(id)?.api();
936
+ });
937
+ return scope;
938
+ }
939
+ getFunctionScope() {
940
+ const scope = {};
941
+ set(scope, 'sum', (values) => {
942
+ return sum(values);
943
+ });
944
+ Object.entries(this.builderService.functions).forEach((i) => {
945
+ set(scope, i[0], (...args) => {
946
+ return i[1](...args);
947
+ });
948
+ });
949
+ return scope;
950
+ }
951
+ getVariablesScope() {
952
+ const scope = {};
953
+ set(scope, 'eval', (path) => get(this.builderService.variables, path));
954
+ return scope;
955
+ }
956
+ async assignTriggers() {
957
+ this.node().triggers?.forEach((t) => {
958
+ const event = this.evaluateTrigger(t.event);
959
+ event?.pipe(this.unsubscriber.takeUntilDestroy).subscribe((c) => {
960
+ this.evaluateAction(t.action);
961
+ });
962
+ });
963
+ }
964
+ evaluateTrigger(templateExpression) {
965
+ try {
966
+ const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
967
+ if (!expressionMatch) {
968
+ throw Error(`No valid expression found in "${templateExpression}"`);
969
+ }
970
+ const expression = expressionMatch[1];
971
+ // Cache the evaluation function instead of the result
972
+ const scope = this.getGlobalScope();
973
+ const sandbox = new Function('scope', `with (scope) { return ( function() { return ${expression}; })(); }`);
974
+ return sandbox(scope);
975
+ }
976
+ catch (error) {
977
+ console.error('Error evaluating expression:', error);
978
+ return null;
979
+ }
980
+ }
981
+ evaluateAction(templateExpression) {
982
+ try {
983
+ const expressionMatch = templateExpression.match(/\{\{\s*(.*?)\s*\}\}/);
984
+ if (!expressionMatch) {
985
+ throw Error(`No valid expression found in "${templateExpression}"`);
986
+ }
987
+ const expression = expressionMatch[1];
988
+ // Cache the evaluation function instead of the result
989
+ const scope = this.getGlobalScope();
990
+ const sandbox = new Function('scope', `with (scope) { ${expression} }`);
991
+ sandbox(scope);
992
+ }
993
+ catch (error) {
994
+ console.error('Error evaluating expression:', error);
995
+ }
996
+ }
997
+ static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXPWidgetRendererDirective, deps: [], target: i0.ɵɵFactoryTarget.Directive }); }
998
+ static { this.ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "17.1.0", version: "18.2.0", type: AXPWidgetRendererDirective, selector: "[axp-widget-renderer]", inputs: { parentNode: { classPropertyName: "parentNode", publicName: "parentNode", isSignal: true, isRequired: false, transformFunction: null }, index: { classPropertyName: "index", publicName: "index", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: true, transformFunction: null }, node: { classPropertyName: "node", publicName: "node", isSignal: true, isRequired: true, transformFunction: null } }, providers: [
999
+ {
1000
+ provide: AXUnsubscriber,
1001
+ },
1002
+ ], ngImport: i0 }); }
1003
+ }
1004
+ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXPWidgetRendererDirective, decorators: [{
1005
+ type: Directive,
1006
+ args: [{
1007
+ selector: '[axp-widget-renderer]',
1008
+ providers: [
1009
+ {
1010
+ provide: AXUnsubscriber,
1011
+ },
1012
+ ],
1013
+ }]
1014
+ }], ctorParameters: () => [] });
1015
+
1016
+ const COMPONENTS = [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective];
745
1017
  class AXPLayoutBuilderModule {
746
1018
  static forRoot(config) {
747
1019
  return {
@@ -782,7 +1054,7 @@ class AXPLayoutBuilderModule {
782
1054
  });
783
1055
  }
784
1056
  static { this.ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXPLayoutBuilderModule, deps: [{ token: 'AXPLayoutBuilderModuleFactory', optional: true }], target: i0.ɵɵFactoryTarget.NgModule }); }
785
- static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.0", ngImport: i0, type: AXPLayoutBuilderModule, declarations: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent], imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule], exports: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent] }); }
1057
+ static { this.ɵmod = i0.ɵɵngDeclareNgModule({ minVersion: "14.0.0", version: "18.2.0", ngImport: i0, type: AXPLayoutBuilderModule, declarations: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective], imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule], exports: [AXPWidgetContainerComponent, AXPWidgetRendererComponent, AXPWidgetColumnRendererComponent, AXPWidgetRendererDirective] }); }
786
1058
  static { this.ɵinj = i0.ɵɵngDeclareInjector({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXPLayoutBuilderModule, imports: [CommonModule, PortalModule, AXSkeletonModule, CommonModule] }); }
787
1059
  }
788
1060
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.0", ngImport: i0, type: AXPLayoutBuilderModule, decorators: [{
@@ -864,5 +1136,5 @@ const AXP_WIDGETS_GROUPS = [
864
1136
  * Generated bundle index. Do not edit.
865
1137
  */
866
1138
 
867
- export { AXPColumnWidgetComponent, AXPContainerWidgetComponent, AXPLayoutBuilderModule, AXPLayoutBuilderService, AXPLayoutElement, AXPWidgetColumnRendererComponent, AXPWidgetComponent, AXPWidgetContainerComponent, AXPWidgetRegistryService, AXPWidgetRendererComponent, 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_TOKEN, cloneProperty };
1139
+ export { AXPColumnWidgetComponent, AXPContainerWidgetComponent, AXPLayoutBuilderModule, AXPLayoutBuilderService, AXPLayoutElement, AXPWidgetColumnRendererComponent, AXPWidgetComponent, AXPWidgetContainerComponent, 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_TOKEN, cloneProperty };
868
1140
  //# sourceMappingURL=acorex-platform-layout-builder.mjs.map