@oneblink/apps-react 4.1.0-beta.7 → 4.1.0-beta.8

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 (177) hide show
  1. package/README.md +2 -8
  2. package/dist/OneBlinkAutoSaveForm.d.ts +25 -5
  3. package/dist/OneBlinkAutoSaveForm.js +12 -0
  4. package/dist/OneBlinkAutoSaveForm.js.map +1 -1
  5. package/dist/OneBlinkForm.d.ts +558 -8
  6. package/dist/OneBlinkForm.js +546 -0
  7. package/dist/OneBlinkForm.js.map +1 -1
  8. package/dist/OneBlinkFormBase.d.ts +53 -8
  9. package/dist/OneBlinkFormBase.js +49 -25
  10. package/dist/OneBlinkFormBase.js.map +1 -1
  11. package/dist/OneBlinkReadOnlyForm.d.ts +83 -6
  12. package/dist/OneBlinkReadOnlyForm.js +80 -1
  13. package/dist/OneBlinkReadOnlyForm.js.map +1 -1
  14. package/dist/PaymentReceipt.d.ts +59 -0
  15. package/dist/PaymentReceipt.js +61 -6
  16. package/dist/PaymentReceipt.js.map +1 -1
  17. package/dist/components/formStore/FormStoreTableProvider.js +23 -1
  18. package/dist/components/formStore/FormStoreTableProvider.js.map +1 -1
  19. package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.d.ts +5 -0
  20. package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.js +5 -0
  21. package/dist/components/formStore/OneBlinkFormStoreClearFiltersButton.js.map +1 -1
  22. package/dist/components/formStore/OneBlinkFormStoreColumnsButton.d.ts +5 -0
  23. package/dist/components/formStore/OneBlinkFormStoreColumnsButton.js +5 -0
  24. package/dist/components/formStore/OneBlinkFormStoreColumnsButton.js.map +1 -1
  25. package/dist/components/formStore/OneBlinkFormStoreDownloadButton.d.ts +5 -0
  26. package/dist/components/formStore/OneBlinkFormStoreDownloadButton.js +5 -0
  27. package/dist/components/formStore/OneBlinkFormStoreDownloadButton.js.map +1 -1
  28. package/dist/components/formStore/OneBlinkFormStoreProvider.d.ts +5 -0
  29. package/dist/components/formStore/OneBlinkFormStoreProvider.js +5 -0
  30. package/dist/components/formStore/OneBlinkFormStoreProvider.js.map +1 -1
  31. package/dist/components/formStore/OneBlinkFormStoreRefreshButton.d.ts +5 -0
  32. package/dist/components/formStore/OneBlinkFormStoreRefreshButton.js +5 -0
  33. package/dist/components/formStore/OneBlinkFormStoreRefreshButton.js.map +1 -1
  34. package/dist/components/formStore/OneBlinkFormStoreTable.d.ts +4 -0
  35. package/dist/components/formStore/OneBlinkFormStoreTable.js +4 -0
  36. package/dist/components/formStore/OneBlinkFormStoreTable.js.map +1 -1
  37. package/dist/components/formStore/table/ColumnFilters.js.map +1 -1
  38. package/dist/components/pickers/V4CompatibleDatePicker.d.ts +5 -0
  39. package/dist/components/pickers/V4CompatibleDatePicker.js +5 -0
  40. package/dist/components/pickers/V4CompatibleDatePicker.js.map +1 -1
  41. package/dist/components/pickers/V4CompatibleDateTimePicker.d.ts +5 -0
  42. package/dist/components/pickers/V4CompatibleDateTimePicker.js +5 -0
  43. package/dist/components/pickers/V4CompatibleDateTimePicker.js.map +1 -1
  44. package/dist/components/pickers/V4CompatibleTimePicker.d.ts +5 -0
  45. package/dist/components/pickers/V4CompatibleTimePicker.js +5 -0
  46. package/dist/components/pickers/V4CompatibleTimePicker.js.map +1 -1
  47. package/dist/components/renderer/LookupButton.d.ts +3 -1
  48. package/dist/components/renderer/LookupButton.js +7 -5
  49. package/dist/components/renderer/LookupButton.js.map +1 -1
  50. package/dist/components/renderer/LookupNotification.js +60 -15
  51. package/dist/components/renderer/LookupNotification.js.map +1 -1
  52. package/dist/components/renderer/OneBlinkFormElements.d.ts +3 -3
  53. package/dist/components/renderer/OneBlinkFormElements.js.map +1 -1
  54. package/dist/components/renderer/PageFormElements.d.ts +3 -3
  55. package/dist/components/renderer/PageFormElements.js.map +1 -1
  56. package/dist/components/renderer/ProgressBar.d.ts +7 -3
  57. package/dist/components/renderer/ProgressBar.js +5 -0
  58. package/dist/components/renderer/ProgressBar.js.map +1 -1
  59. package/dist/form-elements/FormElementABN.js +1 -1
  60. package/dist/form-elements/FormElementABN.js.map +1 -1
  61. package/dist/form-elements/FormElementBSB.js +1 -1
  62. package/dist/form-elements/FormElementBSB.js.map +1 -1
  63. package/dist/form-elements/FormElementBarcodeScanner.js +3 -3
  64. package/dist/form-elements/FormElementBarcodeScanner.js.map +1 -1
  65. package/dist/form-elements/FormElementCalculation.js.map +1 -1
  66. package/dist/form-elements/FormElementCheckBoxes.js +1 -1
  67. package/dist/form-elements/FormElementCheckBoxes.js.map +1 -1
  68. package/dist/form-elements/FormElementDate.js +1 -1
  69. package/dist/form-elements/FormElementDate.js.map +1 -1
  70. package/dist/form-elements/FormElementDateTime.js +1 -1
  71. package/dist/form-elements/FormElementDateTime.js.map +1 -1
  72. package/dist/form-elements/FormElementEmail.js +1 -1
  73. package/dist/form-elements/FormElementEmail.js.map +1 -1
  74. package/dist/form-elements/FormElementForm.d.ts +4 -4
  75. package/dist/form-elements/FormElementForm.js.map +1 -1
  76. package/dist/form-elements/FormElementNumber.js +1 -1
  77. package/dist/form-elements/FormElementNumber.js.map +1 -1
  78. package/dist/form-elements/FormElementRepeatableSet.d.ts +4 -4
  79. package/dist/form-elements/FormElementRepeatableSet.js.map +1 -1
  80. package/dist/form-elements/FormElementSelect.js +1 -1
  81. package/dist/form-elements/FormElementSelect.js.map +1 -1
  82. package/dist/form-elements/FormElementSummary.js.map +1 -1
  83. package/dist/form-elements/FormElementTelephone.js +1 -1
  84. package/dist/form-elements/FormElementTelephone.js.map +1 -1
  85. package/dist/form-elements/FormElementText.js +1 -1
  86. package/dist/form-elements/FormElementText.js.map +1 -1
  87. package/dist/form-elements/FormElementTextarea.js +1 -1
  88. package/dist/form-elements/FormElementTextarea.js.map +1 -1
  89. package/dist/form-elements/FormElementTime.js +1 -1
  90. package/dist/form-elements/FormElementTime.js.map +1 -1
  91. package/dist/hooks/useAuth.d.ts +81 -6
  92. package/dist/hooks/useAuth.js +54 -0
  93. package/dist/hooks/useAuth.js.map +1 -1
  94. package/dist/hooks/useBooleanState.d.ts +42 -5
  95. package/dist/hooks/useBooleanState.js +36 -0
  96. package/dist/hooks/useBooleanState.js.map +1 -1
  97. package/dist/hooks/useClickOutsideElement.d.ts +40 -0
  98. package/dist/hooks/useClickOutsideElement.js +40 -0
  99. package/dist/hooks/useClickOutsideElement.js.map +1 -1
  100. package/dist/hooks/useConditionalLogic.d.ts +2 -3
  101. package/dist/hooks/useConditionalLogic.js.map +1 -1
  102. package/dist/hooks/useDrafts.d.ts +82 -0
  103. package/dist/hooks/useDrafts.js +204 -0
  104. package/dist/hooks/useDrafts.js.map +1 -0
  105. package/dist/hooks/useFormSubmissionAutoSaveState.d.ts +18 -5
  106. package/dist/hooks/useFormSubmissionAutoSaveState.js +10 -0
  107. package/dist/hooks/useFormSubmissionAutoSaveState.js.map +1 -1
  108. package/dist/hooks/useFormSubmissionModelContext.d.ts +4 -4
  109. package/dist/hooks/useFormSubmissionModelContext.js.map +1 -1
  110. package/dist/hooks/useFormSubmissionState.d.ts +45 -5
  111. package/dist/hooks/useFormSubmissionState.js +37 -0
  112. package/dist/hooks/useFormSubmissionState.js.map +1 -1
  113. package/dist/hooks/useFormValidation.d.ts +3 -3
  114. package/dist/hooks/useFormValidation.js.map +1 -1
  115. package/dist/hooks/useInjectPages.d.ts +2 -3
  116. package/dist/hooks/useInjectPages.js.map +1 -1
  117. package/dist/hooks/useIsMounted.d.ts +20 -0
  118. package/dist/hooks/useIsMounted.js +19 -0
  119. package/dist/hooks/useIsMounted.js.map +1 -1
  120. package/dist/hooks/useIsOffline.d.ts +54 -0
  121. package/dist/hooks/useIsOffline.js +54 -0
  122. package/dist/hooks/useIsOffline.js.map +1 -1
  123. package/dist/hooks/useLoadDataState.d.ts +46 -3
  124. package/dist/hooks/useLoadDataState.js +41 -0
  125. package/dist/hooks/useLoadDataState.js.map +1 -1
  126. package/dist/hooks/useLogin.d.ts +400 -13
  127. package/dist/hooks/useLogin.js +300 -0
  128. package/dist/hooks/useLogin.js.map +1 -1
  129. package/dist/hooks/useLookupNotification.d.ts +11 -4
  130. package/dist/hooks/useLookupNotification.js +42 -3
  131. package/dist/hooks/useLookupNotification.js.map +1 -1
  132. package/dist/hooks/useLookups.d.ts +3 -3
  133. package/dist/hooks/useLookups.js.map +1 -1
  134. package/dist/hooks/useNullableState.d.ts +46 -1
  135. package/dist/hooks/useNullableState.js +42 -1
  136. package/dist/hooks/useNullableState.js.map +1 -1
  137. package/dist/hooks/usePendingSubmissions.d.ts +103 -0
  138. package/dist/hooks/usePendingSubmissions.js +195 -0
  139. package/dist/hooks/usePendingSubmissions.js.map +1 -0
  140. package/dist/hooks/useReplaceableText.js +2 -1
  141. package/dist/hooks/useReplaceableText.js.map +1 -1
  142. package/dist/hooks/useSignUp.d.ts +5 -0
  143. package/dist/hooks/useSignUp.js +5 -0
  144. package/dist/hooks/useSignUp.js.map +1 -1
  145. package/dist/index.d.ts +7 -4
  146. package/dist/index.js +5 -2
  147. package/dist/index.js.map +1 -1
  148. package/dist/services/checkBsbsAreInvalid.d.ts +2 -3
  149. package/dist/services/checkBsbsAreInvalid.js.map +1 -1
  150. package/dist/services/checkIfAttachmentsExist.d.ts +2 -3
  151. package/dist/services/checkIfAttachmentsExist.js.map +1 -1
  152. package/dist/services/checkIfBsbsAreValidating.d.ts +2 -3
  153. package/dist/services/checkIfBsbsAreValidating.js.map +1 -1
  154. package/dist/services/cleanFormSubmissionModel.d.ts +4 -4
  155. package/dist/services/cleanFormSubmissionModel.js +2 -1
  156. package/dist/services/cleanFormSubmissionModel.js.map +1 -1
  157. package/dist/services/form-validation.d.ts +3 -3
  158. package/dist/services/form-validation.js.map +1 -1
  159. package/dist/services/generate-default-data.d.ts +2 -3
  160. package/dist/services/generate-default-data.js +3 -1
  161. package/dist/services/generate-default-data.js.map +1 -1
  162. package/dist/services/generateFreshdeskDependentFieldElements.js.map +1 -1
  163. package/dist/services/getDateRangeConfiguration.d.ts +2 -3
  164. package/dist/services/getDateRangeConfiguration.js.map +1 -1
  165. package/dist/services/getRepeatableSetEntriesConfiguration.d.ts +2 -3
  166. package/dist/services/getRepeatableSetEntriesConfiguration.js.map +1 -1
  167. package/dist/styles/receipt.scss +1 -1
  168. package/dist/styles/repeatable-set.scss +2 -2
  169. package/dist/typedoc.d.ts +2 -0
  170. package/dist/typedoc.js +3 -0
  171. package/dist/typedoc.js.map +1 -0
  172. package/dist/types/form.d.ts +5 -6
  173. package/dist/types/form.js.map +1 -1
  174. package/package.json +10 -4
  175. package/dist/services/determineIsInfoPage.d.ts +0 -2
  176. package/dist/services/determineIsInfoPage.js +0 -17
  177. package/dist/services/determineIsInfoPage.js.map +0 -1
@@ -0,0 +1,204 @@
1
+ import * as React from 'react';
2
+ import { draftService, submissionService } from '@oneblink/apps';
3
+ import useAuth from './useAuth';
4
+ import useIsMounted from './useIsMounted';
5
+ import useIsOffline from './useIsOffline';
6
+ const defaultLoadState = {
7
+ isLoading: false,
8
+ loadError: null,
9
+ drafts: [],
10
+ };
11
+ const defaultSyncState = {
12
+ isSyncing: false,
13
+ syncError: null,
14
+ };
15
+ const DraftsContext = React.createContext(undefined);
16
+ /**
17
+ * React Component that provides the context for the `useDrafts()` hook to be
18
+ * used by components further down your component tree. **It should only be
19
+ * included in your component tree once and ideally at the root of the
20
+ * application.**
21
+ *
22
+ * #### Example
23
+ *
24
+ * ```jsx
25
+ * import * as React from 'react'
26
+ * import { DraftsContextProvider, useDrafts } from '@oneblink/apps-react'
27
+ *
28
+ * function Component() {
29
+ * const draftsContext = useDrafts()
30
+ * // use drafts here
31
+ * }
32
+ *
33
+ * function App() {
34
+ * return (
35
+ * <DraftsContextProvider>
36
+ * <Component />
37
+ * </DraftsContextProvider>
38
+ * )
39
+ * }
40
+ *
41
+ * const root = document.getElementById('root')
42
+ * if (root) {
43
+ * ReactDOM.render(<App />, root)
44
+ * }
45
+ * ```
46
+ *
47
+ * @param props
48
+ * @returns
49
+ * @group Components
50
+ */
51
+ export function DraftsContextProvider({
52
+ /** The identifier for the forms app associated with the user's drafts */
53
+ formsAppId,
54
+ /**
55
+ * `true` if drafts are enabled, otherwise `false`. Can be used for account
56
+ * tier validation.
57
+ */
58
+ isDraftsEnabled,
59
+ /** Your application components */
60
+ children, }) {
61
+ const isMounted = useIsMounted();
62
+ const isOffline = useIsOffline();
63
+ const { isLoggedIn, isUsingFormsKey } = useAuth();
64
+ const [syncState, setSyncState] = React.useState(defaultSyncState);
65
+ const clearSyncError = React.useCallback(() => {
66
+ setSyncState((currentState) => ({
67
+ ...currentState,
68
+ syncError: null,
69
+ }));
70
+ }, []);
71
+ const syncDrafts = React.useCallback(async () => {
72
+ if (!isDraftsEnabled || !isLoggedIn || isUsingFormsKey) {
73
+ return;
74
+ }
75
+ if (isMounted.current) {
76
+ setSyncState({
77
+ isSyncing: true,
78
+ syncError: null,
79
+ });
80
+ }
81
+ let newError = null;
82
+ try {
83
+ await draftService.syncDrafts({
84
+ formsAppId,
85
+ throwError: false,
86
+ });
87
+ }
88
+ catch (error) {
89
+ newError = error;
90
+ }
91
+ if (isMounted.current) {
92
+ setSyncState({
93
+ isSyncing: false,
94
+ syncError: newError,
95
+ });
96
+ }
97
+ }, [formsAppId, isDraftsEnabled, isLoggedIn, isMounted, isUsingFormsKey]);
98
+ const [loadState, setLoadState] = React.useState(defaultLoadState);
99
+ const clearLoadError = React.useCallback(() => {
100
+ setLoadState((currentState) => ({
101
+ ...currentState,
102
+ loadError: null,
103
+ }));
104
+ }, []);
105
+ const reloadDrafts = React.useCallback(async () => {
106
+ if (!isLoggedIn) {
107
+ if (isMounted.current) {
108
+ setLoadState({
109
+ isLoading: false,
110
+ loadError: null,
111
+ drafts: [],
112
+ });
113
+ }
114
+ return;
115
+ }
116
+ if (isMounted.current) {
117
+ setLoadState((currentState) => ({
118
+ isLoading: true,
119
+ loadError: null,
120
+ drafts: currentState.drafts,
121
+ }));
122
+ }
123
+ let newError = null;
124
+ let newDrafts = [];
125
+ try {
126
+ newDrafts = await draftService.getDrafts();
127
+ }
128
+ catch (error) {
129
+ newError = error;
130
+ }
131
+ if (isMounted.current) {
132
+ setLoadState({
133
+ isLoading: false,
134
+ loadError: newError,
135
+ drafts: newDrafts,
136
+ });
137
+ }
138
+ }, [isMounted, isLoggedIn]);
139
+ const deleteDraft = React.useCallback((draftId) => {
140
+ return draftService.deleteDraft(draftId, formsAppId);
141
+ }, [formsAppId]);
142
+ const value = React.useMemo(() => ({
143
+ // Sync
144
+ syncDrafts,
145
+ isSyncing: syncState.isSyncing,
146
+ syncError: syncState.syncError,
147
+ clearSyncError,
148
+ // Load
149
+ reloadDrafts,
150
+ isLoading: loadState.isLoading,
151
+ drafts: loadState.drafts,
152
+ loadError: loadState.loadError,
153
+ clearLoadError,
154
+ // Delete,
155
+ deleteDraft,
156
+ }), [
157
+ clearLoadError,
158
+ clearSyncError,
159
+ loadState.drafts,
160
+ loadState.isLoading,
161
+ loadState.loadError,
162
+ reloadDrafts,
163
+ syncDrafts,
164
+ syncState.isSyncing,
165
+ syncState.syncError,
166
+ deleteDraft,
167
+ ]);
168
+ React.useEffect(() => {
169
+ reloadDrafts();
170
+ const unregisterPendingQueueListener = submissionService.registerPendingQueueListener(reloadDrafts);
171
+ const unregisterDraftsListener = draftService.registerDraftsListener((drafts) => {
172
+ setLoadState({
173
+ isLoading: false,
174
+ drafts,
175
+ loadError: null,
176
+ });
177
+ });
178
+ return () => {
179
+ unregisterPendingQueueListener();
180
+ unregisterDraftsListener();
181
+ };
182
+ }, [reloadDrafts]);
183
+ React.useEffect(() => {
184
+ if (!isOffline) {
185
+ syncDrafts();
186
+ }
187
+ }, [isOffline, syncDrafts]);
188
+ return (React.createElement(DraftsContext.Provider, { value: value }, children));
189
+ }
190
+ /**
191
+ * React hook to get the context value for Drafts. Will throw an Error if used
192
+ * outside of the `<DraftsContextProvider />` component.
193
+ *
194
+ * @returns
195
+ * @group Hooks
196
+ */
197
+ export default function useDrafts() {
198
+ const value = React.useContext(DraftsContext);
199
+ if (!value) {
200
+ throw new Error(`"useDrafts" hook was used outside of the "<DraftsContextProvider />" component's children.`);
201
+ }
202
+ return value;
203
+ }
204
+ //# sourceMappingURL=useDrafts.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useDrafts.js","sourceRoot":"","sources":["../../src/hooks/useDrafts.tsx"],"names":[],"mappings":"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","sourcesContent":["import * as React from 'react'\nimport { draftService, submissionService } from '@oneblink/apps'\nimport { SubmissionTypes } from '@oneblink/types'\nimport useAuth from './useAuth'\nimport useIsMounted from './useIsMounted'\nimport useIsOffline from './useIsOffline'\n\n/** The value returned from `useDrafts()` hook */\nexport type DraftsContextValue = {\n /** `true` drafts are currently loading. */\n isLoading: boolean\n /** An Error object if loading drafts fails */\n loadError: Error | null\n /** The incomplete submissions that were saved for later */\n drafts: SubmissionTypes.FormsAppDraft[]\n /** A function to trigger loading of the drafts */\n reloadDrafts: () => unknown\n /** A function to clear Error object from loading drafts */\n clearLoadError: () => void\n /** `true` drafts are syncing with other devices */\n isSyncing: boolean\n /** A function to trigger syncing of the drafts */\n syncDrafts: () => unknown\n /** An Error object if syncing drafts fails */\n syncError: Error | null\n /** A function to clear Error object from syncing drafts */\n clearSyncError: () => void\n /** A function to remove a draft */\n deleteDraft: (draftId: string) => Promise<void>\n}\n\nconst defaultLoadState = {\n isLoading: false,\n loadError: null,\n drafts: [],\n}\n\nconst defaultSyncState = {\n isSyncing: false,\n syncError: null,\n}\n\nconst DraftsContext = React.createContext<DraftsContextValue | undefined>(\n undefined,\n)\n\n/**\n * React Component that provides the context for the `useDrafts()` hook to be\n * used by components further down your component tree. **It should only be\n * included in your component tree once and ideally at the root of the\n * application.**\n *\n * #### Example\n *\n * ```jsx\n * import * as React from 'react'\n * import { DraftsContextProvider, useDrafts } from '@oneblink/apps-react'\n *\n * function Component() {\n * const draftsContext = useDrafts()\n * // use drafts here\n * }\n *\n * function App() {\n * return (\n * <DraftsContextProvider>\n * <Component />\n * </DraftsContextProvider>\n * )\n * }\n *\n * const root = document.getElementById('root')\n * if (root) {\n * ReactDOM.render(<App />, root)\n * }\n * ```\n *\n * @param props\n * @returns\n * @group Components\n */\nexport function DraftsContextProvider({\n /** The identifier for the forms app associated with the user's drafts */\n formsAppId,\n /**\n * `true` if drafts are enabled, otherwise `false`. Can be used for account\n * tier validation.\n */\n isDraftsEnabled,\n /** Your application components */\n children,\n}: {\n formsAppId: number\n isDraftsEnabled: boolean\n children: React.ReactNode\n}) {\n const isMounted = useIsMounted()\n const isOffline = useIsOffline()\n const { isLoggedIn, isUsingFormsKey } = useAuth()\n\n const [syncState, setSyncState] = React.useState<{\n isSyncing: boolean\n syncError: Error | null\n }>(defaultSyncState)\n const clearSyncError = React.useCallback(() => {\n setSyncState((currentState) => ({\n ...currentState,\n syncError: null,\n }))\n }, [])\n const syncDrafts = React.useCallback(async () => {\n if (!isDraftsEnabled || !isLoggedIn || isUsingFormsKey) {\n return\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: true,\n syncError: null,\n })\n }\n\n let newError = null\n\n try {\n await draftService.syncDrafts({\n formsAppId,\n throwError: false,\n })\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setSyncState({\n isSyncing: false,\n syncError: newError,\n })\n }\n }, [formsAppId, isDraftsEnabled, isLoggedIn, isMounted, isUsingFormsKey])\n\n const [loadState, setLoadState] = React.useState<{\n isLoading: boolean\n loadError: Error | null\n drafts: SubmissionTypes.FormsAppDraft[]\n }>(defaultLoadState)\n const clearLoadError = React.useCallback(() => {\n setLoadState((currentState) => ({\n ...currentState,\n loadError: null,\n }))\n }, [])\n const reloadDrafts = React.useCallback(async () => {\n if (!isLoggedIn) {\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: null,\n drafts: [],\n })\n }\n return\n }\n\n if (isMounted.current) {\n setLoadState((currentState) => ({\n isLoading: true,\n loadError: null,\n drafts: currentState.drafts,\n }))\n }\n\n let newError = null\n let newDrafts: SubmissionTypes.FormsAppDraft[] = []\n\n try {\n newDrafts = await draftService.getDrafts()\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setLoadState({\n isLoading: false,\n loadError: newError,\n drafts: newDrafts,\n })\n }\n }, [isMounted, isLoggedIn])\n\n const deleteDraft = React.useCallback(\n (draftId) => {\n return draftService.deleteDraft(draftId, formsAppId)\n },\n [formsAppId],\n )\n\n const value = React.useMemo(\n () => ({\n // Sync\n syncDrafts,\n isSyncing: syncState.isSyncing,\n syncError: syncState.syncError,\n clearSyncError,\n // Load\n reloadDrafts,\n isLoading: loadState.isLoading,\n drafts: loadState.drafts,\n loadError: loadState.loadError,\n clearLoadError,\n // Delete,\n deleteDraft,\n }),\n [\n clearLoadError,\n clearSyncError,\n loadState.drafts,\n loadState.isLoading,\n loadState.loadError,\n reloadDrafts,\n syncDrafts,\n syncState.isSyncing,\n syncState.syncError,\n deleteDraft,\n ],\n )\n\n React.useEffect(() => {\n reloadDrafts()\n const unregisterPendingQueueListener =\n submissionService.registerPendingQueueListener(reloadDrafts)\n const unregisterDraftsListener = draftService.registerDraftsListener(\n (drafts) => {\n setLoadState({\n isLoading: false,\n drafts,\n loadError: null,\n })\n },\n )\n return () => {\n unregisterPendingQueueListener()\n unregisterDraftsListener()\n }\n }, [reloadDrafts])\n\n React.useEffect(() => {\n if (!isOffline) {\n syncDrafts()\n }\n }, [isOffline, syncDrafts])\n\n return (\n <DraftsContext.Provider value={value}>{children}</DraftsContext.Provider>\n )\n}\n\n/**\n * React hook to get the context value for Drafts. Will throw an Error if used\n * outside of the `<DraftsContextProvider />` component.\n *\n * @returns\n * @group Hooks\n */\nexport default function useDrafts(): DraftsContextValue {\n const value = React.useContext(DraftsContext)\n if (!value) {\n throw new Error(\n `\"useDrafts\" hook was used outside of the \"<DraftsContextProvider />\" component's children.`,\n )\n }\n return value\n}\n"]}
@@ -1,7 +1,16 @@
1
1
  import * as React from 'react';
2
2
  import { submissionService } from '@oneblink/apps';
3
- import { FormTypes } from '@oneblink/types';
4
- import { FormSubmissionModel } from '../types/form';
3
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
4
+ /**
5
+ * Use this if you want to implement a controlled auto saving form. See
6
+ * {@link OneBlinkFormControlled} for a full example. If you do not need to
7
+ * control the `submission` or `definition` properties, you can use the
8
+ * {@link OneBlinkAutoSaveForm} component.
9
+ *
10
+ * @param options
11
+ * @returns
12
+ * @group Hooks
13
+ */
5
14
  export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, onCancel, onSubmit, onSaveDraft, }: {
6
15
  form: FormTypes.Form;
7
16
  removeAutoSaveDataBeforeSubmit?: boolean;
@@ -9,12 +18,14 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
9
18
  autoSaveKey: string;
10
19
  onCancel: () => unknown;
11
20
  onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown;
12
- initialSubmission?: FormSubmissionModel;
21
+ initialSubmission?: SubmissionTypes.S3SubmissionData['submission'];
13
22
  resumeAtElement?: FormTypes.FormElement;
14
23
  onSaveDraft?: (newDraftSubmission: submissionService.NewDraftSubmission) => unknown;
15
24
  }): {
16
25
  definition: FormTypes.Form;
17
- submission: FormSubmissionModel;
26
+ submission: {
27
+ [name: string]: unknown;
28
+ };
18
29
  lastElementUpdated: FormTypes.FormElement | undefined;
19
30
  isLoadingAutoSaveSubmission: boolean;
20
31
  isAutoSaveSubmissionAvailable: boolean;
@@ -26,7 +37,9 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
26
37
  handleNavigateAway: () => void;
27
38
  setFormSubmission: React.Dispatch<React.SetStateAction<{
28
39
  definition: FormTypes.Form;
29
- submission: FormSubmissionModel;
40
+ submission: {
41
+ [name: string]: unknown;
42
+ };
30
43
  lastElementUpdated: FormTypes.FormElement | undefined;
31
44
  }>>;
32
45
  };
@@ -2,6 +2,16 @@ import * as React from 'react';
2
2
  import _throttle from 'lodash.throttle';
3
3
  import { autoSaveService, Sentry } from '@oneblink/apps';
4
4
  import useFormSubmissionState from './useFormSubmissionState';
5
+ /**
6
+ * Use this if you want to implement a controlled auto saving form. See
7
+ * {@link OneBlinkFormControlled} for a full example. If you do not need to
8
+ * control the `submission` or `definition` properties, you can use the
9
+ * {@link OneBlinkAutoSaveForm} component.
10
+ *
11
+ * @param options
12
+ * @returns
13
+ * @group Hooks
14
+ */
5
15
  export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, onCancel, onSubmit, onSaveDraft, }) {
6
16
  const [{ definition, submission, lastElementUpdated }, setFormSubmission] = useFormSubmissionState(form, initialSubmission, resumeAtElement);
7
17
  const [{ isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement }, setAutoSaveState,] = React.useState({
@@ -1 +1 @@
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 '@oneblink/apps'\nimport { FormTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport { FormSubmissionModel } from '../types/form'\nimport { FormElement } from '@oneblink/types/typescript/forms'\n\nexport default function useFormSubmissionAutoSaveState({\n form,\n initialSubmission,\n resumeAtElement,\n removeAutoSaveDataBeforeSubmit,\n removeAutoSaveDataBeforeSaveDraft,\n autoSaveKey,\n onCancel,\n onSubmit,\n onSaveDraft,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\n onCancel: () => unknown\n onSubmit: (newFormSubmission: submissionService.NewFormSubmission) => unknown\n initialSubmission?: FormSubmissionModel\n resumeAtElement?: FormTypes.FormElement\n onSaveDraft?: (\n newDraftSubmission: submissionService.NewDraftSubmission,\n ) => unknown\n}) {\n const [{ definition, submission, lastElementUpdated }, setFormSubmission] =\n useFormSubmissionState(form, initialSubmission, resumeAtElement)\n\n const [\n { isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: FormSubmissionModel | null\n autoSaveElement: FormElement | null\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (model: FormSubmissionModel, lastElementUpdated?: FormElement) => {\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 .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id])\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 =\n await autoSaveService.getAutoSaveData<FormSubmissionModel>(\n definition.id,\n autoSaveKey,\n )\n const autoSaveElement =\n await autoSaveService.getAutoSaveData<FormElement>(\n definition.id,\n `LAST_ELEMENT_UPDATED_${autoSaveKey}`,\n )\n if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\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 })\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 )\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n deleteAutoSaveSubmission()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [deleteAutoSaveSubmission])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n }))\n }\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [autoSaveSubmission, setFormSubmission, autoSaveElement])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable: autoSaveSubmission !== null,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\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 '@oneblink/apps'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport { FormElement } from '@oneblink/types/typescript/forms'\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 onCancel,\n onSubmit,\n onSaveDraft,\n}: {\n form: FormTypes.Form\n removeAutoSaveDataBeforeSubmit?: boolean\n removeAutoSaveDataBeforeSaveDraft?: boolean\n autoSaveKey: string\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}) {\n const [{ definition, submission, lastElementUpdated }, setFormSubmission] =\n useFormSubmissionState(form, initialSubmission, resumeAtElement)\n\n const [\n { isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n\n const throttledAutoSave = React.useMemo(() => {\n return _throttle(\n (\n model: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormElement,\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 .catch((error) => {\n console.warn('Error while auto saving', error)\n Sentry.captureException(error)\n })\n },\n 9580, // https://en.wikipedia.org/wiki/100_metres\n { trailing: true, leading: false },\n )\n }, [autoSaveKey, definition.id])\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 if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\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 })\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 )\n\n return newFormSubmission\n })\n },\n [setFormSubmission, throttledAutoSave],\n )\n\n const startNewSubmission = React.useCallback(() => {\n deleteAutoSaveSubmission()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [deleteAutoSaveSubmission])\n\n const continueAutoSaveSubmission = React.useCallback(() => {\n if (autoSaveSubmission) {\n setFormSubmission((currentFormSubmission) => ({\n ...currentFormSubmission,\n submission: autoSaveSubmission,\n lastElementUpdated: autoSaveElement ? autoSaveElement : undefined,\n }))\n }\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n })\n }, [autoSaveSubmission, setFormSubmission, autoSaveElement])\n\n return {\n definition,\n submission,\n lastElementUpdated,\n isLoadingAutoSaveSubmission,\n isAutoSaveSubmissionAvailable: autoSaveSubmission !== null,\n startNewSubmission,\n continueAutoSaveSubmission,\n handleSubmit,\n handleCancel,\n handleSaveDraft,\n handleNavigateAway,\n setFormSubmission: setFormSubmissionAutoSave,\n }\n}\n"]}
@@ -1,14 +1,14 @@
1
- import { FormTypes } from '@oneblink/types';
1
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import { FormElement } from '@oneblink/types/typescript/forms';
3
3
  import * as React from 'react';
4
- import { FormElementsConditionallyShown, FormSubmissionModel } from '../types/form';
4
+ import { FormElementsConditionallyShown } from '../types/form';
5
5
  export type FormSubmissionModelContextValue = {
6
- formSubmissionModel: FormSubmissionModel;
6
+ formSubmissionModel: SubmissionTypes.S3SubmissionData['submission'];
7
7
  parent?: FormSubmissionModelContextValue;
8
8
  elements: FormElement[];
9
9
  };
10
10
  export declare function FormSubmissionModelContextProvider({ children, model, elements, formElementsConditionallyShown, }: {
11
- model: FormSubmissionModel;
11
+ model: SubmissionTypes.S3SubmissionData['submission'];
12
12
  elements: FormTypes.FormElement[];
13
13
  formElementsConditionallyShown: FormElementsConditionallyShown | undefined;
14
14
  children: React.ReactNode;
@@ -1 +1 @@
1
- {"version":3,"file":"useFormSubmissionModelContext.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionModelContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,wBAAwB,MAAM,sCAAsC,CAAA;AAY3E,MAAM,0BAA0B,GAAG,KAAK,CAAC,aAAa,CAEpD,SAAS,CAAC,CAAA;AAEZ,MAAM,UAAU,kCAAkC,CAAC,EACjD,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,8BAA8B,GAM/B;IACC,MAAM,0BAA0B,GAAG,KAAK,CAAC,UAAU,CACjD,0BAA0B,CAC3B,CAAA;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC/B,OAAO;YACL,mBAAmB,EAAE,wBAAwB,CAC3C,KAAK,EACL,QAAQ,EACR,8BAA8B,EAC9B,IAAI,CACL,CAAC,KAAK;YACP,MAAM,EAAE,0BAA0B;YAClC,QAAQ;SACT,CAAA;IACH,CAAC,EAAE;QACD,KAAK;QACL,QAAQ;QACR,8BAA8B;QAC9B,0BAA0B;KAC3B,CAAC,CAAA;IACF,OAAO,CACL,oBAAC,0BAA0B,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAC9C,QAAQ,CAC2B,CACvC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB;IAC5C,MAAM,0BAA0B,GAAG,KAAK,CAAC,UAAU,CACjD,0BAA0B,CAC3B,CAAA;IACD,IAAI,CAAC,0BAA0B,EAAE;QAC/B,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAA;KACF;IACD,OAAO,0BAA0B,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,IAAI,0BAA0B,GAAG,sBAAsB,EAAE,CAAA;IACzD,OAAO,0BAA0B,CAAC,MAAM,EAAE;QACxC,0BAA0B,GAAG,0BAA0B,CAAC,MAAM,CAAA;KAC/D;IACD,OAAO,0BAA0B,CAAA;AACnC,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport { FormElement } from '@oneblink/types/typescript/forms'\nimport * as React from 'react'\nimport cleanFormSubmissionModel from '../services/cleanFormSubmissionModel'\nimport {\n FormElementsConditionallyShown,\n FormSubmissionModel,\n} from '../types/form'\n\nexport type FormSubmissionModelContextValue = {\n formSubmissionModel: FormSubmissionModel\n parent?: FormSubmissionModelContextValue\n elements: FormElement[]\n}\n\nconst FormSubmissionModelContext = React.createContext<\n FormSubmissionModelContextValue | undefined\n>(undefined)\n\nexport function FormSubmissionModelContextProvider({\n children,\n model,\n elements,\n formElementsConditionallyShown,\n}: {\n model: FormSubmissionModel\n elements: FormTypes.FormElement[]\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined\n children: React.ReactNode\n}) {\n const formSubmissionModelContext = React.useContext(\n FormSubmissionModelContext,\n )\n const value = React.useMemo(() => {\n return {\n formSubmissionModel: cleanFormSubmissionModel(\n model,\n elements,\n formElementsConditionallyShown,\n true,\n ).model,\n parent: formSubmissionModelContext,\n elements,\n }\n }, [\n model,\n elements,\n formElementsConditionallyShown,\n formSubmissionModelContext,\n ])\n return (\n <FormSubmissionModelContext.Provider value={value}>\n {children}\n </FormSubmissionModelContext.Provider>\n )\n}\n\nexport default function useFormSubmissionModel() {\n const formSubmissionModelContext = React.useContext(\n FormSubmissionModelContext,\n )\n if (!formSubmissionModelContext) {\n throw new Error(\n '\"FormSubmissionModelContext\" does not have a value in this context',\n )\n }\n return formSubmissionModelContext\n}\n\nexport function useFormSubmissionModelParent() {\n let formSubmissionModelContext = useFormSubmissionModel()\n while (formSubmissionModelContext.parent) {\n formSubmissionModelContext = formSubmissionModelContext.parent\n }\n return formSubmissionModelContext\n}\n"]}
1
+ {"version":3,"file":"useFormSubmissionModelContext.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionModelContext.tsx"],"names":[],"mappings":"AAEA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,wBAAwB,MAAM,sCAAsC,CAAA;AAS3E,MAAM,0BAA0B,GAAG,KAAK,CAAC,aAAa,CAEpD,SAAS,CAAC,CAAA;AAEZ,MAAM,UAAU,kCAAkC,CAAC,EACjD,QAAQ,EACR,KAAK,EACL,QAAQ,EACR,8BAA8B,GAM/B;IACC,MAAM,0BAA0B,GAAG,KAAK,CAAC,UAAU,CACjD,0BAA0B,CAC3B,CAAA;IACD,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC/B,OAAO;YACL,mBAAmB,EAAE,wBAAwB,CAC3C,KAAK,EACL,QAAQ,EACR,8BAA8B,EAC9B,IAAI,CACL,CAAC,KAAK;YACP,MAAM,EAAE,0BAA0B;YAClC,QAAQ;SACT,CAAA;IACH,CAAC,EAAE;QACD,KAAK;QACL,QAAQ;QACR,8BAA8B;QAC9B,0BAA0B;KAC3B,CAAC,CAAA;IACF,OAAO,CACL,oBAAC,0BAA0B,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,IAC9C,QAAQ,CAC2B,CACvC,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,sBAAsB;IAC5C,MAAM,0BAA0B,GAAG,KAAK,CAAC,UAAU,CACjD,0BAA0B,CAC3B,CAAA;IACD,IAAI,CAAC,0BAA0B,EAAE;QAC/B,MAAM,IAAI,KAAK,CACb,oEAAoE,CACrE,CAAA;KACF;IACD,OAAO,0BAA0B,CAAA;AACnC,CAAC;AAED,MAAM,UAAU,4BAA4B;IAC1C,IAAI,0BAA0B,GAAG,sBAAsB,EAAE,CAAA;IACzD,OAAO,0BAA0B,CAAC,MAAM,EAAE;QACxC,0BAA0B,GAAG,0BAA0B,CAAC,MAAM,CAAA;KAC/D;IACD,OAAO,0BAA0B,CAAA;AACnC,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport { FormElement } from '@oneblink/types/typescript/forms'\nimport * as React from 'react'\nimport cleanFormSubmissionModel from '../services/cleanFormSubmissionModel'\nimport { FormElementsConditionallyShown } from '../types/form'\n\nexport type FormSubmissionModelContextValue = {\n formSubmissionModel: SubmissionTypes.S3SubmissionData['submission']\n parent?: FormSubmissionModelContextValue\n elements: FormElement[]\n}\n\nconst FormSubmissionModelContext = React.createContext<\n FormSubmissionModelContextValue | undefined\n>(undefined)\n\nexport function FormSubmissionModelContextProvider({\n children,\n model,\n elements,\n formElementsConditionallyShown,\n}: {\n model: SubmissionTypes.S3SubmissionData['submission']\n elements: FormTypes.FormElement[]\n formElementsConditionallyShown: FormElementsConditionallyShown | undefined\n children: React.ReactNode\n}) {\n const formSubmissionModelContext = React.useContext(\n FormSubmissionModelContext,\n )\n const value = React.useMemo(() => {\n return {\n formSubmissionModel: cleanFormSubmissionModel(\n model,\n elements,\n formElementsConditionallyShown,\n true,\n ).model,\n parent: formSubmissionModelContext,\n elements,\n }\n }, [\n model,\n elements,\n formElementsConditionallyShown,\n formSubmissionModelContext,\n ])\n return (\n <FormSubmissionModelContext.Provider value={value}>\n {children}\n </FormSubmissionModelContext.Provider>\n )\n}\n\nexport default function useFormSubmissionModel() {\n const formSubmissionModelContext = React.useContext(\n FormSubmissionModelContext,\n )\n if (!formSubmissionModelContext) {\n throw new Error(\n '\"FormSubmissionModelContext\" does not have a value in this context',\n )\n }\n return formSubmissionModelContext\n}\n\nexport function useFormSubmissionModelParent() {\n let formSubmissionModelContext = useFormSubmissionModel()\n while (formSubmissionModelContext.parent) {\n formSubmissionModelContext = formSubmissionModelContext.parent\n }\n return formSubmissionModelContext\n}\n"]}
@@ -1,12 +1,52 @@
1
1
  import * as React from 'react';
2
- import { FormTypes } from '@oneblink/types';
3
- import { FormSubmissionModel } from '../types/form';
4
- export default function useFormSubmissionState(form: FormTypes.Form, initialSubmission?: FormSubmissionModel, lastElementUpdated?: FormTypes.FormElement): [{
2
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
3
+ /**
4
+ * This function is a simple wrapper around the react hook `useState()`. The
5
+ * results can be passed to the [`<OneBlinkForm
6
+ * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link
7
+ * component.
8
+ *
9
+ * ## Example
10
+ *
11
+ * ```js
12
+ * import {
13
+ * useFormSubmissionState,
14
+ * OneBlinkFormControlled,
15
+ * } from '@oneblink/apps-react'
16
+ *
17
+ * function Uncontrolled({ form, initialSubmission, ...props }) {
18
+ * const [{ definition, submission }, setFormSubmission] =
19
+ * useFormSubmissionState(form, initialSubmission)
20
+ *
21
+ * return (
22
+ * <OneBlinkFormControlled
23
+ * {...props}
24
+ * definition={definition}
25
+ * submission={submission}
26
+ * setFormSubmission={setFormSubmission}
27
+ * lastElementUpdated={lastElementUpdated}
28
+ * />
29
+ * )
30
+ * }
31
+ * ```
32
+ *
33
+ * @param form The OneBlink Form to render
34
+ * @param initialSubmission The initial submission data to populate the form
35
+ * with
36
+ * @param lastElementUpdated
37
+ * @returns
38
+ * @group Hooks
39
+ */
40
+ export default function useFormSubmissionState(form: FormTypes.Form, initialSubmission?: SubmissionTypes.S3SubmissionData['submission'], lastElementUpdated?: FormTypes.FormElement): [{
5
41
  definition: FormTypes.Form;
6
- submission: FormSubmissionModel;
42
+ submission: {
43
+ [name: string]: unknown;
44
+ };
7
45
  lastElementUpdated: FormTypes.FormElement | undefined;
8
46
  }, React.Dispatch<React.SetStateAction<{
9
47
  definition: FormTypes.Form;
10
- submission: FormSubmissionModel;
48
+ submission: {
49
+ [name: string]: unknown;
50
+ };
11
51
  lastElementUpdated: FormTypes.FormElement | undefined;
12
52
  }>>];
@@ -1,6 +1,43 @@
1
1
  import * as React from 'react';
2
2
  import _cloneDeep from 'lodash.clonedeep';
3
3
  import generateDefaultData from '../services/generate-default-data';
4
+ /**
5
+ * This function is a simple wrapper around the react hook `useState()`. The
6
+ * results can be passed to the [`<OneBlinkForm
7
+ * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link
8
+ * component.
9
+ *
10
+ * ## Example
11
+ *
12
+ * ```js
13
+ * import {
14
+ * useFormSubmissionState,
15
+ * OneBlinkFormControlled,
16
+ * } from '@oneblink/apps-react'
17
+ *
18
+ * function Uncontrolled({ form, initialSubmission, ...props }) {
19
+ * const [{ definition, submission }, setFormSubmission] =
20
+ * useFormSubmissionState(form, initialSubmission)
21
+ *
22
+ * return (
23
+ * <OneBlinkFormControlled
24
+ * {...props}
25
+ * definition={definition}
26
+ * submission={submission}
27
+ * setFormSubmission={setFormSubmission}
28
+ * lastElementUpdated={lastElementUpdated}
29
+ * />
30
+ * )
31
+ * }
32
+ * ```
33
+ *
34
+ * @param form The OneBlink Form to render
35
+ * @param initialSubmission The initial submission data to populate the form
36
+ * with
37
+ * @param lastElementUpdated
38
+ * @returns
39
+ * @group Hooks
40
+ */
4
41
  export default function useFormSubmissionState(form, initialSubmission, lastElementUpdated) {
5
42
  return React.useState(() => {
6
43
  const definition = _cloneDeep(form);
@@ -1 +1 @@
1
- {"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AAGnE,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,IAAoB,EACpB,iBAAuC,EACvC,kBAA0C;IAE1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,WAAW,GAAG,mBAAmB,CACrC,UAAU,CAAC,QAAQ,EACnB,iBAAiB,IAAI,EAAE,CACxB,CAAA;QACD,OAAO;YACL,UAAU;YACV,UAAU,EAAE,WAAW;YACvB,kBAAkB;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { FormTypes } from '@oneblink/types'\nimport generateDefaultData from '../services/generate-default-data'\nimport { FormSubmissionModel } from '../types/form'\n\nexport default function useFormSubmissionState(\n form: FormTypes.Form,\n initialSubmission?: FormSubmissionModel,\n lastElementUpdated?: FormTypes.FormElement,\n) {\n return React.useState(() => {\n const definition = _cloneDeep(form)\n const defaultData = generateDefaultData(\n definition.elements,\n initialSubmission || {},\n )\n return {\n definition,\n submission: defaultData,\n lastElementUpdated,\n }\n })\n}\n"]}
1
+ {"version":3,"file":"useFormSubmissionState.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionState.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,UAAU,MAAM,kBAAkB,CAAA;AAEzC,OAAO,mBAAmB,MAAM,mCAAmC,CAAA;AACnE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAoCG;AACH,MAAM,CAAC,OAAO,UAAU,sBAAsB,CAC5C,IAAoB,EACpB,iBAAkE,EAClE,kBAA0C;IAE1C,OAAO,KAAK,CAAC,QAAQ,CAAC,GAAG,EAAE;QACzB,MAAM,UAAU,GAAG,UAAU,CAAC,IAAI,CAAC,CAAA;QACnC,MAAM,WAAW,GAAG,mBAAmB,CACrC,UAAU,CAAC,QAAQ,EACnB,iBAAiB,IAAI,EAAE,CACxB,CAAA;QACD,OAAO;YACL,UAAU;YACV,UAAU,EAAE,WAAW;YACvB,kBAAkB;SACnB,CAAA;IACH,CAAC,CAAC,CAAA;AACJ,CAAC","sourcesContent":["import * as React from 'react'\nimport _cloneDeep from 'lodash.clonedeep'\nimport { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport generateDefaultData from '../services/generate-default-data'\n/**\n * This function is a simple wrapper around the react hook `useState()`. The\n * results can be passed to the [`<OneBlinkForm\n * />`](https://oneblink.github.io/apps-react/somewhere) //TODO: Fix link\n * component.\n *\n * ## Example\n *\n * ```js\n * import {\n * useFormSubmissionState,\n * OneBlinkFormControlled,\n * } from '@oneblink/apps-react'\n *\n * function Uncontrolled({ form, initialSubmission, ...props }) {\n * const [{ definition, submission }, setFormSubmission] =\n * useFormSubmissionState(form, initialSubmission)\n *\n * return (\n * <OneBlinkFormControlled\n * {...props}\n * definition={definition}\n * submission={submission}\n * setFormSubmission={setFormSubmission}\n * lastElementUpdated={lastElementUpdated}\n * />\n * )\n * }\n * ```\n *\n * @param form The OneBlink Form to render\n * @param initialSubmission The initial submission data to populate the form\n * with\n * @param lastElementUpdated\n * @returns\n * @group Hooks\n */\nexport default function useFormSubmissionState(\n form: FormTypes.Form,\n initialSubmission?: SubmissionTypes.S3SubmissionData['submission'],\n lastElementUpdated?: FormTypes.FormElement,\n) {\n return React.useState(() => {\n const definition = _cloneDeep(form)\n const defaultData = generateDefaultData(\n definition.elements,\n initialSubmission || {},\n )\n return {\n definition,\n submission: defaultData,\n lastElementUpdated,\n }\n })\n}\n"]}
@@ -1,7 +1,7 @@
1
- import { FormTypes } from '@oneblink/types';
2
- import { FormElementsConditionallyShown, FormSubmissionModel } from '../types/form';
1
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
+ import { FormElementsConditionallyShown } from '../types/form';
3
3
  export default function useFormValidation(pages: FormTypes.PageElement[]): {
4
4
  executedLookup: (element: FormTypes.LookupFormElement) => void;
5
5
  executeLookupFailed: (element: FormTypes.LookupFormElement) => void;
6
- validate: (submission: FormSubmissionModel, formElementsConditionallyShown: FormElementsConditionallyShown) => import("../types/form").FormElementsValidation | undefined;
6
+ validate: (submission: SubmissionTypes.S3SubmissionData['submission'], formElementsConditionallyShown: FormElementsConditionallyShown) => import("../types/form").FormElementsValidation | undefined;
7
7
  };
@@ -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,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,6BAA6B,CAAA;AAMpC,SAAS,4BAA4B,CACnC,YAAqC;IAErC,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC;gBACd,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,CAAC;iBACtD,CAAA;aACF;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC;gBACpB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,CAC3B;qBACF;iBACF,CAAA;aACF;YACD,OAAO,CAAC,CAAC;gBACP,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;aAC9B;SACF;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,CAAC,6BAA6B,EAAE,gCAAgC,CAAC,GACrE,KAAK,CAAC,QAAQ,CAAW,EAAE,CAAC,CAAA;IAE9B,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAA8C,EAAE,EAAE;YACjD,IAAI,oCAAoC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBAC7D,OAAO,oCAAoC,CAAA;aAC5C;YACD,OAAO,CAAC,GAAG,oCAAoC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;QAC9D,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IACD,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAAoC,EAAE,EAAE;YACvC,OAAO,oCAAoC,CAAC,MAAM,CAChD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CACxC,CAAA;QACH,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IAED,MAAM,uBAAuB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjD,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1C,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,6BAA6B,CAC9B,CAAA;IACH,CAAC,EAAE,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAC,CAAA;IAE5D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA+B,EAC/B,8BAA8D,EAC9D,EAAE;QACF,OAAO,kBAAkB,CACvB,gBAAgB,EAChB,UAAU,EACV,8BAA8B,CAC/B,CAAA;IACH,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAA;IAED,OAAO;QACL,cAAc;QACd,mBAAmB;QACnB,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport {\n validateSubmission,\n generateValidationSchema,\n} from '../services/form-validation'\nimport {\n FormElementsConditionallyShown,\n FormSubmissionModel,\n} from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements),\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 ),\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 [elementIdsWithLookupsExecuted, setElementIdsWithLookupsExecuted] =\n React.useState<string[]>([])\n\n const executedLookup = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted: string[]) => {\n if (currentElementIdsWithLookupsExecuted.includes(element.id)) {\n return currentElementIdsWithLookupsExecuted\n }\n return [...currentElementIdsWithLookupsExecuted, element.id]\n },\n )\n },\n [],\n )\n const executeLookupFailed = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted) => {\n return currentElementIdsWithLookupsExecuted.filter(\n (elementId) => elementId !== element.id,\n )\n },\n )\n },\n [],\n )\n\n const formElementsWithoutName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages)\n }, [pages])\n\n const validationSchema = React.useMemo(() => {\n return generateValidationSchema(\n formElementsWithoutName,\n elementIdsWithLookupsExecuted,\n )\n }, [formElementsWithoutName, elementIdsWithLookupsExecuted])\n\n const handleValidate = React.useCallback(\n (\n submission: FormSubmissionModel,\n formElementsConditionallyShown: FormElementsConditionallyShown,\n ) => {\n return validateSubmission(\n validationSchema,\n submission,\n formElementsConditionallyShown,\n )\n },\n [validationSchema],\n )\n\n return {\n executedLookup,\n executeLookupFailed,\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,EACL,kBAAkB,EAClB,wBAAwB,GACzB,MAAM,6BAA6B,CAAA;AAGpC,SAAS,4BAA4B,CACnC,YAAqC;IAErC,OAAO,YAAY,CAAC,MAAM,CACxB,CAAC,IAAI,EAAE,WAAW,EAAE,EAAE;QACpB,QAAQ,WAAW,CAAC,IAAI,EAAE;YACxB,KAAK,MAAM,CAAC;YACZ,KAAK,SAAS,CAAC,CAAC;gBACd,OAAO;oBACL,GAAG,IAAI;oBACP,GAAG,4BAA4B,CAAC,WAAW,CAAC,QAAQ,CAAC;iBACtD,CAAA;aACF;YACD,KAAK,UAAU,CAAC;YAChB,KAAK,MAAM,CAAC;YACZ,KAAK,eAAe,CAAC,CAAC;gBACpB,OAAO;oBACL,GAAG,IAAI;oBACP;wBACE,GAAG,WAAW;wBACd,QAAQ,EAAE,4BAA4B,CACpC,WAAW,CAAC,QAAQ,IAAI,EAAE,CAC3B;qBACF;iBACF,CAAA;aACF;YACD,OAAO,CAAC,CAAC;gBACP,OAAO,CAAC,GAAG,IAAI,EAAE,WAAW,CAAC,CAAA;aAC9B;SACF;IACH,CAAC,EACD,EAAE,CACH,CAAA;AACH,CAAC;AAED,MAAM,CAAC,OAAO,UAAU,iBAAiB,CAAC,KAA8B;IACtE,MAAM,CAAC,6BAA6B,EAAE,gCAAgC,CAAC,GACrE,KAAK,CAAC,QAAQ,CAAW,EAAE,CAAC,CAAA;IAE9B,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAA8C,EAAE,EAAE;YACjD,IAAI,oCAAoC,CAAC,QAAQ,CAAC,OAAO,CAAC,EAAE,CAAC,EAAE;gBAC7D,OAAO,oCAAoC,CAAA;aAC5C;YACD,OAAO,CAAC,GAAG,oCAAoC,EAAE,OAAO,CAAC,EAAE,CAAC,CAAA;QAC9D,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IACD,MAAM,mBAAmB,GAAG,KAAK,CAAC,WAAW,CAC3C,CAAC,OAAoC,EAAE,EAAE;QACvC,gCAAgC,CAC9B,CAAC,oCAAoC,EAAE,EAAE;YACvC,OAAO,oCAAoC,CAAC,MAAM,CAChD,CAAC,SAAS,EAAE,EAAE,CAAC,SAAS,KAAK,OAAO,CAAC,EAAE,CACxC,CAAA;QACH,CAAC,CACF,CAAA;IACH,CAAC,EACD,EAAE,CACH,CAAA;IAED,MAAM,uBAAuB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QACjD,OAAO,4BAA4B,CAAC,KAAK,CAAC,CAAA;IAC5C,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAAA;IAEX,MAAM,gBAAgB,GAAG,KAAK,CAAC,OAAO,CAAC,GAAG,EAAE;QAC1C,OAAO,wBAAwB,CAC7B,uBAAuB,EACvB,6BAA6B,CAC9B,CAAA;IACH,CAAC,EAAE,CAAC,uBAAuB,EAAE,6BAA6B,CAAC,CAAC,CAAA;IAE5D,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CACtC,CACE,UAA0D,EAC1D,8BAA8D,EAC9D,EAAE;QACF,OAAO,kBAAkB,CACvB,gBAAgB,EAChB,UAAU,EACV,8BAA8B,CAC/B,CAAA;IACH,CAAC,EACD,CAAC,gBAAgB,CAAC,CACnB,CAAA;IAED,OAAO;QACL,cAAc;QACd,mBAAmB;QACnB,QAAQ,EAAE,cAAc;KACzB,CAAA;AACH,CAAC","sourcesContent":["import { FormTypes, SubmissionTypes } from '@oneblink/types'\nimport * as React from 'react'\n\nimport {\n validateSubmission,\n generateValidationSchema,\n} from '../services/form-validation'\nimport { FormElementsConditionallyShown } from '../types/form'\n\nfunction stripFormElementsWithoutName(\n formElements: FormTypes.FormElement[],\n): FormTypes.FormElementWithName[] {\n return formElements.reduce<FormTypes.FormElementWithName[]>(\n (memo, formElement) => {\n switch (formElement.type) {\n case 'page':\n case 'section': {\n return [\n ...memo,\n ...stripFormElementsWithoutName(formElement.elements),\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 ),\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 [elementIdsWithLookupsExecuted, setElementIdsWithLookupsExecuted] =\n React.useState<string[]>([])\n\n const executedLookup = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted: string[]) => {\n if (currentElementIdsWithLookupsExecuted.includes(element.id)) {\n return currentElementIdsWithLookupsExecuted\n }\n return [...currentElementIdsWithLookupsExecuted, element.id]\n },\n )\n },\n [],\n )\n const executeLookupFailed = React.useCallback(\n (element: FormTypes.LookupFormElement) => {\n setElementIdsWithLookupsExecuted(\n (currentElementIdsWithLookupsExecuted) => {\n return currentElementIdsWithLookupsExecuted.filter(\n (elementId) => elementId !== element.id,\n )\n },\n )\n },\n [],\n )\n\n const formElementsWithoutName = React.useMemo(() => {\n return stripFormElementsWithoutName(pages)\n }, [pages])\n\n const validationSchema = React.useMemo(() => {\n return generateValidationSchema(\n formElementsWithoutName,\n elementIdsWithLookupsExecuted,\n )\n }, [formElementsWithoutName, elementIdsWithLookupsExecuted])\n\n const handleValidate = React.useCallback(\n (\n submission: SubmissionTypes.S3SubmissionData['submission'],\n formElementsConditionallyShown: FormElementsConditionallyShown,\n ) => {\n return validateSubmission(\n validationSchema,\n submission,\n formElementsConditionallyShown,\n )\n },\n [validationSchema],\n )\n\n return {\n executedLookup,\n executeLookupFailed,\n validate: handleValidate,\n }\n}\n"]}
@@ -1,7 +1,6 @@
1
- import { FormTypes } from '@oneblink/types';
1
+ import { FormTypes, SubmissionTypes } from '@oneblink/types';
2
2
  import * as React from 'react';
3
- import { FormSubmissionModel } from '../types/form';
4
- type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data?: FormSubmissionModel) => void;
3
+ type InjectPagesContextValue = (lookupFormElement: FormTypes.LookupFormElement, pageElements: FormTypes.PageElement[], data?: SubmissionTypes.S3SubmissionData['submission']) => void;
5
4
  export declare const InjectPagesContext: React.Context<InjectPagesContextValue>;
6
5
  export default function useInjectPages(): InjectPagesContextValue;
7
6
  export {};
@@ -1 +1 @@
1
- {"version":3,"file":"useInjectPages.js","sourceRoot":"","sources":["../../src/hooks/useInjectPages.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAS9B,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 } from '@oneblink/types'\nimport * as React from 'react'\nimport { FormSubmissionModel } from '../types/form'\n\ntype InjectPagesContextValue = (\n lookupFormElement: FormTypes.LookupFormElement,\n pageElements: FormTypes.PageElement[],\n data?: FormSubmissionModel,\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;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,3 +1,23 @@
1
+ /**
2
+ * This function is a react hook for determining whether the consuming component
3
+ * is currently mounted on the DOM.
4
+ *
5
+ * ## Example
6
+ *
7
+ * ```js
8
+ * import { useIsMounted } from '@oneblink/apps-react'
9
+ *
10
+ * const isMounted = useIsMounted()
11
+ *
12
+ * if (isMounted.current) {
13
+ * // DO SOMETHING HERE
14
+ * }
15
+ * ```
16
+ *
17
+ * @returns
18
+ * @group Hooks
19
+ */
1
20
  export default function useIsMounted(): {
21
+ /** Whether the current component is mounted. */
2
22
  current: boolean;
3
23
  };
@@ -1,4 +1,23 @@
1
1
  import * as React from 'react';
2
+ /**
3
+ * This function is a react hook for determining whether the consuming component
4
+ * is currently mounted on the DOM.
5
+ *
6
+ * ## Example
7
+ *
8
+ * ```js
9
+ * import { useIsMounted } from '@oneblink/apps-react'
10
+ *
11
+ * const isMounted = useIsMounted()
12
+ *
13
+ * if (isMounted.current) {
14
+ * // DO SOMETHING HERE
15
+ * }
16
+ * ```
17
+ *
18
+ * @returns
19
+ * @group Hooks
20
+ */
2
21
  export default function useIsMounted() {
3
22
  const isMounted = React.useRef(false);
4
23
  React.useEffect(() => {
@@ -1 +1 @@
1
- {"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B,MAAM,CAAC,OAAO,UAAU,YAAY;IAClC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as React from 'react'\n\nexport default function useIsMounted(): { current: boolean } {\n const isMounted = React.useRef(false)\n React.useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n return isMounted\n}\n"]}
1
+ {"version":3,"file":"useIsMounted.js","sourceRoot":"","sources":["../../src/hooks/useIsMounted.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAE9B;;;;;;;;;;;;;;;;;;GAkBG;AACH,MAAM,CAAC,OAAO,UAAU,YAAY;IAIlC,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,KAAK,CAAC,CAAA;IACrC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,SAAS,CAAC,OAAO,GAAG,IAAI,CAAA;QACxB,OAAO,GAAG,EAAE;YACV,SAAS,CAAC,OAAO,GAAG,KAAK,CAAA;QAC3B,CAAC,CAAA;IACH,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,OAAO,SAAS,CAAA;AAClB,CAAC","sourcesContent":["import * as React from 'react'\n\n/**\n * This function is a react hook for determining whether the consuming component\n * is currently mounted on the DOM.\n *\n * ## Example\n *\n * ```js\n * import { useIsMounted } from '@oneblink/apps-react'\n *\n * const isMounted = useIsMounted()\n *\n * if (isMounted.current) {\n * // DO SOMETHING HERE\n * }\n * ```\n *\n * @returns\n * @group Hooks\n */\nexport default function useIsMounted(): {\n /** Whether the current component is mounted. */\n current: boolean\n} {\n const isMounted = React.useRef(false)\n React.useEffect(() => {\n isMounted.current = true\n return () => {\n isMounted.current = false\n }\n }, [])\n return isMounted\n}\n"]}