@hubsync/esign-web-sdk 6.9.12 → 6.9.13

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.
@@ -457,11 +457,9 @@ export class VerdocsSign {
457
457
  }
458
458
  focusNextFieldAfter(field) {
459
459
  setTimeout(() => {
460
- const fields = this.getSortedFillableFields();
461
- const currentIndex = fields.findIndex(f => f.name === field.name);
462
- if (currentIndex >= 0 && currentIndex < fields.length - 1) {
463
- this.focusFieldElement(fields[currentIndex + 1]);
464
- }
460
+ const next = this.getNextUnfilledField(field);
461
+ if (next)
462
+ this.focusFieldElement(next);
465
463
  }, 100);
466
464
  }
467
465
  focusFieldElement(field) {
@@ -476,11 +474,6 @@ export class VerdocsSign {
476
474
  handleStartSigning() {
477
475
  this.markEnvelopeStarted();
478
476
  this.signingProgressMode = 'signing';
479
- const fields = this.getSortedFillableFields();
480
- const startField = fields.find(field => !this.isFieldActuallyFilled(field)) || fields[0];
481
- if (startField) {
482
- this.focusFieldElement(startField);
483
- }
484
477
  this.adoptingSignature = true;
485
478
  }
486
479
  async handleFieldChange(field, e) {
@@ -641,12 +634,10 @@ export class VerdocsSign {
641
634
  }
642
635
  return;
643
636
  }
644
- // Find all unfilled fields and move to the next one in sequence
645
- const allUnfilled = this.getSortedFillableFields().filter(f => !this.isFieldActuallyFilled(f));
646
- const nextUnfilled = this.getNextFieldFromList(allUnfilled);
647
- if (nextUnfilled) {
648
- this.focusFieldElement(nextUnfilled);
649
- }
637
+ const currentField = this.getSortedFillableFields().find(f => f.name === this.focusedField);
638
+ const next = this.getNextUnfilledField(currentField);
639
+ if (next)
640
+ this.focusFieldElement(next);
650
641
  }
651
642
  handleNextOptional() {
652
643
  const unfilledOptional = this.getSortedFillableFields().filter(f => !f.required && !this.isFieldActuallyFilled(f));
@@ -670,8 +661,10 @@ export class VerdocsSign {
670
661
  }
671
662
  // See if everything that "needs to be" filled in is, and all "fillable fields" are valid
672
663
  checkRecipientFields() {
673
- const invalidFields = this.getRecipientFields().filter(field => !isFieldValid(field, this.getRecipientFields()));
674
- if (invalidFields.length < 1) {
664
+ const allFields = this.getSortedFillableFields();
665
+ const requiredIncomplete = allFields.some(f => f.required && !this.isFieldActuallyFilled(f));
666
+ const invalidFilled = allFields.some(f => this.isFieldActuallyFilled(f) && !isFieldValid(f, this.getRecipientFields()));
667
+ if (!requiredIncomplete && !invalidFilled) {
675
668
  this.nextButtonLabel = 'Finish';
676
669
  if (!this.nextSubmits) {
677
670
  this.nextSubmits = true;
@@ -715,20 +708,15 @@ export class VerdocsSign {
715
708
  (field.type !== 'radio' || field.value === 'true') &&
716
709
  (field.type !== 'checkbox' || field.value === 'true'));
717
710
  }
718
- getNextRequiredField() {
719
- // Find and focus the next incomplete field (that is fillable)
720
- const emptyFields = this.getSortedFillableFields().filter(field => field.required && !this.isFieldActuallyFilled(field));
721
- sortFields(emptyFields);
722
- if (emptyFields.length === 0) {
723
- const allUnfilled = this.getSortedFillableFields().filter(field => !this.isFieldActuallyFilled(field));
724
- sortFields(allUnfilled);
725
- if (allUnfilled.length > 0) {
726
- // If we are here, there are no required fields left, but there are optional ones.
727
- return this.getNextFieldFromList(allUnfilled);
728
- }
729
- return null;
730
- }
731
- return this.getNextFieldFromList(emptyFields);
711
+ getNextUnfilledField(after) {
712
+ const allFields = this.getSortedFillableFields();
713
+ const startIndex = after ? allFields.findIndex(f => f.name === after.name) + 1 : 0;
714
+ // Look forward from current position first
715
+ const nextAfter = allFields.slice(startIndex).find(f => !this.isFieldActuallyFilled(f));
716
+ if (nextAfter)
717
+ return nextAfter;
718
+ // Wrap to beginning if nothing unfilled ahead
719
+ return allFields.slice(0, startIndex).find(f => !this.isFieldActuallyFilled(f)) || null;
732
720
  }
733
721
  getNextFieldFromList(fields) {
734
722
  const focusedIndex = fields.findIndex(field => field.name === this.focusedField);
@@ -761,14 +749,16 @@ export class VerdocsSign {
761
749
  // Remove existing flags
762
750
  const existingFlags = controlsDiv.querySelectorAll('.verdocs-flag-instance');
763
751
  existingFlags.forEach(el => el.remove());
764
- let nextField = this.getNextRequiredField();
765
752
  const focusedFieldObj = this.getRecipientFields().find(f => f.name === this.focusedField);
766
- // If the currently focused field is unfilled, we should point the flag to IT, not the next one.
767
- // getNextRequiredField() is designed for the "Next" button (skipping current), but the visual flag
768
- // should guide the user to the current task if it's incomplete.
753
+ // If the currently focused field is unfilled, point the flag to it.
754
+ // Otherwise find the next unfilled field forward from the current position.
755
+ let nextField;
769
756
  if (focusedFieldObj && !this.isFieldActuallyFilled(focusedFieldObj)) {
770
757
  nextField = focusedFieldObj;
771
758
  }
759
+ else {
760
+ nextField = this.getNextUnfilledField(focusedFieldObj);
761
+ }
772
762
  if (nextField && nextField.page === pageInfo.pageNumber && nextField.document_id === pageInfo.documentId) {
773
763
  const variant = 'fill';
774
764
  let label = 'FILL';
@@ -1105,7 +1095,7 @@ export class VerdocsSign {
1105
1095
  return (h("span", { class: "remaining-count" }, remaining, " required field", remaining === 1 ? '' : 's', " left"));
1106
1096
  }
1107
1097
  return (h("span", { class: "remaining-count" }, h("span", { class: "check-icon", innerHTML: CheckCircleIcon }), "All required fields complete", optionalLeft > 0 && h("span", { class: "separator" }, "|"), optionalLeft > 0 && (h("span", { class: "review-optional", onClick: () => this.handleNextOptional() }, "Review ", optionalLeft, " optional"))));
1108
- })(), !this.finishLater && (h("verdocs-button", { size: "xsmall", label: this.nextButtonLabel === 'Next' ? 'Next Required' : this.nextButtonLabel, disabled: !this.agreed || this.submitting, onClick: () => this.handleNext() })), h("div", { class: { 'icon-button': true, 'minus': true, 'disabled': this.zoomLevel === 'normal' }, innerHTML: ToolbarMinusIcon, onClick: () => this.handleZoomOut() }), h("div", { class: { 'icon-button': true, 'plus': true, 'disabled': this.zoomLevel === 'zoom2' }, innerHTML: ToolbarPlusIcon, onClick: () => this.handleZoomIn() }), h("verdocs-dropdown", { options: !this.isDone && !this.finishLater ? inProgressMenuOptions : doneMenuOptions, onOptionSelected: e => this.handleOptionSelected(e) })))), this.toolbarStyle === 'controls' && (h("div", { class: "controls-toolbar" }, h("div", { class: "left-controls" }, h("div", { class: "title" }, this.envelope.name)), h("div", { class: "center-controls", style: { display: 'none' } }, h("span", { class: "label" }, "Page"), h("div", { class: "select-wrapper" }, h("verdocs-select-input", { options: pageOptions, value: this.pageNumber.toString(), onInput: e => this.handlePageSelect(e) })), h("span", { class: "count" }, "of ", totalPages)), h("div", { class: "right-controls" }, h("verdocs-button", { class: "mobile-next-button", label: this.nextButtonLabel, size: "xsmall", disabled: !this.agreed || this.submitting, onClick: () => this.handleNext() }), h("div", { class: { 'icon-button': true, 'minus': true, 'disabled': this.zoomLevel === 'normal' }, innerHTML: ToolbarMinusIcon, onClick: () => this.handleZoomOut() }), h("div", { class: { 'icon-button': true, 'plus': true, 'disabled': this.zoomLevel === 'zoom2' }, innerHTML: ToolbarPlusIcon, onClick: () => this.handleZoomIn() }), h("div", { class: "icon-button download", innerHTML: ToolbarDownloadIcon, onClick: () => this.handleOptionSelected({ detail: { id: 'download' } }) }), h("div", { class: "icon-button print", innerHTML: ToolbarPrintIcon, onClick: () => this.handleOptionSelected({ detail: { id: 'print' } }) })))), h("verdocs-signing-progress", { mode: this.signingProgressMode, focusedField: this.focusedField, fields: this.getSortedFillableFields(), recipientFields: this.getRecipientFields(), onStarted: () => {
1098
+ })(), !this.finishLater && (h("verdocs-button", { size: "xsmall", label: this.nextButtonLabel, disabled: !this.agreed || this.submitting, onClick: () => this.handleNext() })), h("div", { class: { 'icon-button': true, 'minus': true, 'disabled': this.zoomLevel === 'normal' }, innerHTML: ToolbarMinusIcon, onClick: () => this.handleZoomOut() }), h("div", { class: { 'icon-button': true, 'plus': true, 'disabled': this.zoomLevel === 'zoom2' }, innerHTML: ToolbarPlusIcon, onClick: () => this.handleZoomIn() }), h("verdocs-dropdown", { options: !this.isDone && !this.finishLater ? inProgressMenuOptions : doneMenuOptions, onOptionSelected: e => this.handleOptionSelected(e) })))), this.toolbarStyle === 'controls' && (h("div", { class: "controls-toolbar" }, h("div", { class: "left-controls" }, h("div", { class: "title" }, this.envelope.name)), h("div", { class: "center-controls", style: { display: 'none' } }, h("span", { class: "label" }, "Page"), h("div", { class: "select-wrapper" }, h("verdocs-select-input", { options: pageOptions, value: this.pageNumber.toString(), onInput: e => this.handlePageSelect(e) })), h("span", { class: "count" }, "of ", totalPages)), h("div", { class: "right-controls" }, h("verdocs-button", { class: "mobile-next-button", label: this.nextButtonLabel, size: "xsmall", disabled: !this.agreed || this.submitting, onClick: () => this.handleNext() }), h("div", { class: { 'icon-button': true, 'minus': true, 'disabled': this.zoomLevel === 'normal' }, innerHTML: ToolbarMinusIcon, onClick: () => this.handleZoomOut() }), h("div", { class: { 'icon-button': true, 'plus': true, 'disabled': this.zoomLevel === 'zoom2' }, innerHTML: ToolbarPlusIcon, onClick: () => this.handleZoomIn() }), h("div", { class: "icon-button download", innerHTML: ToolbarDownloadIcon, onClick: () => this.handleOptionSelected({ detail: { id: 'download' } }) }), h("div", { class: "icon-button print", innerHTML: ToolbarPrintIcon, onClick: () => this.handleOptionSelected({ detail: { id: 'print' } }) })))), h("verdocs-signing-progress", { mode: this.signingProgressMode, focusedField: this.focusedField, fields: this.getSortedFillableFields(), recipientFields: this.getRecipientFields(), onStarted: () => {
1109
1099
  this.handleStartSigning();
1110
1100
  }, onNext: () => this.handleNext(), onPrevious: () => this.handlePrev(), onExit: () => this.handleNext() }), h("div", { class: `document signed-document-container zoom-${this.zoomLevel}` }, (this.envelope.documents || []).map(envelopeDocument => {
1111
1101
  const pageNumbers = integerSequence(1, envelopeDocument.pages);
@@ -1146,7 +1136,10 @@ export class VerdocsSign {
1146
1136
  this.showSpinner = false;
1147
1137
  this.adoptingSignature = false;
1148
1138
  this.markEnvelopeStarted();
1149
- // Apply the new signature/initials to the field that triggered the dialog.
1139
+ // Apply the new signature/initials to the field that triggered the dialog (e.g. user
1140
+ // clicked an existing sig/initial field). Track which field was applied so we can
1141
+ // advance forward from it rather than jumping back to the start of the document.
1142
+ let appliedToField = null;
1150
1143
  if (this.focusedField) {
1151
1144
  const fieldObj = this.getRecipientFields().find(f => f.name === this.focusedField);
1152
1145
  if (fieldObj) {
@@ -1154,10 +1147,16 @@ export class VerdocsSign {
1154
1147
  if (id) {
1155
1148
  const updateResult = await updateEnvelopeField(this.endpoint, this.envelopeId, this.roleId, fieldObj.name, id, false);
1156
1149
  this.updateRecipientFieldValue(fieldObj.name, updateResult);
1150
+ appliedToField = fieldObj;
1157
1151
  }
1158
1152
  }
1159
1153
  this.focusedField = '';
1160
1154
  }
1155
+ // Navigate to the next unfilled field: forward from where we applied (or from the
1156
+ // beginning when adopting at session start with no pre-focused field).
1157
+ const nextField = this.getNextUnfilledField(appliedToField !== null && appliedToField !== void 0 ? appliedToField : undefined);
1158
+ if (nextField)
1159
+ this.focusFieldElement(nextField);
1161
1160
  // Update any existing field elements in the DOM with the new IDs. This prevents them from
1162
1161
  // needing to show the adoption dialog again if they are clicked.
1163
1162
  const sigFields = this.el.querySelectorAll('verdocs-field-signature');