@oneblink/apps-react 13.0.0-beta.1 → 13.0.0-beta.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.
Files changed (123) hide show
  1. package/dist/OneBlinkFormBase.d.ts +23 -3
  2. package/dist/OneBlinkFormBase.js +351 -193
  3. package/dist/OneBlinkFormBase.js.map +1 -1
  4. package/dist/OneBlinkReadOnlyForm.d.ts +17 -7
  5. package/dist/OneBlinkReadOnlyForm.js +24 -8
  6. package/dist/OneBlinkReadOnlyForm.js.map +1 -1
  7. package/dist/apps/approvals-service.d.ts +2 -60
  8. package/dist/apps/approvals-service.js +1 -181
  9. package/dist/apps/approvals-service.js.map +1 -1
  10. package/dist/apps/services/api/submissions.d.ts +3 -2
  11. package/dist/apps/services/api/submissions.js +3 -6
  12. package/dist/apps/services/api/submissions.js.map +1 -1
  13. package/dist/apps/submission-service.d.ts +11 -5
  14. package/dist/apps/submission-service.js +9 -4
  15. package/dist/apps/submission-service.js.map +1 -1
  16. package/dist/components/renderer/LookupButton.d.ts +1 -2
  17. package/dist/components/renderer/LookupButton.js +7 -6
  18. package/dist/components/renderer/LookupButton.js.map +1 -1
  19. package/dist/components/renderer/LookupNotification.js +31 -24
  20. package/dist/components/renderer/LookupNotification.js.map +1 -1
  21. package/dist/components/renderer/OneBlinkFormElements.d.ts +5 -7
  22. package/dist/components/renderer/OneBlinkFormElements.js +10 -35
  23. package/dist/components/renderer/OneBlinkFormElements.js.map +1 -1
  24. package/dist/components/renderer/PageFormElements.js +8 -3
  25. package/dist/components/renderer/PageFormElements.js.map +1 -1
  26. package/dist/components/renderer/ReverseGeocode.js +6 -11
  27. package/dist/components/renderer/ReverseGeocode.js.map +1 -1
  28. package/dist/form-elements/FormElementABN.js +1 -1
  29. package/dist/form-elements/FormElementABN.js.map +1 -1
  30. package/dist/form-elements/FormElementBSB.js +1 -1
  31. package/dist/form-elements/FormElementBSB.js.map +1 -1
  32. package/dist/form-elements/FormElementBarcodeScanner.js +1 -1
  33. package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
  34. package/dist/form-elements/FormElementCalculation.js +1 -0
  35. package/dist/form-elements/FormElementCalculation.js.map +1 -1
  36. package/dist/form-elements/FormElementCheckBoxes.js +1 -1
  37. package/dist/form-elements/FormElementCheckBoxes.js.map +1 -1
  38. package/dist/form-elements/FormElementDate.js +1 -1
  39. package/dist/form-elements/FormElementDate.js.map +1 -1
  40. package/dist/form-elements/FormElementDateTime.js +1 -1
  41. package/dist/form-elements/FormElementDateTime.js.map +1 -1
  42. package/dist/form-elements/FormElementEmail.js +1 -1
  43. package/dist/form-elements/FormElementEmail.js.map +1 -1
  44. package/dist/form-elements/FormElementForm.d.ts +8 -9
  45. package/dist/form-elements/FormElementForm.js +4 -3
  46. package/dist/form-elements/FormElementForm.js.map +1 -1
  47. package/dist/form-elements/FormElementLookupButton.js +4 -3
  48. package/dist/form-elements/FormElementLookupButton.js.map +1 -1
  49. package/dist/form-elements/FormElementNumber.js +1 -1
  50. package/dist/form-elements/FormElementNumber.js.map +1 -1
  51. package/dist/form-elements/FormElementRepeatableSet.d.ts +4 -4
  52. package/dist/form-elements/FormElementRepeatableSet.js +6 -4
  53. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  54. package/dist/form-elements/FormElementSection.d.ts +3 -3
  55. package/dist/form-elements/FormElementSection.js +2 -2
  56. package/dist/form-elements/FormElementSection.js.map +1 -1
  57. package/dist/form-elements/FormElementSelect.js +1 -1
  58. package/dist/form-elements/FormElementSelect.js.map +1 -1
  59. package/dist/form-elements/FormElementSummary.js +2 -0
  60. package/dist/form-elements/FormElementSummary.js.map +1 -1
  61. package/dist/form-elements/FormElementTelephone.js +1 -1
  62. package/dist/form-elements/FormElementTelephone.js.map +1 -1
  63. package/dist/form-elements/FormElementText.js +1 -1
  64. package/dist/form-elements/FormElementText.js.map +1 -1
  65. package/dist/form-elements/FormElementTextarea.js +1 -1
  66. package/dist/form-elements/FormElementTextarea.js.map +1 -1
  67. package/dist/form-elements/FormElementTime.js +1 -1
  68. package/dist/form-elements/FormElementTime.js.map +1 -1
  69. package/dist/hooks/useAreLookupsDisallowed.d.ts +2 -0
  70. package/dist/hooks/useAreLookupsDisallowed.js +12 -0
  71. package/dist/hooks/useAreLookupsDisallowed.js.map +1 -0
  72. package/dist/hooks/useEditableFormElementIds.d.ts +3 -0
  73. package/dist/hooks/useEditableFormElementIds.js +6 -0
  74. package/dist/hooks/useEditableFormElementIds.js.map +1 -0
  75. package/dist/hooks/useFormElementOptions.js +2 -0
  76. package/dist/hooks/useFormElementOptions.js.map +1 -1
  77. package/dist/hooks/useFormIsDirty.d.ts +56 -0
  78. package/dist/hooks/useFormIsDirty.js +121 -0
  79. package/dist/hooks/useFormIsDirty.js.map +1 -0
  80. package/dist/hooks/useFormSubmissionAttempt.d.ts +88 -0
  81. package/dist/hooks/useFormSubmissionAttempt.js +103 -0
  82. package/dist/hooks/useFormSubmissionAttempt.js.map +1 -0
  83. package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +2 -9
  84. package/dist/hooks/useFormSubmissionAutoSaveState.js +4 -2
  85. package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
  86. package/dist/hooks/useFormValidation.d.ts +1 -1
  87. package/dist/hooks/useFormValidation.js +2 -1
  88. package/dist/hooks/useFormValidation.js.map +1 -1
  89. package/dist/hooks/useInjectPages.d.ts +2 -1
  90. package/dist/hooks/useInjectPages.js.map +1 -1
  91. package/dist/hooks/useIsFormElementReadOnly.d.ts +2 -0
  92. package/dist/hooks/useIsFormElementReadOnly.js +13 -0
  93. package/dist/hooks/useIsFormElementReadOnly.js.map +1 -0
  94. package/dist/hooks/useLookupNotification.d.ts +23 -2
  95. package/dist/hooks/useLookupNotification.js +2 -1
  96. package/dist/hooks/useLookupNotification.js.map +1 -1
  97. package/dist/hooks/useLookups.d.ts +3 -3
  98. package/dist/hooks/useLookups.js +7 -4
  99. package/dist/hooks/useLookups.js.map +1 -1
  100. package/dist/index.d.ts +2 -0
  101. package/dist/index.js +2 -0
  102. package/dist/index.js.map +1 -1
  103. package/dist/services/form-validation/extensions.d.ts +2 -1
  104. package/dist/services/form-validation/extensions.js +2 -1
  105. package/dist/services/form-validation/extensions.js.map +1 -1
  106. package/dist/services/form-validation/validateSubmission.d.ts +2 -1
  107. package/dist/services/form-validation/validateSubmission.js +14 -9
  108. package/dist/services/form-validation/validateSubmission.js.map +1 -1
  109. package/dist/services/getFlowInstanceNodesWithMeta.d.ts +70 -0
  110. package/dist/services/getFlowInstanceNodesWithMeta.js +247 -0
  111. package/dist/services/getFlowInstanceNodesWithMeta.js.map +1 -0
  112. package/dist/types/form.d.ts +17 -3
  113. package/dist/types/form.js.map +1 -1
  114. package/dist/utils/read-only-form-elements.d.ts +37 -0
  115. package/dist/utils/read-only-form-elements.js +63 -0
  116. package/dist/utils/read-only-form-elements.js.map +1 -0
  117. package/package.json +4 -3
  118. package/dist/services/isElementReadOnlyForAudience.d.ts +0 -20
  119. package/dist/services/isElementReadOnlyForAudience.js +0 -46
  120. package/dist/services/isElementReadOnlyForAudience.js.map +0 -1
  121. package/dist/services/resolveFormElementReadOnly.d.ts +0 -10
  122. package/dist/services/resolveFormElementReadOnly.js +0 -17
  123. package/dist/services/resolveFormElementReadOnly.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"useFormSubmissionAutoSaveState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionAutoSaveState.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,SAAS,MAAM,iBAAiB,CAAA;AACvC,OAAO,EAAE,eAAe,EAAqB,MAAM,EAAE,MAAM,SAAS,CAAA;AAEpE,OAAO,sBAAsB,MAAM,0BAA0B,CAAA;AAC7D,OAAO,yBAAyB,MAAM,6BAA6B,CAAA;AAGnE,OAAO,EACL,sCAAsC,EACtC,wBAAwB,GACzB,MAAM,mCAAmC,CAAA;AAE1C;;;;;;;;;GASG;AACH,MAAM,CAAC,OAAO,UAAU,8BAA8B,CAAC,EACrD,IAAI,EACJ,iBAAiB,EACjB,eAAe,EACf,8BAA8B,EAC9B,iCAAiC,EACjC,WAAW,EACX,cAAc,EACd,QAAQ,EACR,QAAQ,EACR,WAAW,EACX,kBAAkB,EAClB,oCAAoC,GAgBrC;IACC,MAAM,CACJ,EACE,UAAU,EACV,UAAU,EACV,kBAAkB,EAClB,eAAe,EACf,YAAY,GACb,EACD,iBAAiB,EAClB,GAAG,sBAAsB,CACxB,IAAI,EACJ,iBAAiB,EACjB,eAAe,EACf,kBAAkB,CACnB,CAAA;IAED,MAAM,CAAC,4BAA4B,EAAE,8BAA8B,CAAC,GAClE,yBAAyB,CAAC,oCAAoC,CAAC,CAAA;IAEjE,MAAM,CACJ,EACE,2BAA2B,EAC3B,kBAAkB,EAClB,eAAe,EACf,oBAAoB,EACpB,sCAAsC,GACvC,EACD,gBAAgB,EACjB,GAAG,KAAK,CAAC,QAAQ,CAMf;QACD,2BAA2B,EAAE,IAAI;QACjC,kBAAkB,EAAE,IAAI;QACxB,eAAe,EAAE,IAAI;QACrB,oBAAoB,EAAE,IAAI;QAC1B,sCAAsC,EAAE,CAAC;KAC1C,CAAC,CAAA;IAEF,MAAM,iBAAiB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC3C,OAAO,SAAS,CACd,CACE,KAAqD,EACrD,kBAAgC,EAChC,YAA2B,EAC3B,EAAE;YACF,IAAI,CAAC,cAAc,EAAE,CAAC;gBACpB,QAAQ,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,IAAI,EAAE,CAAC;oBACjC,KAAK,SAAS,CAAC;oBACf,KAAK,aAAa,CAAC;oBACnB,KAAK,SAAS,CAAC,CAAC,CAAC;wBACf,OAAM;oBACR,CAAC;gBACH,CAAC;gBACD,OAAO,CAAC,GAAG,CAAC,gBAAgB,CAAC,CAAA;gBAC7B,eAAe;qBACZ,kBAAkB,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,EAAE,KAAK,CAAC;qBACrD,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,kBAAkB,EAAE,CAAC;wBACvB,OAAO,eAAe,CAAC,kBAAkB,CACvC,UAAU,CAAC,EAAE,EACb,wBAAwB,WAAW,EAAE,EACrC,kBAAkB,CACnB,CAAA;oBACH,CAAC;gBACH,CAAC,CAAC;qBACD,IAAI,CAAC,GAAG,EAAE;oBACT,IAAI,YAAY,EAAE,CAAC;wBACjB,OAAO,eAAe,CAAC,kBAAkB,CAEtC,UAAU,CAAC,EAAE,EAAE,iBAAiB,WAAW,EAAE,EAAE;4BAChD,YAAY;yBACb,CAAC,CAAA;oBACJ,CAAC;gBACH,CAAC,CAAC;qBACD,IAAI,CAAC,GAAG,EAAE;oBACT,OAAO,eAAe,CAAC,kBAAkB,CAEtC,UAAU,CAAC,EAAE,EAAE,6BAA6B,WAAW,EAAE,EAAE;wBAC5D,8BAA8B,EAAE,4BAA4B,EAAE;qBAC/D,CAAC,CAAA;gBACJ,CAAC,CAAC;qBACD,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;oBACf,OAAO,CAAC,IAAI,CAAC,yBAAyB,EAAE,KAAK,CAAC,CAAA;oBAC9C,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;gBAChC,CAAC,CAAC,CAAA;YACN,CAAC;QACH,CAAC,EACD,IAAI,EAAE,2CAA2C;QACjD,EAAE,QAAQ,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CACnC,CAAA;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,EAAE,cAAc,EAAE,4BAA4B,CAAC,CAAC,CAAA;IAE9E,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5C,IAAI,iBAAiB,EAAE,CAAC;YACtB,iBAAiB,CAAC,MAAM,EAAE,CAAA;QAC5B,CAAC;IACH,CAAC,EAAE,CAAC,iBAAiB,CAAC,CAAC,CAAA;IAEvB,MAAM,wBAAwB,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACtD,OAAO,eAAe;aACnB,kBAAkB,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC;aAC9C,KAAK,CAAC,CAAC,KAAK,EAAE,EAAE;YACf,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;YACtD,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;QAChC,CAAC,CAAC,CAAA;IACN,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAEhC,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CACpC,CAAC,gBAAqD,EAAE,EAAE;QACxD,cAAc,EAAE,CAAA;QAChB,IAAI,8BAA8B,KAAK,KAAK,EAAE,CAAC;YAC7C,wBAAwB,EAAE,CAAA;QAC5B,CAAC;QACD,QAAQ,CAAC,gBAAgB,CAAC,CAAA;IAC5B,CAAC,EACD;QACE,cAAc;QACd,wBAAwB;QACxB,QAAQ;QACR,8BAA8B;KAC/B,CACF,CAAA;IAED,MAAM,eAAe,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACzC,IAAI,WAAW,EAAE,CAAC;YAChB,OAAO,CAAC,kBAAwD,EAAE,EAAE;gBAClE,cAAc,EAAE,CAAA;gBAChB,IAAI,iCAAiC,KAAK,KAAK,EAAE,CAAC;oBAChD,wBAAwB,EAAE,CAAA;gBAC5B,CAAC;gBACD,IAAI,WAAW,EAAE,CAAC;oBAChB,WAAW,CAAC,kBAAkB,CAAC,CAAA;gBACjC,CAAC;YACH,CAAC,CAAA;QACH,CAAC;IACH,CAAC,EAAE;QACD,cAAc;QACd,wBAAwB;QACxB,WAAW;QACX,iCAAiC;KAClC,CAAC,CAAA;IAEF,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAChD,cAAc,EAAE,CAAA;QAChB,wBAAwB,EAAE,CAAA;IAC5B,CAAC,EAAE,CAAC,cAAc,EAAE,wBAAwB,CAAC,CAAC,CAAA;IAE9C,MAAM,YAAY,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC1C,cAAc,EAAE,CAAA;QAChB,wBAAwB,EAAE,CAAA;QAC1B,QAAQ,EAAE,CAAA;IACZ,CAAC,EAAE,CAAC,cAAc,EAAE,wBAAwB,EAAE,QAAQ,CAAC,CAAC,CAAA;IAExD,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,MAAM,GAAG,KAAK,CAAA;QAClB,MAAM,gBAAgB,GAAG,KAAK,IAAI,EAAE;YAClC,IAAI,CAAC;gBACH,MAAM,kBAAkB,GAAG,MAAM,eAAe,CAAC,eAAe,CAE9D,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;gBAC7B,MAAM,eAAe,GACnB,MAAM,eAAe,CAAC,eAAe,CACnC,UAAU,CAAC,EAAE,EACb,wBAAwB,WAAW,EAAE,CACtC,CAAA;gBACH,MAAM,wBAAwB,GAAG,MAAM,eAAe,CAAC,eAAe,CAEnE,UAAU,CAAC,EAAE,EAAE,iBAAiB,WAAW,EAAE,CAAC,CAAA;gBACjD,MAAM,sCAAsC,GAC1C,MAAM,eAAe,CAAC,eAAe,CAElC,UAAU,CAAC,EAAE,EAAE,6BAA6B,WAAW,EAAE,CAAC,CAAA;gBAE/D,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,gBAAgB,CAAC;wBACf,2BAA2B,EAAE,KAAK;wBAClC,kBAAkB;wBAClB,eAAe;wBACf,oBAAoB,EAClB,CAAA,wBAAwB,aAAxB,wBAAwB,uBAAxB,wBAAwB,CAAE,YAAY,KAAI,IAAI;wBAChD,sCAAsC,EACpC,CAAA,sCAAsC,aAAtC,sCAAsC,uBAAtC,sCAAsC,CAAE,8BAA8B;4BACtE,CAAC;qBACJ,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,8BAA8B,EAAE,KAAK,CAAC,CAAA;gBACnD,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;gBAC9B,IAAI,CAAC,MAAM,EAAE,CAAC;oBACZ,gBAAgB,CAAC;wBACf,2BAA2B,EAAE,KAAK;wBAClC,kBAAkB,EAAE,IAAI;wBACxB,eAAe,EAAE,IAAI;wBACrB,oBAAoB,EAAE,IAAI;wBAC1B,sCAAsC,EAAE,CAAC;qBAC1C,CAAC,CAAA;gBACJ,CAAC;YACH,CAAC;QACH,CAAC,CAAA;QACD,gBAAgB,EAAE,CAAA;QAClB,OAAO,GAAG,EAAE;YACV,MAAM,GAAG,IAAI,CAAA;QACf,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,WAAW,EAAE,UAAU,CAAC,EAAE,CAAC,CAAC,CAAA;IAEhC,wCAAwC;IACxC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,OAAO,GAAG,EAAE;YACV,cAAc,EAAE,CAAA;QAClB,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,cAAc,CAAC,CAAC,CAAA;IAEpB,MAAM,yBAAyB,GAA6B,KAAK,CAAC,WAAW,CAC3E,CAAC,cAAc,EAAE,EAAE;QACjB,iBAAiB,CAAC,CAAC,qBAAqB,EAAE,EAAE;YAC1C,MAAM,iBAAiB,GACrB,OAAO,cAAc,KAAK,UAAU;gBAClC,CAAC,CAAC,cAAc,CAAC,qBAAqB,CAAC;gBACvC,CAAC,CAAC,cAAc,CAAA;YAEpB,iBAAiB,CACf,iBAAiB,CAAC,UAAU,EAC5B,iBAAiB,CAAC,kBAAkB,EACpC,iBAAiB,CAAC,YAAY,CAC/B,CAAA;YAED,OAAO,iBAAiB,CAAA;QAC1B,CAAC,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,iBAAiB,EAAE,iBAAiB,CAAC,CACvC,CAAA;IAED,MAAM,kBAAkB,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAChD,wBAAwB,CAAC,uBAAuB,EAAE;YAChD,MAAM,EAAE,UAAU,CAAC,EAAE;YACrB,QAAQ,EAAE,UAAU,CAAC,IAAI;YACzB,kBAAkB,EAChB,sCAAsC,CAAC,eAAe,CAAC;YACzD,oBAAoB,EAAE,sCAAsC;SAC7D,CAAC,CAAA;QACF,wBAAwB,EAAE,CAAA;QAC1B,8BAA8B,EAAE,CAAA;QAChC,gBAAgB,CAAC;YACf,2BAA2B,EAAE,KAAK;YAClC,kBAAkB,EAAE,IAAI;YACxB,eAAe,EAAE,IAAI;YACrB,oBAAoB,EAAE,IAAI;YAC1B,sCAAsC,EAAE,CAAC;SAC1C,CAAC,CAAA;IACJ,CAAC,EAAE;QACD,eAAe;QACf,sCAAsC;QACtC,UAAU,CAAC,EAAE;QACb,UAAU,CAAC,IAAI;QACf,wBAAwB;QACxB,8BAA8B;KAC/B,CAAC,CAAA;IAEF,MAAM,0BAA0B,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QACxD,IAAI,kBAAkB,EAAE,CAAC;YACvB,iBAAiB,CAAC,CAAC,qBAAqB,EAAE,EAAE,CAAC,CAAC;gBAC5C,GAAG,qBAAqB;gBACxB,UAAU,EAAE,kBAAkB;gBAC9B,kBAAkB,EAAE,eAAe,CAAC,CAAC,CAAC,eAAe,CAAC,CAAC,CAAC,SAAS;gBACjE,YAAY,EAAE,oBAAoB,IAAI,EAAE;aACzC,CAAC,CAAC,CAAA;QACL,CAAC;QACD,8BAA8B,CAAC,sCAAsC,CAAC,CAAA;QACtE,gBAAgB,CAAC;YACf,2BAA2B,EAAE,KAAK;YAClC,kBAAkB,EAAE,IAAI;YACxB,eAAe,EAAE,IAAI;YACrB,oBAAoB,EAAE,IAAI;YAC1B,sCAAsC,EAAE,CAAC;SAC1C,CAAC,CAAA;IACJ,CAAC,EAAE;QACD,kBAAkB;QAClB,8BAA8B;QAC9B,sCAAsC;QACtC,iBAAiB;QACjB,eAAe;QACf,oBAAoB;KACrB,CAAC,CAAA;IAEF,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,IAAI,CAAC,oBAAoB,EAAE,CAAC;YAC9B,0BAA0B,EAAE,CAAA;QAC9B,CAAC;IACH,CAAC,EAAE,CAAC,0BAA0B,EAAE,IAAI,CAAC,oBAAoB,CAAC,CAAC,CAAA;IAE3D,OAAO;QACL,UAAU;QACV,UAAU;QACV,kBAAkB;QAClB,eAAe;QACf,YAAY;QACZ,2BAA2B;QAC3B,6BAA6B,EAC3B,kBAAkB,KAAK,IAAI,IAAI,CAAC,IAAI,CAAC,oBAAoB;QAC3D,kBAAkB;QAClB,0BAA0B;QAC1B,YAAY;QACZ,YAAY;QACZ,eAAe;QACf,kBAAkB;QAClB,iBAAiB,EAAE,yBAAyB;QAC5C,4BAA4B;KAC7B,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport _throttle from 'lodash.throttle'\nimport { autoSaveService, submissionService, Sentry } from '../apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport useFormSubmissionDuration from './useFormSubmissionDuration'\nimport { FormElement } from '@oneblink/types/typescript/forms'\nimport { SectionState } from '../types/form'\nimport {\n getElementDisplayNameForAnalyticsEvent,\n sendGoogleAnalyticsEvent,\n} from '../utils/sendGoogleAnalyticsEvent'\n\n/**\n * Use this if you want to implement a controlled auto saving form. See\n * {@link OneBlinkFormControlled} for a full example. If you do not need to\n * control the `submission` or `definition` properties, you can use the\n * {@link OneBlinkAutoSaveForm} component.\n *\n * @param options\n * @returns\n * @group Hooks\n */\nexport default function useFormSubmissionAutoSaveState({\n form,\n initialSubmission,\n resumeAtElement,\n removeAutoSaveDataBeforeSubmit,\n removeAutoSaveDataBeforeSaveDraft,\n autoSaveKey,\n formIsDisabled,\n onCancel,\n onSubmit,\n onSaveDraft,\n resumeSectionState,\n resumePreviousElapsedDurationSeconds,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\n formIsDisabled?: boolean\n onCancel: () => unknown\n onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission']\n resumeAtElement?: FormTypes.FormElement\n onSaveDraft?: (\n newDraftSubmission: submissionService.NewDraftSubmission,\n ) => unknown\n resumeSectionState?: SectionState\n resumePreviousElapsedDurationSeconds?: number\n}) {\n const [\n {\n definition,\n submission,\n lastElementUpdated,\n executedLookups,\n sectionState,\n },\n setFormSubmission,\n ] = useFormSubmissionState(\n form,\n initialSubmission,\n resumeAtElement,\n resumeSectionState,\n )\n\n const [getCurrentSubmissionDuration, resetCurrentSubmissionDuration] =\n useFormSubmissionDuration(resumePreviousElapsedDurationSeconds)\n\n const [\n {\n isLoadingAutoSaveSubmission,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState,\n autoSavePreviousElapsedDurationSeconds,\n },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n autoSaveSectionState: SectionState | null\n autoSavePreviousElapsedDurationSeconds: number\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (\n model: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormElement,\n sectionState?: SectionState,\n ) => {\n if (!formIsDisabled) {\n switch (lastElementUpdated?.type) {\n case 'summary':\n case 'calculation':\n case 'captcha': {\n return\n }\n }\n console.log('Auto saving...')\n autoSaveService\n .upsertAutoSaveData(definition.id, autoSaveKey, model)\n .then(() => {\n if (lastElementUpdated) {\n return autoSaveService.upsertAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n lastElementUpdated,\n )\n }\n })\n .then(() => {\n if (sectionState) {\n return autoSaveService.upsertAutoSaveData<{\n sectionState: SectionState\n }>(definition.id, `SECTION_STATE_${autoSaveKey}`, {\n sectionState,\n })\n }\n })\n .then(() => {\n return autoSaveService.upsertAutoSaveData<{\n previousElapsedDurationSeconds: number\n }>(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`, {\n previousElapsedDurationSeconds: getCurrentSubmissionDuration(),\n })\n })\n .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n }\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id, formIsDisabled, getCurrentSubmissionDuration])\n\n const cancelAutoSave = React.useCallback(() => {\n if (throttledAutoSave) {\n throttledAutoSave.cancel()\n }\n }, [throttledAutoSave])\n\n const deleteAutoSaveSubmission = React.useCallback(() => {\n return autoSaveService\n .deleteAutoSaveData(definition.id, autoSaveKey)\n .catch((error) => {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n })\n }, [autoSaveKey, definition.id])\n\n const handleSubmit = React.useCallback(\n (submissionResult: submissionService.NewFormSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSubmit !== false) {\n deleteAutoSaveSubmission()\n }\n onSubmit(submissionResult)\n },\n [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSubmit,\n removeAutoSaveDataBeforeSubmit,\n ],\n )\n\n const handleSaveDraft = React.useMemo(() => {\n if (onSaveDraft) {\n return (newDraftSubmission: submissionService.NewDraftSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSaveDraft !== false) {\n deleteAutoSaveSubmission()\n }\n if (onSaveDraft) {\n onSaveDraft(newDraftSubmission)\n }\n }\n }\n }, [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSaveDraft,\n removeAutoSaveDataBeforeSaveDraft,\n ])\n\n const handleNavigateAway = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n }, [cancelAutoSave, deleteAutoSaveSubmission])\n\n const handleCancel = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n onCancel()\n }, [cancelAutoSave, deleteAutoSaveSubmission, onCancel])\n\n React.useEffect(() => {\n let ignore = false\n const loadAutoSaveData = async () => {\n try {\n const autoSaveSubmission = await autoSaveService.getAutoSaveData<\n SubmissionTypes.S3SubmissionData['submission']\n >(definition.id, autoSaveKey)\n const autoSaveElement =\n await autoSaveService.getAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n )\n const autoSaveSectionStateData = await autoSaveService.getAutoSaveData<{\n sectionState: SectionState\n }>(definition.id, `SECTION_STATE_${autoSaveKey}`)\n const autoSavePreviousElapsedDurationSeconds =\n await autoSaveService.getAutoSaveData<{\n previousElapsedDurationSeconds: number\n }>(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`)\n\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState:\n autoSaveSectionStateData?.sectionState || null,\n autoSavePreviousElapsedDurationSeconds:\n autoSavePreviousElapsedDurationSeconds?.previousElapsedDurationSeconds ||\n 0,\n })\n }\n } catch (error) {\n console.warn('Error loading auto save data', error)\n Sentry.captureException(error)\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }\n }\n }\n loadAutoSaveData()\n return () => {\n ignore = true\n }\n }, [autoSaveKey, definition.id])\n\n // Clean up throttle function on unmount\n React.useEffect(() => {\n return () => {\n cancelAutoSave()\n }\n }, [cancelAutoSave])\n\n const setFormSubmissionAutoSave: typeof setFormSubmission = React.useCallback(\n (formSubmission) => {\n setFormSubmission((currentFormSubmission) => {\n const newFormSubmission =\n typeof formSubmission === 'function'\n ? formSubmission(currentFormSubmission)\n : formSubmission\n\n throttledAutoSave(\n newFormSubmission.submission,\n newFormSubmission.lastElementUpdated,\n newFormSubmission.sectionState,\n )\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n sendGoogleAnalyticsEvent('oneblink_form_abandon', {\n formId: definition.id,\n formName: definition.name,\n lastElementUpdated:\n getElementDisplayNameForAnalyticsEvent(autoSaveElement),\n durationUntilAbandon: autoSavePreviousElapsedDurationSeconds,\n })\n deleteAutoSaveSubmission()\n resetCurrentSubmissionDuration()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }, [\n autoSaveElement,\n autoSavePreviousElapsedDurationSeconds,\n definition.id,\n definition.name,\n deleteAutoSaveSubmission,\n resetCurrentSubmissionDuration,\n ])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n sectionState: autoSaveSectionState || [],\n }))\n }\n resetCurrentSubmissionDuration(autoSavePreviousElapsedDurationSeconds)\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }, [\n autoSaveSubmission,\n resetCurrentSubmissionDuration,\n autoSavePreviousElapsedDurationSeconds,\n setFormSubmission,\n autoSaveElement,\n autoSaveSectionState,\n ])\n\n React.useEffect(() => {\n if (form.continueWithAutosave) {\n continueAutoSaveSubmission()\n }\n }, [continueAutoSaveSubmission, form.continueWithAutosave])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n executedLookups,\n sectionState,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable:\n autoSaveSubmission !== null && !form.continueWithAutosave,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\n getCurrentSubmissionDuration,\n }\n}\n"]}
1
+ {"version":3,"file":"useFormSubmissionAutoSaveState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionAutoSaveState.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport _throttle from 'lodash.throttle'\nimport { autoSaveService, submissionService, Sentry } from '../apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport useFormSubmissionDuration from './useFormSubmissionDuration'\nimport { FormElement } from '@oneblink/types/typescript/forms'\nimport { SectionState, SetFormSubmission } from '../types/form'\nimport {\n getElementDisplayNameForAnalyticsEvent,\n sendGoogleAnalyticsEvent,\n} from '../utils/sendGoogleAnalyticsEvent'\n\n/**\n * Use this if you want to implement a controlled auto saving form. See\n * {@link OneBlinkFormControlled} for a full example. If you do not need to\n * control the `submission` or `definition` properties, you can use the\n * {@link OneBlinkAutoSaveForm} component.\n *\n * @param options\n * @returns\n * @group Hooks\n */\nexport default function useFormSubmissionAutoSaveState({\n form,\n initialSubmission,\n resumeAtElement,\n removeAutoSaveDataBeforeSubmit,\n removeAutoSaveDataBeforeSaveDraft,\n autoSaveKey,\n formIsDisabled,\n onCancel,\n onSubmit,\n onSaveDraft,\n resumeSectionState,\n resumePreviousElapsedDurationSeconds,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\n formIsDisabled?: boolean\n onCancel: () => unknown\n onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission']\n resumeAtElement?: FormTypes.FormElement\n onSaveDraft?: (\n newDraftSubmission: submissionService.NewDraftSubmission,\n ) => unknown\n resumeSectionState?: SectionState\n resumePreviousElapsedDurationSeconds?: number\n}) {\n const [\n {\n definition,\n submission,\n lastElementUpdated,\n executedLookups,\n sectionState,\n },\n setFormSubmission,\n ] = useFormSubmissionState(\n form,\n initialSubmission,\n resumeAtElement,\n resumeSectionState,\n )\n\n const [getCurrentSubmissionDuration, resetCurrentSubmissionDuration] =\n useFormSubmissionDuration(resumePreviousElapsedDurationSeconds)\n\n const [\n {\n isLoadingAutoSaveSubmission,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState,\n autoSavePreviousElapsedDurationSeconds,\n },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n autoSaveSectionState: SectionState | null\n autoSavePreviousElapsedDurationSeconds: number\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (\n model: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormElement,\n sectionState?: SectionState,\n ) => {\n if (!formIsDisabled) {\n switch (lastElementUpdated?.type) {\n case 'summary':\n case 'calculation':\n case 'captcha': {\n return\n }\n }\n console.log('Auto saving...')\n autoSaveService\n .upsertAutoSaveData(definition.id, autoSaveKey, model)\n .then(() => {\n if (lastElementUpdated) {\n return autoSaveService.upsertAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n lastElementUpdated,\n )\n }\n })\n .then(() => {\n if (sectionState) {\n return autoSaveService.upsertAutoSaveData<{\n sectionState: SectionState\n }>(definition.id, `SECTION_STATE_${autoSaveKey}`, {\n sectionState,\n })\n }\n })\n .then(() => {\n return autoSaveService.upsertAutoSaveData<{\n previousElapsedDurationSeconds: number\n }>(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`, {\n previousElapsedDurationSeconds: getCurrentSubmissionDuration(),\n })\n })\n .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n }\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id, formIsDisabled, getCurrentSubmissionDuration])\n\n const cancelAutoSave = React.useCallback(() => {\n if (throttledAutoSave) {\n throttledAutoSave.cancel()\n }\n }, [throttledAutoSave])\n\n const deleteAutoSaveSubmission = React.useCallback(() => {\n return autoSaveService\n .deleteAutoSaveData(definition.id, autoSaveKey)\n .catch((error) => {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n })\n }, [autoSaveKey, definition.id])\n\n const handleSubmit = React.useCallback(\n (submissionResult: submissionService.NewFormSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSubmit !== false) {\n deleteAutoSaveSubmission()\n }\n onSubmit(submissionResult)\n },\n [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSubmit,\n removeAutoSaveDataBeforeSubmit,\n ],\n )\n\n const handleSaveDraft = React.useMemo(() => {\n if (onSaveDraft) {\n return (newDraftSubmission: submissionService.NewDraftSubmission) => {\n cancelAutoSave()\n if (removeAutoSaveDataBeforeSaveDraft !== false) {\n deleteAutoSaveSubmission()\n }\n if (onSaveDraft) {\n onSaveDraft(newDraftSubmission)\n }\n }\n }\n }, [\n cancelAutoSave,\n deleteAutoSaveSubmission,\n onSaveDraft,\n removeAutoSaveDataBeforeSaveDraft,\n ])\n\n const handleNavigateAway = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n }, [cancelAutoSave, deleteAutoSaveSubmission])\n\n const handleCancel = React.useCallback(() => {\n cancelAutoSave()\n deleteAutoSaveSubmission()\n onCancel()\n }, [cancelAutoSave, deleteAutoSaveSubmission, onCancel])\n\n React.useEffect(() => {\n let ignore = false\n const loadAutoSaveData = async () => {\n try {\n const autoSaveSubmission = await autoSaveService.getAutoSaveData<\n SubmissionTypes.S3SubmissionData['submission']\n >(definition.id, autoSaveKey)\n const autoSaveElement =\n await autoSaveService.getAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n )\n const autoSaveSectionStateData = await autoSaveService.getAutoSaveData<{\n sectionState: SectionState\n }>(definition.id, `SECTION_STATE_${autoSaveKey}`)\n const autoSavePreviousElapsedDurationSeconds =\n await autoSaveService.getAutoSaveData<{\n previousElapsedDurationSeconds: number\n }>(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`)\n\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState:\n autoSaveSectionStateData?.sectionState || null,\n autoSavePreviousElapsedDurationSeconds:\n autoSavePreviousElapsedDurationSeconds?.previousElapsedDurationSeconds ||\n 0,\n })\n }\n } catch (error) {\n console.warn('Error loading auto save data', error)\n Sentry.captureException(error)\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }\n }\n }\n loadAutoSaveData()\n return () => {\n ignore = true\n }\n }, [autoSaveKey, definition.id])\n\n // Clean up throttle function on unmount\n React.useEffect(() => {\n return () => {\n cancelAutoSave()\n }\n }, [cancelAutoSave])\n\n const setFormSubmissionAutoSave: SetFormSubmission = React.useCallback(\n (formSubmission, options) => {\n setFormSubmission((currentFormSubmission) => {\n const newFormSubmission =\n typeof formSubmission === 'function'\n ? formSubmission(currentFormSubmission)\n : formSubmission\n\n if (!options?.isDerivedChange) {\n throttledAutoSave(\n newFormSubmission.submission,\n newFormSubmission.lastElementUpdated,\n newFormSubmission.sectionState,\n )\n }\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n sendGoogleAnalyticsEvent('oneblink_form_abandon', {\n formId: definition.id,\n formName: definition.name,\n lastElementUpdated:\n getElementDisplayNameForAnalyticsEvent(autoSaveElement),\n durationUntilAbandon: autoSavePreviousElapsedDurationSeconds,\n })\n deleteAutoSaveSubmission()\n resetCurrentSubmissionDuration()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }, [\n autoSaveElement,\n autoSavePreviousElapsedDurationSeconds,\n definition.id,\n definition.name,\n deleteAutoSaveSubmission,\n resetCurrentSubmissionDuration,\n ])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n sectionState: autoSaveSectionState || [],\n }))\n }\n resetCurrentSubmissionDuration(autoSavePreviousElapsedDurationSeconds)\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n autoSavePreviousElapsedDurationSeconds: 0,\n })\n }, [\n autoSaveSubmission,\n resetCurrentSubmissionDuration,\n autoSavePreviousElapsedDurationSeconds,\n setFormSubmission,\n autoSaveElement,\n autoSaveSectionState,\n ])\n\n React.useEffect(() => {\n if (form.continueWithAutosave) {\n continueAutoSaveSubmission()\n }\n }, [continueAutoSaveSubmission, form.continueWithAutosave])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n executedLookups,\n sectionState,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable:\n autoSaveSubmission !== null && !form.continueWithAutosave,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\n getCurrentSubmissionDuration,\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import { CaptchaType, ExecutedLookups, FormElementsConditionallyShown } from '../types/form';
3
3
  export default function useFormValidation(pages: FormTypes.PageElement[]): {
4
- validate: (submission: SubmissionTypes.S3SubmissionData["submission"], formElementsConditionallyShown: FormElementsConditionallyShown, executedLookups: ExecutedLookups, captchaType: CaptchaType, isOffline: boolean, audience: FormTypes.FormElementHiddenFromAudience) => import("../types/form").FormElementsValidation | undefined;
4
+ validate: (submission: SubmissionTypes.S3SubmissionData["submission"], formElementsConditionallyShown: FormElementsConditionallyShown, executedLookups: ExecutedLookups, captchaType: CaptchaType, isOffline: boolean, audience: FormTypes.FormElementHiddenFromAudience, editableFormElementIds?: string[]) => import("../types/form").FormElementsValidation | undefined;
5
5
  };
@@ -42,7 +42,7 @@ export default function useFormValidation(pages) {
42
42
  const formElementsWithName = React.useMemo(() => {
43
43
  return stripFormElementsWithoutName(pages, false);
44
44
  }, [pages]);
45
- const handleValidate = React.useCallback((submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience) => {
45
+ const handleValidate = React.useCallback((submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, editableFormElementIds) => {
46
46
  return validateSubmission({
47
47
  elements: formElementsWithName,
48
48
  submission,
@@ -51,6 +51,7 @@ export default function useFormValidation(pages) {
51
51
  captchaType,
52
52
  isOffline,
53
53
  audience,
54
+ editableFormElementIds,
54
55
  });
55
56
  }, [formElementsWithName]);
56
57
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"useFormValidation.js","sourceRoot":"","sources":["../../src/hooks/useFormValidation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,kBAAkB,MAAM,gDAAgD,CAAA;AAO/E,SAAS,4BAA4B,CACnC,YAAqC,EACrC,mBAA4B;IAE5B,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,MAAM,UAAU,GACd,mBAAmB;YACnB,CAAC,UAAU,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAA;QAE9D,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;YACzB,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,gEAAgE;gBAChE,kEAAkE;gBAClE,yBAAyB;gBACzB,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO,IAAI,CAAA;gBACb,CAAC;gBACD,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;YAC/B,CAAC;YACD,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;iBAClE,CAAA;YACH,CAAC;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,EAC1B,UAAU,CACX;qBACF;iBACF,CAAA;YACH,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,oBAAoB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC9C,OAAO,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IACnD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA0D,EAC1D,8BAA8D,EAC9D,eAAgC,EAChC,WAAwB,EACxB,SAAkB,EAClB,QAAiD,EACjD,EAAE;QACF,OAAO,kBAAkB,CAAC;YACxB,QAAQ,EAAE,oBAAoB;YAC9B,UAAU;YACV,8BAA8B;YAC9B,eAAe;YACf,WAAW;YACX,SAAS;YACT,QAAQ;SACT,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,oBAAoB,CAAC,CACvB,CAAA;IAED,OAAO;QACL,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport validateSubmission from '../services/form-validation/validateSubmission'\nimport {\n CaptchaType,\n ExecutedLookups,\n FormElementsConditionallyShown,\n} from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n hasReadOnlyAncestor: boolean,\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n const isReadOnly =\n hasReadOnlyAncestor ||\n ('readOnly' in formElement && formElement.readOnly === true)\n\n switch (formElement.type) {\n case 'captcha': {\n // The renderer omits a captcha inside a read-only container, so\n // requiring one here would fail validation with an error the user\n // cannot see or resolve.\n if (isReadOnly) {\n return memo\n }\n return [...memo, formElement]\n }\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements, isReadOnly),\n ]\n }\n case 'infoPage':\n case 'form':\n case 'repeatableSet': {\n return [\n ...memo,\n {\n ...formElement,\n elements: stripFormElementsWithoutName(\n formElement.elements || [],\n isReadOnly,\n ),\n },\n ]\n }\n default: {\n return [...memo, formElement]\n }\n }\n },\n [],\n )\n}\n\nexport default function useFormValidation(pages: FormTypes.PageElement[]) {\n const formElementsWithName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages, false)\n }, [pages])\n\n const handleValidate = React.useCallback(\n (\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown: FormElementsConditionallyShown,\n executedLookups: ExecutedLookups,\n captchaType: CaptchaType,\n isOffline: boolean,\n audience: FormTypes.FormElementHiddenFromAudience,\n ) => {\n return validateSubmission({\n elements: formElementsWithName,\n submission,\n formElementsConditionallyShown,\n executedLookups,\n captchaType,\n isOffline,\n audience,\n })\n },\n [formElementsWithName],\n )\n\n return {\n validate: handleValidate,\n }\n}\n"]}
1
+ {"version":3,"file":"useFormValidation.js","sourceRoot":"","sources":["../../src/hooks/useFormValidation.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,OAAO,kBAAkB,MAAM,gDAAgD,CAAA;AAO/E,SAAS,4BAA4B,CACnC,YAAqC,EACrC,mBAA4B;IAE5B,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,MAAM,UAAU,GACd,mBAAmB;YACnB,CAAC,UAAU,IAAI,WAAW,IAAI,WAAW,CAAC,QAAQ,KAAK,IAAI,CAAC,CAAA;QAE9D,QAAQ,WAAW,CAAC,IAAI,EAAE,CAAC;YACzB,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,gEAAgE;gBAChE,kEAAkE;gBAClE,yBAAyB;gBACzB,IAAI,UAAU,EAAE,CAAC;oBACf,OAAO,IAAI,CAAA;gBACb,CAAC;gBACD,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;YAC/B,CAAC;YACD,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC,CAAC;gBACf,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,EAAE,UAAU,CAAC;iBAClE,CAAA;YACH,CAAC;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC,CAAC;gBACrB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,EAC1B,UAAU,CACX;qBACF;iBACF,CAAA;YACH,CAAC;YACD,OAAO,CAAC,CAAC,CAAC;gBACR,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;YAC/B,CAAC;QACH,CAAC;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,oBAAoB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC9C,OAAO,4BAA4B,CAAC,KAAK,EAAE,KAAK,CAAC,CAAA;IACnD,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA0D,EAC1D,8BAA8D,EAC9D,eAAgC,EAChC,WAAwB,EACxB,SAAkB,EAClB,QAAiD,EACjD,sBAAiC,EACjC,EAAE;QACF,OAAO,kBAAkB,CAAC;YACxB,QAAQ,EAAE,oBAAoB;YAC9B,UAAU;YACV,8BAA8B;YAC9B,eAAe;YACf,WAAW;YACX,SAAS;YACT,QAAQ;YACR,sBAAsB;SACvB,CAAC,CAAA;IACJ,CAAC,EACD,CAAC,oBAAoB,CAAC,CACvB,CAAA;IAED,OAAO;QACL,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport validateSubmission from '../services/form-validation/validateSubmission'\nimport {\n CaptchaType,\n ExecutedLookups,\n FormElementsConditionallyShown,\n} from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n hasReadOnlyAncestor: boolean,\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n const isReadOnly =\n hasReadOnlyAncestor ||\n ('readOnly' in formElement && formElement.readOnly === true)\n\n switch (formElement.type) {\n case 'captcha': {\n // The renderer omits a captcha inside a read-only container, so\n // requiring one here would fail validation with an error the user\n // cannot see or resolve.\n if (isReadOnly) {\n return memo\n }\n return [...memo, formElement]\n }\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements, isReadOnly),\n ]\n }\n case 'infoPage':\n case 'form':\n case 'repeatableSet': {\n return [\n ...memo,\n {\n ...formElement,\n elements: stripFormElementsWithoutName(\n formElement.elements || [],\n isReadOnly,\n ),\n },\n ]\n }\n default: {\n return [...memo, formElement]\n }\n }\n },\n [],\n )\n}\n\nexport default function useFormValidation(pages: FormTypes.PageElement[]) {\n const formElementsWithName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages, false)\n }, [pages])\n\n const handleValidate = React.useCallback(\n (\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown: FormElementsConditionallyShown,\n executedLookups: ExecutedLookups,\n captchaType: CaptchaType,\n isOffline: boolean,\n audience: FormTypes.FormElementHiddenFromAudience,\n editableFormElementIds?: string[],\n ) => {\n return validateSubmission({\n elements: formElementsWithName,\n submission,\n formElementsConditionallyShown,\n executedLookups,\n captchaType,\n isOffline,\n audience,\n editableFormElementIds,\n })\n },\n [formElementsWithName],\n )\n\n return {\n validate: handleValidate,\n }\n}\n"]}
@@ -1,6 +1,7 @@
1
1
  import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import * as React from 'react';
3
- type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data?: SubmissionTypes.S3SubmissionData['submission']) => void;
3
+ import { SetFormSubmissionOptions } from '../types/form';
4
+ type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data: SubmissionTypes.S3SubmissionData['submission'] | undefined, options: SetFormSubmissionOptions) => void;
4
5
  export declare const InjectPagesContext: React.Context<InjectPagesContextValue>;
5
6
  export default function useInjectPages(): InjectPagesContextValue;
6
7
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useInjectPages.js","sourceRoot":"","sources":["../../src/hooks/useInjectPages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAQ9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CACnD,GAAG,EAAE,GAAE,CAAC,CACT,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,OAAO,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AAC7C,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\ntype InjectPagesContextValue = (\n lookupFormElement: FormTypes.LookupFormElement,\n pageElements: FormTypes.PageElement[],\n data?: SubmissionTypes.S3SubmissionData['submission'],\n) => void\n\nexport const InjectPagesContext = React.createContext<InjectPagesContextValue>(\n () => {},\n)\n\nexport default function useInjectPages() {\n return React.useContext(InjectPagesContext)\n}\n"]}
1
+ {"version":3,"file":"useInjectPages.js","sourceRoot":"","sources":["../../src/hooks/useInjectPages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAU9B,MAAM,CAAC,MAAM,kBAAkB,GAAG,KAAK,CAAC,aAAa,CACnD,GAAG,EAAE,GAAE,CAAC,CACT,CAAA;AAED,MAAM,CAAC,OAAO,UAAU,cAAc;IACpC,OAAO,KAAK,CAAC,UAAU,CAAC,kBAAkB,CAAC,CAAA;AAC7C,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\nimport { SetFormSubmissionOptions } from '../types/form'\n\ntype InjectPagesContextValue = (\n lookupFormElement: FormTypes.LookupFormElement,\n pageElements: FormTypes.PageElement[],\n data: SubmissionTypes.S3SubmissionData['submission'] | undefined,\n options: SetFormSubmissionOptions,\n) => void\n\nexport const InjectPagesContext = React.createContext<InjectPagesContextValue>(\n () => {},\n)\n\nexport default function useInjectPages() {\n return React.useContext(InjectPagesContext)\n}\n"]}
@@ -0,0 +1,2 @@
1
+ import { FormTypes } from '@oneblink/types';
2
+ export default function useIsFormElementReadOnly(element: FormTypes.FormElement | FormTypes.LookupFormElement, isInheritedReadOnly?: boolean): boolean;
@@ -0,0 +1,13 @@
1
+ import useEditableFormElementIds from './useEditableFormElementIds';
2
+ import useFormIsReadOnly from './useFormIsReadOnly';
3
+ import { checkIsFormElementReadOnly } from '../utils/read-only-form-elements';
4
+ export default function useIsFormElementReadOnly(element, isInheritedReadOnly) {
5
+ const isFormReadOnly = useFormIsReadOnly();
6
+ const editableFormElementIds = useEditableFormElementIds();
7
+ return checkIsFormElementReadOnly(element, {
8
+ isFormReadOnly,
9
+ isInheritedReadOnly,
10
+ editableFormElementIds,
11
+ });
12
+ }
13
+ //# sourceMappingURL=useIsFormElementReadOnly.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useIsFormElementReadOnly.js","sourceRoot":"","sources":["../../src/hooks/useIsFormElementReadOnly.ts"],"names":[],"mappings":"AACA,OAAO,yBAAyB,MAAM,6BAA6B,CAAA;AACnE,OAAO,iBAAiB,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,0BAA0B,EAAE,MAAM,kCAAkC,CAAA;AAE7E,MAAM,CAAC,OAAO,UAAU,wBAAwB,CAC9C,OAA4D,EAC5D,mBAA6B;IAE7B,MAAM,cAAc,GAAG,iBAAiB,EAAE,CAAA;IAC1C,MAAM,sBAAsB,GAAG,yBAAyB,EAAE,CAAA;IAE1D,OAAO,0BAA0B,CAAC,OAAO,EAAE;QACzC,cAAc;QACd,mBAAmB;QACnB,sBAAsB;KACvB,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\r\nimport useEditableFormElementIds from './useEditableFormElementIds'\r\nimport useFormIsReadOnly from './useFormIsReadOnly'\r\nimport { checkIsFormElementReadOnly } from '../utils/read-only-form-elements'\r\n\r\nexport default function useIsFormElementReadOnly(\r\n element: FormTypes.FormElement | FormTypes.LookupFormElement,\r\n isInheritedReadOnly?: boolean,\r\n): boolean {\r\n const isFormReadOnly = useFormIsReadOnly()\r\n const editableFormElementIds = useEditableFormElementIds()\r\n\r\n return checkIsFormElementReadOnly(element, {\r\n isFormReadOnly,\r\n isInheritedReadOnly,\r\n editableFormElementIds,\r\n })\r\n}\r\n"]}
@@ -1,13 +1,24 @@
1
1
  import * as React from 'react';
2
2
  export type LookupNotificationContextValue = {
3
3
  isLookup: boolean;
4
- isDisabled: boolean;
4
+ /**
5
+ * A lookup HTTP request is in flight. Used to disable lookup/retry buttons
6
+ * so a second request cannot be started until the current one finishes.
7
+ */
8
+ isLookupRequestInFlight: boolean;
5
9
  isLoading: boolean;
6
10
  allowLookupOnEmptyValue: boolean;
11
+ /**
12
+ * Lookups must not run for this element, e.g. a read-only form or a field
13
+ * an approver cannot edit. The lookup button is disabled and `onLookup` is
14
+ * a no-op.
15
+ */
16
+ areLookupsDisallowed: boolean;
7
17
  onLookup: (options: {
8
18
  newValue: unknown;
9
19
  abortController: AbortController;
10
20
  continueLookupOnAbort: boolean;
21
+ isDerivedChange?: boolean;
11
22
  }) => Promise<void>;
12
23
  isLookingUp: boolean;
13
24
  };
@@ -15,8 +26,18 @@ export declare const LookupNotificationContext: React.Context<LookupNotification
15
26
  export default function useLookupNotification(value: unknown): {
16
27
  onLookup: () => void;
17
28
  isLookup: boolean;
18
- isDisabled: boolean;
29
+ /**
30
+ * A lookup HTTP request is in flight. Used to disable lookup/retry buttons
31
+ * so a second request cannot be started until the current one finishes.
32
+ */
33
+ isLookupRequestInFlight: boolean;
19
34
  isLoading: boolean;
20
35
  allowLookupOnEmptyValue: boolean;
36
+ /**
37
+ * Lookups must not run for this element, e.g. a read-only form or a field
38
+ * an approver cannot edit. The lookup button is disabled and `onLookup` is
39
+ * a no-op.
40
+ */
41
+ areLookupsDisallowed: boolean;
21
42
  isLookingUp: boolean;
22
43
  };
@@ -1,9 +1,10 @@
1
1
  import * as React from 'react';
2
2
  const defaultContext = {
3
3
  isLookup: false,
4
- isDisabled: false,
4
+ isLookupRequestInFlight: false,
5
5
  isLoading: false,
6
6
  allowLookupOnEmptyValue: false,
7
+ areLookupsDisallowed: false,
7
8
  onLookup: async () => undefined,
8
9
  isLookingUp: false,
9
10
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useLookupNotification.js","sourceRoot":"","sources":["../../src/hooks/useLookupNotification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAe9B,MAAM,cAAc,GAAG;IACrB,QAAQ,EAAE,KAAK;IACf,UAAU,EAAE,KAAK;IACjB,SAAS,EAAE,KAAK;IAChB,uBAAuB,EAAE,KAAK;IAC9B,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IAC/B,WAAW,EAAE,KAAK;CACnB,CAAA;AAED,MAAM,CAAC,MAAM,yBAAyB,GACpC,KAAK,CAAC,aAAa,CAAiC,cAAc,CAAC,CAAA;AAErE,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAc;IAC1D,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IAE1E,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAEvD,0EAA0E;IAC1E,yEAAyE;IACzE,qBAAqB;IACrB,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAyB,IAAI,CAAC,CAAA;IAErE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,kBAAkB,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAA;QAClD,QAAQ,CAAC;YACP,QAAQ,EAAE,KAAK;YACf,eAAe,EAAE,kBAAkB,CAAC,OAAO;YAC3C,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAA;QACF,uDAAuD;QACvD,uDAAuD;QACvD,2DAA2D;QAC3D,2DAA2D;QAC3D,uDAAuD;IACzD,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAA;QAClD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,GAAG,EAAE;gBACV,eAAe,CAAC,KAAK,EAAE,CAAA;YACzB,CAAC,CAAA;QACH,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;IAExB,OAAO;QACL,GAAG,KAAK;QACR,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YAC/B,cAAc,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAA;QAChE,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\n\nexport type LookupNotificationContextValue = {\n isLookup: boolean\n isDisabled: boolean\n isLoading: boolean\n allowLookupOnEmptyValue: boolean\n onLookup: (options: {\n newValue: unknown\n abortController: AbortController\n continueLookupOnAbort: boolean\n }) => Promise<void>\n isLookingUp: boolean\n}\n\nconst defaultContext = {\n isLookup: false,\n isDisabled: false,\n isLoading: false,\n allowLookupOnEmptyValue: false,\n onLookup: async () => undefined,\n isLookingUp: false,\n}\n\nexport const LookupNotificationContext =\n React.createContext<LookupNotificationContextValue>(defaultContext)\n\nexport default function useLookupNotification(value: unknown) {\n const { onLookup, ...state } = React.useContext(LookupNotificationContext)\n\n // We use a number to trigger the lookup function so that we can have\n // the effect below run every time the onLookup function is called.\n // We need it in an useEffect so that we can pass an abort controller\n // and have it aborted if the user clicks the lookup button again.\n const [lookupCount, setLookupCount] = React.useState(0)\n\n // We use a ref here to keep the abort controller outside of the useEffect\n // below. This way we can abort the lookup if the value changes while the\n // lookup is running.\n const abortControllerRef = React.useRef<AbortController | null>(null)\n\n React.useEffect(() => {\n if (lookupCount === 0) {\n return\n }\n abortControllerRef.current = new AbortController()\n onLookup({\n newValue: value,\n abortController: abortControllerRef.current,\n continueLookupOnAbort: false,\n })\n // Wants to use \"onLookup\" and \"value\" as dependencies,\n // however, these will change on any change made on any\n // element. Checking if \"lookupCount\" has changed is enough\n // to trigger a lookup when the correct dependencies change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [lookupCount])\n\n React.useEffect(() => {\n const abortController = abortControllerRef.current\n if (abortController) {\n return () => {\n abortController.abort()\n }\n }\n }, [value, lookupCount])\n\n return {\n ...state,\n onLookup: React.useCallback(() => {\n setLookupCount((currentLookupCount) => currentLookupCount + 1)\n }, []),\n }\n}\n"]}
1
+ {"version":3,"file":"useLookupNotification.js","sourceRoot":"","sources":["../../src/hooks/useLookupNotification.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AA0B9B,MAAM,cAAc,GAAG;IACrB,QAAQ,EAAE,KAAK;IACf,uBAAuB,EAAE,KAAK;IAC9B,SAAS,EAAE,KAAK;IAChB,uBAAuB,EAAE,KAAK;IAC9B,oBAAoB,EAAE,KAAK;IAC3B,QAAQ,EAAE,KAAK,IAAI,EAAE,CAAC,SAAS;IAC/B,WAAW,EAAE,KAAK;CACnB,CAAA;AAED,MAAM,CAAC,MAAM,yBAAyB,GACpC,KAAK,CAAC,aAAa,CAAiC,cAAc,CAAC,CAAA;AAErE,MAAM,CAAC,OAAO,UAAU,qBAAqB,CAAC,KAAc;IAC1D,MAAM,EAAE,QAAQ,EAAE,GAAG,KAAK,EAAE,GAAG,KAAK,CAAC,UAAU,CAAC,yBAAyB,CAAC,CAAA;IAE1E,qEAAqE;IACrE,mEAAmE;IACnE,qEAAqE;IACrE,kEAAkE;IAClE,MAAM,CAAC,WAAW,EAAE,cAAc,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAA;IAEvD,0EAA0E;IAC1E,yEAAyE;IACzE,qBAAqB;IACrB,MAAM,kBAAkB,GAAG,KAAK,CAAC,MAAM,CAAyB,IAAI,CAAC,CAAA;IAErE,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,WAAW,KAAK,CAAC,EAAE,CAAC;YACtB,OAAM;QACR,CAAC;QACD,kBAAkB,CAAC,OAAO,GAAG,IAAI,eAAe,EAAE,CAAA;QAClD,QAAQ,CAAC;YACP,QAAQ,EAAE,KAAK;YACf,eAAe,EAAE,kBAAkB,CAAC,OAAO;YAC3C,qBAAqB,EAAE,KAAK;SAC7B,CAAC,CAAA;QACF,uDAAuD;QACvD,uDAAuD;QACvD,2DAA2D;QAC3D,2DAA2D;QAC3D,uDAAuD;IACzD,CAAC,EAAE,CAAC,WAAW,CAAC,CAAC,CAAA;IAEjB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,eAAe,GAAG,kBAAkB,CAAC,OAAO,CAAA;QAClD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,GAAG,EAAE;gBACV,eAAe,CAAC,KAAK,EAAE,CAAA;YACzB,CAAC,CAAA;QACH,CAAC;IACH,CAAC,EAAE,CAAC,KAAK,EAAE,WAAW,CAAC,CAAC,CAAA;IAExB,OAAO;QACL,GAAG,KAAK;QACR,QAAQ,EAAE,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;YAC/B,cAAc,CAAC,CAAC,kBAAkB,EAAE,EAAE,CAAC,kBAAkB,GAAG,CAAC,CAAC,CAAA;QAChE,CAAC,EAAE,EAAE,CAAC;KACP,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\n\nexport type LookupNotificationContextValue = {\n isLookup: boolean\n /**\n * A lookup HTTP request is in flight. Used to disable lookup/retry buttons\n * so a second request cannot be started until the current one finishes.\n */\n isLookupRequestInFlight: boolean\n isLoading: boolean\n allowLookupOnEmptyValue: boolean\n /**\n * Lookups must not run for this element, e.g. a read-only form or a field\n * an approver cannot edit. The lookup button is disabled and `onLookup` is\n * a no-op.\n */\n areLookupsDisallowed: boolean\n onLookup: (options: {\n newValue: unknown\n abortController: AbortController\n continueLookupOnAbort: boolean\n isDerivedChange?: boolean\n }) => Promise<void>\n isLookingUp: boolean\n}\n\nconst defaultContext = {\n isLookup: false,\n isLookupRequestInFlight: false,\n isLoading: false,\n allowLookupOnEmptyValue: false,\n areLookupsDisallowed: false,\n onLookup: async () => undefined,\n isLookingUp: false,\n}\n\nexport const LookupNotificationContext =\n React.createContext<LookupNotificationContextValue>(defaultContext)\n\nexport default function useLookupNotification(value: unknown) {\n const { onLookup, ...state } = React.useContext(LookupNotificationContext)\n\n // We use a number to trigger the lookup function so that we can have\n // the effect below run every time the onLookup function is called.\n // We need it in an useEffect so that we can pass an abort controller\n // and have it aborted if the user clicks the lookup button again.\n const [lookupCount, setLookupCount] = React.useState(0)\n\n // We use a ref here to keep the abort controller outside of the useEffect\n // below. This way we can abort the lookup if the value changes while the\n // lookup is running.\n const abortControllerRef = React.useRef<AbortController | null>(null)\n\n React.useEffect(() => {\n if (lookupCount === 0) {\n return\n }\n abortControllerRef.current = new AbortController()\n onLookup({\n newValue: value,\n abortController: abortControllerRef.current,\n continueLookupOnAbort: false,\n })\n // Wants to use \"onLookup\" and \"value\" as dependencies,\n // however, these will change on any change made on any\n // element. Checking if \"lookupCount\" has changed is enough\n // to trigger a lookup when the correct dependencies change\n // eslint-disable-next-line react-hooks/exhaustive-deps\n }, [lookupCount])\n\n React.useEffect(() => {\n const abortController = abortControllerRef.current\n if (abortController) {\n return () => {\n abortController.abort()\n }\n }\n }, [value, lookupCount])\n\n return {\n ...state,\n onLookup: React.useCallback(() => {\n setLookupCount((currentLookupCount) => currentLookupCount + 1)\n }, []),\n }\n}\n"]}
@@ -1,5 +1,5 @@
1
1
  import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
- import { SetFormSubmission } from '../types/form';
3
- export default function useLookups(formId: number, setFormSubmission: SetFormSubmission): {
4
- handlePagesLookupResult: (element: FormTypes.LookupFormElement, elementLookupData: FormTypes.PageElement[], dataLookupResult?: SubmissionTypes.S3SubmissionData["submission"]) => void;
2
+ import { SetFormSubmission, SetFormSubmissionOptions } from '../types/form';
3
+ export default function useLookups(formId: number, setFormSubmission: SetFormSubmission, markFormDirty: () => void): {
4
+ handlePagesLookupResult: (element: FormTypes.LookupFormElement, elementLookupData: FormTypes.PageElement[], dataLookupResult: SubmissionTypes.S3SubmissionData["submission"] | undefined, options: SetFormSubmissionOptions) => void;
5
5
  };
@@ -1,12 +1,15 @@
1
1
  import * as React from 'react';
2
2
  import { formElementsService } from '@oneblink/sdk-core';
3
3
  import generateDefaultData from '../services/generate-default-data';
4
- export default function useLookups(formId, setFormSubmission) {
5
- const handlePagesLookupResult = React.useCallback((element, elementLookupData, dataLookupResult) => {
4
+ export default function useLookups(formId, setFormSubmission, markFormDirty) {
5
+ const handlePagesLookupResult = React.useCallback((element, elementLookupData, dataLookupResult, options) => {
6
6
  const newPageElements = elementLookupData.map((e) => ({
7
7
  ...e,
8
8
  injectedByElementId: element.id,
9
9
  }));
10
+ if (!options.isDerivedChange) {
11
+ markFormDirty();
12
+ }
10
13
  setFormSubmission((currentFormSubmission) => {
11
14
  const definition = {
12
15
  ...currentFormSubmission.definition,
@@ -60,8 +63,8 @@ export default function useLookups(formId, setFormSubmission) {
60
63
  },
61
64
  sectionState: currentFormSubmission.sectionState,
62
65
  };
63
- });
64
- }, [formId, setFormSubmission]);
66
+ }, options);
67
+ }, [formId, markFormDirty, setFormSubmission]);
65
68
  return {
66
69
  handlePagesLookupResult,
67
70
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useLookups.js","sourceRoot":"","sources":["../../src/hooks/useLookups.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { formElementsService } from '@oneblink/sdk-core'\n\nimport generateDefaultData from '../services/generate-default-data'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { SetFormSubmission } from '../types/form'\n\nexport default function useLookups(\n formId: number,\n setFormSubmission: SetFormSubmission,\n) {\n const handlePagesLookupResult = React.useCallback(\n (\n element: FormTypes.LookupFormElement,\n elementLookupData: FormTypes.PageElement[],\n dataLookupResult?: SubmissionTypes.S3SubmissionData['submission'],\n ) => {\n const newPageElements = elementLookupData.map((e) => ({\n ...e,\n injectedByElementId: element.id,\n }))\n setFormSubmission((currentFormSubmission) => {\n const definition: FormTypes.Form = {\n ...currentFormSubmission.definition,\n isMultiPage: true,\n }\n if (!currentFormSubmission.definition.isMultiPage) {\n definition.elements = [\n {\n id: formId.toString(),\n type: 'page',\n label: 'Page 1',\n elements: currentFormSubmission.definition.elements,\n conditionallyShow: false,\n requiresAllConditionallyShowPredicates: false,\n },\n ...newPageElements,\n ]\n } else {\n const indexOfPage =\n currentFormSubmission.definition.elements.findIndex(\n (pageElement: FormTypes.FormElement) => {\n if (pageElement.type === 'page') {\n return formElementsService.findFormElement(\n pageElement.elements,\n (el) => el.id === element.id,\n )\n }\n },\n )\n if (indexOfPage === -1) {\n return currentFormSubmission\n }\n definition.elements =\n currentFormSubmission.definition.elements.reduce(\n (\n partialPageElements: FormTypes.FormElement[],\n pageElement: FormTypes.FormElement,\n index: number,\n ) => {\n // @ts-expect-error Sorry typescript, we need to add a property you don't approve of :(\n if (pageElement.injectedByElementId !== element.id) {\n partialPageElements.push(pageElement)\n }\n if (index === indexOfPage) {\n partialPageElements.push(...newPageElements)\n }\n return partialPageElements\n },\n [],\n )\n }\n\n const submission = generateDefaultData(definition.elements, {\n ...currentFormSubmission.submission,\n ...dataLookupResult,\n })\n return {\n submission,\n definition,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: {\n ...currentFormSubmission.executedLookups,\n [element.name]: true,\n },\n sectionState: currentFormSubmission.sectionState,\n }\n })\n },\n [formId, setFormSubmission],\n )\n\n return {\n handlePagesLookupResult,\n }\n}\n"]}
1
+ {"version":3,"file":"useLookups.js","sourceRoot":"","sources":["../../src/hooks/useLookups.ts"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { formElementsService } from '@oneblink/sdk-core'\n\nimport generateDefaultData from '../services/generate-default-data'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { SetFormSubmission, SetFormSubmissionOptions } from '../types/form'\n\nexport default function useLookups(\n formId: number,\n setFormSubmission: SetFormSubmission,\n markFormDirty: () => void,\n) {\n const handlePagesLookupResult = React.useCallback(\n (\n element: FormTypes.LookupFormElement,\n elementLookupData: FormTypes.PageElement[],\n dataLookupResult:\n | SubmissionTypes.S3SubmissionData['submission']\n | undefined,\n options: SetFormSubmissionOptions,\n ) => {\n const newPageElements = elementLookupData.map((e) => ({\n ...e,\n injectedByElementId: element.id,\n }))\n if (!options.isDerivedChange) {\n markFormDirty()\n }\n setFormSubmission((currentFormSubmission) => {\n const definition: FormTypes.Form = {\n ...currentFormSubmission.definition,\n isMultiPage: true,\n }\n if (!currentFormSubmission.definition.isMultiPage) {\n definition.elements = [\n {\n id: formId.toString(),\n type: 'page',\n label: 'Page 1',\n elements: currentFormSubmission.definition.elements,\n conditionallyShow: false,\n requiresAllConditionallyShowPredicates: false,\n },\n ...newPageElements,\n ]\n } else {\n const indexOfPage =\n currentFormSubmission.definition.elements.findIndex(\n (pageElement: FormTypes.FormElement) => {\n if (pageElement.type === 'page') {\n return formElementsService.findFormElement(\n pageElement.elements,\n (el) => el.id === element.id,\n )\n }\n },\n )\n if (indexOfPage === -1) {\n return currentFormSubmission\n }\n definition.elements =\n currentFormSubmission.definition.elements.reduce(\n (\n partialPageElements: FormTypes.FormElement[],\n pageElement: FormTypes.FormElement,\n index: number,\n ) => {\n // @ts-expect-error Sorry typescript, we need to add a property you don't approve of :(\n if (pageElement.injectedByElementId !== element.id) {\n partialPageElements.push(pageElement)\n }\n if (index === indexOfPage) {\n partialPageElements.push(...newPageElements)\n }\n return partialPageElements\n },\n [],\n )\n }\n\n const submission = generateDefaultData(definition.elements, {\n ...currentFormSubmission.submission,\n ...dataLookupResult,\n })\n return {\n submission,\n definition,\n lastElementUpdated: currentFormSubmission.lastElementUpdated,\n executedLookups: {\n ...currentFormSubmission.executedLookups,\n [element.name]: true,\n },\n sectionState: currentFormSubmission.sectionState,\n }\n }, options)\n },\n [formId, markFormDirty, setFormSubmission],\n )\n\n return {\n handlePagesLookupResult,\n }\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -25,6 +25,8 @@ export { default as useFormSubmissionState } from './hooks/useFormSubmissionStat
25
25
  export { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState';
26
26
  export { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader';
27
27
  export { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration';
28
+ export { FormSubmissionAttemptContextProvider, useFormSubmissionAttempt, FormSubmissionAttempt, FormSubmissionAttemptAllowNavigation, } from './hooks/useFormSubmissionAttempt';
29
+ export { FormIsDirtyContextProvider, useFormIsDirty, useAllowFormNavigation, } from './hooks/useFormIsDirty';
28
30
  export { default as ProgressBar } from './components/renderer/ProgressBar';
29
31
  export { default as LoadingWithMessage } from './components/LoadingWithMessage';
30
32
  export { default as PaymentReceipt } from './PaymentReceipt';
package/dist/index.js CHANGED
@@ -25,6 +25,8 @@ export { default as useFormSubmissionState } from './hooks/useFormSubmissionStat
25
25
  export { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState';
26
26
  export { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader';
27
27
  export { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration';
28
+ export { FormSubmissionAttemptContextProvider, useFormSubmissionAttempt, } from './hooks/useFormSubmissionAttempt';
29
+ export { FormIsDirtyContextProvider, useFormIsDirty, useAllowFormNavigation, } from './hooks/useFormIsDirty';
28
30
  export { default as ProgressBar } from './components/renderer/ProgressBar';
29
31
  export { default as LoadingWithMessage } from './components/LoadingWithMessage';
30
32
  export { default as PaymentReceipt } from './PaymentReceipt';
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n OneBlinkFormBaseProps,\n OneBlinkFormControlledProps,\n OneBlinkFormProps,\n OneBlinkFormUncontrolled as OneBlinkForm,\n OneBlinkFormControlled,\n} from './OneBlinkForm'\nexport { default as OneBlinkAutoSaveForm } from './OneBlinkAutoSaveForm'\nexport { default as OneBlinkReadOnlyForm } from './OneBlinkReadOnlyForm'\nexport { OneBlinkFormStoreProvider } from './components/formStore/OneBlinkFormStoreProvider'\nexport { default as OneBlinkFormStoreClearFiltersButton } from './components/formStore/OneBlinkFormStoreClearFiltersButton'\nexport { default as OneBlinkFormStoreColumnsButton } from './components/formStore/OneBlinkFormStoreColumnsButton'\nexport { default as OneBlinkFormStoreDownloadButton } from './components/formStore/OneBlinkFormStoreDownloadButton'\nexport { default as OneBlinkFormStoreRefreshButton } from './components/formStore/OneBlinkFormStoreRefreshButton'\nexport { default as OneBlinkFormStoreTable } from './components/formStore/OneBlinkFormStoreTable'\n\nexport { default as useIsMounted } from './hooks/useIsMounted'\nexport { default as useResendCoolDown } from './hooks/useResendCoolDown'\nexport { default as useBooleanState } from './hooks/useBooleanState'\nexport { default as useNullableState } from './hooks/useNullableState'\nexport { default as useClickOutsideElement } from './hooks/useClickOutsideElement'\nexport {\n default as useIsOffline,\n IsOfflineContextProvider,\n} from './hooks/useIsOffline'\nexport { default as useLogin, UseLoginValue } from './hooks/useLogin'\nexport { default as useSignUp } from './hooks/useSignUp'\nexport {\n default as useAuth,\n AuthContextProvider,\n AuthContextValue,\n} from './hooks/useAuth'\nexport {\n default as usePendingSubmissions,\n PendingSubmissionsContextProvider,\n PendingSubmissionsContextValue,\n} from './hooks/usePendingSubmissions'\nexport {\n default as useDrafts,\n DraftsContextProvider,\n DraftsContextValue,\n} from './hooks/useDrafts'\nexport {\n default as useLoadDataState,\n LoadDataState,\n} from './hooks/useLoadDataState'\nexport { default as useLoadResourcesState } from './hooks/useLoadResourcesState'\nexport { default as useLoadDataEffect } from './hooks/useLoadDataEffect'\nexport { default as useFormSubmissionState } from './hooks/useFormSubmissionState'\nexport { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState'\nexport { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader'\nexport { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration'\n\nexport { default as ProgressBar } from './components/renderer/ProgressBar'\nexport { default as LoadingWithMessage } from './components/LoadingWithMessage'\nexport { default as PaymentReceipt } from './PaymentReceipt'\nexport { default as PaymentForm } from './components/payments/PaymentForm'\n\nexport { default as CalendarBookingsForm } from './components/calendar-bookings/CalendarBookingsForm'\nexport { default as CalendarBookingsRescheduleForm } from './components/calendar-bookings/CalendarBookingsReschedulingForm'\nexport { default as CalendarBookingsCancelForm } from './components/calendar-bookings/CalendarBookingsCancelForm'\n\nexport { default as MultiFactorAuthentication } from './components/mfa/MultiFactorAuthentication'\nexport { default as MfaAuthenticatorAppDialog } from './components/mfa/MfaAuthenticatorAppDialog'\nexport { default as MfaDisableDialog } from './components/mfa/MfaDisableDialog'\nexport { default as MfaRemovePhoneNumberDialog } from './components/mfa/MfaRemovePhoneNumberDialog'\nexport { default as MfaPhoneNumberDialog } from './components/mfa/MfaPhoneNumberDialog'\nexport { default as MfaSuccessSnackbar } from './components/mfa/MfaSuccessSnackbar'\nexport { default as MfaErrorSnackbar } from './components/mfa/MfaErrorSnackbar'\nexport { default as MfaStatusChip } from './components/mfa/MfaStatusChip'\nexport {\n default as useMfa,\n MfaProvider,\n useUserMeetsMfaRequirement,\n} from './hooks/useMfa'\n\nexport { default as DownloadableFiles } from './components/downloadable-files'\n\nexport {\n default as ImageCropper,\n getAspectRatio,\n generateCroppedImageBlob,\n PercentCrop,\n} from './components/ImageCropper'\n\nexport * from './types/form'\n// Former apps package now exported through here\nexport * from './apps'\n"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n OneBlinkFormBaseProps,\n OneBlinkFormControlledProps,\n OneBlinkFormProps,\n OneBlinkFormUncontrolled as OneBlinkForm,\n OneBlinkFormControlled,\n} from './OneBlinkForm'\nexport { default as OneBlinkAutoSaveForm } from './OneBlinkAutoSaveForm'\nexport { default as OneBlinkReadOnlyForm } from './OneBlinkReadOnlyForm'\nexport { OneBlinkFormStoreProvider } from './components/formStore/OneBlinkFormStoreProvider'\nexport { default as OneBlinkFormStoreClearFiltersButton } from './components/formStore/OneBlinkFormStoreClearFiltersButton'\nexport { default as OneBlinkFormStoreColumnsButton } from './components/formStore/OneBlinkFormStoreColumnsButton'\nexport { default as OneBlinkFormStoreDownloadButton } from './components/formStore/OneBlinkFormStoreDownloadButton'\nexport { default as OneBlinkFormStoreRefreshButton } from './components/formStore/OneBlinkFormStoreRefreshButton'\nexport { default as OneBlinkFormStoreTable } from './components/formStore/OneBlinkFormStoreTable'\n\nexport { default as useIsMounted } from './hooks/useIsMounted'\nexport { default as useResendCoolDown } from './hooks/useResendCoolDown'\nexport { default as useBooleanState } from './hooks/useBooleanState'\nexport { default as useNullableState } from './hooks/useNullableState'\nexport { default as useClickOutsideElement } from './hooks/useClickOutsideElement'\nexport {\n default as useIsOffline,\n IsOfflineContextProvider,\n} from './hooks/useIsOffline'\nexport { default as useLogin, UseLoginValue } from './hooks/useLogin'\nexport { default as useSignUp } from './hooks/useSignUp'\nexport {\n default as useAuth,\n AuthContextProvider,\n AuthContextValue,\n} from './hooks/useAuth'\nexport {\n default as usePendingSubmissions,\n PendingSubmissionsContextProvider,\n PendingSubmissionsContextValue,\n} from './hooks/usePendingSubmissions'\nexport {\n default as useDrafts,\n DraftsContextProvider,\n DraftsContextValue,\n} from './hooks/useDrafts'\nexport {\n default as useLoadDataState,\n LoadDataState,\n} from './hooks/useLoadDataState'\nexport { default as useLoadResourcesState } from './hooks/useLoadResourcesState'\nexport { default as useLoadDataEffect } from './hooks/useLoadDataEffect'\nexport { default as useFormSubmissionState } from './hooks/useFormSubmissionState'\nexport { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState'\nexport { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader'\nexport { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration'\nexport {\n FormSubmissionAttemptContextProvider,\n useFormSubmissionAttempt,\n FormSubmissionAttempt,\n FormSubmissionAttemptAllowNavigation,\n} from './hooks/useFormSubmissionAttempt'\nexport {\n FormIsDirtyContextProvider,\n useFormIsDirty,\n useAllowFormNavigation,\n} from './hooks/useFormIsDirty'\n\nexport { default as ProgressBar } from './components/renderer/ProgressBar'\nexport { default as LoadingWithMessage } from './components/LoadingWithMessage'\nexport { default as PaymentReceipt } from './PaymentReceipt'\nexport { default as PaymentForm } from './components/payments/PaymentForm'\n\nexport { default as CalendarBookingsForm } from './components/calendar-bookings/CalendarBookingsForm'\nexport { default as CalendarBookingsRescheduleForm } from './components/calendar-bookings/CalendarBookingsReschedulingForm'\nexport { default as CalendarBookingsCancelForm } from './components/calendar-bookings/CalendarBookingsCancelForm'\n\nexport { default as MultiFactorAuthentication } from './components/mfa/MultiFactorAuthentication'\nexport { default as MfaAuthenticatorAppDialog } from './components/mfa/MfaAuthenticatorAppDialog'\nexport { default as MfaDisableDialog } from './components/mfa/MfaDisableDialog'\nexport { default as MfaRemovePhoneNumberDialog } from './components/mfa/MfaRemovePhoneNumberDialog'\nexport { default as MfaPhoneNumberDialog } from './components/mfa/MfaPhoneNumberDialog'\nexport { default as MfaSuccessSnackbar } from './components/mfa/MfaSuccessSnackbar'\nexport { default as MfaErrorSnackbar } from './components/mfa/MfaErrorSnackbar'\nexport { default as MfaStatusChip } from './components/mfa/MfaStatusChip'\nexport {\n default as useMfa,\n MfaProvider,\n useUserMeetsMfaRequirement,\n} from './hooks/useMfa'\n\nexport { default as DownloadableFiles } from './components/downloadable-files'\n\nexport {\n default as ImageCropper,\n getAspectRatio,\n generateCroppedImageBlob,\n PercentCrop,\n} from './components/ImageCropper'\n\nexport * from './types/form'\n// Former apps package now exported through here\nexport * from './apps'\n"]}
@@ -11,7 +11,7 @@ declare const validationExtensions: {
11
11
  regex<DefaultValue>(value: unknown, formElement: FormTypes.FormElementWithInput<DefaultValue>): string[];
12
12
  attachment(value: unknown): string[];
13
13
  numberRegex(value: unknown, formElement: FormTypes.NumberElement): string[];
14
- nestedElements(value: unknown, { formElement, formElements, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, }: {
14
+ nestedElements(value: unknown, { formElement, formElements, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, editableFormElementIds, }: {
15
15
  formElement: FormTypes.FormElementWithName;
16
16
  formElements: FormTypes.FormElementWithName[] | undefined;
17
17
  formElementsConditionallyShown: FormElementsConditionallyShown | undefined;
@@ -19,6 +19,7 @@ declare const validationExtensions: {
19
19
  captchaType: CaptchaType;
20
20
  isOffline: boolean;
21
21
  audience: FormTypes.FormElementHiddenFromAudience;
22
+ editableFormElementIds?: string[];
22
23
  }): {
23
24
  type: "formElements";
24
25
  formElements: import("../../types/form").FormElementsValidation;
@@ -53,7 +53,7 @@ const validationExtensions = {
53
53
  }
54
54
  return [];
55
55
  },
56
- nestedElements(value, { formElement, formElements, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, }) {
56
+ nestedElements(value, { formElement, formElements, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, editableFormElementIds, }) {
57
57
  if (formElements) {
58
58
  const nestedExecutedLookupsValue = executedLookups !== undefined &&
59
59
  typeof executedLookups !== 'boolean' &&
@@ -74,6 +74,7 @@ const validationExtensions = {
74
74
  captchaType,
75
75
  isOffline,
76
76
  audience,
77
+ editableFormElementIds,
77
78
  });
78
79
  if (errors) {
79
80
  return {
@@ -1 +1 @@
1
- {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../../src/services/form-validation/extensions.ts"],"names":[],"mappings":"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","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport {\n CaptchaType,\n ExecutedLookups,\n FormElementsConditionallyShown,\n} from '../../types/form'\nimport validateSubmission from './validateSubmission'\nimport {\n generateLookupValidationMessage,\n getInvalidAttachment,\n} from './validators'\nimport { validators } from './validate-dot-js'\n\nconst validationExtensions = {\n lookups({\n executedLookups,\n formElement,\n }: {\n formElement: FormTypes.LookupFormElement &\n FormTypes.FormElementRequired & {\n type: FormTypes.FormElement['type']\n }\n executedLookups: ExecutedLookups\n }): string[] {\n if (!formElement.isDataLookup && !formElement.isElementLookup) {\n return []\n }\n\n // Lookups must only be executed on required form elements\n if (!formElement.required) {\n return []\n }\n\n const elementExecutedLookups = executedLookups?.[formElement.name]\n if (elementExecutedLookups === true) {\n return []\n }\n\n return [\n generateLookupValidationMessage(\n formElement.lookupButton,\n formElement.type === 'lookupButton'\n ? formElement.requiredMessage\n : undefined,\n ),\n ]\n },\n\n presence(\n value: unknown,\n { required, requiredMessage }: FormTypes.FormElementRequired,\n message: string,\n ) {\n if (required) {\n return validators.presence(value, {\n message: requiredMessage || message,\n })\n }\n return []\n },\n\n regex<DefaultValue>(\n value: unknown,\n formElement: FormTypes.FormElementWithInput<DefaultValue>,\n ) {\n if (formElement.regexPattern) {\n return validators.regexValidation(value, {\n pattern: formElement.regexPattern,\n flags: formElement.regexFlags,\n message: formElement.regexMessage,\n })\n }\n return []\n },\n\n attachment(value: unknown): string[] {\n const attachmentError = getInvalidAttachment(value)\n if (attachmentError) {\n return [attachmentError.errorMessage]\n }\n return []\n },\n\n numberRegex(value: unknown, formElement: FormTypes.NumberElement) {\n if (\n formElement.regexPattern &&\n typeof value === 'number' &&\n !Number.isNaN(value)\n ) {\n return validationExtensions.regex(value.toString(), formElement)\n }\n return []\n },\n\n nestedElements(\n value: unknown,\n {\n formElement,\n formElements,\n formElementsConditionallyShown,\n executedLookups,\n captchaType,\n isOffline,\n audience,\n }: {\n formElement: FormTypes.FormElementWithName\n formElements: FormTypes.FormElementWithName[] | undefined\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined\n executedLookups: ExecutedLookups\n captchaType: CaptchaType\n isOffline: boolean\n audience: FormTypes.FormElementHiddenFromAudience\n },\n ) {\n if (formElements) {\n const nestedExecutedLookupsValue =\n executedLookups !== undefined &&\n typeof executedLookups !== 'boolean' &&\n !Array.isArray(executedLookups)\n ? executedLookups[formElement.name]\n : {}\n\n const formElementConditionallyShown =\n formElementsConditionallyShown?.[formElement.name]\n const errors = validateSubmission({\n elements: formElements as FormTypes.FormElementWithName[],\n submission: value as SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown:\n formElementConditionallyShown?.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined,\n executedLookups:\n typeof nestedExecutedLookupsValue !== 'boolean' &&\n !Array.isArray(nestedExecutedLookupsValue)\n ? nestedExecutedLookupsValue\n : {},\n captchaType,\n isOffline,\n audience,\n })\n if (errors) {\n return {\n type: 'formElements' as const,\n formElements: errors,\n }\n }\n }\n },\n\n offline(isOffline: boolean, message: string) {\n return isOffline ? [message] : []\n },\n}\n\nexport default validationExtensions\n"]}
1
+ {"version":3,"file":"extensions.js","sourceRoot":"","sources":["../../../src/services/form-validation/extensions.ts"],"names":[],"mappings":"AAMA,OAAO,kBAAkB,MAAM,sBAAsB,CAAA;AACrD,OAAO,EACL,+BAA+B,EAC/B,oBAAoB,GACrB,MAAM,cAAc,CAAA;AACrB,OAAO,EAAE,UAAU,EAAE,MAAM,mBAAmB,CAAA;AAE9C,MAAM,oBAAoB,GAAG;IAC3B,OAAO,CAAC,EACN,eAAe,EACf,WAAW,GAOZ;QACC,IAAI,CAAC,WAAW,CAAC,YAAY,IAAI,CAAC,WAAW,CAAC,eAAe,EAAE,CAAC;YAC9D,OAAO,EAAE,CAAA;QACX,CAAC;QAED,0DAA0D;QAC1D,IAAI,CAAC,WAAW,CAAC,QAAQ,EAAE,CAAC;YAC1B,OAAO,EAAE,CAAA;QACX,CAAC;QAED,MAAM,sBAAsB,GAAG,eAAe,aAAf,eAAe,uBAAf,eAAe,CAAG,WAAW,CAAC,IAAI,CAAC,CAAA;QAClE,IAAI,sBAAsB,KAAK,IAAI,EAAE,CAAC;YACpC,OAAO,EAAE,CAAA;QACX,CAAC;QAED,OAAO;YACL,+BAA+B,CAC7B,WAAW,CAAC,YAAY,EACxB,WAAW,CAAC,IAAI,KAAK,cAAc;gBACjC,CAAC,CAAC,WAAW,CAAC,eAAe;gBAC7B,CAAC,CAAC,SAAS,CACd;SACF,CAAA;IACH,CAAC;IAED,QAAQ,CACN,KAAc,EACd,EAAE,QAAQ,EAAE,eAAe,EAAiC,EAC5D,OAAe;QAEf,IAAI,QAAQ,EAAE,CAAC;YACb,OAAO,UAAU,CAAC,QAAQ,CAAC,KAAK,EAAE;gBAChC,OAAO,EAAE,eAAe,IAAI,OAAO;aACpC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,KAAK,CACH,KAAc,EACd,WAAyD;QAEzD,IAAI,WAAW,CAAC,YAAY,EAAE,CAAC;YAC7B,OAAO,UAAU,CAAC,eAAe,CAAC,KAAK,EAAE;gBACvC,OAAO,EAAE,WAAW,CAAC,YAAY;gBACjC,KAAK,EAAE,WAAW,CAAC,UAAU;gBAC7B,OAAO,EAAE,WAAW,CAAC,YAAY;aAClC,CAAC,CAAA;QACJ,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,UAAU,CAAC,KAAc;QACvB,MAAM,eAAe,GAAG,oBAAoB,CAAC,KAAK,CAAC,CAAA;QACnD,IAAI,eAAe,EAAE,CAAC;YACpB,OAAO,CAAC,eAAe,CAAC,YAAY,CAAC,CAAA;QACvC,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,WAAW,CAAC,KAAc,EAAE,WAAoC;QAC9D,IACE,WAAW,CAAC,YAAY;YACxB,OAAO,KAAK,KAAK,QAAQ;YACzB,CAAC,MAAM,CAAC,KAAK,CAAC,KAAK,CAAC,EACpB,CAAC;YACD,OAAO,oBAAoB,CAAC,KAAK,CAAC,KAAK,CAAC,QAAQ,EAAE,EAAE,WAAW,CAAC,CAAA;QAClE,CAAC;QACD,OAAO,EAAE,CAAA;IACX,CAAC;IAED,cAAc,CACZ,KAAc,EACd,EACE,WAAW,EACX,YAAY,EACZ,8BAA8B,EAC9B,eAAe,EACf,WAAW,EACX,SAAS,EACT,QAAQ,EACR,sBAAsB,GAUvB;QAED,IAAI,YAAY,EAAE,CAAC;YACjB,MAAM,0BAA0B,GAC9B,eAAe,KAAK,SAAS;gBAC7B,OAAO,eAAe,KAAK,SAAS;gBACpC,CAAC,KAAK,CAAC,OAAO,CAAC,eAAe,CAAC;gBAC7B,CAAC,CAAC,eAAe,CAAC,WAAW,CAAC,IAAI,CAAC;gBACnC,CAAC,CAAC,EAAE,CAAA;YAER,MAAM,6BAA6B,GACjC,8BAA8B,aAA9B,8BAA8B,uBAA9B,8BAA8B,CAAG,WAAW,CAAC,IAAI,CAAC,CAAA;YACpD,MAAM,MAAM,GAAG,kBAAkB,CAAC;gBAChC,QAAQ,EAAE,YAA+C;gBACzD,UAAU,EAAE,KAAuD;gBACnE,8BAA8B,EAC5B,CAAA,6BAA6B,aAA7B,6BAA6B,uBAA7B,6BAA6B,CAAE,IAAI,MAAK,cAAc;oBACpD,CAAC,CAAC,6BAA6B,CAAC,YAAY;oBAC5C,CAAC,CAAC,SAAS;gBACf,eAAe,EACb,OAAO,0BAA0B,KAAK,SAAS;oBAC/C,CAAC,KAAK,CAAC,OAAO,CAAC,0BAA0B,CAAC;oBACxC,CAAC,CAAC,0BAA0B;oBAC5B,CAAC,CAAC,EAAE;gBACR,WAAW;gBACX,SAAS;gBACT,QAAQ;gBACR,sBAAsB;aACvB,CAAC,CAAA;YACF,IAAI,MAAM,EAAE,CAAC;gBACX,OAAO;oBACL,IAAI,EAAE,cAAuB;oBAC7B,YAAY,EAAE,MAAM;iBACrB,CAAA;YACH,CAAC;QACH,CAAC;IACH,CAAC;IAED,OAAO,CAAC,SAAkB,EAAE,OAAe;QACzC,OAAO,SAAS,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;IACnC,CAAC;CACF,CAAA;AAED,eAAe,oBAAoB,CAAA","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport {\n CaptchaType,\n ExecutedLookups,\n FormElementsConditionallyShown,\n} from '../../types/form'\nimport validateSubmission from './validateSubmission'\nimport {\n generateLookupValidationMessage,\n getInvalidAttachment,\n} from './validators'\nimport { validators } from './validate-dot-js'\n\nconst validationExtensions = {\n lookups({\n executedLookups,\n formElement,\n }: {\n formElement: FormTypes.LookupFormElement &\n FormTypes.FormElementRequired & {\n type: FormTypes.FormElement['type']\n }\n executedLookups: ExecutedLookups\n }): string[] {\n if (!formElement.isDataLookup && !formElement.isElementLookup) {\n return []\n }\n\n // Lookups must only be executed on required form elements\n if (!formElement.required) {\n return []\n }\n\n const elementExecutedLookups = executedLookups?.[formElement.name]\n if (elementExecutedLookups === true) {\n return []\n }\n\n return [\n generateLookupValidationMessage(\n formElement.lookupButton,\n formElement.type === 'lookupButton'\n ? formElement.requiredMessage\n : undefined,\n ),\n ]\n },\n\n presence(\n value: unknown,\n { required, requiredMessage }: FormTypes.FormElementRequired,\n message: string,\n ) {\n if (required) {\n return validators.presence(value, {\n message: requiredMessage || message,\n })\n }\n return []\n },\n\n regex<DefaultValue>(\n value: unknown,\n formElement: FormTypes.FormElementWithInput<DefaultValue>,\n ) {\n if (formElement.regexPattern) {\n return validators.regexValidation(value, {\n pattern: formElement.regexPattern,\n flags: formElement.regexFlags,\n message: formElement.regexMessage,\n })\n }\n return []\n },\n\n attachment(value: unknown): string[] {\n const attachmentError = getInvalidAttachment(value)\n if (attachmentError) {\n return [attachmentError.errorMessage]\n }\n return []\n },\n\n numberRegex(value: unknown, formElement: FormTypes.NumberElement) {\n if (\n formElement.regexPattern &&\n typeof value === 'number' &&\n !Number.isNaN(value)\n ) {\n return validationExtensions.regex(value.toString(), formElement)\n }\n return []\n },\n\n nestedElements(\n value: unknown,\n {\n formElement,\n formElements,\n formElementsConditionallyShown,\n executedLookups,\n captchaType,\n isOffline,\n audience,\n editableFormElementIds,\n }: {\n formElement: FormTypes.FormElementWithName\n formElements: FormTypes.FormElementWithName[] | undefined\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined\n executedLookups: ExecutedLookups\n captchaType: CaptchaType\n isOffline: boolean\n audience: FormTypes.FormElementHiddenFromAudience\n editableFormElementIds?: string[]\n },\n ) {\n if (formElements) {\n const nestedExecutedLookupsValue =\n executedLookups !== undefined &&\n typeof executedLookups !== 'boolean' &&\n !Array.isArray(executedLookups)\n ? executedLookups[formElement.name]\n : {}\n\n const formElementConditionallyShown =\n formElementsConditionallyShown?.[formElement.name]\n const errors = validateSubmission({\n elements: formElements as FormTypes.FormElementWithName[],\n submission: value as SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown:\n formElementConditionallyShown?.type === 'formElements'\n ? formElementConditionallyShown.formElements\n : undefined,\n executedLookups:\n typeof nestedExecutedLookupsValue !== 'boolean' &&\n !Array.isArray(nestedExecutedLookupsValue)\n ? nestedExecutedLookupsValue\n : {},\n captchaType,\n isOffline,\n audience,\n editableFormElementIds,\n })\n if (errors) {\n return {\n type: 'formElements' as const,\n formElements: errors,\n }\n }\n }\n },\n\n offline(isOffline: boolean, message: string) {\n return isOffline ? [message] : []\n },\n}\n\nexport default validationExtensions\n"]}
@@ -1,7 +1,7 @@
1
1
  import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import { CaptchaType, ExecutedLookups, FormElementsConditionallyShown, FormElementsValidation } from '../../types/form';
3
3
  export declare const RECAPTCHA_OFFLINE_MESSAGE = "We could not verify you are human while you are offline.";
4
- export default function validateSubmission({ elements, submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, }: {
4
+ export default function validateSubmission({ elements, submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, editableFormElementIds, }: {
5
5
  elements: FormTypes.FormElementWithName[];
6
6
  submission: SubmissionTypes.S3SubmissionData['submission'];
7
7
  formElementsConditionallyShown: FormElementsConditionallyShown | undefined;
@@ -9,4 +9,5 @@ export default function validateSubmission({ elements, submission, formElementsC
9
9
  captchaType: CaptchaType;
10
10
  isOffline: boolean;
11
11
  audience: FormTypes.FormElementHiddenFromAudience;
12
+ editableFormElementIds?: string[];
12
13
  }): FormElementsValidation | undefined;
@@ -9,9 +9,9 @@ import { generateConfirmationFormElementName } from '../dynamic-elements';
9
9
  import { determineLookupButtonIsRequired } from './determineLookupButtonIsRequired';
10
10
  import { defaultAutoSnapshotButtonLabel, generateArcGISAutomatedSnapshotFileName, } from '../../form-elements/FormElementArcGISWebMap';
11
11
  import { fileUploadService } from '@oneblink/sdk-core';
12
- import isElementReadOnlyForAudience, { isElementEditableForAudience, } from '../isElementReadOnlyForAudience';
12
+ import { checkIsFormElementEditable, checkIsFormElementIdEditable, } from '../../utils/read-only-form-elements';
13
13
  export const RECAPTCHA_OFFLINE_MESSAGE = 'We could not verify you are human while you are offline.';
14
- export default function validateSubmission({ elements, submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, }) {
14
+ export default function validateSubmission({ elements, submission, formElementsConditionallyShown, executedLookups, captchaType, isOffline, audience, editableFormElementIds, }) {
15
15
  const formElementsValidation = elements.reduce((partialFormElementsValidation, formElement) => {
16
16
  var _a, _b, _c, _d, _e;
17
17
  switch (formElement.type) {
@@ -29,11 +29,11 @@ export default function validateSubmission({ elements, submission, formElementsC
29
29
  if (formElementConditionallyShown === null || formElementConditionallyShown === void 0 ? void 0 : formElementConditionallyShown.isHidden) {
30
30
  return partialFormElementsValidation;
31
31
  }
32
- // An audience that cannot change this element, or anything nested inside
33
- // it, has no way to resolve an error on it. Approvers still see the page
32
+ // A user that cannot change this element, or anything nested inside it,
33
+ // has no way to resolve an error on it. Reviewers still see the page
34
34
  // navigation buttons and can submit the form by pressing Enter, either of
35
35
  // which would otherwise reveal errors on fields locked to them.
36
- if (!isElementEditableForAudience(formElement, audience)) {
36
+ if (!checkIsFormElementEditable(formElement, editableFormElementIds)) {
37
37
  return partialFormElementsValidation;
38
38
  }
39
39
  const value = submission === null || submission === void 0 ? void 0 : submission[formElement.name];
@@ -60,7 +60,7 @@ export default function validateSubmission({ elements, submission, formElementsC
60
60
  }
61
61
  case 'captcha': {
62
62
  // An approver edit is not a new submission, so the renderer never
63
- // shows a captcha to an approver, regardless of `approverEditability`.
63
+ // shows a captcha to an approver, regardless of editable element ids.
64
64
  // Mirror that unconditionally rather than relying on the editability
65
65
  // check above.
66
66
  if (audience === 'APPROVER') {
@@ -425,9 +425,10 @@ export default function validateSubmission({ elements, submission, formElementsC
425
425
  const setErrorMessages = [];
426
426
  // The entry count can only be corrected by adding or removing
427
427
  // entries, which requires the set itself to be editable. Its entries
428
- // are still validated below, as they may contain elements this
429
- // audience can edit even while the set is locked.
430
- if (!isElementReadOnlyForAudience(formElement, audience)) {
428
+ // are still validated below, as they may contain elements that are
429
+ // listed even while the set is locked.
430
+ if (editableFormElementIds === undefined ||
431
+ checkIsFormElementIdEditable(formElement, editableFormElementIds)) {
431
432
  const minSetEntries = getCleanRepeatableSetConfiguration(formElement.minSetEntries, elements, submission, formElementsConditionallyShown);
432
433
  const maxSetEntries = getCleanRepeatableSetConfiguration(formElement.maxSetEntries, elements, submission, formElementsConditionallyShown);
433
434
  setErrorMessages.push(...validators.length(value, {
@@ -462,6 +463,7 @@ export default function validateSubmission({ elements, submission, formElementsC
462
463
  captchaType,
463
464
  isOffline,
464
465
  audience,
466
+ editableFormElementIds,
465
467
  });
466
468
  if (entryValidation) {
467
469
  errorsByIndex[index] = entryValidation;
@@ -487,6 +489,7 @@ export default function validateSubmission({ elements, submission, formElementsC
487
489
  captchaType,
488
490
  isOffline,
489
491
  audience,
492
+ editableFormElementIds,
490
493
  });
491
494
  if (nestedFormValidation) {
492
495
  partialFormElementsValidation[formElement.name] =
@@ -504,6 +507,7 @@ export default function validateSubmission({ elements, submission, formElementsC
504
507
  captchaType,
505
508
  isOffline,
506
509
  audience,
510
+ editableFormElementIds,
507
511
  });
508
512
  if (nestedFormValidation) {
509
513
  partialFormElementsValidation[formElement.name] =
@@ -521,6 +525,7 @@ export default function validateSubmission({ elements, submission, formElementsC
521
525
  captchaType,
522
526
  isOffline,
523
527
  audience,
528
+ editableFormElementIds,
524
529
  });
525
530
  if (nestedFormValidation) {
526
531
  partialFormElementsValidation[formElement.name] =