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