form-builder-pro 1.0.6 → 1.0.7

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.
package/dist/index.mjs CHANGED
@@ -4166,6 +4166,7 @@ var formStore = createStore((set, get) => ({
4166
4166
  existingForms: [],
4167
4167
  templates: [],
4168
4168
  masterTypes: [],
4169
+ dropdownOptionsMap: {},
4169
4170
  setSchema: (schema) => {
4170
4171
  const convertIndexesToOptions = (indexes) => {
4171
4172
  if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
@@ -4183,18 +4184,43 @@ var formStore = createStore((set, get) => ({
4183
4184
  return { label: String(item), value: String(item) };
4184
4185
  });
4185
4186
  };
4187
+ const areDefaultOptions = (options) => {
4188
+ if (!options || options.length === 0)
4189
+ return true;
4190
+ return options.every(
4191
+ (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
4192
+ );
4193
+ };
4186
4194
  const state = get();
4187
4195
  if (state.masterTypes && state.masterTypes.length > 0 && schema.sections) {
4188
4196
  const updatedSections = schema.sections.map((section) => ({
4189
4197
  ...section,
4190
4198
  fields: section.fields.map((field) => {
4191
- if (field.type === "select" && field.groupName && (!field.options || field.options.length === 0)) {
4199
+ if (field.type === "select" && field.groupName) {
4192
4200
  const masterType = state.masterTypes.find(
4193
4201
  (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
4194
4202
  );
4195
- if (masterType && masterType.indexes && masterType.indexes.length > 0) {
4196
- const options = convertIndexesToOptions(masterType.indexes);
4197
- return { ...field, options };
4203
+ if (masterType) {
4204
+ if (masterType.enumName && state.dropdownOptionsMap && state.dropdownOptionsMap[masterType.enumName]) {
4205
+ return { ...field, options: state.dropdownOptionsMap[masterType.enumName] };
4206
+ }
4207
+ if (!masterType.indexes || masterType.indexes.length === 0) {
4208
+ console.warn(`[FormBuilder] Master type "${masterType.displayName}" (${masterType.name}) has empty indexes array. Dropdown will have no options. Please ensure the API returns populated indexes.`, {
4209
+ masterTypeId: masterType.id,
4210
+ masterTypeName: masterType.name,
4211
+ enumName: masterType.enumName,
4212
+ indexes: masterType.indexes
4213
+ });
4214
+ }
4215
+ if (masterType.indexes && masterType.indexes.length > 0) {
4216
+ if (!field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
4217
+ const options = convertIndexesToOptions(masterType.indexes);
4218
+ console.log(`[FormBuilder] Populating ${options.length} options from master type "${masterType.displayName}"`);
4219
+ return { ...field, options };
4220
+ }
4221
+ }
4222
+ } else {
4223
+ console.warn("[FormBuilder] Master type not found for groupName:", field.groupName);
4198
4224
  }
4199
4225
  }
4200
4226
  return field;
@@ -4205,34 +4231,129 @@ var formStore = createStore((set, get) => ({
4205
4231
  set({ schema });
4206
4232
  }
4207
4233
  },
4208
- togglePreview: () => set((state) => ({ isPreviewMode: !state.isPreviewMode })),
4234
+ togglePreview: () => {
4235
+ const state = get();
4236
+ if (state.masterTypes && state.masterTypes.length > 0 && state.schema.sections) {
4237
+ const convertIndexesToOptions = (indexes) => {
4238
+ if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
4239
+ return [];
4240
+ }
4241
+ return indexes.map((item, index2) => {
4242
+ if (typeof item === "string") {
4243
+ return { label: item, value: item };
4244
+ }
4245
+ if (typeof item === "object" && item !== null) {
4246
+ const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
4247
+ const value = item.value || item.id || item.name || String(index2);
4248
+ return { label, value };
4249
+ }
4250
+ return { label: String(item), value: String(item) };
4251
+ });
4252
+ };
4253
+ const areDefaultOptions = (options) => {
4254
+ if (!options || options.length === 0)
4255
+ return true;
4256
+ return options.every(
4257
+ (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
4258
+ );
4259
+ };
4260
+ const updatedSections = state.schema.sections.map((section) => ({
4261
+ ...section,
4262
+ fields: section.fields.map((field) => {
4263
+ if (field.type === "select" && field.groupName) {
4264
+ const masterType = state.masterTypes.find(
4265
+ (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
4266
+ );
4267
+ if (masterType && masterType.indexes && masterType.indexes.length > 0) {
4268
+ if (!field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
4269
+ const options = convertIndexesToOptions(masterType.indexes);
4270
+ return { ...field, options };
4271
+ }
4272
+ }
4273
+ }
4274
+ return field;
4275
+ })
4276
+ }));
4277
+ const hasChanges = updatedSections.some(
4278
+ (section, idx) => section.fields.some(
4279
+ (field, fieldIdx) => field !== state.schema.sections[idx]?.fields[fieldIdx]
4280
+ )
4281
+ );
4282
+ if (hasChanges) {
4283
+ set({
4284
+ schema: { ...state.schema, sections: updatedSections },
4285
+ isPreviewMode: !state.isPreviewMode
4286
+ });
4287
+ } else {
4288
+ set({ isPreviewMode: !state.isPreviewMode });
4289
+ }
4290
+ } else {
4291
+ set({ isPreviewMode: !state.isPreviewMode });
4292
+ }
4293
+ },
4209
4294
  // New Actions
4210
4295
  setExistingForms: (forms) => set({ existingForms: forms }),
4211
4296
  setTemplates: (templates) => set({ templates }),
4297
+ setDropdownOptionsMap: (map) => {
4298
+ set({ dropdownOptionsMap: map });
4299
+ const state = get();
4300
+ if (state.schema && state.schema.sections) {
4301
+ const updatedSections = state.schema.sections.map((section) => ({
4302
+ ...section,
4303
+ fields: section.fields.map((field) => {
4304
+ if (field.type === "select" && field.groupName) {
4305
+ const masterType = state.masterTypes.find(
4306
+ (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
4307
+ );
4308
+ if (masterType && masterType.enumName && map[masterType.enumName]) {
4309
+ return { ...field, options: map[masterType.enumName] };
4310
+ }
4311
+ }
4312
+ return field;
4313
+ })
4314
+ }));
4315
+ set({ schema: { ...state.schema, sections: updatedSections } });
4316
+ }
4317
+ },
4212
4318
  setMasterTypes: (masterTypes) => {
4213
4319
  set({ masterTypes });
4214
4320
  const state = get();
4215
4321
  if (state.schema && state.schema.sections) {
4322
+ const convertIndexesToOptions = (indexes) => {
4323
+ if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
4324
+ return [];
4325
+ }
4326
+ return indexes.map((item, index2) => {
4327
+ if (typeof item === "string") {
4328
+ return { label: item, value: item };
4329
+ }
4330
+ if (typeof item === "object" && item !== null) {
4331
+ const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
4332
+ const value = item.value || item.id || item.name || String(index2);
4333
+ return { label, value };
4334
+ }
4335
+ return { label: String(item), value: String(item) };
4336
+ });
4337
+ };
4338
+ const areDefaultOptions = (options) => {
4339
+ if (!options || options.length === 0)
4340
+ return true;
4341
+ return options.every(
4342
+ (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
4343
+ );
4344
+ };
4216
4345
  const updatedSections = state.schema.sections.map((section) => ({
4217
4346
  ...section,
4218
4347
  fields: section.fields.map((field) => {
4219
- if (field.type === "select" && field.groupName && (!field.options || field.options.length === 0)) {
4348
+ if (field.type === "select" && field.groupName) {
4220
4349
  const masterType = masterTypes.find(
4221
4350
  (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
4222
4351
  );
4223
4352
  if (masterType && masterType.indexes && masterType.indexes.length > 0) {
4224
- const options = masterType.indexes.map((item, index2) => {
4225
- if (typeof item === "string") {
4226
- return { label: item, value: item };
4227
- }
4228
- if (typeof item === "object" && item !== null) {
4229
- const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
4230
- const value = item.value || item.id || item.name || String(index2);
4231
- return { label, value };
4232
- }
4233
- return { label: String(item), value: String(item) };
4234
- });
4235
- return { ...field, options };
4353
+ if (!field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
4354
+ const options = convertIndexesToOptions(masterType.indexes);
4355
+ return { ...field, options };
4356
+ }
4236
4357
  }
4237
4358
  }
4238
4359
  return field;
@@ -4694,14 +4815,16 @@ var FieldRenderer = class {
4694
4815
 
4695
4816
  // src/renderer/FormRenderer.ts
4696
4817
  var FormRenderer = class {
4697
- constructor(container, schema, onSubmit) {
4818
+ constructor(container, schema, onSubmit, onDropdownValueChange) {
4698
4819
  __publicField(this, "container");
4699
4820
  __publicField(this, "schema");
4700
4821
  __publicField(this, "data", {});
4701
4822
  __publicField(this, "onSubmit");
4823
+ __publicField(this, "onDropdownValueChange");
4702
4824
  this.container = container;
4703
4825
  this.schema = schema;
4704
4826
  this.onSubmit = onSubmit;
4827
+ this.onDropdownValueChange = onDropdownValueChange;
4705
4828
  this.render();
4706
4829
  }
4707
4830
  setSchema(schema) {
@@ -4736,6 +4859,12 @@ var FormRenderer = class {
4736
4859
  fieldWrapper.className = spanClass;
4737
4860
  const fieldEl = FieldRenderer.render(field, this.data[field.id], (val) => {
4738
4861
  this.data[field.id] = val;
4862
+ if (field.type === "select" && this.onDropdownValueChange) {
4863
+ this.onDropdownValueChange({
4864
+ fieldId: field.id,
4865
+ value: val || ""
4866
+ });
4867
+ }
4739
4868
  });
4740
4869
  fieldWrapper.appendChild(fieldEl);
4741
4870
  grid.appendChild(fieldWrapper);
@@ -7302,6 +7431,21 @@ var FormBuilder = class {
7302
7431
  if (options.data?.masterTypes) {
7303
7432
  formStore.getState().setMasterTypes(options.data.masterTypes);
7304
7433
  }
7434
+ if (options.masterTypeGroups) {
7435
+ const masterTypes = options.masterTypeGroups.map((group) => ({
7436
+ id: group.id,
7437
+ name: group.displayName.toLowerCase().replace(/\s+/g, "-"),
7438
+ // Generate name from displayName
7439
+ displayName: group.displayName,
7440
+ enumName: group.enumName,
7441
+ indexes: [],
7442
+ active: true
7443
+ }));
7444
+ formStore.getState().setMasterTypes(masterTypes);
7445
+ }
7446
+ if (options.dropdownOptionsMap) {
7447
+ formStore.getState().setDropdownOptionsMap(options.dropdownOptionsMap);
7448
+ }
7305
7449
  this.render();
7306
7450
  this.setupSubscriptions();
7307
7451
  }
@@ -7335,6 +7479,23 @@ var FormBuilder = class {
7335
7479
  formStore.getState().setTemplates(templates);
7336
7480
  this.render();
7337
7481
  }
7482
+ updateDropdownOptionsMap(dropdownOptionsMap) {
7483
+ formStore.getState().setDropdownOptionsMap(dropdownOptionsMap);
7484
+ this.render();
7485
+ }
7486
+ updateMasterTypeGroups(masterTypeGroups) {
7487
+ const masterTypes = masterTypeGroups.map((group) => ({
7488
+ id: group.id,
7489
+ name: group.displayName.toLowerCase().replace(/\s+/g, "-"),
7490
+ // Generate name from displayName
7491
+ displayName: group.displayName,
7492
+ enumName: group.enumName,
7493
+ indexes: [],
7494
+ active: true
7495
+ }));
7496
+ formStore.getState().setMasterTypes(masterTypes);
7497
+ this.render();
7498
+ }
7338
7499
  loadFormTemplates(formTemplates) {
7339
7500
  const extractedSections = [];
7340
7501
  formTemplates.forEach((form) => {
@@ -7376,11 +7537,63 @@ var FormBuilder = class {
7376
7537
  wrapper.appendChild(this.renderToolbar(state));
7377
7538
  const main = createElement("div", { className: "flex flex-col md:flex-row flex-1 overflow-hidden" });
7378
7539
  if (state.isPreviewMode) {
7379
- const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
7380
- const inner = createElement("div", { className: "w-full max-w-3xl" });
7381
- new FormRenderer(inner, state.schema, (data) => alert(JSON.stringify(data, null, 2)));
7382
- previewContainer.appendChild(inner);
7383
- main.appendChild(previewContainer);
7540
+ const masterTypes = state.masterTypes;
7541
+ if (masterTypes && masterTypes.length > 0 && state.schema.sections) {
7542
+ const convertIndexesToOptions = (indexes) => {
7543
+ if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
7544
+ return [];
7545
+ }
7546
+ return indexes.map((item, index2) => {
7547
+ if (typeof item === "string") {
7548
+ return { label: item, value: item };
7549
+ }
7550
+ if (typeof item === "object" && item !== null) {
7551
+ const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
7552
+ const value = item.value || item.id || item.name || String(index2);
7553
+ return { label, value };
7554
+ }
7555
+ return { label: String(item), value: String(item) };
7556
+ });
7557
+ };
7558
+ const areDefaultOptions = (options) => {
7559
+ if (!options || options.length === 0)
7560
+ return true;
7561
+ return options.every(
7562
+ (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
7563
+ );
7564
+ };
7565
+ const previewSchema = {
7566
+ ...state.schema,
7567
+ sections: state.schema.sections.map((section) => ({
7568
+ ...section,
7569
+ fields: section.fields.map((field) => {
7570
+ if (field.type === "select" && field.groupName) {
7571
+ const masterType = masterTypes.find(
7572
+ (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
7573
+ );
7574
+ if (masterType && masterType.indexes && masterType.indexes.length > 0) {
7575
+ if (!field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
7576
+ const options = convertIndexesToOptions(masterType.indexes);
7577
+ return { ...field, options };
7578
+ }
7579
+ }
7580
+ }
7581
+ return field;
7582
+ })
7583
+ }))
7584
+ };
7585
+ const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
7586
+ const inner = createElement("div", { className: "w-full max-w-3xl" });
7587
+ new FormRenderer(inner, previewSchema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7588
+ previewContainer.appendChild(inner);
7589
+ main.appendChild(previewContainer);
7590
+ } else {
7591
+ const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
7592
+ const inner = createElement("div", { className: "w-full max-w-3xl" });
7593
+ new FormRenderer(inner, state.schema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7594
+ previewContainer.appendChild(inner);
7595
+ main.appendChild(previewContainer);
7596
+ }
7384
7597
  } else {
7385
7598
  const toolboxWrapper = createElement("div", { className: "form-builder-toolbox-wrapper w-full md:w-80 bg-white dark:bg-gray-900 border-r md:border-r border-b md:border-b-0 border-gray-200 dark:border-gray-800" });
7386
7599
  toolboxWrapper.appendChild(this.renderToolbox());
@@ -7689,6 +7902,7 @@ var FormBuilder = class {
7689
7902
  if (selectedField.type === "select") {
7690
7903
  const masterTypes = formStore.getState().masterTypes;
7691
7904
  const activeMasterTypes = masterTypes.filter((mt) => mt.active === true);
7905
+ const dropdownOptionsMap = formStore.getState().dropdownOptionsMap;
7692
7906
  const convertIndexesToOptions = (indexes) => {
7693
7907
  if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
7694
7908
  return [];
@@ -7711,11 +7925,16 @@ var FormBuilder = class {
7711
7925
  const groupNameSelect = createElement("select", {
7712
7926
  className: "w-full px-3 py-2 border border-gray-300 dark:border-gray-700 rounded-md bg-transparent",
7713
7927
  onchange: (e) => {
7714
- const selectedValue = e.target.value;
7715
- if (selectedValue) {
7716
- const selectedMasterType = activeMasterTypes.find((mt) => mt.id === selectedValue || mt.name === selectedValue);
7928
+ const selectedEnumName = e.target.value;
7929
+ if (selectedEnumName) {
7930
+ const selectedMasterType = activeMasterTypes.find((mt) => mt.enumName === selectedEnumName);
7717
7931
  if (selectedMasterType) {
7718
- const options = convertIndexesToOptions(selectedMasterType.indexes || []);
7932
+ let options = [];
7933
+ if (dropdownOptionsMap && dropdownOptionsMap[selectedEnumName]) {
7934
+ options = dropdownOptionsMap[selectedEnumName];
7935
+ } else if (selectedMasterType.indexes && selectedMasterType.indexes.length > 0) {
7936
+ options = convertIndexesToOptions(selectedMasterType.indexes);
7937
+ }
7719
7938
  formStore.getState().updateField(selectedField.id, {
7720
7939
  groupName: {
7721
7940
  id: selectedMasterType.id,
@@ -7723,6 +7942,12 @@ var FormBuilder = class {
7723
7942
  },
7724
7943
  options: options.length > 0 ? options : void 0
7725
7944
  });
7945
+ if (this.options.onGroupSelectionChange) {
7946
+ this.options.onGroupSelectionChange({
7947
+ fieldId: selectedField.id,
7948
+ groupEnumName: selectedEnumName
7949
+ });
7950
+ }
7726
7951
  }
7727
7952
  } else {
7728
7953
  formStore.getState().updateField(selectedField.id, {
@@ -7740,8 +7965,9 @@ var FormBuilder = class {
7740
7965
  }));
7741
7966
  activeMasterTypes.forEach((mt) => {
7742
7967
  const isSelected = selectedField.groupName && (selectedField.groupName.id === mt.id || selectedField.groupName.name === mt.name);
7968
+ const optionValue = mt.enumName || mt.id || mt.name;
7743
7969
  groupNameSelect.appendChild(createElement("option", {
7744
- value: mt.id || mt.name,
7970
+ value: optionValue,
7745
7971
  text: mt.displayName || mt.name,
7746
7972
  selected: !!isSelected
7747
7973
  }));
@@ -7752,8 +7978,13 @@ var FormBuilder = class {
7752
7978
  const currentMasterType = activeMasterTypes.find(
7753
7979
  (mt) => mt.id === selectedField.groupName?.id || mt.name === selectedField.groupName?.name
7754
7980
  );
7755
- if (currentMasterType && currentMasterType.indexes && currentMasterType.indexes.length > 0) {
7756
- const options = convertIndexesToOptions(currentMasterType.indexes);
7981
+ if (currentMasterType) {
7982
+ let options = [];
7983
+ if (currentMasterType.enumName && dropdownOptionsMap && dropdownOptionsMap[currentMasterType.enumName]) {
7984
+ options = dropdownOptionsMap[currentMasterType.enumName];
7985
+ } else if (currentMasterType.indexes && currentMasterType.indexes.length > 0) {
7986
+ options = convertIndexesToOptions(currentMasterType.indexes);
7987
+ }
7757
7988
  if (options.length > 0) {
7758
7989
  formStore.getState().updateField(selectedField.id, { options });
7759
7990
  }