form-builder-pro 1.0.13 → 1.0.15

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
@@ -7564,10 +7564,20 @@ var SectionList = class {
7564
7564
 
7565
7565
  // src/builder/FormBuilder.ts
7566
7566
  var FormBuilder = class {
7567
+ // Track previous preview state to detect mode changes
7567
7568
  constructor(container, options = {}) {
7568
7569
  __publicField(this, "container");
7569
7570
  __publicField(this, "unsubscribe");
7570
7571
  __publicField(this, "options");
7572
+ __publicField(this, "requestedMasterTypesCache", /* @__PURE__ */ new Set());
7573
+ // Cache to track requested master types
7574
+ __publicField(this, "isTriggeringApiCalls", false);
7575
+ // Flag to prevent concurrent API triggers
7576
+ __publicField(this, "previewRenderer", null);
7577
+ // Store FormRenderer instance to preserve selections
7578
+ __publicField(this, "lastPreviewSchema", null);
7579
+ // Track last preview schema to detect changes
7580
+ __publicField(this, "wasInPreviewMode", false);
7571
7581
  __publicField(this, "activeTab", "fields");
7572
7582
  if (!container) {
7573
7583
  throw new Error("Builder container not found. Please ensure the container element exists before initializing FormBuilder.");
@@ -7648,6 +7658,9 @@ var FormBuilder = class {
7648
7658
  }
7649
7659
  updateDropdownOptionsMap(dropdownOptionsMap) {
7650
7660
  formStore.getState().setDropdownOptionsMap(dropdownOptionsMap);
7661
+ Object.keys(dropdownOptionsMap).forEach((groupEnumName) => {
7662
+ if (dropdownOptionsMap[groupEnumName] && dropdownOptionsMap[groupEnumName].length > 0) ;
7663
+ });
7651
7664
  this.render();
7652
7665
  }
7653
7666
  updateMasterTypeGroups(masterTypeGroups) {
@@ -7704,106 +7717,145 @@ var FormBuilder = class {
7704
7717
  wrapper.appendChild(this.renderToolbar(state));
7705
7718
  const main = createElement("div", { className: "flex flex-col md:flex-row flex-1 overflow-hidden" });
7706
7719
  if (state.isPreviewMode) {
7707
- const masterTypes = state.masterTypes;
7720
+ const masterTypes = state.masterTypes || [];
7708
7721
  const dropdownOptionsMap = state.dropdownOptionsMap;
7709
- if (masterTypes && masterTypes.length > 0 && state.schema.sections) {
7710
- const convertIndexesToOptions = (indexes) => {
7711
- if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
7712
- return [];
7713
- }
7714
- return indexes.map((item, index2) => {
7715
- if (typeof item === "string") {
7716
- return { label: item, value: item };
7717
- }
7718
- if (typeof item === "object" && item !== null) {
7719
- const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
7720
- const value = item.value || item.id || item.name || String(index2);
7721
- return { label, value };
7722
+ if (state.schema.sections) {
7723
+ let previewSchema = state.schema;
7724
+ if (masterTypes && masterTypes.length > 0) {
7725
+ const convertIndexesToOptions = (indexes) => {
7726
+ if (!indexes || !Array.isArray(indexes) || indexes.length === 0) {
7727
+ return [];
7722
7728
  }
7723
- return { label: String(item), value: String(item) };
7724
- });
7725
- };
7726
- const areDefaultOptions = (options) => {
7727
- if (!options || options.length === 0)
7728
- return true;
7729
- return options.every(
7730
- (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
7731
- );
7732
- };
7733
- const fieldsNeedingApiCall = [];
7734
- const previewSchema = {
7735
- ...state.schema,
7736
- sections: state.schema.sections.map((section) => ({
7737
- ...section,
7738
- fields: section.fields.map((field) => {
7739
- if (field.type === "select") {
7740
- let masterType;
7741
- if (field.masterTypeName) {
7742
- masterType = masterTypes.find(
7743
- (mt) => mt.active === true && mt.enumName === field.masterTypeName
7744
- );
7745
- if (masterType && masterType.enumName) {
7746
- fieldsNeedingApiCall.push({
7747
- fieldId: field.id,
7748
- groupEnumName: masterType.enumName
7749
- });
7750
- }
7751
- } else if (field.groupName) {
7752
- masterType = masterTypes.find(
7753
- (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
7754
- );
7755
- }
7756
- if (masterType) {
7757
- let options = [];
7758
- if (masterType.enumName && dropdownOptionsMap && dropdownOptionsMap[masterType.enumName]) {
7759
- options = dropdownOptionsMap[masterType.enumName];
7760
- } else if (masterType.indexes && masterType.indexes.length > 0) {
7761
- options = convertIndexesToOptions(masterType.indexes);
7729
+ return indexes.map((item, index2) => {
7730
+ if (typeof item === "string") {
7731
+ return { label: item, value: item };
7732
+ }
7733
+ if (typeof item === "object" && item !== null) {
7734
+ const label = item.label || item.name || item.displayName || item.text || `Option ${index2 + 1}`;
7735
+ const value = item.value || item.id || item.name || String(index2);
7736
+ return { label, value };
7737
+ }
7738
+ return { label: String(item), value: String(item) };
7739
+ });
7740
+ };
7741
+ const areDefaultOptions = (options) => {
7742
+ if (!options || options.length === 0)
7743
+ return true;
7744
+ return options.every(
7745
+ (opt, idx) => opt.label === `Option ${idx + 1}` && (opt.value === `opt${idx + 1}` || opt.value === `Option ${idx + 1}`)
7746
+ );
7747
+ };
7748
+ const fieldsNeedingApiCall = [];
7749
+ previewSchema = {
7750
+ ...state.schema,
7751
+ sections: state.schema.sections.map((section) => ({
7752
+ ...section,
7753
+ fields: section.fields.map((field) => {
7754
+ if (field.type === "select") {
7755
+ let masterType;
7756
+ if (field.masterTypeName) {
7757
+ masterType = masterTypes.find(
7758
+ (mt) => mt.active === true && mt.enumName === field.masterTypeName
7759
+ );
7760
+ if (masterType && masterType.enumName) {
7761
+ const hasOptionsInMap = dropdownOptionsMap && dropdownOptionsMap[masterType.enumName] && dropdownOptionsMap[masterType.enumName].length > 0;
7762
+ const hasOptionsInIndexes = masterType.indexes && masterType.indexes.length > 0;
7763
+ const alreadyRequested = this.requestedMasterTypesCache.has(masterType.enumName);
7764
+ if (!hasOptionsInMap && !hasOptionsInIndexes && !alreadyRequested) {
7765
+ this.requestedMasterTypesCache.add(masterType.enumName);
7766
+ fieldsNeedingApiCall.push({
7767
+ fieldId: field.id,
7768
+ groupEnumName: masterType.enumName
7769
+ });
7770
+ }
7771
+ }
7772
+ } else if (field.groupName) {
7773
+ masterType = masterTypes.find(
7774
+ (mt) => mt.active === true && (mt.id === field.groupName?.id || mt.name === field.groupName?.name)
7775
+ );
7762
7776
  }
7763
- if (options.length > 0) {
7764
- if (field.masterTypeName || !field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
7765
- return { ...field, options };
7777
+ if (masterType) {
7778
+ let options = [];
7779
+ if (masterType.enumName && dropdownOptionsMap && dropdownOptionsMap[masterType.enumName]) {
7780
+ options = dropdownOptionsMap[masterType.enumName];
7781
+ } else if (masterType.indexes && masterType.indexes.length > 0) {
7782
+ options = convertIndexesToOptions(masterType.indexes);
7783
+ }
7784
+ if (options.length > 0) {
7785
+ if (field.masterTypeName || !field.options || field.options.length === 0 || areDefaultOptions(field.options)) {
7786
+ return { ...field, options };
7787
+ }
7766
7788
  }
7767
7789
  }
7768
7790
  }
7769
- }
7770
- return field;
7771
- })
7772
- }))
7773
- };
7774
- if (fieldsNeedingApiCall.length > 0 && this.options.onGroupSelectionChange) {
7775
- setTimeout(() => {
7776
- const uniqueApiCalls = /* @__PURE__ */ new Map();
7777
- fieldsNeedingApiCall.forEach(({ fieldId, groupEnumName }) => {
7778
- if (!uniqueApiCalls.has(groupEnumName)) {
7779
- uniqueApiCalls.set(groupEnumName, []);
7780
- }
7781
- uniqueApiCalls.get(groupEnumName).push(fieldId);
7782
- });
7783
- uniqueApiCalls.forEach((fieldIds, groupEnumName) => {
7784
- if (process.env.NODE_ENV === "development") {
7785
- console.log(`[FormBuilder] Preview: Triggering API call for masterTypeName "${groupEnumName}" (affects ${fieldIds.length} field(s))`);
7786
- }
7787
- this.options.onGroupSelectionChange({
7788
- fieldId: fieldIds[0],
7789
- groupEnumName
7791
+ return field;
7792
+ })
7793
+ }))
7794
+ };
7795
+ if (fieldsNeedingApiCall.length > 0 && this.options.onGroupSelectionChange && !this.isTriggeringApiCalls) {
7796
+ this.isTriggeringApiCalls = true;
7797
+ setTimeout(() => {
7798
+ const uniqueApiCalls = /* @__PURE__ */ new Map();
7799
+ fieldsNeedingApiCall.forEach(({ fieldId, groupEnumName }) => {
7800
+ if (!uniqueApiCalls.has(groupEnumName)) {
7801
+ uniqueApiCalls.set(groupEnumName, []);
7802
+ }
7803
+ uniqueApiCalls.get(groupEnumName).push(fieldId);
7790
7804
  });
7791
- });
7792
- }, 0);
7805
+ uniqueApiCalls.forEach((fieldIds, groupEnumName) => {
7806
+ if (process.env.NODE_ENV === "development") {
7807
+ console.log(`[FormBuilder] Preview: Triggering API call for masterTypeName "${groupEnumName}" (affects ${fieldIds.length} field(s))`);
7808
+ }
7809
+ this.options.onGroupSelectionChange({
7810
+ fieldId: fieldIds[0],
7811
+ groupEnumName
7812
+ });
7813
+ });
7814
+ setTimeout(() => {
7815
+ this.isTriggeringApiCalls = false;
7816
+ }, 100);
7817
+ }, 0);
7818
+ }
7793
7819
  }
7794
7820
  const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
7795
7821
  const inner = createElement("div", { className: "w-full max-w-3xl" });
7796
- new FormRenderer(inner, previewSchema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7822
+ const structureChanged = !this.lastPreviewSchema || this.lastPreviewSchema.id !== previewSchema.id || this.lastPreviewSchema.sections.length !== previewSchema.sections.length || JSON.stringify(this.lastPreviewSchema.sections.map((s) => ({ id: s.id, fields: s.fields.map((f) => ({ id: f.id, type: f.type })) }))) !== JSON.stringify(previewSchema.sections.map((s) => ({ id: s.id, fields: s.fields.map((f) => ({ id: f.id, type: f.type })) })));
7823
+ if (!this.previewRenderer || structureChanged) {
7824
+ if (this.previewRenderer) {
7825
+ inner.innerHTML = "";
7826
+ }
7827
+ this.previewRenderer = new FormRenderer(inner, previewSchema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7828
+ this.lastPreviewSchema = previewSchema;
7829
+ } else {
7830
+ if (this.lastPreviewSchema) {
7831
+ const optionsChanged = JSON.stringify(this.lastPreviewSchema.sections.flatMap((s) => s.fields.map((f) => f.options))) !== JSON.stringify(previewSchema.sections.flatMap((s) => s.fields.map((f) => f.options)));
7832
+ if (optionsChanged && this.previewRenderer) {
7833
+ this.previewRenderer.setSchema(previewSchema);
7834
+ this.lastPreviewSchema = previewSchema;
7835
+ }
7836
+ }
7837
+ }
7797
7838
  previewContainer.appendChild(inner);
7798
7839
  main.appendChild(previewContainer);
7799
7840
  } else {
7800
7841
  const previewContainer = createElement("div", { className: "flex-1 p-8 overflow-y-auto bg-white dark:bg-gray-900 flex justify-center" });
7801
7842
  const inner = createElement("div", { className: "w-full max-w-3xl" });
7802
- new FormRenderer(inner, state.schema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7843
+ if (!this.previewRenderer) {
7844
+ this.previewRenderer = new FormRenderer(inner, state.schema, (data) => alert(JSON.stringify(data, null, 2)), this.options.onDropdownValueChange);
7845
+ this.lastPreviewSchema = state.schema;
7846
+ } else {
7847
+ this.previewRenderer.setSchema(state.schema);
7848
+ this.lastPreviewSchema = state.schema;
7849
+ }
7803
7850
  previewContainer.appendChild(inner);
7804
7851
  main.appendChild(previewContainer);
7805
7852
  }
7806
7853
  } else {
7854
+ if (this.wasInPreviewMode) {
7855
+ this.previewRenderer = null;
7856
+ this.lastPreviewSchema = null;
7857
+ }
7858
+ this.wasInPreviewMode = false;
7807
7859
  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" });
7808
7860
  toolboxWrapper.appendChild(this.renderToolbox());
7809
7861
  main.appendChild(toolboxWrapper);