@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 {
|
|
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]=\"
|
|
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
|
-
|
|
1899
|
-
//
|
|
1900
|
-
|
|
1901
|
-
//
|
|
1902
|
-
|
|
1903
|
-
|
|
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",
|
|
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,
|
|
2009
|
-
}]
|
|
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
|