@oneblink/apps-react 8.14.0-beta.1 → 8.14.0-beta.2

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.
@@ -2,6 +2,8 @@ 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
+ import useFormSubmissionDuration from './useFormSubmissionDuration';
6
+ import { getElementDisplayNameForAnalyticsEvent, sendGoogleAnalyticsEvent, } from '../utils/sendGoogleAnalyticsEvent';
5
7
  /**
6
8
  * Use this if you want to implement a controlled auto saving form. See
7
9
  * {@link OneBlinkFormControlled} for a full example. If you do not need to
@@ -12,13 +14,15 @@ import useFormSubmissionState from './useFormSubmissionState';
12
14
  * @returns
13
15
  * @group Hooks
14
16
  */
15
- export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, formIsDisabled, onCancel, onSubmit, onSaveDraft, resumeSectionState, }) {
17
+ export default function useFormSubmissionAutoSaveState({ form, initialSubmission, resumeAtElement, removeAutoSaveDataBeforeSubmit, removeAutoSaveDataBeforeSaveDraft, autoSaveKey, formIsDisabled, onCancel, onSubmit, onSaveDraft, resumeSectionState, resumePreviousElapsedDurationSeconds, }) {
16
18
  const [{ definition, submission, lastElementUpdated, executedLookups, sectionState, }, setFormSubmission,] = useFormSubmissionState(form, initialSubmission, resumeAtElement, resumeSectionState);
17
- const [{ isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement, autoSaveSectionState, }, setAutoSaveState,] = React.useState({
19
+ const [getCurrentSubmissionDuration, resetCurrentSubmissionDuration] = useFormSubmissionDuration(resumePreviousElapsedDurationSeconds);
20
+ const [{ isLoadingAutoSaveSubmission, autoSaveSubmission, autoSaveElement, autoSaveSectionState, autoSavePreviousElapsedDurationSeconds, }, setAutoSaveState,] = React.useState({
18
21
  isLoadingAutoSaveSubmission: true,
19
22
  autoSaveSubmission: null,
20
23
  autoSaveElement: null,
21
24
  autoSaveSectionState: null,
25
+ autoSavePreviousElapsedDurationSeconds: 0,
22
26
  });
23
27
  const throttledAutoSave = React.useMemo(() => {
24
28
  return _throttle((model, lastElementUpdated, sectionState) => {
@@ -44,6 +48,11 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
44
48
  sectionState,
45
49
  });
46
50
  }
51
+ })
52
+ .then(() => {
53
+ return autoSaveService.upsertAutoSaveData(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`, {
54
+ previousElapsedDurationSeconds: getCurrentSubmissionDuration(),
55
+ });
47
56
  })
48
57
  .catch((error) => {
49
58
  console.warn('Error while auto saving', error);
@@ -52,7 +61,7 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
52
61
  }
53
62
  }, 9580, // https://en.wikipedia.org/wiki/100_metres
54
63
  { trailing: true, leading: false });
55
- }, [autoSaveKey, definition.id, formIsDisabled]);
64
+ }, [autoSaveKey, definition.id, formIsDisabled, getCurrentSubmissionDuration]);
56
65
  const cancelAutoSave = React.useCallback(() => {
57
66
  if (throttledAutoSave) {
58
67
  throttledAutoSave.cancel();
@@ -112,12 +121,15 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
112
121
  const autoSaveSubmission = await autoSaveService.getAutoSaveData(definition.id, autoSaveKey);
113
122
  const autoSaveElement = await autoSaveService.getAutoSaveData(definition.id, `LAST_ELEMENT_UPDATED_${autoSaveKey}`);
114
123
  const autoSaveSectionStateData = await autoSaveService.getAutoSaveData(definition.id, `SECTION_STATE_${autoSaveKey}`);
124
+ const autoSavePreviousElapsedDurationSeconds = await autoSaveService.getAutoSaveData(definition.id, `PREVIOUS_ELAPSED_DURATION_${autoSaveKey}`);
115
125
  if (!ignore) {
116
126
  setAutoSaveState({
117
127
  isLoadingAutoSaveSubmission: false,
118
128
  autoSaveSubmission,
119
129
  autoSaveElement,
120
130
  autoSaveSectionState: (autoSaveSectionStateData === null || autoSaveSectionStateData === void 0 ? void 0 : autoSaveSectionStateData.sectionState) || null,
131
+ autoSavePreviousElapsedDurationSeconds: (autoSavePreviousElapsedDurationSeconds === null || autoSavePreviousElapsedDurationSeconds === void 0 ? void 0 : autoSavePreviousElapsedDurationSeconds.previousElapsedDurationSeconds) ||
132
+ 0,
121
133
  });
122
134
  }
123
135
  }
@@ -130,6 +142,7 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
130
142
  autoSaveSubmission: null,
131
143
  autoSaveElement: null,
132
144
  autoSaveSectionState: null,
145
+ autoSavePreviousElapsedDurationSeconds: 0,
133
146
  });
134
147
  }
135
148
  }
@@ -155,14 +168,29 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
155
168
  });
156
169
  }, [setFormSubmission, throttledAutoSave]);
157
170
  const startNewSubmission = React.useCallback(() => {
171
+ sendGoogleAnalyticsEvent('oneblink_form_abandon', {
172
+ formId: definition.id,
173
+ formName: definition.name,
174
+ lastElementUpdated: getElementDisplayNameForAnalyticsEvent(autoSaveElement),
175
+ durationUntilAbandon: autoSavePreviousElapsedDurationSeconds,
176
+ });
158
177
  deleteAutoSaveSubmission();
178
+ resetCurrentSubmissionDuration();
159
179
  setAutoSaveState({
160
180
  isLoadingAutoSaveSubmission: false,
161
181
  autoSaveSubmission: null,
162
182
  autoSaveElement: null,
163
183
  autoSaveSectionState: null,
184
+ autoSavePreviousElapsedDurationSeconds: 0,
164
185
  });
165
- }, [deleteAutoSaveSubmission]);
186
+ }, [
187
+ autoSaveElement,
188
+ autoSavePreviousElapsedDurationSeconds,
189
+ definition.id,
190
+ definition.name,
191
+ deleteAutoSaveSubmission,
192
+ resetCurrentSubmissionDuration,
193
+ ]);
166
194
  const continueAutoSaveSubmission = React.useCallback(() => {
167
195
  if (autoSaveSubmission) {
168
196
  setFormSubmission((currentFormSubmission) => ({
@@ -172,14 +200,18 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
172
200
  sectionState: autoSaveSectionState || [],
173
201
  }));
174
202
  }
203
+ resetCurrentSubmissionDuration(autoSavePreviousElapsedDurationSeconds);
175
204
  setAutoSaveState({
176
205
  isLoadingAutoSaveSubmission: false,
177
206
  autoSaveSubmission: null,
178
207
  autoSaveElement: null,
179
208
  autoSaveSectionState: null,
209
+ autoSavePreviousElapsedDurationSeconds: 0,
180
210
  });
181
211
  }, [
182
212
  autoSaveSubmission,
213
+ resetCurrentSubmissionDuration,
214
+ autoSavePreviousElapsedDurationSeconds,
183
215
  setFormSubmission,
184
216
  autoSaveElement,
185
217
  autoSaveSectionState,
@@ -204,6 +236,7 @@ export default function useFormSubmissionAutoSaveState({ form, initialSubmission
204
236
  handleSaveDraft,
205
237
  handleNavigateAway,
206
238
  setFormSubmission: setFormSubmissionAutoSave,
239
+ getCurrentSubmissionDuration,
207
240
  };
208
241
  }
209
242
  //# sourceMappingURL=useFormSubmissionAutoSaveState.js.map
@@ -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, SubmissionTypes } from '@oneblink/types'\nimport useFormSubmissionState from './useFormSubmissionState'\nimport { FormElement } from '@oneblink/types/typescript/forms'\nimport { SectionState } from '../types/form'\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}: {\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}) {\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 [\n {\n isLoadingAutoSaveSubmission,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState,\n },\n setAutoSaveState,\n ] = React.useState<{\n isLoadingAutoSaveSubmission: boolean\n autoSaveSubmission: SubmissionTypes.S3SubmissionData['submission'] | null\n autoSaveElement: FormElement | null\n autoSaveSectionState: SectionState | null\n }>({\n isLoadingAutoSaveSubmission: true,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\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 .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])\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 if (!ignore) {\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission,\n autoSaveElement,\n autoSaveSectionState:\n autoSaveSectionStateData?.sectionState || null,\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 })\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 deleteAutoSaveSubmission()\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: 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 sectionState: autoSaveSectionState || [],\n }))\n }\n setAutoSaveState({\n isLoadingAutoSaveSubmission: false,\n autoSaveSubmission: null,\n autoSaveElement: null,\n autoSaveSectionState: null,\n })\n }, [\n autoSaveSubmission,\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 }\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 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"]}
@@ -0,0 +1 @@
1
+ export default function useFormSubmissionDuration(initialPreviousElapsedDurationSeconds?: number): readonly [() => number, (newPreviousElapsedDurationSeconds?: number) => void];
@@ -0,0 +1,18 @@
1
+ import * as React from 'react';
2
+ import { differenceInSeconds } from 'date-fns';
3
+ export default function useFormSubmissionDuration(initialPreviousElapsedDurationSeconds) {
4
+ // a "seconds" value indicating the previous time spent on this form submission
5
+ const [previousElapsedDurationSeconds, setPreviousElapsedDurationSeconds] = React.useState(initialPreviousElapsedDurationSeconds);
6
+ const startTime = React.useRef(Date.now());
7
+ // return the current submission duration in seconds
8
+ const getCurrentSubmissionDuration = React.useCallback(() => {
9
+ const currentSessionDuration = differenceInSeconds(Date.now(), startTime.current);
10
+ return currentSessionDuration + (previousElapsedDurationSeconds || 0);
11
+ }, [previousElapsedDurationSeconds]);
12
+ const resetCurrentSubmissionDuration = React.useCallback((newPreviousElapsedDurationSeconds) => {
13
+ setPreviousElapsedDurationSeconds(newPreviousElapsedDurationSeconds);
14
+ startTime.current = Date.now();
15
+ }, []);
16
+ return [getCurrentSubmissionDuration, resetCurrentSubmissionDuration];
17
+ }
18
+ //# sourceMappingURL=useFormSubmissionDuration.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"useFormSubmissionDuration.js","sourceRoot":"","sources":["../../src/hooks/useFormSubmissionDuration.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,mBAAmB,EAAE,MAAM,UAAU,CAAA;AAE9C,MAAM,CAAC,OAAO,UAAU,yBAAyB,CAC/C,qCAA8C;IAE9C,+EAA+E;IAC/E,MAAM,CAAC,8BAA8B,EAAE,iCAAiC,CAAC,GACvE,KAAK,CAAC,QAAQ,CAAqB,qCAAqC,CAAC,CAAA;IAC3E,MAAM,SAAS,GAAG,KAAK,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,CAAA;IAE1C,oDAAoD;IACpD,MAAM,4BAA4B,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC1D,MAAM,sBAAsB,GAAG,mBAAmB,CAAC,IAAI,CAAC,GAAG,EAAE,EAAE,SAAS,CAAC,OAAO,CAAC,CAAA;QACjF,OAAO,sBAAsB,GAAG,CAAC,8BAA8B,IAAI,CAAC,CAAC,CAAA;IACvE,CAAC,EAAE,CAAC,8BAA8B,CAAC,CAAC,CAAA;IAEpC,MAAM,8BAA8B,GAAG,KAAK,CAAC,WAAW,CACtD,CAAC,iCAA0C,EAAE,EAAE;QAC7C,iCAAiC,CAAC,iCAAiC,CAAC,CAAA;QACpE,SAAS,CAAC,OAAO,GAAG,IAAI,CAAC,GAAG,EAAE,CAAA;IAChC,CAAC,EACD,EAAE,CACH,CAAA;IAED,OAAO,CAAC,4BAA4B,EAAE,8BAA8B,CAAU,CAAA;AAChF,CAAC","sourcesContent":["import * as React from 'react'\nimport { differenceInSeconds } from 'date-fns'\n\nexport default function useFormSubmissionDuration(\n initialPreviousElapsedDurationSeconds?: number,\n) {\n // a \"seconds\" value indicating the previous time spent on this form submission\n const [previousElapsedDurationSeconds, setPreviousElapsedDurationSeconds] =\n React.useState<number | undefined>(initialPreviousElapsedDurationSeconds)\n const startTime = React.useRef(Date.now())\n\n // return the current submission duration in seconds\n const getCurrentSubmissionDuration = React.useCallback(() => {\n const currentSessionDuration = differenceInSeconds(Date.now(), startTime.current)\n return currentSessionDuration + (previousElapsedDurationSeconds || 0)\n }, [previousElapsedDurationSeconds])\n\n const resetCurrentSubmissionDuration = React.useCallback(\n (newPreviousElapsedDurationSeconds?: number) => {\n setPreviousElapsedDurationSeconds(newPreviousElapsedDurationSeconds)\n startTime.current = Date.now()\n },\n [],\n )\n\n return [getCurrentSubmissionDuration, resetCurrentSubmissionDuration] as const\n}\n"]}
package/dist/index.d.ts CHANGED
@@ -23,6 +23,7 @@ export { default as useLoadDataEffect } from './hooks/useLoadDataEffect';
23
23
  export { default as useFormSubmissionState } from './hooks/useFormSubmissionState';
24
24
  export { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState';
25
25
  export { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader';
26
+ export { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration';
26
27
  export { default as ProgressBar } from './components/renderer/ProgressBar';
27
28
  export { default as PaymentReceipt } from './PaymentReceipt';
28
29
  export { default as PaymentForm } from './components/payments/PaymentForm';
package/dist/index.js CHANGED
@@ -23,6 +23,7 @@ export { default as useLoadDataEffect } from './hooks/useLoadDataEffect';
23
23
  export { default as useFormSubmissionState } from './hooks/useFormSubmissionState';
24
24
  export { default as useFormSubmissionAutoSaveState } from './hooks/useFormSubmissionAutoSaveState';
25
25
  export { default as useGoogleJsApiLoader } from './hooks/useGoogleJsApiLoader';
26
+ export { default as useFormSubmissionDuration } from './hooks/useFormSubmissionDuration';
26
27
  export { default as ProgressBar } from './components/renderer/ProgressBar';
27
28
  export { default as PaymentReceipt } from './PaymentReceipt';
28
29
  export { default as PaymentForm } from './components/payments/PaymentForm';
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 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 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'\n\nexport { default as ProgressBar } from './components/renderer/ProgressBar'\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'\n\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"]}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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","sourcesContent":["export {\n OneBlinkFormBaseProps,\n OneBlinkFormControlledProps,\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 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 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'\n\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"]}
@@ -1 +1,3 @@
1
+ import { FormTypes } from '@oneblink/types';
1
2
  export declare const sendGoogleAnalyticsEvent: (eventName: string, eventParams: Record<string, unknown>) => void;
3
+ export declare const getElementDisplayNameForAnalyticsEvent: (lastElementUpdated?: FormTypes.FormElement | null) => string | undefined;
@@ -1,4 +1,4 @@
1
- import { Sentry } from "@oneblink/apps";
1
+ import { Sentry } from '@oneblink/apps';
2
2
  export const sendGoogleAnalyticsEvent = (eventName, eventParams) => {
3
3
  if (typeof window.gtag === 'function') {
4
4
  try {
@@ -11,4 +11,11 @@ export const sendGoogleAnalyticsEvent = (eventName, eventParams) => {
11
11
  }
12
12
  }
13
13
  };
14
+ export const getElementDisplayNameForAnalyticsEvent = (lastElementUpdated) => {
15
+ if (!lastElementUpdated)
16
+ return;
17
+ return lastElementUpdated && 'label' in lastElementUpdated
18
+ ? lastElementUpdated.label
19
+ : (lastElementUpdated === null || lastElementUpdated === void 0 ? void 0 : lastElementUpdated.name) || (lastElementUpdated === null || lastElementUpdated === void 0 ? void 0 : lastElementUpdated.id);
20
+ };
14
21
  //# sourceMappingURL=sendGoogleAnalyticsEvent.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"sendGoogleAnalyticsEvent.js","sourceRoot":"","sources":["../../src/utils/sendGoogleAnalyticsEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAEvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,SAAiB,EACjB,WAAoC,EACpC,EAAE;IACF,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;YAC1E,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,CAAC,CAAC,CAAA;YACvE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;AACH,CAAC,CAAA","sourcesContent":["import { Sentry } from \"@oneblink/apps\"\n\nexport const sendGoogleAnalyticsEvent = (\n eventName: string,\n eventParams: Record<string, unknown>,\n) => {\n if (typeof window.gtag === 'function') {\n try {\n console.log('pushing event to google analytics: ', eventName, eventParams)\n window.gtag('event', eventName, eventParams)\n } catch (e) {\n console.warn('An error occured pushing event to google analytics: ', e)\n Sentry.captureException(e)\n }\n }\n}\n"]}
1
+ {"version":3,"file":"sendGoogleAnalyticsEvent.js","sourceRoot":"","sources":["../../src/utils/sendGoogleAnalyticsEvent.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAGvC,MAAM,CAAC,MAAM,wBAAwB,GAAG,CACtC,SAAiB,EACjB,WAAoC,EACpC,EAAE;IACF,IAAI,OAAO,MAAM,CAAC,IAAI,KAAK,UAAU,EAAE,CAAC;QACtC,IAAI,CAAC;YACH,OAAO,CAAC,GAAG,CAAC,qCAAqC,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;YAC1E,MAAM,CAAC,IAAI,CAAC,OAAO,EAAE,SAAS,EAAE,WAAW,CAAC,CAAA;QAC9C,CAAC;QAAC,OAAO,CAAC,EAAE,CAAC;YACX,OAAO,CAAC,IAAI,CAAC,sDAAsD,EAAE,CAAC,CAAC,CAAA;YACvE,MAAM,CAAC,gBAAgB,CAAC,CAAC,CAAC,CAAA;QAC5B,CAAC;IACH,CAAC;AACH,CAAC,CAAA;AAED,MAAM,CAAC,MAAM,sCAAsC,GAAG,CACpD,kBAAiD,EACjD,EAAE;IACF,IAAI,CAAC,kBAAkB;QAAE,OAAM;IAC/B,OAAO,kBAAkB,IAAI,OAAO,IAAI,kBAAkB;QACxD,CAAC,CAAC,kBAAkB,CAAC,KAAK;QAC1B,CAAC,CAAC,CAAA,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,IAAI,MAAI,kBAAkB,aAAlB,kBAAkB,uBAAlB,kBAAkB,CAAE,EAAE,CAAA,CAAA;AACxD,CAAC,CAAA","sourcesContent":["import { Sentry } from '@oneblink/apps'\nimport { FormTypes } from '@oneblink/types'\n\nexport const sendGoogleAnalyticsEvent = (\n eventName: string,\n eventParams: Record<string, unknown>,\n) => {\n if (typeof window.gtag === 'function') {\n try {\n console.log('pushing event to google analytics: ', eventName, eventParams)\n window.gtag('event', eventName, eventParams)\n } catch (e) {\n console.warn('An error occured pushing event to google analytics: ', e)\n Sentry.captureException(e)\n }\n }\n}\n\nexport const getElementDisplayNameForAnalyticsEvent = (\n lastElementUpdated?: FormTypes.FormElement | null,\n) => {\n if (!lastElementUpdated) return\n return lastElementUpdated && 'label' in lastElementUpdated\n ? lastElementUpdated.label\n : lastElementUpdated?.name || lastElementUpdated?.id\n}\n"]}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@oneblink/apps-react",
3
3
  "description": "Helper functions for OneBlink apps in ReactJS.",
4
- "version": "8.14.0-beta.1",
4
+ "version": "8.14.0-beta.2",
5
5
  "author": "OneBlink <developers@oneblink.io> (https://oneblink.io)",
6
6
  "bugs": {
7
7
  "url": "https://github.com/oneblink/apps-react/issues"
@@ -48,7 +48,7 @@
48
48
  "@mui/lab": "^5.0.0-alpha.152",
49
49
  "@mui/material": "^5.15.6",
50
50
  "@mui/x-date-pickers": "^6.20.2",
51
- "@oneblink/apps": "^23.6.0-beta.2",
51
+ "@oneblink/apps": "^23.7.0-beta.1",
52
52
  "@oneblink/release-cli": "^3.4.0-beta.1",
53
53
  "@oneblink/types": "github:oneblink/types",
54
54
  "@types/blueimp-load-image": "^5.16.6",