@masterteam/form-builder 0.0.9 → 0.0.11

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.
@@ -27,9 +27,9 @@ import { CrudStateBase, handleApiRequest, RadioCardsFieldConfig } from '@mastert
27
27
  import { DynamicForm } from '@masterteam/forms/dynamic-form';
28
28
  import { ToggleField } from '@masterteam/components/toggle-field';
29
29
  import { ModalRef } from '@masterteam/components/dialog';
30
- import { FormulaToolbar, FormulaEditor, serializeTokens } from '@masterteam/components/formula';
30
+ import { CONDITION_FUNCTION_CATEGORIES, CONDITION_OPERATORS, FormulaToolbar, FormulaEditor, VALIDATION_FUNCTION_CATEGORIES, VALIDATION_OPERATORS, serializeTokens } from '@masterteam/components/formula';
31
31
  import { Tooltip } from '@masterteam/components/tooltip';
32
- import { Tabs } from '@masterteam/components/tabs';
32
+ import { ClientForm } from '@masterteam/forms/client-form';
33
33
  import { takeUntilDestroyed } from '@angular/core/rxjs-interop';
34
34
  import { Table } from '@masterteam/components/table';
35
35
  import { RadioCards } from '@masterteam/components/radio-cards';
@@ -63,6 +63,13 @@ class SetProperties {
63
63
  this.properties = properties;
64
64
  }
65
65
  }
66
+ class SetPreviewInfo {
67
+ payload;
68
+ static type = '[FormBuilder] Set Preview Info';
69
+ constructor(payload) {
70
+ this.payload = payload;
71
+ }
72
+ }
66
73
  // ============================================================================
67
74
  // Form Configuration Actions
68
75
  // ============================================================================
@@ -229,6 +236,8 @@ const DEFAULT_STATE = {
229
236
  formConfiguration: null,
230
237
  // Properties for field enrichment
231
238
  properties: [],
239
+ // Preview form context
240
+ previewInfo: null,
232
241
  // Loading state (from LoadingStateShape)
233
242
  loadingActive: [],
234
243
  errors: {},
@@ -276,6 +285,9 @@ let FormBuilderState = class FormBuilderState extends CrudStateBase {
276
285
  static getValidations(state) {
277
286
  return state?.formConfiguration?.validations ?? [];
278
287
  }
288
+ static getPreviewInfo(state) {
289
+ return state?.previewInfo ?? null;
290
+ }
279
291
  // ============================================================================
280
292
  // Module Configuration Actions
281
293
  // ============================================================================
@@ -303,6 +315,11 @@ let FormBuilderState = class FormBuilderState extends CrudStateBase {
303
315
  properties: action.properties,
304
316
  });
305
317
  }
318
+ setPreviewInfo(ctx, action) {
319
+ ctx.patchState({
320
+ previewInfo: action.payload,
321
+ });
322
+ }
306
323
  // ============================================================================
307
324
  // Form Configuration Actions
308
325
  // ============================================================================
@@ -818,6 +835,9 @@ __decorate([
818
835
  __decorate([
819
836
  Action(SetProperties)
820
837
  ], FormBuilderState.prototype, "setProperties", null);
838
+ __decorate([
839
+ Action(SetPreviewInfo)
840
+ ], FormBuilderState.prototype, "setPreviewInfo", null);
821
841
  __decorate([
822
842
  Action(GetFormConfiguration)
823
843
  ], FormBuilderState.prototype, "getFormConfiguration", null);
@@ -890,6 +910,9 @@ __decorate([
890
910
  __decorate([
891
911
  Selector()
892
912
  ], FormBuilderState, "getValidations", null);
913
+ __decorate([
914
+ Selector()
915
+ ], FormBuilderState, "getPreviewInfo", null);
893
916
  FormBuilderState = __decorate([
894
917
  State({
895
918
  name: 'formBuilder',
@@ -898,7 +921,7 @@ FormBuilderState = __decorate([
898
921
  ], FormBuilderState);
899
922
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FormBuilderState, decorators: [{
900
923
  type: Injectable
901
- }], propDecorators: { setModuleInfo: [], resetState: [], setProperties: [], getFormConfiguration: [], resetFormConfiguration: [], addSection: [], updateSection: [], deleteSection: [], addField: [], updateField: [], deleteField: [], reorderFields: [], moveField: [], addValidation: [], updateValidation: [], deleteValidation: [], toggleValidationActive: [] } });
924
+ }], propDecorators: { setModuleInfo: [], resetState: [], setProperties: [], setPreviewInfo: [], getFormConfiguration: [], resetFormConfiguration: [], addSection: [], updateSection: [], deleteSection: [], addField: [], updateField: [], deleteField: [], reorderFields: [], moveField: [], addValidation: [], updateValidation: [], deleteValidation: [], toggleValidationActive: [] } });
902
925
 
903
926
  class FormBuilderFacade {
904
927
  store = inject(Store);
@@ -915,6 +938,7 @@ class FormBuilderFacade {
915
938
  parentModuleType = select(FormBuilderState.getParentModuleType);
916
939
  parentModuleId = select(FormBuilderState.getParentModuleId);
917
940
  parentPath = select(FormBuilderState.getParentPath);
941
+ previewInfo = select(FormBuilderState.getPreviewInfo);
918
942
  // ============================================================================
919
943
  // Loading Signals
920
944
  // ============================================================================
@@ -971,6 +995,9 @@ class FormBuilderFacade {
971
995
  setProperties(properties) {
972
996
  return this.store.dispatch(new SetProperties(properties));
973
997
  }
998
+ setPreviewInfo(payload) {
999
+ return this.store.dispatch(new SetPreviewInfo(payload));
1000
+ }
974
1001
  // ============================================================================
975
1002
  // Form Configuration Dispatchers
976
1003
  // ============================================================================
@@ -1033,262 +1060,6 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1033
1060
  args: [{ providedIn: 'root' }]
1034
1061
  }] });
1035
1062
 
1036
- /**
1037
- * Condition Formula Constants
1038
- * Static functions and operators for condition formulas (Show/Hide/Enable/Disable)
1039
- */
1040
- /**
1041
- * Functions for field conditions
1042
- */
1043
- const CONDITION_FUNCTION_CATEGORIES = [
1044
- {
1045
- name: 'Logic',
1046
- displayName: 'Field Visibility',
1047
- functions: [
1048
- {
1049
- name: 'SHOW_IF',
1050
- category: 'Logic',
1051
- description: 'Show this field when condition is true',
1052
- signature: 'SHOW_IF(condition)',
1053
- parameters: [
1054
- {
1055
- name: 'condition',
1056
- type: 'boolean',
1057
- description: 'When true, field is visible',
1058
- required: true,
1059
- },
1060
- ],
1061
- returnType: 'boolean',
1062
- examples: [
1063
- 'SHOW_IF(@Status == "Active")',
1064
- 'SHOW_IF(@Type == "Custom")',
1065
- ],
1066
- },
1067
- {
1068
- name: 'HIDE_IF',
1069
- category: 'Logic',
1070
- description: 'Hide this field when condition is true',
1071
- signature: 'HIDE_IF(condition)',
1072
- parameters: [
1073
- {
1074
- name: 'condition',
1075
- type: 'boolean',
1076
- description: 'When true, field is hidden',
1077
- required: true,
1078
- },
1079
- ],
1080
- returnType: 'boolean',
1081
- examples: ['HIDE_IF(@Status == "Closed")', 'HIDE_IF(ISNULL(@Parent))'],
1082
- },
1083
- {
1084
- name: 'DISABLE_IF',
1085
- category: 'Logic',
1086
- description: 'Disable this field when condition is true',
1087
- signature: 'DISABLE_IF(condition)',
1088
- parameters: [
1089
- {
1090
- name: 'condition',
1091
- type: 'boolean',
1092
- description: 'When true, field is disabled',
1093
- required: true,
1094
- },
1095
- ],
1096
- returnType: 'boolean',
1097
- examples: [
1098
- 'DISABLE_IF(@IsLocked == true)',
1099
- 'DISABLE_IF(@Status == "Approved")',
1100
- ],
1101
- },
1102
- {
1103
- name: 'ENABLE_IF',
1104
- category: 'Logic',
1105
- description: 'Enable this field when condition is true',
1106
- signature: 'ENABLE_IF(condition)',
1107
- parameters: [
1108
- {
1109
- name: 'condition',
1110
- type: 'boolean',
1111
- description: 'When true, field is enabled',
1112
- required: true,
1113
- },
1114
- ],
1115
- returnType: 'boolean',
1116
- examples: [
1117
- 'ENABLE_IF(@Status == "Draft")',
1118
- 'ENABLE_IF(@CanEdit == true)',
1119
- ],
1120
- },
1121
- ],
1122
- },
1123
- {
1124
- name: 'Aggregation',
1125
- displayName: 'Logic Helpers',
1126
- functions: [
1127
- {
1128
- name: 'AND',
1129
- category: 'Aggregation',
1130
- description: 'Returns true if all conditions are true',
1131
- signature: 'AND(condition1, condition2)',
1132
- parameters: [
1133
- {
1134
- name: 'condition1',
1135
- type: 'boolean',
1136
- description: 'First condition',
1137
- required: true,
1138
- },
1139
- {
1140
- name: 'condition2',
1141
- type: 'boolean',
1142
- description: 'Second condition',
1143
- required: true,
1144
- },
1145
- ],
1146
- returnType: 'boolean',
1147
- examples: ['AND(@Status == "Active", @Priority > 0)'],
1148
- },
1149
- {
1150
- name: 'OR',
1151
- category: 'Aggregation',
1152
- description: 'Returns true if any condition is true',
1153
- signature: 'OR(condition1, condition2)',
1154
- parameters: [
1155
- {
1156
- name: 'condition1',
1157
- type: 'boolean',
1158
- description: 'First condition',
1159
- required: true,
1160
- },
1161
- {
1162
- name: 'condition2',
1163
- type: 'boolean',
1164
- description: 'Second condition',
1165
- required: true,
1166
- },
1167
- ],
1168
- returnType: 'boolean',
1169
- examples: ['OR(@Status == "Active", @Status == "Pending")'],
1170
- },
1171
- {
1172
- name: 'NOT',
1173
- category: 'Aggregation',
1174
- description: 'Returns the opposite of the condition',
1175
- signature: 'NOT(condition)',
1176
- parameters: [
1177
- {
1178
- name: 'condition',
1179
- type: 'boolean',
1180
- description: 'The condition to negate',
1181
- required: true,
1182
- },
1183
- ],
1184
- returnType: 'boolean',
1185
- examples: ['NOT(@IsCompleted)'],
1186
- },
1187
- {
1188
- name: 'ISNULL',
1189
- category: 'Aggregation',
1190
- description: 'Returns true if value is null or empty',
1191
- signature: 'ISNULL(value)',
1192
- parameters: [
1193
- {
1194
- name: 'value',
1195
- type: 'any',
1196
- description: 'The value to check',
1197
- required: true,
1198
- },
1199
- ],
1200
- returnType: 'boolean',
1201
- examples: ['ISNULL(@Description)'],
1202
- },
1203
- {
1204
- name: 'CONTAINS',
1205
- category: 'Aggregation',
1206
- description: 'Returns true if text contains the search string',
1207
- signature: 'CONTAINS(text, search)',
1208
- parameters: [
1209
- {
1210
- name: 'text',
1211
- type: 'string',
1212
- description: 'The text to search in',
1213
- required: true,
1214
- },
1215
- {
1216
- name: 'search',
1217
- type: 'string',
1218
- description: 'The string to search for',
1219
- required: true,
1220
- },
1221
- ],
1222
- returnType: 'boolean',
1223
- examples: ['CONTAINS(@Name, "Project")'],
1224
- },
1225
- ],
1226
- },
1227
- ];
1228
- /**
1229
- * Operators for conditions
1230
- */
1231
- const CONDITION_OPERATORS = [
1232
- // Comparison
1233
- {
1234
- symbol: '==',
1235
- name: 'Equal',
1236
- type: 'comparison',
1237
- description: 'Equal to',
1238
- precedence: 3,
1239
- },
1240
- {
1241
- symbol: '!=',
1242
- name: 'Not Equal',
1243
- type: 'comparison',
1244
- description: 'Not equal to',
1245
- precedence: 3,
1246
- },
1247
- {
1248
- symbol: '>',
1249
- name: 'Greater Than',
1250
- type: 'comparison',
1251
- description: 'Greater than',
1252
- precedence: 4,
1253
- },
1254
- {
1255
- symbol: '<',
1256
- name: 'Less Than',
1257
- type: 'comparison',
1258
- description: 'Less than',
1259
- precedence: 4,
1260
- },
1261
- {
1262
- symbol: '>=',
1263
- name: 'Greater or Equal',
1264
- type: 'comparison',
1265
- description: 'Greater than or equal',
1266
- precedence: 4,
1267
- },
1268
- {
1269
- symbol: '<=',
1270
- name: 'Less or Equal',
1271
- type: 'comparison',
1272
- description: 'Less than or equal',
1273
- precedence: 4,
1274
- },
1275
- // Logical
1276
- {
1277
- symbol: '&&',
1278
- name: 'And',
1279
- type: 'logical',
1280
- description: 'Logical AND',
1281
- precedence: 2,
1282
- },
1283
- {
1284
- symbol: '||',
1285
- name: 'Or',
1286
- type: 'logical',
1287
- description: 'Logical OR',
1288
- precedence: 1,
1289
- },
1290
- ];
1291
-
1292
1063
  /**
1293
1064
  * Field Conditions Dialog
1294
1065
  *
@@ -1596,7 +1367,7 @@ class FBFieldForm {
1596
1367
  });
1597
1368
  }
1598
1369
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBFieldForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
1599
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBFieldForm, isStandalone: true, selector: "mt-fb-field-form", inputs: { sectionId: { classPropertyName: "sectionId", publicName: "sectionId", isSignal: true, isRequired: false, transformFunction: null }, initialData: { classPropertyName: "initialData", publicName: "initialData", isSignal: true, isRequired: false, transformFunction: null }, allSections: { classPropertyName: "allSections", publicName: "allSections", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"mt-2 h-full overflow-y-auto pb-10 flex flex-col gap-4\">\r\n <mt-dynamic-form\r\n [formConfig]=\"activeFormConfig()\"\r\n [formControl]=\"formControl\"\r\n >\r\n </mt-dynamic-form>\r\n\r\n @if (isManageProperties()) {\r\n <!-- isRead Toggle -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('is-read')\"\r\n [descriptionCard]=\"t('is-read-description')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"isReadControl\"\r\n ></mt-toggle-field>\r\n\r\n <!-- isWrite Toggle -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('is-write')\"\r\n [descriptionCard]=\"t('is-write-description')\"\r\n icon=\"general.edit-02\"\r\n [formControl]=\"isWriteControl\"\r\n ></mt-toggle-field>\r\n } @else {\r\n <!-- Show/Hide Toggle with Set Conditions -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-description')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n class=\"mt-3\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('set-conditions')\"\r\n size=\"small\"\r\n (onClick)=\"onSetConditions()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modalService.footerClass\">\r\n @if (initialData() && !isManageProperties()) {\r\n <mt-button\r\n [tooltip]=\"t('delete')\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n icon=\"general.trash-01\"\r\n [loading]=\"deleting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"onDelete($event)\"\r\n class=\"me-auto\"\r\n ></mt-button>\r\n }\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [disabled]=\"submitting() || deleting()\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n [disabled]=\"!formControl.valid || deleting()\"\r\n [label]=\"t('save')\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }] });
1370
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBFieldForm, isStandalone: true, selector: "mt-fb-field-form", inputs: { sectionId: { classPropertyName: "sectionId", publicName: "sectionId", isSignal: true, isRequired: false, transformFunction: null }, initialData: { classPropertyName: "initialData", publicName: "initialData", isSignal: true, isRequired: false, transformFunction: null }, allSections: { classPropertyName: "allSections", publicName: "allSections", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"mt-2 h-full overflow-y-auto pb-10 flex flex-col gap-4\">\r\n <mt-dynamic-form\r\n [formConfig]=\"activeFormConfig()\"\r\n [formControl]=\"formControl\"\r\n >\r\n </mt-dynamic-form>\r\n\r\n @if (isManageProperties()) {\r\n <!-- isRead Toggle -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('is-read')\"\r\n [descriptionCard]=\"t('is-read-description')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"isReadControl\"\r\n ></mt-toggle-field>\r\n\r\n <!-- isWrite Toggle -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('is-write')\"\r\n [descriptionCard]=\"t('is-write-description')\"\r\n icon=\"general.edit-02\"\r\n [formControl]=\"isWriteControl\"\r\n ></mt-toggle-field>\r\n } @else {\r\n <!-- Show/Hide Toggle with Set Conditions -->\r\n <mt-toggle-field\r\n toggleShape=\"card\"\r\n [label]=\"t('show-hide')\"\r\n [descriptionCard]=\"t('show-hide-description')\"\r\n icon=\"general.eye\"\r\n [formControl]=\"showHideControl\"\r\n class=\"mt-3\"\r\n >\r\n <ng-template #toggleCardBottom>\r\n @if (showHideControl.value) {\r\n <div class=\"mt-3\">\r\n <mt-button\r\n [label]=\"t('set-conditions')\"\r\n size=\"small\"\r\n (onClick)=\"onSetConditions()\"\r\n ></mt-button>\r\n </div>\r\n }\r\n </ng-template>\r\n </mt-toggle-field>\r\n }\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modalService.footerClass\">\r\n @if (initialData() && !isManageProperties()) {\r\n <mt-button\r\n [tooltip]=\"t('delete')\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n icon=\"general.trash-01\"\r\n [loading]=\"deleting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"onDelete($event)\"\r\n class=\"me-auto\"\r\n ></mt-button>\r\n }\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [disabled]=\"submitting() || deleting()\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n [disabled]=\"!formControl.valid || deleting()\"\r\n [label]=\"t('save')\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: ToggleField, selector: "mt-toggle-field", inputs: ["label", "labelPosition", "placeholder", "readonly", "pInputs", "required", "toggleShape", "size", "icon", "descriptionCard"], outputs: ["onChange"] }] });
1600
1371
  }
1601
1372
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBFieldForm, decorators: [{
1602
1373
  type: Component,
@@ -1712,7 +1483,7 @@ class FBSectionForm {
1712
1483
  });
1713
1484
  }
1714
1485
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBSectionForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
1715
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBSectionForm, isStandalone: true, selector: "mt-fb-section-form", inputs: { sectionId: { classPropertyName: "sectionId", publicName: "sectionId", isSignal: true, isRequired: false, transformFunction: null }, initialData: { classPropertyName: "initialData", publicName: "initialData", isSignal: true, isRequired: false, transformFunction: null }, sectionsCount: { classPropertyName: "sectionsCount", publicName: "sectionsCount", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"mt-4 h-full overflow-y-auto pb-10\">\r\n <mt-dynamic-form [formConfig]=\"formConfig\" [formControl]=\"formControl\">\r\n </mt-dynamic-form>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modalService.footerClass\">\r\n @if (sectionId()) {\r\n <mt-button\r\n [tooltip]=\"t('delete')\"\r\n severity=\"danger\"\r\n outlined\r\n icon=\"general.trash-01\"\r\n [loading]=\"deleting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"onDelete($event)\"\r\n class=\"me-auto\"\r\n ></mt-button>\r\n }\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [disabled]=\"submitting() || deleting()\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n [disabled]=\"!formControl.valid || deleting()\"\r\n [label]=\"t('save')\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }] });
1486
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBSectionForm, isStandalone: true, selector: "mt-fb-section-form", inputs: { sectionId: { classPropertyName: "sectionId", publicName: "sectionId", isSignal: true, isRequired: false, transformFunction: null }, initialData: { classPropertyName: "initialData", publicName: "initialData", isSignal: true, isRequired: false, transformFunction: null }, sectionsCount: { classPropertyName: "sectionsCount", publicName: "sectionsCount", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"mt-4 h-full overflow-y-auto pb-10\">\r\n <mt-dynamic-form [formConfig]=\"formConfig\" [formControl]=\"formControl\">\r\n </mt-dynamic-form>\r\n </div>\r\n </div>\r\n\r\n <div [class]=\"modalService.footerClass\">\r\n @if (sectionId()) {\r\n <mt-button\r\n [tooltip]=\"t('delete')\"\r\n severity=\"danger\"\r\n outlined\r\n icon=\"general.trash-01\"\r\n [loading]=\"deleting()\"\r\n [disabled]=\"submitting()\"\r\n (onClick)=\"onDelete($event)\"\r\n class=\"me-auto\"\r\n ></mt-button>\r\n }\r\n <mt-button\r\n [label]=\"t('cancel')\"\r\n severity=\"secondary\"\r\n [disabled]=\"submitting() || deleting()\"\r\n (onClick)=\"onCancel()\"\r\n >\r\n </mt-button>\r\n <mt-button\r\n [disabled]=\"!formControl.valid || deleting()\"\r\n [label]=\"t('save')\"\r\n severity=\"primary\"\r\n [loading]=\"submitting()\"\r\n (onClick)=\"onSave()\"\r\n >\r\n </mt-button>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"], outputs: ["runtimeMessagesChange"] }, { kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }] });
1716
1487
  }
1717
1488
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBSectionForm, decorators: [{
1718
1489
  type: Component,
@@ -1870,11 +1641,21 @@ class FBSection {
1870
1641
  LookupLog: 'actionableTable',
1871
1642
  LookupMatrix: 'select',
1872
1643
  Location: 'select',
1644
+ Connection: 'schema-connection',
1873
1645
  };
1874
1646
  return typeMap[field.type] ?? 'text';
1875
1647
  }
1648
+ getFieldConfig(field) {
1649
+ const type = this.getFieldType(field);
1650
+ const base = { readonly: true, type };
1651
+ if (type === 'schema-connection') {
1652
+ const prop = field.property;
1653
+ base['configuration'] = prop ? (prop['configuration'] ?? {}) : {};
1654
+ }
1655
+ return base;
1656
+ }
1876
1657
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBSection, deps: [], target: i0.ɵɵFactoryTarget.Component });
1877
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBSection, isStandalone: true, selector: "mt-fb-section", inputs: { section: { classPropertyName: "section", publicName: "section", isSignal: true, isRequired: true, transformFunction: null }, sectionsCount: { classPropertyName: "sectionsCount", publicName: "sectionsCount", isSignal: true, isRequired: false, transformFunction: null }, allSections: { classPropertyName: "allSections", publicName: "allSections", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onFieldDrop: "onFieldDrop" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div class=\"flex flex-col\">\r\n <div\r\n class=\"flex justify-between items-center bg-primary py-3 px-3 text-primary-contrast rounded-xl\"\r\n >\r\n <mt-icon\r\n class=\"text-2xl cursor-pointer transition-[rotate]\"\r\n [class.rotate-180]=\"expanded()\"\r\n icon=\"arrow.chevron-down\"\r\n (click)=\"toggleExpanded()\"\r\n ></mt-icon>\r\n\r\n <div class=\"flex gap-3 items-center\">\r\n <span class=\"font-semibold\">\r\n {{ sectionName() }}\r\n </span>\r\n @if (!isManageProperties()) {\r\n <mt-icon\r\n class=\"text-lg cursor-pointer\"\r\n icon=\"general.edit-02\"\r\n (click)=\"editSection($event)\"\r\n [mtTooltip]=\"t('edit-section')\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n <span></span>\r\n </div>\r\n @if (expanded()) {\r\n <div\r\n cdkDropList\r\n [id]=\"section().id\"\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"displayFields()\"\r\n [cdkDropListDisabled]=\"isManageProperties()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-12 gap-4 relative py-4\"\r\n [class.min-h-27]=\"displayFields().length === 0\"\r\n >\r\n @for (field of displayFields(); track field.id) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"field\"\r\n [cdkDragDisabled]=\"\r\n isManageProperties() || field._pending || field._deleting\r\n \"\r\n [class]=\"\r\n getFieldColSpan(field) +\r\n (isManageProperties()\r\n ? ''\r\n : ' cursor-grab active:cursor-grabbing')\r\n \"\r\n >\r\n <div\r\n *cdkDragPlaceholder\r\n [class]=\"\r\n 'h-full min-h-27 bg-black/10 rounded-2xl ' +\r\n getFieldColSpan(field)\r\n \"\r\n ></div>\r\n @if (field._pending) {\r\n <!-- Skeleton for pending field -->\r\n <mt-card class=\"h-full animate-pulse\">\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1 space-y-3\">\r\n <div class=\"h-4 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <mt-card\r\n class=\"h-full relative transition-all duration-200\"\r\n [class.opacity-50]=\"field._deleting\"\r\n [class.opacity-40]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n [class.blur-[1px]]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n >\r\n @if (field._deleting) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center bg-white/50 rounded-xl z-10\"\r\n >\r\n <div\r\n class=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\"\r\n ></div>\r\n </div>\r\n }\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1\">\r\n <form [formGroup]=\"getFormGroup(field)\">\r\n <div class=\"flex items-center gap-4 mb-2\">\r\n <div class=\"font-semibold\">\r\n {{ field.name }}\r\n </div>\r\n @if (isManageProperties()) {\r\n <div class=\"flex items-center gap-1.5 ms-auto\">\r\n @if (field.isRead === false) {\r\n <span\r\n class=\"text-xs font-medium text-red-500 bg-red-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"hidden\") }}\r\n </span>\r\n } @else if (field.isWrite === false) {\r\n <span\r\n class=\"text-xs font-medium text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"read-only\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <mt-dynamic-field\r\n [fieldName]=\"field.name\"\r\n [fieldConfig]=\"{\r\n readonly: true,\r\n type: getFieldType(field),\r\n }\"\r\n />\r\n </form>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.settings-01\"\r\n [tooltip]=\"t('edit-field')\"\r\n [variant]=\"'outlined'\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"editField(field)\"\r\n ></mt-button>\r\n @if (!isManageProperties()) {\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n [tooltip]=\"t('remove-field')\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"removeField($event, field)\"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n } @empty {\r\n <mt-card class=\"absolute inset-0 top-4 h-full\" paddingless>\r\n <div class=\"size-full p-4\">\r\n <div\r\n class=\"flex justify-center items-center gap-4 h-full border-1 border-primary rounded-xl bg-primary-50 text-primary\"\r\n >\r\n <mt-icon icon=\"editor.move\" class=\"text-3xl\" />\r\n <span>{{ t(\"drag-from-the-side\") }}</span>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DynamicField, selector: "mt-dynamic-field", inputs: ["fieldConfig", "fieldName"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }] });
1658
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBSection, isStandalone: true, selector: "mt-fb-section", inputs: { section: { classPropertyName: "section", publicName: "section", isSignal: true, isRequired: true, transformFunction: null }, sectionsCount: { classPropertyName: "sectionsCount", publicName: "sectionsCount", isSignal: true, isRequired: false, transformFunction: null }, allSections: { classPropertyName: "allSections", publicName: "allSections", isSignal: true, isRequired: false, transformFunction: null }, mode: { classPropertyName: "mode", publicName: "mode", isSignal: true, isRequired: false, transformFunction: null } }, outputs: { onFieldDrop: "onFieldDrop" }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div class=\"flex flex-col\">\r\n <div\r\n class=\"flex justify-between items-center bg-primary py-3 px-3 text-primary-contrast rounded-xl\"\r\n >\r\n <mt-icon\r\n class=\"text-2xl cursor-pointer transition-[rotate]\"\r\n [class.rotate-180]=\"expanded()\"\r\n icon=\"arrow.chevron-down\"\r\n (click)=\"toggleExpanded()\"\r\n ></mt-icon>\r\n\r\n <div class=\"flex gap-3 items-center\">\r\n <span class=\"font-semibold\">\r\n {{ sectionName() }}\r\n </span>\r\n @if (!isManageProperties()) {\r\n <mt-icon\r\n class=\"text-lg cursor-pointer\"\r\n icon=\"general.edit-02\"\r\n (click)=\"editSection($event)\"\r\n [mtTooltip]=\"t('edit-section')\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n <span></span>\r\n </div>\r\n @if (expanded()) {\r\n <div\r\n cdkDropList\r\n [id]=\"section().id\"\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"displayFields()\"\r\n [cdkDropListDisabled]=\"isManageProperties()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-12 gap-4 relative py-4\"\r\n [class.min-h-27]=\"displayFields().length === 0\"\r\n >\r\n @for (field of displayFields(); track field.id) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"field\"\r\n [cdkDragDisabled]=\"\r\n isManageProperties() || field._pending || field._deleting\r\n \"\r\n [class]=\"\r\n getFieldColSpan(field) +\r\n (isManageProperties()\r\n ? ''\r\n : ' cursor-grab active:cursor-grabbing')\r\n \"\r\n >\r\n <div\r\n *cdkDragPlaceholder\r\n [class]=\"\r\n 'h-full min-h-27 bg-black/10 rounded-2xl ' +\r\n getFieldColSpan(field)\r\n \"\r\n ></div>\r\n @if (field._pending) {\r\n <!-- Skeleton for pending field -->\r\n <mt-card class=\"h-full animate-pulse\">\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1 space-y-3\">\r\n <div class=\"h-4 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <mt-card\r\n class=\"h-full relative transition-all duration-200\"\r\n [class.opacity-50]=\"field._deleting\"\r\n [class.opacity-40]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n [class.blur-[1px]]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n >\r\n @if (field._deleting) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center bg-white/50 rounded-xl z-10\"\r\n >\r\n <div\r\n class=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\"\r\n ></div>\r\n </div>\r\n }\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1\">\r\n <form [formGroup]=\"getFormGroup(field)\">\r\n <div class=\"flex items-center gap-4 mb-2\">\r\n <div class=\"font-semibold\">\r\n {{ field.name }}\r\n </div>\r\n @if (isManageProperties()) {\r\n <div class=\"flex items-center gap-1.5 ms-auto\">\r\n @if (field.isRead === false) {\r\n <span\r\n class=\"text-xs font-medium text-red-500 bg-red-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"hidden\") }}\r\n </span>\r\n } @else if (field.isWrite === false) {\r\n <span\r\n class=\"text-xs font-medium text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"read-only\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <mt-dynamic-field\r\n [fieldName]=\"field.name\"\r\n [fieldConfig]=\"getFieldConfig(field)\"\r\n />\r\n </form>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.settings-01\"\r\n [tooltip]=\"t('edit-field')\"\r\n [variant]=\"'outlined'\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"editField(field)\"\r\n ></mt-button>\r\n @if (!isManageProperties()) {\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n [tooltip]=\"t('remove-field')\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"removeField($event, field)\"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n } @empty {\r\n <mt-card class=\"absolute inset-0 top-4 h-full\" paddingless>\r\n <div class=\"size-full p-4\">\r\n <div\r\n class=\"flex justify-center items-center gap-4 h-full border-1 border-primary rounded-xl bg-primary-50 text-primary\"\r\n >\r\n <mt-icon icon=\"editor.move\" class=\"text-3xl\" />\r\n <span>{{ t(\"drag-from-the-side\") }}</span>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "component", type: Button, selector: "mt-button", inputs: ["icon", "label", "tooltip", "class", "type", "styleClass", "severity", "badge", "variant", "badgeSeverity", "size", "iconPos", "autofocus", "fluid", "raised", "rounded", "text", "plain", "outlined", "link", "disabled", "loading", "pInputs"], outputs: ["onClick", "onFocus", "onBlur"] }, { kind: "component", type: Card, selector: "mt-card", inputs: ["class", "title", "paddingless"] }, { kind: "component", type: Icon, selector: "mt-icon", inputs: ["icon"] }, { kind: "directive", type: CdkDrag, selector: "[cdkDrag]", inputs: ["cdkDragData", "cdkDragLockAxis", "cdkDragRootElement", "cdkDragBoundary", "cdkDragStartDelay", "cdkDragFreeDragPosition", "cdkDragDisabled", "cdkDragConstrainPosition", "cdkDragPreviewClass", "cdkDragPreviewContainer", "cdkDragScale"], outputs: ["cdkDragStarted", "cdkDragReleased", "cdkDragEnded", "cdkDragEntered", "cdkDragExited", "cdkDragDropped", "cdkDragMoved"], exportAs: ["cdkDrag"] }, { kind: "directive", type: CdkDropList, selector: "[cdkDropList], cdk-drop-list", inputs: ["cdkDropListConnectedTo", "cdkDropListData", "cdkDropListOrientation", "id", "cdkDropListLockAxis", "cdkDropListDisabled", "cdkDropListSortingDisabled", "cdkDropListEnterPredicate", "cdkDropListSortPredicate", "cdkDropListAutoScrollDisabled", "cdkDropListAutoScrollStep", "cdkDropListElementContainer", "cdkDropListHasAnchor"], outputs: ["cdkDropListDropped", "cdkDropListEntered", "cdkDropListExited", "cdkDropListSorted"], exportAs: ["cdkDropList"] }, { kind: "directive", type: CdkDragPlaceholder, selector: "ng-template[cdkDragPlaceholder]", inputs: ["data"] }, { kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: DynamicField, selector: "mt-dynamic-field", inputs: ["fieldConfig", "fieldName"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.ɵNgNoValidate, selector: "form:not([ngNoForm]):not([ngNativeValidate])" }, { kind: "directive", type: i1.NgControlStatusGroup, selector: "[formGroupName],[formArrayName],[ngModelGroup],[formGroup],[formArray],form:not([ngNoForm]),[ngForm]" }, { kind: "directive", type: i1.FormGroupDirective, selector: "[formGroup]", inputs: ["formGroup"], outputs: ["ngSubmit"], exportAs: ["ngForm"] }, { kind: "directive", type: Tooltip, selector: "[mtTooltip]" }] });
1878
1659
  }
1879
1660
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBSection, decorators: [{
1880
1661
  type: Component,
@@ -1889,434 +1670,28 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
1889
1670
  DynamicField,
1890
1671
  ReactiveFormsModule,
1891
1672
  Tooltip,
1892
- ], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div class=\"flex flex-col\">\r\n <div\r\n class=\"flex justify-between items-center bg-primary py-3 px-3 text-primary-contrast rounded-xl\"\r\n >\r\n <mt-icon\r\n class=\"text-2xl cursor-pointer transition-[rotate]\"\r\n [class.rotate-180]=\"expanded()\"\r\n icon=\"arrow.chevron-down\"\r\n (click)=\"toggleExpanded()\"\r\n ></mt-icon>\r\n\r\n <div class=\"flex gap-3 items-center\">\r\n <span class=\"font-semibold\">\r\n {{ sectionName() }}\r\n </span>\r\n @if (!isManageProperties()) {\r\n <mt-icon\r\n class=\"text-lg cursor-pointer\"\r\n icon=\"general.edit-02\"\r\n (click)=\"editSection($event)\"\r\n [mtTooltip]=\"t('edit-section')\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n <span></span>\r\n </div>\r\n @if (expanded()) {\r\n <div\r\n cdkDropList\r\n [id]=\"section().id\"\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"displayFields()\"\r\n [cdkDropListDisabled]=\"isManageProperties()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-12 gap-4 relative py-4\"\r\n [class.min-h-27]=\"displayFields().length === 0\"\r\n >\r\n @for (field of displayFields(); track field.id) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"field\"\r\n [cdkDragDisabled]=\"\r\n isManageProperties() || field._pending || field._deleting\r\n \"\r\n [class]=\"\r\n getFieldColSpan(field) +\r\n (isManageProperties()\r\n ? ''\r\n : ' cursor-grab active:cursor-grabbing')\r\n \"\r\n >\r\n <div\r\n *cdkDragPlaceholder\r\n [class]=\"\r\n 'h-full min-h-27 bg-black/10 rounded-2xl ' +\r\n getFieldColSpan(field)\r\n \"\r\n ></div>\r\n @if (field._pending) {\r\n <!-- Skeleton for pending field -->\r\n <mt-card class=\"h-full animate-pulse\">\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1 space-y-3\">\r\n <div class=\"h-4 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <mt-card\r\n class=\"h-full relative transition-all duration-200\"\r\n [class.opacity-50]=\"field._deleting\"\r\n [class.opacity-40]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n [class.blur-[1px]]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n >\r\n @if (field._deleting) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center bg-white/50 rounded-xl z-10\"\r\n >\r\n <div\r\n class=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\"\r\n ></div>\r\n </div>\r\n }\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1\">\r\n <form [formGroup]=\"getFormGroup(field)\">\r\n <div class=\"flex items-center gap-4 mb-2\">\r\n <div class=\"font-semibold\">\r\n {{ field.name }}\r\n </div>\r\n @if (isManageProperties()) {\r\n <div class=\"flex items-center gap-1.5 ms-auto\">\r\n @if (field.isRead === false) {\r\n <span\r\n class=\"text-xs font-medium text-red-500 bg-red-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"hidden\") }}\r\n </span>\r\n } @else if (field.isWrite === false) {\r\n <span\r\n class=\"text-xs font-medium text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"read-only\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <mt-dynamic-field\r\n [fieldName]=\"field.name\"\r\n [fieldConfig]=\"{\r\n readonly: true,\r\n type: getFieldType(field),\r\n }\"\r\n />\r\n </form>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.settings-01\"\r\n [tooltip]=\"t('edit-field')\"\r\n [variant]=\"'outlined'\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"editField(field)\"\r\n ></mt-button>\r\n @if (!isManageProperties()) {\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n [tooltip]=\"t('remove-field')\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"removeField($event, field)\"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n } @empty {\r\n <mt-card class=\"absolute inset-0 top-4 h-full\" paddingless>\r\n <div class=\"size-full p-4\">\r\n <div\r\n class=\"flex justify-center items-center gap-4 h-full border-1 border-primary rounded-xl bg-primary-50 text-primary\"\r\n >\r\n <mt-icon icon=\"editor.move\" class=\"text-3xl\" />\r\n <span>{{ t(\"drag-from-the-side\") }}</span>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
1673
+ ], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div class=\"flex flex-col\">\r\n <div\r\n class=\"flex justify-between items-center bg-primary py-3 px-3 text-primary-contrast rounded-xl\"\r\n >\r\n <mt-icon\r\n class=\"text-2xl cursor-pointer transition-[rotate]\"\r\n [class.rotate-180]=\"expanded()\"\r\n icon=\"arrow.chevron-down\"\r\n (click)=\"toggleExpanded()\"\r\n ></mt-icon>\r\n\r\n <div class=\"flex gap-3 items-center\">\r\n <span class=\"font-semibold\">\r\n {{ sectionName() }}\r\n </span>\r\n @if (!isManageProperties()) {\r\n <mt-icon\r\n class=\"text-lg cursor-pointer\"\r\n icon=\"general.edit-02\"\r\n (click)=\"editSection($event)\"\r\n [mtTooltip]=\"t('edit-section')\"\r\n ></mt-icon>\r\n }\r\n </div>\r\n <span></span>\r\n </div>\r\n @if (expanded()) {\r\n <div\r\n cdkDropList\r\n [id]=\"section().id\"\r\n cdkDropListOrientation=\"mixed\"\r\n [cdkDropListData]=\"displayFields()\"\r\n [cdkDropListDisabled]=\"isManageProperties()\"\r\n (cdkDropListDropped)=\"onDrop($event)\"\r\n class=\"grid grid-cols-12 gap-4 relative py-4\"\r\n [class.min-h-27]=\"displayFields().length === 0\"\r\n >\r\n @for (field of displayFields(); track field.id) {\r\n <div\r\n cdkDrag\r\n [cdkDragData]=\"field\"\r\n [cdkDragDisabled]=\"\r\n isManageProperties() || field._pending || field._deleting\r\n \"\r\n [class]=\"\r\n getFieldColSpan(field) +\r\n (isManageProperties()\r\n ? ''\r\n : ' cursor-grab active:cursor-grabbing')\r\n \"\r\n >\r\n <div\r\n *cdkDragPlaceholder\r\n [class]=\"\r\n 'h-full min-h-27 bg-black/10 rounded-2xl ' +\r\n getFieldColSpan(field)\r\n \"\r\n ></div>\r\n @if (field._pending) {\r\n <!-- Skeleton for pending field -->\r\n <mt-card class=\"h-full animate-pulse\">\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1 space-y-3\">\r\n <div class=\"h-4 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n <div class=\"h-8 w-8 bg-surface-200 rounded\"></div>\r\n </div>\r\n </div>\r\n </mt-card>\r\n } @else {\r\n <mt-card\r\n class=\"h-full relative transition-all duration-200\"\r\n [class.opacity-50]=\"field._deleting\"\r\n [class.opacity-40]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n [class.blur-[1px]]=\"\r\n isManageProperties() && field.isRead === false\r\n \"\r\n >\r\n @if (field._deleting) {\r\n <div\r\n class=\"absolute inset-0 flex items-center justify-center bg-white/50 rounded-xl z-10\"\r\n >\r\n <div\r\n class=\"animate-spin h-6 w-6 border-2 border-primary border-t-transparent rounded-full\"\r\n ></div>\r\n </div>\r\n }\r\n <div class=\"flex gap-2\">\r\n <div class=\"flex-1\">\r\n <form [formGroup]=\"getFormGroup(field)\">\r\n <div class=\"flex items-center gap-4 mb-2\">\r\n <div class=\"font-semibold\">\r\n {{ field.name }}\r\n </div>\r\n @if (isManageProperties()) {\r\n <div class=\"flex items-center gap-1.5 ms-auto\">\r\n @if (field.isRead === false) {\r\n <span\r\n class=\"text-xs font-medium text-red-500 bg-red-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"hidden\") }}\r\n </span>\r\n } @else if (field.isWrite === false) {\r\n <span\r\n class=\"text-xs font-medium text-amber-600 bg-amber-50 px-1.5 py-0.5 rounded\"\r\n >\r\n {{ t(\"read-only\") }}\r\n </span>\r\n }\r\n </div>\r\n }\r\n </div>\r\n\r\n <mt-dynamic-field\r\n [fieldName]=\"field.name\"\r\n [fieldConfig]=\"getFieldConfig(field)\"\r\n />\r\n </form>\r\n </div>\r\n <div class=\"flex flex-col gap-1\">\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.settings-01\"\r\n [tooltip]=\"t('edit-field')\"\r\n [variant]=\"'outlined'\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"editField(field)\"\r\n ></mt-button>\r\n @if (!isManageProperties()) {\r\n <mt-button\r\n size=\"small\"\r\n icon=\"general.trash-01\"\r\n severity=\"danger\"\r\n [variant]=\"'outlined'\"\r\n [tooltip]=\"t('remove-field')\"\r\n [disabled]=\"field._deleting\"\r\n (onClick)=\"removeField($event, field)\"\r\n ></mt-button>\r\n }\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n } @empty {\r\n <mt-card class=\"absolute inset-0 top-4 h-full\" paddingless>\r\n <div class=\"size-full p-4\">\r\n <div\r\n class=\"flex justify-center items-center gap-4 h-full border-1 border-primary rounded-xl bg-primary-50 text-primary\"\r\n >\r\n <mt-icon icon=\"editor.move\" class=\"text-3xl\" />\r\n <span>{{ t(\"drag-from-the-side\") }}</span>\r\n </div>\r\n </div>\r\n </mt-card>\r\n }\r\n </div>\r\n }\r\n </div>\r\n</ng-container>\r\n" }]
1893
1674
  }], ctorParameters: () => [], propDecorators: { section: [{ type: i0.Input, args: [{ isSignal: true, alias: "section", required: true }] }], sectionsCount: [{ type: i0.Input, args: [{ isSignal: true, alias: "sectionsCount", required: false }] }], allSections: [{ type: i0.Input, args: [{ isSignal: true, alias: "allSections", required: false }] }], mode: [{ type: i0.Input, args: [{ isSignal: true, alias: "mode", required: false }] }], onFieldDrop: [{ type: i0.Output, args: ["onFieldDrop"] }] } });
1894
1675
 
1895
1676
  class FBPreviewForm {
1896
1677
  modalService = inject(ModalService);
1897
1678
  ref = inject(ModalRef);
1898
- transloco = inject(TranslocoService);
1899
- // Inputs
1900
- sections = input([], ...(ngDevMode ? [{ debugName: "sections" }] : []));
1901
- // Tab state
1902
- activeTab = signal('create', ...(ngDevMode ? [{ debugName: "activeTab" }] : []));
1903
- isLoading = signal(false, ...(ngDevMode ? [{ debugName: "isLoading" }] : []));
1904
- tabOptions = [
1905
- {
1906
- label: this.transloco.translate('formBuilder.create-form'),
1907
- value: 'create',
1908
- },
1909
- { label: this.transloco.translate('formBuilder.edit-form'), value: 'edit' },
1910
- ];
1911
- // Form control for dynamic form
1912
- formControl = new FormControl();
1913
- constructor() {
1914
- // Show skeleton briefly when tab changes to force rebuild
1915
- effect(() => {
1916
- this.activeTab(); // Track tab changes
1917
- this.isLoading.set(true);
1918
- setTimeout(() => this.isLoading.set(false), 50);
1919
- });
1920
- }
1921
- // Convert enriched sections to DynamicFormConfig based on active tab
1922
- formConfig = computed(() => {
1923
- const sections = this.sections();
1924
- const mode = this.activeTab();
1925
- return {
1926
- sections: sections
1927
- .map((section, sectionIndex) => {
1928
- const lang = document.documentElement.lang;
1929
- const sectionName = section.name[lang] ?? section.name['en'] ?? '';
1930
- // Filter fields based on mode
1931
- const visibleFields = section.fields.filter((field) => {
1932
- if (mode === 'create') {
1933
- return !field.hiddenInCreation;
1934
- }
1935
- else {
1936
- return !field.hiddenInEditForm;
1937
- }
1938
- });
1939
- return {
1940
- key: section.id,
1941
- label: sectionName,
1942
- type: 'header',
1943
- columns: 12,
1944
- order: section.order ?? sectionIndex,
1945
- fields: visibleFields.map((field, fieldIndex) => {
1946
- const colSpan = this.getColSpan(field.width);
1947
- return {
1948
- key: `field_${field.propertyKey}`,
1949
- label: field.name,
1950
- type: this.mapFieldType(field.type),
1951
- colSpan,
1952
- order: field.order ?? fieldIndex,
1953
- placeholder: field.name,
1954
- };
1955
- }),
1956
- };
1957
- })
1958
- .filter((section) => section.fields.length > 0), // Hide empty sections
1959
- };
1960
- }, ...(ngDevMode ? [{ debugName: "formConfig" }] : []));
1961
- /**
1962
- * Map property view type to dynamic form field type
1963
- */
1964
- mapFieldType(viewType) {
1965
- const typeMap = {
1966
- User: 'select',
1967
- Text: 'text',
1968
- LongText: 'editor-field',
1969
- Percentage: 'slider',
1970
- Date: 'date',
1971
- Currency: 'text',
1972
- Number: 'number',
1973
- Lookup: 'select',
1974
- LookupMultiSelect: 'select',
1975
- Checkbox: 'toggle',
1976
- InternalModule: 'select',
1977
- DynamicList: 'select',
1978
- API: 'select',
1979
- Time: 'date',
1980
- Status: 'select',
1981
- Attachment: 'attachment',
1982
- EditableListView: 'actionableTable',
1983
- LookupLog: 'actionableTable',
1984
- LookupMatrix: 'select',
1985
- Location: 'select',
1986
- };
1987
- return typeMap[viewType] ?? 'text';
1988
- }
1989
- /**
1990
- * Convert field width to colSpan
1991
- */
1992
- getColSpan(width) {
1993
- const widthMap = {
1994
- '25': 3,
1995
- '50': 6,
1996
- '100': 12,
1997
- };
1998
- return widthMap[width] ?? 12;
1999
- }
1679
+ facade = inject(FormBuilderFacade);
1680
+ // Preview info from store
1681
+ previewInfo = this.facade.previewInfo;
1682
+ // Derive moduleKey and operationKey from previewInfo
1683
+ moduleKey = computed(() => this.previewInfo()?.moduleKey ?? '', ...(ngDevMode ? [{ debugName: "moduleKey" }] : []));
1684
+ operationKey = computed(() => this.previewInfo()?.operationKey ?? '', ...(ngDevMode ? [{ debugName: "operationKey" }] : []));
2000
1685
  onClose() {
2001
1686
  this.ref.close();
2002
1687
  }
2003
1688
  static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBPreviewForm, deps: [], target: i0.ɵɵFactoryTarget.Component });
2004
- static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBPreviewForm, isStandalone: true, selector: "mt-fb-preview-form", inputs: { sections: { classPropertyName: "sections", publicName: "sections", isSignal: true, isRequired: false, transformFunction: null } }, ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <!-- Tabs for Create/Edit mode -->\r\n <div class=\"flex justify-center mb-4\">\r\n <mt-tabs [options]=\"tabOptions\" [(active)]=\"activeTab\"></mt-tabs>\r\n </div>\r\n\r\n <div class=\"h-full overflow-y-auto px-3 pb-10\">\r\n @if (isLoading()) {\r\n <div class=\"space-y-4 animate-pulse\">\r\n <div class=\"h-6 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded w-2/3\"></div>\r\n </div>\r\n } @else if (formConfig().sections.length > 0) {\r\n <mt-dynamic-form\r\n [formConfig]=\"formConfig()\"\r\n [formControl]=\"formControl\"\r\n >\r\n </mt-dynamic-form>\r\n } @else {\r\n <div\r\n class=\"flex justify-center items-center h-64 text-muted-color text-lg\"\r\n >\r\n {{ t(\"no-fields-visible\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "ngmodule", type: ReactiveFormsModule }, { kind: "directive", type: i1.NgControlStatus, selector: "[formControlName],[ngModel],[formControl]" }, { kind: "directive", type: i1.FormControlDirective, selector: "[formControl]", inputs: ["formControl", "disabled", "ngModel"], outputs: ["ngModelChange"], exportAs: ["ngForm"] }, { kind: "component", type: DynamicForm, selector: "mt-dynamic-form", inputs: ["formConfig"] }, { kind: "component", type: Tabs, selector: "mt-tabs", inputs: ["options", "optionLabel", "optionValue", "active", "size", "fluid", "disabled"], outputs: ["activeChange", "onChange"] }] });
1689
+ static ɵcmp = i0.ɵɵngDeclareComponent({ minVersion: "17.0.0", version: "21.0.3", type: FBPreviewForm, isStandalone: true, selector: "mt-fb-preview-form", ngImport: i0, template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"h-full overflow-y-auto px-3 pb-10\">\r\n @if (moduleKey() && operationKey()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"previewInfo()?.moduleId\"\r\n [levelId]=\"previewInfo()?.levelId\"\r\n [levelDataId]=\"previewInfo()?.levelDataId\"\r\n [moduleDataId]=\"previewInfo()?.moduleDataId\"\r\n [requestSchemaId]=\"previewInfo()?.requestSchemaId\"\r\n [autoLoad]=\"true\"\r\n [preview]=\"true\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex justify-center items-center h-64 text-muted-color text-lg\"\r\n >\r\n {{ t(\"no-fields-visible\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n", dependencies: [{ kind: "directive", type: TranslocoDirective, selector: "[transloco]", inputs: ["transloco", "translocoParams", "translocoScope", "translocoRead", "translocoPrefix", "translocoLang", "translocoLoadingTpl"] }, { kind: "component", type: ClientForm, selector: "mt-client-form", inputs: ["moduleKey", "operationKey", "moduleId", "levelId", "levelDataId", "moduleDataId", "requestSchemaId", "draftProcessId", "preview", "returnUrl", "readonly", "autoLoad", "formMode", "lang", "lookups"], outputs: ["loaded", "submitted", "errored", "modeDetected", "formSourceDetected"] }] });
2005
1690
  }
2006
1691
  i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImport: i0, type: FBPreviewForm, decorators: [{
2007
1692
  type: Component,
2008
- args: [{ selector: 'mt-fb-preview-form', standalone: true, imports: [TranslocoDirective, ReactiveFormsModule, DynamicForm, Tabs], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <!-- Tabs for Create/Edit mode -->\r\n <div class=\"flex justify-center mb-4\">\r\n <mt-tabs [options]=\"tabOptions\" [(active)]=\"activeTab\"></mt-tabs>\r\n </div>\r\n\r\n <div class=\"h-full overflow-y-auto px-3 pb-10\">\r\n @if (isLoading()) {\r\n <div class=\"space-y-4 animate-pulse\">\r\n <div class=\"h-6 bg-surface-200 rounded w-1/3\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded\"></div>\r\n <div class=\"h-10 bg-surface-200 rounded w-2/3\"></div>\r\n </div>\r\n } @else if (formConfig().sections.length > 0) {\r\n <mt-dynamic-form\r\n [formConfig]=\"formConfig()\"\r\n [formControl]=\"formControl\"\r\n >\r\n </mt-dynamic-form>\r\n } @else {\r\n <div\r\n class=\"flex justify-center items-center h-64 text-muted-color text-lg\"\r\n >\r\n {{ t(\"no-fields-visible\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n" }]
2009
- }], ctorParameters: () => [], propDecorators: { sections: [{ type: i0.Input, args: [{ isSignal: true, alias: "sections", required: false }] }] } });
2010
-
2011
- /**
2012
- * Validation Formula Constants
2013
- * Functions and operators for validation formulas
2014
- */
2015
- const VALIDATION_FUNCTION_CATEGORIES = [
2016
- {
2017
- name: 'Validation',
2018
- displayName: 'Validation',
2019
- functions: [
2020
- {
2021
- name: 'REQUIRED',
2022
- category: 'Validation',
2023
- description: 'Returns true when value is not empty',
2024
- signature: 'REQUIRED(value)',
2025
- parameters: [
2026
- {
2027
- name: 'value',
2028
- type: 'any',
2029
- description: 'Value to check',
2030
- required: true,
2031
- },
2032
- ],
2033
- returnType: 'boolean',
2034
- examples: ['REQUIRED(@Email)'],
2035
- },
2036
- {
2037
- name: 'ISNULL',
2038
- category: 'Validation',
2039
- description: 'Returns true if value is null or empty',
2040
- signature: 'ISNULL(value)',
2041
- parameters: [
2042
- {
2043
- name: 'value',
2044
- type: 'any',
2045
- description: 'Value to check',
2046
- required: true,
2047
- },
2048
- ],
2049
- returnType: 'boolean',
2050
- examples: ['ISNULL(@Phone)'],
2051
- },
2052
- {
2053
- name: 'MIN_LENGTH',
2054
- category: 'Validation',
2055
- description: 'Returns true if value length is at least min',
2056
- signature: 'MIN_LENGTH(value, min)',
2057
- parameters: [
2058
- {
2059
- name: 'value',
2060
- type: 'string',
2061
- description: 'Value to check',
2062
- required: true,
2063
- },
2064
- {
2065
- name: 'min',
2066
- type: 'number',
2067
- description: 'Minimum length',
2068
- required: true,
2069
- },
2070
- ],
2071
- returnType: 'boolean',
2072
- examples: ['MIN_LENGTH(@Password, 8)'],
2073
- },
2074
- {
2075
- name: 'MAX_LENGTH',
2076
- category: 'Validation',
2077
- description: 'Returns true if value length is at most max',
2078
- signature: 'MAX_LENGTH(value, max)',
2079
- parameters: [
2080
- {
2081
- name: 'value',
2082
- type: 'string',
2083
- description: 'Value to check',
2084
- required: true,
2085
- },
2086
- {
2087
- name: 'max',
2088
- type: 'number',
2089
- description: 'Maximum length',
2090
- required: true,
2091
- },
2092
- ],
2093
- returnType: 'boolean',
2094
- examples: ['MAX_LENGTH(@Title, 120)'],
2095
- },
2096
- {
2097
- name: 'REGEX',
2098
- category: 'Validation',
2099
- description: 'Returns true if value matches regex pattern',
2100
- signature: 'REGEX(value, pattern)',
2101
- parameters: [
2102
- {
2103
- name: 'value',
2104
- type: 'string',
2105
- description: 'Value to check',
2106
- required: true,
2107
- },
2108
- {
2109
- name: 'pattern',
2110
- type: 'string',
2111
- description: 'Regex pattern',
2112
- required: true,
2113
- },
2114
- ],
2115
- returnType: 'boolean',
2116
- examples: ['REGEX(@Email, "^[^@]+@[^@]+\\.[^@]+$")'],
2117
- },
2118
- {
2119
- name: 'BEFORE',
2120
- category: 'Validation',
2121
- description: 'Returns true if date is before reference date',
2122
- signature: 'BEFORE(date, reference)',
2123
- parameters: [
2124
- {
2125
- name: 'date',
2126
- type: 'date',
2127
- description: 'Date to check',
2128
- required: true,
2129
- },
2130
- {
2131
- name: 'reference',
2132
- type: 'date',
2133
- description: 'Reference date',
2134
- required: true,
2135
- },
2136
- ],
2137
- returnType: 'boolean',
2138
- examples: ['BEFORE(@EndDate, @StartDate)'],
2139
- },
2140
- {
2141
- name: 'AFTER',
2142
- category: 'Validation',
2143
- description: 'Returns true if date is after reference date',
2144
- signature: 'AFTER(date, reference)',
2145
- parameters: [
2146
- {
2147
- name: 'date',
2148
- type: 'date',
2149
- description: 'Date to check',
2150
- required: true,
2151
- },
2152
- {
2153
- name: 'reference',
2154
- type: 'date',
2155
- description: 'Reference date',
2156
- required: true,
2157
- },
2158
- ],
2159
- returnType: 'boolean',
2160
- examples: ['AFTER(@StartDate, @EndDate)'],
2161
- },
2162
- ],
2163
- },
2164
- {
2165
- name: 'Logic',
2166
- displayName: 'Logic Helpers',
2167
- functions: [
2168
- {
2169
- name: 'AND',
2170
- category: 'Logic',
2171
- description: 'Returns true if all conditions are true',
2172
- signature: 'AND(condition1, condition2)',
2173
- parameters: [
2174
- {
2175
- name: 'condition1',
2176
- type: 'boolean',
2177
- description: 'First condition',
2178
- required: true,
2179
- },
2180
- {
2181
- name: 'condition2',
2182
- type: 'boolean',
2183
- description: 'Second condition',
2184
- required: true,
2185
- },
2186
- ],
2187
- returnType: 'boolean',
2188
- examples: ['AND(REQUIRED(@Email), REGEX(@Email, "^.+@.+$"))'],
2189
- },
2190
- {
2191
- name: 'OR',
2192
- category: 'Logic',
2193
- description: 'Returns true if any condition is true',
2194
- signature: 'OR(condition1, condition2)',
2195
- parameters: [
2196
- {
2197
- name: 'condition1',
2198
- type: 'boolean',
2199
- description: 'First condition',
2200
- required: true,
2201
- },
2202
- {
2203
- name: 'condition2',
2204
- type: 'boolean',
2205
- description: 'Second condition',
2206
- required: true,
2207
- },
2208
- ],
2209
- returnType: 'boolean',
2210
- examples: ['OR(ISNULL(@Phone), REGEX(@Phone, "^\\+?[0-9]+$"))'],
2211
- },
2212
- {
2213
- name: 'NOT',
2214
- category: 'Logic',
2215
- description: 'Returns the opposite of a condition',
2216
- signature: 'NOT(condition)',
2217
- parameters: [
2218
- {
2219
- name: 'condition',
2220
- type: 'boolean',
2221
- description: 'Condition to negate',
2222
- required: true,
2223
- },
2224
- ],
2225
- returnType: 'boolean',
2226
- examples: ['NOT(ISNULL(@Password))'],
2227
- },
2228
- ],
2229
- },
2230
- ];
2231
- const VALIDATION_OPERATORS = [
2232
- // Arithmetic
2233
- {
2234
- symbol: '+',
2235
- name: 'Add',
2236
- type: 'arithmetic',
2237
- description: 'Addition',
2238
- precedence: 4,
2239
- },
2240
- {
2241
- symbol: '-',
2242
- name: 'Subtract',
2243
- type: 'arithmetic',
2244
- description: 'Subtraction',
2245
- precedence: 4,
2246
- },
2247
- {
2248
- symbol: '*',
2249
- name: 'Multiply',
2250
- type: 'arithmetic',
2251
- description: 'Multiplication',
2252
- precedence: 5,
2253
- },
2254
- {
2255
- symbol: '/',
2256
- name: 'Divide',
2257
- type: 'arithmetic',
2258
- description: 'Division',
2259
- precedence: 5,
2260
- },
2261
- // Comparison
2262
- {
2263
- symbol: '==',
2264
- name: 'Equal',
2265
- type: 'comparison',
2266
- description: 'Equal to',
2267
- precedence: 3,
2268
- },
2269
- {
2270
- symbol: '!=',
2271
- name: 'Not Equal',
2272
- type: 'comparison',
2273
- description: 'Not equal to',
2274
- precedence: 3,
2275
- },
2276
- {
2277
- symbol: '>',
2278
- name: 'Greater Than',
2279
- type: 'comparison',
2280
- description: 'Greater than',
2281
- precedence: 3,
2282
- },
2283
- {
2284
- symbol: '<',
2285
- name: 'Less Than',
2286
- type: 'comparison',
2287
- description: 'Less than',
2288
- precedence: 3,
2289
- },
2290
- {
2291
- symbol: '>=',
2292
- name: 'Greater or Equal',
2293
- type: 'comparison',
2294
- description: 'Greater than or equal',
2295
- precedence: 3,
2296
- },
2297
- {
2298
- symbol: '<=',
2299
- name: 'Less or Equal',
2300
- type: 'comparison',
2301
- description: 'Less than or equal',
2302
- precedence: 3,
2303
- },
2304
- // Logical
2305
- {
2306
- symbol: '&&',
2307
- name: 'And',
2308
- type: 'logical',
2309
- description: 'Logical AND',
2310
- precedence: 2,
2311
- },
2312
- {
2313
- symbol: '||',
2314
- name: 'Or',
2315
- type: 'logical',
2316
- description: 'Logical OR',
2317
- precedence: 1,
2318
- },
2319
- ];
1693
+ args: [{ selector: 'mt-fb-preview-form', standalone: true, imports: [TranslocoDirective, ClientForm], template: "<ng-container *transloco=\"let t; prefix: 'formBuilder'\">\r\n <div [class]=\"[modalService.contentClass, 'p-4', 'overflow-y-hidden!']\">\r\n <div class=\"h-full overflow-y-auto px-3 pb-10\">\r\n @if (moduleKey() && operationKey()) {\r\n <mt-client-form\r\n [moduleKey]=\"moduleKey()\"\r\n [operationKey]=\"operationKey()\"\r\n [moduleId]=\"previewInfo()?.moduleId\"\r\n [levelId]=\"previewInfo()?.levelId\"\r\n [levelDataId]=\"previewInfo()?.levelDataId\"\r\n [moduleDataId]=\"previewInfo()?.moduleDataId\"\r\n [requestSchemaId]=\"previewInfo()?.requestSchemaId\"\r\n [autoLoad]=\"true\"\r\n [preview]=\"true\"\r\n />\r\n } @else {\r\n <div\r\n class=\"flex justify-center items-center h-64 text-muted-color text-lg\"\r\n >\r\n {{ t(\"no-fields-visible\") }}\r\n </div>\r\n }\r\n </div>\r\n </div>\r\n</ng-container>\r\n" }]
1694
+ }] });
2320
1695
 
2321
1696
  class FBValidationRuleForm {
2322
1697
  modalService = inject(ModalService);
@@ -3221,7 +2596,6 @@ class FormBuilder {
3221
2596
  position: 'end',
3222
2597
  appendTo: 'page-content',
3223
2598
  dismissible: true,
3224
- inputValues: { sections: this.enrichedSections() },
3225
2599
  });
3226
2600
  }
3227
2601
  openValidationRules() {
@@ -3271,5 +2645,5 @@ i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "21.0.3", ngImpor
3271
2645
  * Generated bundle index. Do not edit.
3272
2646
  */
3273
2647
 
3274
- export { AddField, AddSection, AddValidation, DeleteField, DeleteSection, DeleteValidation, FormBuilder, FormBuilderActionKey, FormBuilderFacade, FormBuilderState, GetFormConfiguration, MoveField, ReorderFields, ResetFormBuilderState, ResetFormConfiguration, SetModuleInfo, SetProperties, ToggleValidationActive, UpdateField, UpdateSection, UpdateValidation };
2648
+ export { AddField, AddSection, AddValidation, DeleteField, DeleteSection, DeleteValidation, FormBuilder, FormBuilderActionKey, FormBuilderFacade, FormBuilderState, GetFormConfiguration, MoveField, ReorderFields, ResetFormBuilderState, ResetFormConfiguration, SetModuleInfo, SetPreviewInfo, SetProperties, ToggleValidationActive, UpdateField, UpdateSection, UpdateValidation };
3275
2649
  //# sourceMappingURL=masterteam-form-builder.mjs.map