@oneblink/apps-react 9.1.1-beta.1 → 10.0.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.
@@ -1,5 +1,7 @@
1
1
  import { getLatestFormSubmissionDraftVersion } from './services/draft-data-store';
2
+ import { SubmissionTypes } from '@oneblink/types';
2
3
  import { DraftSubmission, DraftSubmissionInput, LocalFormSubmissionDraft, ProgressListener } from './types/submissions';
4
+ export type PriorityFn = (a: SubmissionTypes.FormSubmissionDraft, b: SubmissionTypes.FormSubmissionDraft) => number;
3
5
  /**
4
6
  * Register a listener function that will be passed an array of Drafts when a
5
7
  * draft is added, updated or deleted.
@@ -74,9 +76,10 @@ declare function upsertDraft({ formSubmissionDraftId, draftSubmissionInput, auto
74
76
  * const drafts = await draftService.getDrafts()
75
77
  * ```
76
78
  *
79
+ * @param abortSignal - Signal to abort the requests
77
80
  * @returns
78
81
  */
79
- declare function getDrafts(): Promise<LocalFormSubmissionDraft[]>;
82
+ declare function getDrafts(abortSignal?: AbortSignal): Promise<LocalFormSubmissionDraft[]>;
80
83
  /**
81
84
  * Get an array of Drafts that have been submitted publicly on this device.
82
85
  *
@@ -137,9 +140,15 @@ declare function deleteDraft(formSubmissionDraftId: string, formsAppId: number,
137
140
  * @param param0
138
141
  * @returns
139
142
  */
140
- declare function syncDrafts({ formsAppId, throwError, abortSignal, }: {
143
+ declare function syncDrafts({ priorityFn, formsAppId, throwError, abortSignal, }: {
141
144
  /** The id of the OneBlink Forms App to sync drafts with */
142
145
  formsAppId: number;
146
+ /**
147
+ * Function used to determine the order of the draft downloads. It is expected
148
+ * to return a negative value if the first argument is less than the second
149
+ * argument, zero if they're equal, and a positive value otherwise.
150
+ */
151
+ priorityFn?: PriorityFn;
143
152
  /** `true` to throw errors while syncing */
144
153
  throwError?: boolean;
145
154
  /** Signal to abort the requests */
@@ -9,6 +9,7 @@ import { getFormSubmissionDrafts, uploadDraftData } from './services/api/drafts'
9
9
  import { getPendingQueueSubmissions, deletePendingQueueSubmission, } from './services/pending-queue';
10
10
  import { deleteDraftData, getDraftSubmission, getLatestFormSubmissionDraftVersion, getLocalDraftSubmission, removeLocalDraftSubmission, saveDraftSubmission, } from './services/draft-data-store';
11
11
  import Sentry from './Sentry';
12
+ const DRAFT_CHUNK_SIZE = 5;
12
13
  function generateDraftsKey(username) {
13
14
  return `V2_DRAFTS_${username}`;
14
15
  }
@@ -49,6 +50,7 @@ function generateLocalFormSubmissionDraftsFromDraftSubmissions(draftSubmissions,
49
50
  taskActionId: (_d = draftSubmission.taskCompletion) === null || _d === void 0 ? void 0 : _d.taskAction.taskActionId,
50
51
  draftSubmission,
51
52
  versions: undefined,
53
+ downloadStatus: 'SUCCESS',
52
54
  });
53
55
  }
54
56
  }
@@ -69,13 +71,25 @@ async function generatePublicLocalFormSubmissionDraftsFromStorage(publicDraftsSt
69
71
  const localFormSubmissionDrafts = Array.from(localFormSubmissionDraftsMap.values());
70
72
  return _orderBy(localFormSubmissionDrafts, (localFormSubmissionDraft) => {
71
73
  var _a;
72
- return (_a = localFormSubmissionDraft.draftSubmission) === null || _a === void 0 ? void 0 : _a.createdAt;
74
+ return localFormSubmissionDraft.downloadStatus === 'SUCCESS'
75
+ ? (_a = localFormSubmissionDraft.draftSubmission) === null || _a === void 0 ? void 0 : _a.createdAt
76
+ : undefined;
73
77
  });
74
78
  }
75
- async function generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage) {
79
+ async function generateLocalFormSubmissionDraftsFromStorage({ localDraftsStorage, abortSignal, priorityFn, }) {
76
80
  const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds();
77
81
  const deletedDraftIds = new Set(localDraftsStorage.deletedFormSubmissionDrafts.map(({ id }) => id));
78
82
  const localFormSubmissionDraftsMap = generateLocalFormSubmissionDraftsFromDraftSubmissions(localDraftsStorage.unsyncedDraftSubmissions, pendingSubmissionsDraftIds, deletedDraftIds);
83
+ async function broadcastUpdate() {
84
+ const draftsToBroadcast = Array.from(localFormSubmissionDraftsMap.values());
85
+ const orderedDrafts = _orderBy(draftsToBroadcast, (localFormSubmissionDraft) => {
86
+ var _a;
87
+ return (_a = getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)) === null || _a === void 0 ? void 0 : _a.createdAt;
88
+ });
89
+ await executeDraftsListeners(orderedDrafts);
90
+ }
91
+ // At this point we need to store the state of the drafts in localForage
92
+ const draftsToDownload = [];
79
93
  for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {
80
94
  if (
81
95
  // Unsycned version of draft takes priority over the synced version
@@ -84,21 +98,64 @@ async function generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage)
84
98
  !pendingSubmissionsDraftIds.has(formSubmissionDraft.id) &&
85
99
  // Remove any drafts deleted while offline
86
100
  !deletedDraftIds.has(formSubmissionDraft.id)) {
87
- const draftSubmission = await getDraftSubmission(formSubmissionDraft).catch((err) => {
88
- console.warn(`Could not fetch draft submission for draft: ${formSubmissionDraft.id}`, err);
89
- return undefined;
90
- });
101
+ draftsToDownload.push(formSubmissionDraft);
91
102
  localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
92
103
  ...formSubmissionDraft,
93
- draftSubmission,
104
+ downloadStatus: 'PENDING',
105
+ });
106
+ }
107
+ }
108
+ await broadcastUpdate();
109
+ if (draftsToDownload.length) {
110
+ if (priorityFn) {
111
+ draftsToDownload.sort(priorityFn);
112
+ }
113
+ for (let i = 0; i < draftsToDownload.length; i += DRAFT_CHUNK_SIZE) {
114
+ const chunk = draftsToDownload.slice(i, i + DRAFT_CHUNK_SIZE);
115
+ chunk.forEach(async (formSubmissionDraft) => {
116
+ const currentValue = localFormSubmissionDraftsMap.get(formSubmissionDraft.id);
117
+ if (currentValue) {
118
+ localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
119
+ ...currentValue,
120
+ downloadStatus: 'DOWNLOADING',
121
+ });
122
+ }
94
123
  });
124
+ await broadcastUpdate();
125
+ // download the draft data for each draft in the chunk in parallel
126
+ await Promise.all(chunk.map(async (formSubmissionDraft) => {
127
+ try {
128
+ const draftSubmission = await getDraftSubmission(formSubmissionDraft, abortSignal);
129
+ if (draftSubmission) {
130
+ localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
131
+ ...formSubmissionDraft,
132
+ draftSubmission: draftSubmission,
133
+ downloadStatus: 'SUCCESS',
134
+ });
135
+ }
136
+ else {
137
+ localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
138
+ ...formSubmissionDraft,
139
+ downloadStatus: 'NOT_AVAILABLE',
140
+ });
141
+ }
142
+ }
143
+ catch (err) {
144
+ console.warn(`Could not fetch draft submission for draft: ${formSubmissionDraft.id}`, err);
145
+ localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
146
+ ...formSubmissionDraft,
147
+ downloadStatus: 'ERROR',
148
+ downloadError: err.message,
149
+ });
150
+ }
151
+ await broadcastUpdate();
152
+ }));
95
153
  }
96
154
  }
97
155
  const localFormSubmissionDrafts = Array.from(localFormSubmissionDraftsMap.values());
98
156
  return _orderBy(localFormSubmissionDrafts, (localFormSubmissionDraft) => {
99
- var _a, _b;
100
- return (((_a = localFormSubmissionDraft.draftSubmission) === null || _a === void 0 ? void 0 : _a.createdAt) ||
101
- ((_b = getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)) === null || _b === void 0 ? void 0 : _b.createdAt));
157
+ var _a;
158
+ return (_a = getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)) === null || _a === void 0 ? void 0 : _a.createdAt;
102
159
  });
103
160
  }
104
161
  function errorHandler(error) {
@@ -239,7 +296,11 @@ async function upsertDraft({ formSubmissionDraftId, draftSubmissionInput, autoSa
239
296
  localDraftsStorage.unsyncedDraftSubmissions.push(draftSubmission);
240
297
  }
241
298
  }
242
- await setAndBroadcastDrafts(localDraftsStorage);
299
+ await setAndBroadcastDrafts({
300
+ localDraftsStorage,
301
+ abortSignal,
302
+ priorityFn: undefined,
303
+ });
243
304
  }
244
305
  else {
245
306
  let updated = false;
@@ -311,11 +372,16 @@ async function getPublicDraftsFromStorage() {
311
372
  * const drafts = await draftService.getDrafts()
312
373
  * ```
313
374
  *
375
+ * @param abortSignal - Signal to abort the requests
314
376
  * @returns
315
377
  */
316
- async function getDrafts() {
378
+ async function getDrafts(abortSignal) {
317
379
  const localDraftsStorage = await getLocalDraftsFromStorage();
318
- return await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage);
380
+ return await generateLocalFormSubmissionDraftsFromStorage({
381
+ localDraftsStorage,
382
+ abortSignal,
383
+ priorityFn: undefined,
384
+ });
319
385
  }
320
386
  /**
321
387
  * Get an array of Drafts that have been submitted publicly on this device.
@@ -367,7 +433,11 @@ async function getDraftAndData(formsAppId, formSubmissionDraftId, abortSignal) {
367
433
  const localDraftsStorage = await getLocalDraftsFromStorage();
368
434
  if (formSubmissionDrafts) {
369
435
  localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts;
370
- await setAndBroadcastDrafts(localDraftsStorage);
436
+ await setAndBroadcastDrafts({
437
+ localDraftsStorage,
438
+ abortSignal,
439
+ priorityFn: undefined,
440
+ });
371
441
  }
372
442
  else {
373
443
  formSubmissionDrafts = localDraftsStorage.syncedFormSubmissionDrafts;
@@ -376,7 +446,13 @@ async function getDraftAndData(formsAppId, formSubmissionDraftId, abortSignal) {
376
446
  if (!formSubmissionDraft) {
377
447
  return (await getLocalDraftSubmission(formSubmissionDraftId)) || undefined;
378
448
  }
379
- return await getDraftSubmission(formSubmissionDraft);
449
+ const s3SubmissionData = await getDraftSubmission(formSubmissionDraft, abortSignal);
450
+ if (!s3SubmissionData) {
451
+ throw new OneBlinkAppsError("Data has been removed based on your administrator's draft data retention policy.", {
452
+ title: 'Draft Data Unavailable',
453
+ });
454
+ }
455
+ return s3SubmissionData;
380
456
  }
381
457
  else {
382
458
  if (formSubmissionDrafts) {
@@ -425,7 +501,11 @@ async function deleteDraft(formSubmissionDraftId, formsAppId, abortSignal) {
425
501
  localDraftsStorage.unsyncedDraftSubmissions =
426
502
  localDraftsStorage.unsyncedDraftSubmissions.filter((draftSubmission) => draftSubmission.formSubmissionDraftId !== formSubmissionDraftId);
427
503
  }
428
- await setAndBroadcastDrafts(localDraftsStorage);
504
+ await setAndBroadcastDrafts({
505
+ localDraftsStorage,
506
+ abortSignal,
507
+ priorityFn: undefined,
508
+ });
429
509
  }
430
510
  else {
431
511
  let publicDraftsStorage = await getPublicDraftsFromStorage();
@@ -452,7 +532,7 @@ async function setAndBroadcastPublicDrafts(publicDrafts) {
452
532
  const localFormSubmissionDrafts = await generatePublicLocalFormSubmissionDraftsFromStorage(publicDrafts);
453
533
  await executeDraftsListeners(localFormSubmissionDrafts.map((draft) => ({ ...draft, isPublic: true })));
454
534
  }
455
- async function setAndBroadcastDrafts(localDraftsStorage) {
535
+ async function setAndBroadcastDrafts({ localDraftsStorage, abortSignal, priorityFn, }) {
456
536
  const username = getUsername();
457
537
  if (!username) {
458
538
  throw new OneBlinkAppsError('You cannot set your drafts until you have logged in. Please login and try again.', {
@@ -461,7 +541,11 @@ async function setAndBroadcastDrafts(localDraftsStorage) {
461
541
  }
462
542
  await utilsService.localForage.setItem(generateDraftsKey(username), localDraftsStorage);
463
543
  console.log('Drafts have been updated', localDraftsStorage);
464
- const localFormSubmissionDrafts = await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage);
544
+ const localFormSubmissionDrafts = await generateLocalFormSubmissionDraftsFromStorage({
545
+ localDraftsStorage,
546
+ abortSignal,
547
+ priorityFn,
548
+ });
465
549
  await executeDraftsListeners(localFormSubmissionDrafts);
466
550
  }
467
551
  let _isSyncingDrafts = false;
@@ -482,7 +566,7 @@ let _isSyncingDrafts = false;
482
566
  * @param param0
483
567
  * @returns
484
568
  */
485
- async function syncDrafts({ formsAppId, throwError, abortSignal, }) {
569
+ async function syncDrafts({ priorityFn, formsAppId, throwError, abortSignal, }) {
486
570
  if (_isSyncingDrafts) {
487
571
  console.log('Application is currently syncing drafts.');
488
572
  return;
@@ -552,17 +636,25 @@ async function syncDrafts({ formsAppId, throwError, abortSignal, }) {
552
636
  if (formSubmissionDrafts) {
553
637
  localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts;
554
638
  }
555
- await setAndBroadcastDrafts(localDraftsStorage);
556
- if (localDraftsStorage.syncedFormSubmissionDrafts.length) {
557
- console.log('Ensuring all draft data is available for offline use for synced drafts', localDraftsStorage.syncedFormSubmissionDrafts);
558
- for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {
559
- await getDraftSubmission(formSubmissionDraft, abortSignal).catch((error) => {
560
- console.warn('Could not download Draft Data as JSON', error);
561
- });
639
+ console.log('Downloading drafts in the background');
640
+ setAndBroadcastDrafts({ localDraftsStorage, abortSignal, priorityFn })
641
+ .then(async () => {
642
+ console.log('Finished syncing drafts.');
643
+ })
644
+ .catch((error) => {
645
+ if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
646
+ console.log('Syncing drafts has been aborted');
647
+ return;
562
648
  }
563
- }
564
- console.log('Finished syncing drafts.');
565
- _isSyncingDrafts = false;
649
+ console.warn('Error while attempting download drafts in the background', error);
650
+ if (!(error instanceof OneBlinkAppsError)) {
651
+ Sentry.captureException(error);
652
+ }
653
+ })
654
+ .finally(() => {
655
+ _isSyncingDrafts = false;
656
+ });
657
+ // broadcast the drafts and download the draft data in the background
566
658
  }
567
659
  catch (error) {
568
660
  _isSyncingDrafts = false;
@@ -1 +1 @@
1
- {"version":3,"file":"draft-service.js","sourceRoot":"","sources":["../../src/apps/draft-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid'\nimport _orderBy from 'lodash.orderby'\nimport utilsService from './services/utils'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { isOffline } from './offline-service'\nimport { getUsername } from './services/cognito'\nimport { getFormsKeyId, getCurrentFormsAppUser } from './auth-service'\nimport { getFormSubmissionDrafts, uploadDraftData } from './services/api/drafts'\nimport {\n getPendingQueueSubmissions,\n deletePendingQueueSubmission,\n} from './services/pending-queue'\nimport {\n deleteDraftData,\n getDraftSubmission,\n getLatestFormSubmissionDraftVersion,\n getLocalDraftSubmission,\n removeLocalDraftSubmission,\n saveDraftSubmission,\n} from './services/draft-data-store'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from './Sentry'\nimport {\n DraftSubmission,\n DraftSubmissionInput,\n LocalFormSubmissionDraft,\n ProgressListener,\n} from './types/submissions'\n\nfunction generateDraftsKey(username: string) {\n return `V2_DRAFTS_${username}`\n}\n\nfunction generatePublicDraftsKey() {\n return `V2_DRAFTS_PUBLIC`\n}\n\ninterface LocalDraftsStorage {\n deletedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n unsyncedDraftSubmissions: DraftSubmission[]\n syncedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n}\n\nasync function checkIfUsingPrivateDrafts(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n return getCurrentFormsAppUser(formsAppId, abortSignal)\n .then((user) => !!user)\n .catch((error) => {\n if (error.status >= 400 && error.status < 500) {\n return false\n } else {\n Sentry.captureException(error)\n console.log(\n 'Could not determine if the current user has access to this forms app',\n error,\n )\n return false\n }\n })\n}\n\nfunction generateLocalFormSubmissionDraftsFromDraftSubmissions(\n draftSubmissions: DraftSubmission[],\n pendingSubmissionsDraftIds: Set<string>,\n deletedDraftIds: Set<string>,\n) {\n const localFormSubmissionDraftsMap = new Map<\n string,\n LocalFormSubmissionDraft\n >()\n\n for (const draftSubmission of draftSubmissions) {\n if (\n // Remove drafts that are in the pending queue\n !pendingSubmissionsDraftIds.has(draftSubmission.formSubmissionDraftId) &&\n // Remove any drafts deleted while offline\n !deletedDraftIds.has(draftSubmission.formSubmissionDraftId)\n ) {\n localFormSubmissionDraftsMap.set(draftSubmission.formSubmissionDraftId, {\n formsAppId: draftSubmission.formsAppId,\n formId: draftSubmission.definition.id,\n externalId: draftSubmission.externalId,\n jobId: draftSubmission.jobId,\n previousFormSubmissionApprovalId:\n draftSubmission.previousFormSubmissionApprovalId,\n taskId: draftSubmission.taskCompletion?.task.taskId,\n taskGroupInstanceId:\n draftSubmission.taskCompletion?.taskGroupInstance\n ?.taskGroupInstanceId,\n taskActionId: draftSubmission.taskCompletion?.taskAction.taskActionId,\n draftSubmission,\n versions: undefined,\n })\n }\n }\n\n return localFormSubmissionDraftsMap\n}\n\nasync function getPendingSubmissionsDraftIds() {\n const pendingSubmissions = await getPendingQueueSubmissions()\n return pendingSubmissions.reduce<Set<string>>((memo, pendingSubmission) => {\n if (pendingSubmission.formSubmissionDraftId) {\n memo.add(pendingSubmission.formSubmissionDraftId)\n }\n return memo\n }, new Set<string>())\n}\n\nasync function generatePublicLocalFormSubmissionDraftsFromStorage(\n publicDraftsStorage: DraftSubmission[],\n) {\n const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds()\n const localFormSubmissionDraftsMap =\n generateLocalFormSubmissionDraftsFromDraftSubmissions(\n publicDraftsStorage,\n pendingSubmissionsDraftIds,\n new Set(),\n )\n\n const localFormSubmissionDrafts = Array.from(\n localFormSubmissionDraftsMap.values(),\n )\n\n return _orderBy(localFormSubmissionDrafts, (localFormSubmissionDraft) => {\n return localFormSubmissionDraft.draftSubmission?.createdAt\n })\n}\n\nasync function generateLocalFormSubmissionDraftsFromStorage(\n localDraftsStorage: LocalDraftsStorage,\n): Promise<LocalFormSubmissionDraft[]> {\n const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds()\n const deletedDraftIds = new Set(\n localDraftsStorage.deletedFormSubmissionDrafts.map(({ id }) => id),\n )\n\n const localFormSubmissionDraftsMap =\n generateLocalFormSubmissionDraftsFromDraftSubmissions(\n localDraftsStorage.unsyncedDraftSubmissions,\n pendingSubmissionsDraftIds,\n deletedDraftIds,\n )\n\n for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {\n if (\n // Unsycned version of draft takes priority over the synced version\n !localFormSubmissionDraftsMap.has(formSubmissionDraft.id) &&\n // Remove drafts that are in the pending queue\n !pendingSubmissionsDraftIds.has(formSubmissionDraft.id) &&\n // Remove any drafts deleted while offline\n !deletedDraftIds.has(formSubmissionDraft.id)\n ) {\n const draftSubmission = await getDraftSubmission(\n formSubmissionDraft,\n ).catch((err) => {\n console.warn(\n `Could not fetch draft submission for draft: ${formSubmissionDraft.id}`,\n err,\n )\n return undefined\n })\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...formSubmissionDraft,\n draftSubmission,\n })\n }\n }\n\n const localFormSubmissionDrafts = Array.from(\n localFormSubmissionDraftsMap.values(),\n )\n\n return _orderBy(localFormSubmissionDrafts, (localFormSubmissionDraft) => {\n return (\n localFormSubmissionDraft.draftSubmission?.createdAt ||\n getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)\n ?.createdAt\n )\n })\n}\n\nfunction errorHandler(error: Error): Error {\n console.error('Local Forage Error', error)\n if (/The serialized value is too large/.test(error.message)) {\n return new OneBlinkAppsError(\n 'It seems you have run out of space. Please delete some of your drafts to allow new drafts to be created or existing drafts to be updated.',\n {\n originalError: error,\n },\n )\n }\n\n return error\n}\n\nconst draftsListeners: Array<(drafts: LocalFormSubmissionDraft[]) => unknown> =\n []\n\n/**\n * Register a listener function that will be passed an array of Drafts when a\n * draft is added, updated or deleted.\n *\n * #### Example\n *\n * ```js\n * const listener = async (drafts) => {\n * // use drafts here...\n * }\n * const deregister = await draftService.registerDraftsListener(listener)\n *\n * // When no longer needed, remember to deregister the listener\n * deregister()\n * ```\n *\n * @param listener\n * @returns\n */\nfunction registerDraftsListener(\n listener: (drafts: LocalFormSubmissionDraft[]) => unknown,\n): () => void {\n draftsListeners.push(listener)\n\n return () => {\n const index = draftsListeners.indexOf(listener)\n if (index !== -1) {\n draftsListeners.splice(index, 1)\n }\n }\n}\n\nasync function executeDraftsListeners(\n localFormSubmissionDrafts: LocalFormSubmissionDraft[],\n) {\n for (const draftsListener of draftsListeners) {\n draftsListener(localFormSubmissionDrafts)\n }\n}\n\n/**\n * Create or update a Draft in the local store and sync it with remote drafts.\n * Will also handle cleaning up auto save data (if the `autoSaveKey` property is\n * passed).\n *\n * #### Example\n *\n * ```js\n * const abortController = new AbortController()\n * const formSubmissionDraftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003' // pass `undefined` to create a new draft\n * const autoSaveKey = 'SET ME TO DELETE AUTOSAVE DATA AFTER SAVING DRAFT'\n * const draftSubmissionInput = {\n * title: 1,\n * formsAppId: 1,\n * submission: {\n * form: 'data',\n * goes: 'here',\n * },\n * definition: {\n * form: 'definition',\n * goes: 'here',\n * },\n * }\n * await draftService.upsertDraft({\n * formSubmissionDraftId,\n * autoSaveKey,\n * draftSubmissionInput,\n * abortSignal: abortController.signal,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nasync function upsertDraft({\n formSubmissionDraftId,\n draftSubmissionInput,\n autoSaveKey,\n onProgress,\n abortSignal,\n pendingTimestamp,\n}: {\n formSubmissionDraftId: string | undefined\n draftSubmissionInput: DraftSubmissionInput\n autoSaveKey?: string\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n pendingTimestamp?: string\n}): Promise<void> {\n const draftSubmission: DraftSubmission = {\n ...draftSubmissionInput,\n createdAt: new Date().toISOString(),\n formSubmissionDraftId: formSubmissionDraftId || uuidv4(),\n }\n\n const keyId = getFormsKeyId()\n if (keyId) {\n if (isOffline()) {\n throw new OneBlinkAppsError('Drafts cannot be saved while offline.', {\n isOffline: true,\n })\n }\n\n await uploadDraftData(draftSubmission, onProgress, abortSignal)\n return\n }\n\n try {\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(\n draftSubmission.formsAppId,\n )\n const formSubmissionDraftVersion = await saveDraftSubmission({\n draftSubmission,\n autoSaveKey,\n onProgress,\n skipUpload: !isUsingPrivateDrafts,\n })\n\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n\n if (formSubmissionDraftVersion) {\n console.log('Draft was saved on server', formSubmissionDraftVersion)\n localDraftsStorage.syncedFormSubmissionDrafts =\n await getFormSubmissionDrafts(draftSubmission.formsAppId, abortSignal)\n // Remove draft from unsynced incase it was created offline\n if (formSubmissionDraftId) {\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.filter(\n (unsyncedDraftSubmission) =>\n unsyncedDraftSubmission.formSubmissionDraftId !==\n formSubmissionDraftId,\n )\n }\n } else {\n console.log(\n 'Draft could not be saved on server, saving locally to sync later',\n draftSubmission,\n )\n let updated = false\n\n if (formSubmissionDraftId) {\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.map(\n (unsyncedDraftSubmission) => {\n if (\n unsyncedDraftSubmission.formSubmissionDraftId ===\n formSubmissionDraftId\n ) {\n updated = true\n return draftSubmission\n }\n return unsyncedDraftSubmission\n },\n )\n // Remove draft from synced drafts incase it was retrieved while online\n localDraftsStorage.syncedFormSubmissionDrafts =\n localDraftsStorage.syncedFormSubmissionDrafts.filter(\n ({ id }) => id !== formSubmissionDraftId,\n )\n }\n\n if (!updated) {\n localDraftsStorage.unsyncedDraftSubmissions.push(draftSubmission)\n }\n }\n\n await setAndBroadcastDrafts(localDraftsStorage)\n } else {\n let updated = false\n const publicDraftsStorage = (await getPublicDraftsFromStorage()).map(\n (publicDraftSubmission) => {\n if (\n publicDraftSubmission.formSubmissionDraftId ===\n formSubmissionDraftId\n ) {\n updated = true\n return draftSubmission\n }\n return publicDraftSubmission\n },\n )\n if (!updated) {\n publicDraftsStorage.push(draftSubmission)\n }\n await setAndBroadcastPublicDrafts(publicDraftsStorage)\n }\n\n if (pendingTimestamp) {\n await deletePendingQueueSubmission(pendingTimestamp)\n }\n syncDrafts({\n throwError: false,\n formsAppId: draftSubmission.formsAppId,\n })\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n}\n\nasync function getLocalDraftsFromStorage(): Promise<LocalDraftsStorage> {\n const username = getUsername()\n if (username) {\n try {\n const localDraftsStorage =\n await utilsService.localForage.getItem<LocalDraftsStorage>(\n generateDraftsKey(username),\n )\n if (localDraftsStorage) {\n return localDraftsStorage\n }\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n }\n\n return {\n unsyncedDraftSubmissions: [],\n syncedFormSubmissionDrafts: [],\n deletedFormSubmissionDrafts: [],\n }\n}\n\nasync function getPublicDraftsFromStorage(): Promise<DraftSubmission[]> {\n try {\n const publicDrafts = await utilsService.localForage.getItem<\n DraftSubmission[]\n >(generatePublicDraftsKey())\n if (publicDrafts) {\n return publicDrafts\n }\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n\n return []\n}\n\n/**\n * Get an array of Drafts for the currently logged in user.\n *\n * #### Example\n *\n * ```js\n * const drafts = await draftService.getDrafts()\n * ```\n *\n * @returns\n */\nasync function getDrafts(): Promise<LocalFormSubmissionDraft[]> {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n return await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage)\n}\n\n/**\n * Get an array of Drafts that have been submitted publicly on this device.\n *\n * #### Example\n *\n * ```js\n * const drafts = await draftService.getPublicDrafts()\n * ```\n *\n * @returns\n */\nasync function getPublicDrafts(): Promise<LocalFormSubmissionDraft[]> {\n const publicDraftsStorage = await getPublicDraftsFromStorage()\n return await generatePublicLocalFormSubmissionDraftsFromStorage(\n publicDraftsStorage,\n )\n}\n\nasync function tryGetFormSubmissionDrafts(\n formsAppId: number,\n abortSignal: AbortSignal | undefined,\n) {\n try {\n return await getFormSubmissionDrafts(formsAppId, abortSignal)\n } catch (error) {\n if (!(error instanceof OneBlinkAppsError) || !error.isOffline) {\n throw error\n }\n }\n}\n\n/**\n * Get a single Draft and the associated submission data.\n *\n * #### Example\n *\n * ```js\n * const draftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003'\n * const { draft, draftData, lastElementUpdated } =\n * await draftService.getDraftAndData(draftId)\n * // use \"draftData\" to prefill a from\n * ```\n *\n * @param draftId\n * @returns\n */\nasync function getDraftAndData(\n formsAppId: number,\n formSubmissionDraftId: string | undefined | null,\n abortSignal: AbortSignal | undefined,\n): Promise<DraftSubmission | undefined> {\n if (!formSubmissionDraftId) {\n return\n }\n\n let formSubmissionDrafts = await tryGetFormSubmissionDrafts(\n formsAppId,\n abortSignal,\n )\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n if (formSubmissionDrafts) {\n localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts\n await setAndBroadcastDrafts(localDraftsStorage)\n } else {\n formSubmissionDrafts = localDraftsStorage.syncedFormSubmissionDrafts\n }\n\n const formSubmissionDraft = formSubmissionDrafts.find(\n ({ id }) => id === formSubmissionDraftId,\n )\n if (!formSubmissionDraft) {\n return (await getLocalDraftSubmission(formSubmissionDraftId)) || undefined\n }\n\n return await getDraftSubmission(formSubmissionDraft)\n } else {\n if (formSubmissionDrafts) {\n return (await getLocalDraftSubmission(formSubmissionDraftId)) || undefined\n }\n }\n}\n\n/**\n * Remove a draft from the local store and sync with remote drafts.\n *\n * #### Example\n *\n * ```js\n * const draftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003'\n * await draftService.deleteDraft(draftId)\n * ```\n *\n * @param draftId\n * @param formsAppId\n * @returns\n */\nasync function deleteDraft(\n formSubmissionDraftId: string,\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<void> {\n try {\n await removeLocalDraftSubmission(formSubmissionDraftId)\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n const formSubmissionDraft =\n localDraftsStorage.syncedFormSubmissionDrafts.find(\n ({ id }) => id === formSubmissionDraftId,\n )\n if (formSubmissionDraft) {\n const { hasDeletedRemoteDraft } = await deleteDraftData(\n formSubmissionDraftId,\n abortSignal,\n )\n localDraftsStorage.syncedFormSubmissionDrafts =\n localDraftsStorage.syncedFormSubmissionDrafts.filter(\n ({ id }) => id !== formSubmissionDraft.id,\n )\n if (!hasDeletedRemoteDraft) {\n localDraftsStorage.deletedFormSubmissionDrafts.push(\n formSubmissionDraft,\n )\n }\n } else {\n console.log(\n 'Could not find existing draft in synced drafts to delete',\n {\n formSubmissionDraftId,\n localDraftsStorage,\n },\n )\n const draftSubmission =\n localDraftsStorage.unsyncedDraftSubmissions.find(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId === formSubmissionDraftId,\n )\n if (!draftSubmission) {\n return\n }\n\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.filter(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId !== formSubmissionDraftId,\n )\n }\n\n await setAndBroadcastDrafts(localDraftsStorage)\n } else {\n let publicDraftsStorage = await getPublicDraftsFromStorage()\n const draftSubmission = publicDraftsStorage.find(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId === formSubmissionDraftId,\n )\n if (!draftSubmission) {\n return\n }\n\n publicDraftsStorage = publicDraftsStorage.filter(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId !== formSubmissionDraftId,\n )\n\n await setAndBroadcastPublicDrafts(publicDraftsStorage)\n }\n\n syncDrafts({\n throwError: false,\n formsAppId,\n })\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n}\n\nasync function setAndBroadcastPublicDrafts(publicDrafts: DraftSubmission[]) {\n await utilsService.localForage.setItem(\n generatePublicDraftsKey(),\n publicDrafts,\n )\n\n console.log('Public drafts have been updated', publicDrafts)\n const localFormSubmissionDrafts =\n await generatePublicLocalFormSubmissionDraftsFromStorage(publicDrafts)\n await executeDraftsListeners(\n localFormSubmissionDrafts.map((draft) => ({ ...draft, isPublic: true })),\n )\n}\n\nasync function setAndBroadcastDrafts(\n localDraftsStorage: LocalDraftsStorage,\n): Promise<void> {\n const username = getUsername()\n if (!username) {\n throw new OneBlinkAppsError(\n 'You cannot set your drafts until you have logged in. Please login and try again.',\n {\n requiresLogin: true,\n },\n )\n }\n await utilsService.localForage.setItem(\n generateDraftsKey(username),\n localDraftsStorage,\n )\n\n console.log('Drafts have been updated', localDraftsStorage)\n const localFormSubmissionDrafts =\n await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage)\n await executeDraftsListeners(localFormSubmissionDrafts)\n}\n\nlet _isSyncingDrafts = false\n\n/**\n * Force a sync of remote drafts with locally stored drafts. This function will\n * swallow all errors thrown unless `true` is passed for the `throwError`\n * property.\n *\n * #### Example\n *\n * ```js\n * await draftService.syncDrafts({\n * throwError: true,\n * formsAppId: 1,\n * })\n * ```\n *\n * @param param0\n * @returns\n */\nasync function syncDrafts({\n formsAppId,\n throwError,\n abortSignal,\n}: {\n /** The id of the OneBlink Forms App to sync drafts with */\n formsAppId: number\n /** `true` to throw errors while syncing */\n throwError?: boolean\n /** Signal to abort the requests */\n abortSignal?: AbortSignal\n}): Promise<void> {\n if (_isSyncingDrafts) {\n console.log('Application is currently syncing drafts.')\n return\n }\n _isSyncingDrafts = true\n\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n\n if (!isUsingPrivateDrafts) {\n const publicDrafts = await getPublicDraftsFromStorage()\n const filteredPublicDrafts = []\n // iterate through public draft records, and check if a draft submission exists for each record.\n // If no draft submission exists for a record, the draft was likely submitted, so we must remove it\n // from the list of public drafts so it no longer appears in the user's draft list.\n for (const publicDraft of publicDrafts) {\n const localDraftSubmission = await getLocalDraftSubmission(\n publicDraft.formSubmissionDraftId,\n )\n if (localDraftSubmission) {\n filteredPublicDrafts.push(publicDraft)\n }\n }\n await setAndBroadcastPublicDrafts(filteredPublicDrafts)\n _isSyncingDrafts = false\n return\n }\n\n try {\n let localDraftsStorage = await getLocalDraftsFromStorage()\n if (localDraftsStorage.deletedFormSubmissionDrafts.length) {\n console.log(\n 'Removing local draft data for deleted drafts',\n localDraftsStorage.deletedFormSubmissionDrafts,\n )\n const newDeletedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[] =\n []\n for (const formSubmissionDraft of localDraftsStorage.deletedFormSubmissionDrafts) {\n const { hasDeletedRemoteDraft } = await deleteDraftData(\n formSubmissionDraft.id,\n abortSignal,\n )\n if (!hasDeletedRemoteDraft) {\n newDeletedFormSubmissionDrafts.push(formSubmissionDraft)\n }\n }\n\n // Get local drafts again to ensure nothing has happened while processing\n localDraftsStorage = await getLocalDraftsFromStorage()\n localDraftsStorage.deletedFormSubmissionDrafts =\n newDeletedFormSubmissionDrafts\n }\n\n const publicDraftsStorage = await getPublicDraftsFromStorage()\n // if public drafts exist, add them to the current logged in users' unsynced drafts\n // and remove them from local storage\n if (publicDraftsStorage.length) {\n localDraftsStorage.unsyncedDraftSubmissions.push(...publicDraftsStorage)\n await utilsService.localForage.setItem(generatePublicDraftsKey(), [])\n }\n\n if (localDraftsStorage.unsyncedDraftSubmissions.length) {\n console.log(\n `Attempting to upload ${localDraftsStorage.unsyncedDraftSubmissions.length} local unsynced drafts(s).`,\n )\n const newUnsyncedDraftSubmissions: DraftSubmission[] = []\n for (const draftSubmission of localDraftsStorage.unsyncedDraftSubmissions) {\n console.log(\n 'Uploading draft data that was saved while offline',\n draftSubmission.title,\n )\n draftSubmission.backgroundUpload = false\n const formSubmissionDraftVersion = await saveDraftSubmission({\n draftSubmission,\n autoSaveKey: undefined,\n abortSignal,\n skipUpload: !isUsingPrivateDrafts,\n })\n if (!formSubmissionDraftVersion) {\n newUnsyncedDraftSubmissions.push(draftSubmission)\n }\n }\n // Get local drafts again to ensure nothing has happened while processing\n localDraftsStorage = await getLocalDraftsFromStorage()\n localDraftsStorage.unsyncedDraftSubmissions = newUnsyncedDraftSubmissions\n }\n\n const formSubmissionDrafts = await tryGetFormSubmissionDrafts(\n formsAppId,\n abortSignal,\n )\n if (formSubmissionDrafts) {\n localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts\n }\n\n await setAndBroadcastDrafts(localDraftsStorage)\n\n if (localDraftsStorage.syncedFormSubmissionDrafts.length) {\n console.log(\n 'Ensuring all draft data is available for offline use for synced drafts',\n localDraftsStorage.syncedFormSubmissionDrafts,\n )\n for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {\n await getDraftSubmission(formSubmissionDraft, abortSignal).catch(\n (error) => {\n console.warn('Could not download Draft Data as JSON', error)\n },\n )\n }\n }\n\n console.log('Finished syncing drafts.')\n _isSyncingDrafts = false\n } catch (error) {\n _isSyncingDrafts = false\n if (abortSignal?.aborted) {\n console.log('Syncing drafts has been aborted')\n return\n }\n console.warn(\n 'Error while attempting to sync and update local drafts',\n error,\n )\n if (!(error instanceof OneBlinkAppsError)) {\n Sentry.captureException(error)\n }\n if (throwError) {\n throw error\n }\n }\n}\n\nexport {\n registerDraftsListener,\n upsertDraft,\n getDraftAndData,\n getDrafts,\n getPublicDrafts,\n deleteDraft,\n syncDrafts,\n getLatestFormSubmissionDraftVersion,\n LocalFormSubmissionDraft,\n}\n"]}
1
+ {"version":3,"file":"draft-service.js","sourceRoot":"","sources":["../../src/apps/draft-service.ts"],"names":[],"mappings":"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","sourcesContent":["import { v4 as uuidv4 } from 'uuid'\nimport _orderBy from 'lodash.orderby'\nimport utilsService from './services/utils'\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { isOffline } from './offline-service'\nimport { getUsername } from './services/cognito'\nimport { getFormsKeyId, getCurrentFormsAppUser } from './auth-service'\nimport { getFormSubmissionDrafts, uploadDraftData } from './services/api/drafts'\nimport {\n getPendingQueueSubmissions,\n deletePendingQueueSubmission,\n} from './services/pending-queue'\nimport {\n deleteDraftData,\n getDraftSubmission,\n getLatestFormSubmissionDraftVersion,\n getLocalDraftSubmission,\n removeLocalDraftSubmission,\n saveDraftSubmission,\n} from './services/draft-data-store'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from './Sentry'\nimport {\n DraftSubmission,\n DraftSubmissionInput,\n LocalFormSubmissionDraft,\n ProgressListener,\n} from './types/submissions'\n\nexport type PriorityFn = (\n a: SubmissionTypes.FormSubmissionDraft,\n b: SubmissionTypes.FormSubmissionDraft,\n) => number\n\nconst DRAFT_CHUNK_SIZE = 5\n\nfunction generateDraftsKey(username: string) {\n return `V2_DRAFTS_${username}`\n}\n\nfunction generatePublicDraftsKey() {\n return `V2_DRAFTS_PUBLIC`\n}\n\ninterface LocalDraftsStorage {\n deletedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n unsyncedDraftSubmissions: DraftSubmission[]\n syncedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n}\n\nasync function checkIfUsingPrivateDrafts(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<boolean> {\n return getCurrentFormsAppUser(formsAppId, abortSignal)\n .then((user) => !!user)\n .catch((error) => {\n if (error.status >= 400 && error.status < 500) {\n return false\n } else {\n Sentry.captureException(error)\n console.log(\n 'Could not determine if the current user has access to this forms app',\n error,\n )\n return false\n }\n })\n}\n\nfunction generateLocalFormSubmissionDraftsFromDraftSubmissions(\n draftSubmissions: DraftSubmission[],\n pendingSubmissionsDraftIds: Set<string>,\n deletedDraftIds: Set<string>,\n) {\n const localFormSubmissionDraftsMap = new Map<\n string,\n LocalFormSubmissionDraft\n >()\n\n for (const draftSubmission of draftSubmissions) {\n if (\n // Remove drafts that are in the pending queue\n !pendingSubmissionsDraftIds.has(draftSubmission.formSubmissionDraftId) &&\n // Remove any drafts deleted while offline\n !deletedDraftIds.has(draftSubmission.formSubmissionDraftId)\n ) {\n localFormSubmissionDraftsMap.set(draftSubmission.formSubmissionDraftId, {\n formsAppId: draftSubmission.formsAppId,\n formId: draftSubmission.definition.id,\n externalId: draftSubmission.externalId,\n jobId: draftSubmission.jobId,\n previousFormSubmissionApprovalId:\n draftSubmission.previousFormSubmissionApprovalId,\n taskId: draftSubmission.taskCompletion?.task.taskId,\n taskGroupInstanceId:\n draftSubmission.taskCompletion?.taskGroupInstance\n ?.taskGroupInstanceId,\n taskActionId: draftSubmission.taskCompletion?.taskAction.taskActionId,\n draftSubmission,\n versions: undefined,\n downloadStatus: 'SUCCESS',\n })\n }\n }\n\n return localFormSubmissionDraftsMap\n}\n\nasync function getPendingSubmissionsDraftIds() {\n const pendingSubmissions = await getPendingQueueSubmissions()\n return pendingSubmissions.reduce<Set<string>>((memo, pendingSubmission) => {\n if (pendingSubmission.formSubmissionDraftId) {\n memo.add(pendingSubmission.formSubmissionDraftId)\n }\n return memo\n }, new Set<string>())\n}\n\nasync function generatePublicLocalFormSubmissionDraftsFromStorage(\n publicDraftsStorage: DraftSubmission[],\n) {\n const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds()\n const localFormSubmissionDraftsMap =\n generateLocalFormSubmissionDraftsFromDraftSubmissions(\n publicDraftsStorage,\n pendingSubmissionsDraftIds,\n new Set(),\n )\n\n const localFormSubmissionDrafts = Array.from(\n localFormSubmissionDraftsMap.values(),\n )\n\n return _orderBy(localFormSubmissionDrafts, (localFormSubmissionDraft) => {\n return localFormSubmissionDraft.downloadStatus === 'SUCCESS'\n ? localFormSubmissionDraft.draftSubmission?.createdAt\n : undefined\n })\n}\n\nasync function generateLocalFormSubmissionDraftsFromStorage({\n localDraftsStorage,\n abortSignal,\n priorityFn,\n}: {\n localDraftsStorage: LocalDraftsStorage\n abortSignal: AbortSignal | undefined\n priorityFn?: PriorityFn\n}): Promise<LocalFormSubmissionDraft[]> {\n const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds()\n const deletedDraftIds = new Set(\n localDraftsStorage.deletedFormSubmissionDrafts.map(({ id }) => id),\n )\n\n const localFormSubmissionDraftsMap =\n generateLocalFormSubmissionDraftsFromDraftSubmissions(\n localDraftsStorage.unsyncedDraftSubmissions,\n pendingSubmissionsDraftIds,\n deletedDraftIds,\n )\n\n async function broadcastUpdate() {\n const draftsToBroadcast = Array.from(localFormSubmissionDraftsMap.values())\n\n const orderedDrafts = _orderBy(\n draftsToBroadcast,\n (localFormSubmissionDraft) =>\n getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)\n ?.createdAt,\n )\n\n await executeDraftsListeners(orderedDrafts)\n }\n\n // At this point we need to store the state of the drafts in localForage\n const draftsToDownload: SubmissionTypes.FormSubmissionDraft[] = []\n\n for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {\n if (\n // Unsycned version of draft takes priority over the synced version\n !localFormSubmissionDraftsMap.has(formSubmissionDraft.id) &&\n // Remove drafts that are in the pending queue\n !pendingSubmissionsDraftIds.has(formSubmissionDraft.id) &&\n // Remove any drafts deleted while offline\n !deletedDraftIds.has(formSubmissionDraft.id)\n ) {\n draftsToDownload.push(formSubmissionDraft)\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...formSubmissionDraft,\n downloadStatus: 'PENDING',\n })\n }\n }\n\n await broadcastUpdate()\n\n if (draftsToDownload.length) {\n if (priorityFn) {\n draftsToDownload.sort(priorityFn)\n }\n for (let i = 0; i < draftsToDownload.length; i += DRAFT_CHUNK_SIZE) {\n const chunk = draftsToDownload.slice(i, i + DRAFT_CHUNK_SIZE)\n chunk.forEach(async (formSubmissionDraft) => {\n const currentValue = localFormSubmissionDraftsMap.get(\n formSubmissionDraft.id,\n )\n if (currentValue) {\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...currentValue,\n downloadStatus: 'DOWNLOADING',\n })\n }\n })\n await broadcastUpdate()\n // download the draft data for each draft in the chunk in parallel\n await Promise.all(\n chunk.map(async (formSubmissionDraft) => {\n try {\n const draftSubmission = await getDraftSubmission(\n formSubmissionDraft,\n abortSignal,\n )\n if (draftSubmission) {\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...formSubmissionDraft,\n draftSubmission: draftSubmission,\n downloadStatus: 'SUCCESS',\n })\n } else {\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...formSubmissionDraft,\n downloadStatus: 'NOT_AVAILABLE',\n })\n }\n } catch (err) {\n console.warn(\n `Could not fetch draft submission for draft: ${formSubmissionDraft.id}`,\n err,\n )\n\n localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {\n ...formSubmissionDraft,\n downloadStatus: 'ERROR',\n downloadError: (err as Error).message,\n })\n }\n\n await broadcastUpdate()\n }),\n )\n }\n }\n\n const localFormSubmissionDrafts = Array.from(\n localFormSubmissionDraftsMap.values(),\n )\n\n return _orderBy(\n localFormSubmissionDrafts,\n (localFormSubmissionDraft) =>\n getLatestFormSubmissionDraftVersion(localFormSubmissionDraft.versions)\n ?.createdAt,\n )\n}\n\nfunction errorHandler(error: Error): Error {\n console.error('Local Forage Error', error)\n if (/The serialized value is too large/.test(error.message)) {\n return new OneBlinkAppsError(\n 'It seems you have run out of space. Please delete some of your drafts to allow new drafts to be created or existing drafts to be updated.',\n {\n originalError: error,\n },\n )\n }\n\n return error\n}\n\nconst draftsListeners: Array<(drafts: LocalFormSubmissionDraft[]) => unknown> =\n []\n\n/**\n * Register a listener function that will be passed an array of Drafts when a\n * draft is added, updated or deleted.\n *\n * #### Example\n *\n * ```js\n * const listener = async (drafts) => {\n * // use drafts here...\n * }\n * const deregister = await draftService.registerDraftsListener(listener)\n *\n * // When no longer needed, remember to deregister the listener\n * deregister()\n * ```\n *\n * @param listener\n * @returns\n */\nfunction registerDraftsListener(\n listener: (drafts: LocalFormSubmissionDraft[]) => unknown,\n): () => void {\n draftsListeners.push(listener)\n\n return () => {\n const index = draftsListeners.indexOf(listener)\n if (index !== -1) {\n draftsListeners.splice(index, 1)\n }\n }\n}\n\nasync function executeDraftsListeners(\n localFormSubmissionDrafts: LocalFormSubmissionDraft[],\n) {\n for (const draftsListener of draftsListeners) {\n draftsListener(localFormSubmissionDrafts)\n }\n}\n\n/**\n * Create or update a Draft in the local store and sync it with remote drafts.\n * Will also handle cleaning up auto save data (if the `autoSaveKey` property is\n * passed).\n *\n * #### Example\n *\n * ```js\n * const abortController = new AbortController()\n * const formSubmissionDraftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003' // pass `undefined` to create a new draft\n * const autoSaveKey = 'SET ME TO DELETE AUTOSAVE DATA AFTER SAVING DRAFT'\n * const draftSubmissionInput = {\n * title: 1,\n * formsAppId: 1,\n * submission: {\n * form: 'data',\n * goes: 'here',\n * },\n * definition: {\n * form: 'definition',\n * goes: 'here',\n * },\n * }\n * await draftService.upsertDraft({\n * formSubmissionDraftId,\n * autoSaveKey,\n * draftSubmissionInput,\n * abortSignal: abortController.signal,\n * onProgress: (progress) => {\n * // ...\n * },\n * })\n * ```\n *\n * @param options\n * @returns\n */\nasync function upsertDraft({\n formSubmissionDraftId,\n draftSubmissionInput,\n autoSaveKey,\n onProgress,\n abortSignal,\n pendingTimestamp,\n}: {\n formSubmissionDraftId: string | undefined\n draftSubmissionInput: DraftSubmissionInput\n autoSaveKey?: string\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n pendingTimestamp?: string\n}): Promise<void> {\n const draftSubmission: DraftSubmission = {\n ...draftSubmissionInput,\n createdAt: new Date().toISOString(),\n formSubmissionDraftId: formSubmissionDraftId || uuidv4(),\n }\n\n const keyId = getFormsKeyId()\n if (keyId) {\n if (isOffline()) {\n throw new OneBlinkAppsError('Drafts cannot be saved while offline.', {\n isOffline: true,\n })\n }\n\n await uploadDraftData(draftSubmission, onProgress, abortSignal)\n return\n }\n\n try {\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(\n draftSubmission.formsAppId,\n )\n const formSubmissionDraftVersion = await saveDraftSubmission({\n draftSubmission,\n autoSaveKey,\n onProgress,\n skipUpload: !isUsingPrivateDrafts,\n })\n\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n\n if (formSubmissionDraftVersion) {\n console.log('Draft was saved on server', formSubmissionDraftVersion)\n localDraftsStorage.syncedFormSubmissionDrafts =\n await getFormSubmissionDrafts(draftSubmission.formsAppId, abortSignal)\n // Remove draft from unsynced incase it was created offline\n if (formSubmissionDraftId) {\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.filter(\n (unsyncedDraftSubmission) =>\n unsyncedDraftSubmission.formSubmissionDraftId !==\n formSubmissionDraftId,\n )\n }\n } else {\n console.log(\n 'Draft could not be saved on server, saving locally to sync later',\n draftSubmission,\n )\n let updated = false\n\n if (formSubmissionDraftId) {\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.map(\n (unsyncedDraftSubmission) => {\n if (\n unsyncedDraftSubmission.formSubmissionDraftId ===\n formSubmissionDraftId\n ) {\n updated = true\n return draftSubmission\n }\n return unsyncedDraftSubmission\n },\n )\n // Remove draft from synced drafts incase it was retrieved while online\n localDraftsStorage.syncedFormSubmissionDrafts =\n localDraftsStorage.syncedFormSubmissionDrafts.filter(\n ({ id }) => id !== formSubmissionDraftId,\n )\n }\n\n if (!updated) {\n localDraftsStorage.unsyncedDraftSubmissions.push(draftSubmission)\n }\n }\n\n await setAndBroadcastDrafts({\n localDraftsStorage,\n abortSignal,\n priorityFn: undefined,\n })\n } else {\n let updated = false\n const publicDraftsStorage = (await getPublicDraftsFromStorage()).map(\n (publicDraftSubmission) => {\n if (\n publicDraftSubmission.formSubmissionDraftId ===\n formSubmissionDraftId\n ) {\n updated = true\n return draftSubmission\n }\n return publicDraftSubmission\n },\n )\n if (!updated) {\n publicDraftsStorage.push(draftSubmission)\n }\n await setAndBroadcastPublicDrafts(publicDraftsStorage)\n }\n\n if (pendingTimestamp) {\n await deletePendingQueueSubmission(pendingTimestamp)\n }\n syncDrafts({\n throwError: false,\n formsAppId: draftSubmission.formsAppId,\n })\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n}\n\nasync function getLocalDraftsFromStorage(): Promise<LocalDraftsStorage> {\n const username = getUsername()\n if (username) {\n try {\n const localDraftsStorage =\n await utilsService.localForage.getItem<LocalDraftsStorage>(\n generateDraftsKey(username),\n )\n if (localDraftsStorage) {\n return localDraftsStorage\n }\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n }\n\n return {\n unsyncedDraftSubmissions: [],\n syncedFormSubmissionDrafts: [],\n deletedFormSubmissionDrafts: [],\n }\n}\n\nasync function getPublicDraftsFromStorage(): Promise<DraftSubmission[]> {\n try {\n const publicDrafts = await utilsService.localForage.getItem<\n DraftSubmission[]\n >(generatePublicDraftsKey())\n if (publicDrafts) {\n return publicDrafts\n }\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n\n return []\n}\n\n/**\n * Get an array of Drafts for the currently logged in user.\n *\n * #### Example\n *\n * ```js\n * const drafts = await draftService.getDrafts()\n * ```\n *\n * @param abortSignal - Signal to abort the requests\n * @returns\n */\nasync function getDrafts(\n abortSignal?: AbortSignal,\n): Promise<LocalFormSubmissionDraft[]> {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n return await generateLocalFormSubmissionDraftsFromStorage({\n localDraftsStorage,\n abortSignal,\n priorityFn: undefined,\n })\n}\n\n/**\n * Get an array of Drafts that have been submitted publicly on this device.\n *\n * #### Example\n *\n * ```js\n * const drafts = await draftService.getPublicDrafts()\n * ```\n *\n * @returns\n */\nasync function getPublicDrafts(): Promise<LocalFormSubmissionDraft[]> {\n const publicDraftsStorage = await getPublicDraftsFromStorage()\n return await generatePublicLocalFormSubmissionDraftsFromStorage(\n publicDraftsStorage,\n )\n}\n\nasync function tryGetFormSubmissionDrafts(\n formsAppId: number,\n abortSignal: AbortSignal | undefined,\n) {\n try {\n return await getFormSubmissionDrafts(formsAppId, abortSignal)\n } catch (error) {\n if (!(error instanceof OneBlinkAppsError) || !error.isOffline) {\n throw error\n }\n }\n}\n\n/**\n * Get a single Draft and the associated submission data.\n *\n * #### Example\n *\n * ```js\n * const draftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003'\n * const { draft, draftData, lastElementUpdated } =\n * await draftService.getDraftAndData(draftId)\n * // use \"draftData\" to prefill a from\n * ```\n *\n * @param draftId\n * @returns\n */\nasync function getDraftAndData(\n formsAppId: number,\n formSubmissionDraftId: string | undefined | null,\n abortSignal: AbortSignal | undefined,\n): Promise<DraftSubmission | undefined> {\n if (!formSubmissionDraftId) {\n return\n }\n\n let formSubmissionDrafts = await tryGetFormSubmissionDrafts(\n formsAppId,\n abortSignal,\n )\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n if (formSubmissionDrafts) {\n localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts\n await setAndBroadcastDrafts({\n localDraftsStorage,\n abortSignal,\n priorityFn: undefined,\n })\n } else {\n formSubmissionDrafts = localDraftsStorage.syncedFormSubmissionDrafts\n }\n\n const formSubmissionDraft = formSubmissionDrafts.find(\n ({ id }) => id === formSubmissionDraftId,\n )\n if (!formSubmissionDraft) {\n return (await getLocalDraftSubmission(formSubmissionDraftId)) || undefined\n }\n\n const s3SubmissionData = await getDraftSubmission(\n formSubmissionDraft,\n abortSignal,\n )\n if (!s3SubmissionData) {\n throw new OneBlinkAppsError(\n \"Data has been removed based on your administrator's draft data retention policy.\",\n {\n title: 'Draft Data Unavailable',\n },\n )\n }\n return s3SubmissionData\n } else {\n if (formSubmissionDrafts) {\n return (await getLocalDraftSubmission(formSubmissionDraftId)) || undefined\n }\n }\n}\n\n/**\n * Remove a draft from the local store and sync with remote drafts.\n *\n * #### Example\n *\n * ```js\n * const draftId = 'd3aeb944-d0b3-11ea-87d0-0242ac130003'\n * await draftService.deleteDraft(draftId)\n * ```\n *\n * @param draftId\n * @param formsAppId\n * @returns\n */\nasync function deleteDraft(\n formSubmissionDraftId: string,\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<void> {\n try {\n await removeLocalDraftSubmission(formSubmissionDraftId)\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n if (isUsingPrivateDrafts) {\n const localDraftsStorage = await getLocalDraftsFromStorage()\n const formSubmissionDraft =\n localDraftsStorage.syncedFormSubmissionDrafts.find(\n ({ id }) => id === formSubmissionDraftId,\n )\n if (formSubmissionDraft) {\n const { hasDeletedRemoteDraft } = await deleteDraftData(\n formSubmissionDraftId,\n abortSignal,\n )\n localDraftsStorage.syncedFormSubmissionDrafts =\n localDraftsStorage.syncedFormSubmissionDrafts.filter(\n ({ id }) => id !== formSubmissionDraft.id,\n )\n if (!hasDeletedRemoteDraft) {\n localDraftsStorage.deletedFormSubmissionDrafts.push(\n formSubmissionDraft,\n )\n }\n } else {\n console.log(\n 'Could not find existing draft in synced drafts to delete',\n {\n formSubmissionDraftId,\n localDraftsStorage,\n },\n )\n const draftSubmission =\n localDraftsStorage.unsyncedDraftSubmissions.find(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId === formSubmissionDraftId,\n )\n if (!draftSubmission) {\n return\n }\n\n localDraftsStorage.unsyncedDraftSubmissions =\n localDraftsStorage.unsyncedDraftSubmissions.filter(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId !== formSubmissionDraftId,\n )\n }\n\n await setAndBroadcastDrafts({\n localDraftsStorage,\n abortSignal,\n priorityFn: undefined,\n })\n } else {\n let publicDraftsStorage = await getPublicDraftsFromStorage()\n const draftSubmission = publicDraftsStorage.find(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId === formSubmissionDraftId,\n )\n if (!draftSubmission) {\n return\n }\n\n publicDraftsStorage = publicDraftsStorage.filter(\n (draftSubmission) =>\n draftSubmission.formSubmissionDraftId !== formSubmissionDraftId,\n )\n\n await setAndBroadcastPublicDrafts(publicDraftsStorage)\n }\n\n syncDrafts({\n throwError: false,\n formsAppId,\n })\n } catch (err) {\n Sentry.captureException(err)\n throw errorHandler(err as Error)\n }\n}\n\nasync function setAndBroadcastPublicDrafts(publicDrafts: DraftSubmission[]) {\n await utilsService.localForage.setItem(\n generatePublicDraftsKey(),\n publicDrafts,\n )\n\n console.log('Public drafts have been updated', publicDrafts)\n const localFormSubmissionDrafts =\n await generatePublicLocalFormSubmissionDraftsFromStorage(publicDrafts)\n await executeDraftsListeners(\n localFormSubmissionDrafts.map((draft) => ({ ...draft, isPublic: true })),\n )\n}\n\nasync function setAndBroadcastDrafts({\n localDraftsStorage,\n abortSignal,\n priorityFn,\n}: {\n localDraftsStorage: LocalDraftsStorage\n abortSignal: AbortSignal | undefined\n priorityFn: PriorityFn | undefined\n}): Promise<void> {\n const username = getUsername()\n if (!username) {\n throw new OneBlinkAppsError(\n 'You cannot set your drafts until you have logged in. Please login and try again.',\n {\n requiresLogin: true,\n },\n )\n }\n await utilsService.localForage.setItem(\n generateDraftsKey(username),\n localDraftsStorage,\n )\n\n console.log('Drafts have been updated', localDraftsStorage)\n const localFormSubmissionDrafts =\n await generateLocalFormSubmissionDraftsFromStorage({\n localDraftsStorage,\n abortSignal,\n priorityFn,\n })\n await executeDraftsListeners(localFormSubmissionDrafts)\n}\n\nlet _isSyncingDrafts = false\n\n/**\n * Force a sync of remote drafts with locally stored drafts. This function will\n * swallow all errors thrown unless `true` is passed for the `throwError`\n * property.\n *\n * #### Example\n *\n * ```js\n * await draftService.syncDrafts({\n * throwError: true,\n * formsAppId: 1,\n * })\n * ```\n *\n * @param param0\n * @returns\n */\nasync function syncDrafts({\n priorityFn,\n formsAppId,\n throwError,\n abortSignal,\n}: {\n /** The id of the OneBlink Forms App to sync drafts with */\n formsAppId: number\n /**\n * Function used to determine the order of the draft downloads. It is expected\n * to return a negative value if the first argument is less than the second\n * argument, zero if they're equal, and a positive value otherwise.\n */\n priorityFn?: PriorityFn\n /** `true` to throw errors while syncing */\n throwError?: boolean\n /** Signal to abort the requests */\n abortSignal?: AbortSignal\n}): Promise<void> {\n if (_isSyncingDrafts) {\n console.log('Application is currently syncing drafts.')\n return\n }\n _isSyncingDrafts = true\n\n const isUsingPrivateDrafts = await checkIfUsingPrivateDrafts(formsAppId)\n\n if (!isUsingPrivateDrafts) {\n const publicDrafts = await getPublicDraftsFromStorage()\n const filteredPublicDrafts = []\n // iterate through public draft records, and check if a draft submission exists for each record.\n // If no draft submission exists for a record, the draft was likely submitted, so we must remove it\n // from the list of public drafts so it no longer appears in the user's draft list.\n for (const publicDraft of publicDrafts) {\n const localDraftSubmission = await getLocalDraftSubmission(\n publicDraft.formSubmissionDraftId,\n )\n if (localDraftSubmission) {\n filteredPublicDrafts.push(publicDraft)\n }\n }\n await setAndBroadcastPublicDrafts(filteredPublicDrafts)\n _isSyncingDrafts = false\n return\n }\n\n try {\n let localDraftsStorage = await getLocalDraftsFromStorage()\n if (localDraftsStorage.deletedFormSubmissionDrafts.length) {\n console.log(\n 'Removing local draft data for deleted drafts',\n localDraftsStorage.deletedFormSubmissionDrafts,\n )\n const newDeletedFormSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[] =\n []\n for (const formSubmissionDraft of localDraftsStorage.deletedFormSubmissionDrafts) {\n const { hasDeletedRemoteDraft } = await deleteDraftData(\n formSubmissionDraft.id,\n abortSignal,\n )\n if (!hasDeletedRemoteDraft) {\n newDeletedFormSubmissionDrafts.push(formSubmissionDraft)\n }\n }\n\n // Get local drafts again to ensure nothing has happened while processing\n localDraftsStorage = await getLocalDraftsFromStorage()\n localDraftsStorage.deletedFormSubmissionDrafts =\n newDeletedFormSubmissionDrafts\n }\n\n const publicDraftsStorage = await getPublicDraftsFromStorage()\n // if public drafts exist, add them to the current logged in users' unsynced drafts\n // and remove them from local storage\n if (publicDraftsStorage.length) {\n localDraftsStorage.unsyncedDraftSubmissions.push(...publicDraftsStorage)\n await utilsService.localForage.setItem(generatePublicDraftsKey(), [])\n }\n\n if (localDraftsStorage.unsyncedDraftSubmissions.length) {\n console.log(\n `Attempting to upload ${localDraftsStorage.unsyncedDraftSubmissions.length} local unsynced drafts(s).`,\n )\n const newUnsyncedDraftSubmissions: DraftSubmission[] = []\n for (const draftSubmission of localDraftsStorage.unsyncedDraftSubmissions) {\n console.log(\n 'Uploading draft data that was saved while offline',\n draftSubmission.title,\n )\n draftSubmission.backgroundUpload = false\n const formSubmissionDraftVersion = await saveDraftSubmission({\n draftSubmission,\n autoSaveKey: undefined,\n abortSignal,\n skipUpload: !isUsingPrivateDrafts,\n })\n if (!formSubmissionDraftVersion) {\n newUnsyncedDraftSubmissions.push(draftSubmission)\n }\n }\n // Get local drafts again to ensure nothing has happened while processing\n localDraftsStorage = await getLocalDraftsFromStorage()\n localDraftsStorage.unsyncedDraftSubmissions = newUnsyncedDraftSubmissions\n }\n\n const formSubmissionDrafts = await tryGetFormSubmissionDrafts(\n formsAppId,\n abortSignal,\n )\n if (formSubmissionDrafts) {\n localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts\n }\n\n console.log('Downloading drafts in the background')\n setAndBroadcastDrafts({ localDraftsStorage, abortSignal, priorityFn })\n .then(async () => {\n console.log('Finished syncing drafts.')\n })\n .catch((error) => {\n if (abortSignal?.aborted) {\n console.log('Syncing drafts has been aborted')\n return\n }\n console.warn(\n 'Error while attempting download drafts in the background',\n error,\n )\n if (!(error instanceof OneBlinkAppsError)) {\n Sentry.captureException(error)\n }\n })\n .finally(() => {\n _isSyncingDrafts = false\n })\n\n // broadcast the drafts and download the draft data in the background\n } catch (error) {\n _isSyncingDrafts = false\n if (abortSignal?.aborted) {\n console.log('Syncing drafts has been aborted')\n return\n }\n console.warn(\n 'Error while attempting to sync and update local drafts',\n error,\n )\n if (!(error instanceof OneBlinkAppsError)) {\n Sentry.captureException(error)\n }\n if (throwError) {\n throw error\n }\n }\n}\n\nexport {\n registerDraftsListener,\n upsertDraft,\n getDraftAndData,\n getDrafts,\n getPublicDrafts,\n deleteDraft,\n syncDrafts,\n getLatestFormSubmissionDraftVersion,\n LocalFormSubmissionDraft,\n}\n"]}
@@ -14,7 +14,8 @@ import { SubmissionTypes } from '@oneblink/types';
14
14
  *
15
15
  * @param formsAppId
16
16
  * @param jobsLabel
17
+ * @param abortSignal - Signal to abort the requests
17
18
  * @returns
18
19
  */
19
- export declare function getJobs(formsAppId: number, jobsLabel: string): Promise<SubmissionTypes.FormsAppJob[]>;
20
+ export declare function getJobs(formsAppId: number, jobsLabel: string, abortSignal?: AbortSignal): Promise<SubmissionTypes.FormsAppJob[]>;
20
21
  export { ensurePrefillFormDataExists };
@@ -15,8 +15,8 @@ async function removePendingSubmissions(jobList) {
15
15
  return unprocessedJobs;
16
16
  });
17
17
  }
18
- async function tagDrafts(jobList) {
19
- return getDrafts().then((drafts) => jobList.map((job) => {
18
+ async function tagDrafts(jobList, abortSignal) {
19
+ return getDrafts(abortSignal).then((drafts) => jobList.map((job) => {
20
20
  const draft = drafts.find((draft) => draft.jobId === job.id);
21
21
  return {
22
22
  ...job,
@@ -38,9 +38,10 @@ async function tagDrafts(jobList) {
38
38
  *
39
39
  * @param formsAppId
40
40
  * @param jobsLabel
41
+ * @param abortSignal - Signal to abort the requests
41
42
  * @returns
42
43
  */
43
- export async function getJobs(formsAppId, jobsLabel) {
44
+ export async function getJobs(formsAppId, jobsLabel, abortSignal) {
44
45
  if (!isLoggedIn()) {
45
46
  return [];
46
47
  }
@@ -48,7 +49,7 @@ export async function getJobs(formsAppId, jobsLabel) {
48
49
  isSubmitted: false,
49
50
  })
50
51
  .then((data) => removePendingSubmissions(data.jobs))
51
- .then((jobs) => tagDrafts(jobs))
52
+ .then((jobs) => tagDrafts(jobs, abortSignal))
52
53
  .then((jobList) => _orderBy(jobList, ['details.priority', (job) => Date.parse(job.createdAt)], ['asc', 'asc']))
53
54
  .catch((error) => {
54
55
  Sentry.captureException(error);
@@ -1 +1 @@
1
- {"version":3,"file":"job-service.js","sourceRoot":"","sources":["../../src/apps/job-service.ts"],"names":[],"mappings":"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","sourcesContent":["import _orderBy from 'lodash.orderby'\n\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { searchRequest } from './services/fetch'\nimport { getPendingQueueSubmissions } from './services/pending-queue'\nimport { ensurePrefillFormDataExists } from './services/job-prefill'\nimport { isOffline } from './offline-service'\nimport { isLoggedIn } from './auth-service'\nimport { getDrafts } from './draft-service'\nimport tenants from './tenants'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from './Sentry'\n\nasync function removePendingSubmissions(\n jobList: SubmissionTypes.FormsAppJob[],\n) {\n // Get list of pending submissions, remove jobs that are in the pending queue\n return getPendingQueueSubmissions().then((submissions) => {\n const unprocessedJobs = jobList.filter(\n (job) => !submissions.some((sub) => sub.jobId === job.id),\n )\n return unprocessedJobs\n })\n}\n\nasync function tagDrafts(jobList: SubmissionTypes.FormsAppJob[]) {\n return getDrafts().then((drafts) =>\n jobList.map((job) => {\n const draft = drafts.find((draft) => draft.jobId === job.id)\n return {\n ...job,\n draft,\n }\n }),\n )\n}\n\n/**\n * Get Jobs for the current user. Jobs that are in the pending queue will be\n * filtered out and Jobs with drafts will include the `draft` property.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const label = 'Applications'\n * const jobs = await jobService.getJobs(formsAppId, label)\n * ```\n *\n * @param formsAppId\n * @param jobsLabel\n * @returns\n */\nexport async function getJobs(\n formsAppId: number,\n jobsLabel: string,\n): Promise<SubmissionTypes.FormsAppJob[]> {\n if (!isLoggedIn()) {\n return []\n }\n\n return searchRequest<{ jobs: Array<SubmissionTypes.FormsAppJob> }>(\n `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/jobs`,\n {\n isSubmitted: false,\n },\n )\n .then((data) => removePendingSubmissions(data.jobs))\n .then((jobs) => tagDrafts(jobs))\n .then((jobList) =>\n _orderBy(\n jobList,\n ['details.priority', (job) => Date.parse(job.createdAt)],\n ['asc', 'asc'],\n ),\n )\n .catch((error) => {\n Sentry.captureException(error)\n console.warn('Error retrieving Jobs for forms app', error)\n\n if (isOffline()) {\n throw new OneBlinkAppsError(\n 'You are currently offline and do not have a local copy of this app available, please connect to the internet and try again',\n {\n originalError: error,\n isOffline: true,\n },\n )\n }\n\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n `You need to log in to see your ${jobsLabel}. Please login and try again.`,\n {\n originalError: error,\n requiresLogin: true,\n httpStatusCode: error.status,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n `You have not been granted access to ${jobsLabel}. Please contact your administrator to gain the correct level of access.`,\n {\n originalError: error,\n requiresAccessRequest: true,\n httpStatusCode: error.status,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application you are looking for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Application',\n httpStatusCode: error.status,\n },\n )\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n httpStatusCode: error.status,\n },\n )\n }\n }\n })\n}\n\nexport { ensurePrefillFormDataExists }\n"]}
1
+ {"version":3,"file":"job-service.js","sourceRoot":"","sources":["../../src/apps/job-service.ts"],"names":[],"mappings":"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","sourcesContent":["import _orderBy from 'lodash.orderby'\n\nimport OneBlinkAppsError from './services/errors/oneBlinkAppsError'\nimport { searchRequest } from './services/fetch'\nimport { getPendingQueueSubmissions } from './services/pending-queue'\nimport { ensurePrefillFormDataExists } from './services/job-prefill'\nimport { isOffline } from './offline-service'\nimport { isLoggedIn } from './auth-service'\nimport { getDrafts } from './draft-service'\nimport tenants from './tenants'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from './Sentry'\n\nasync function removePendingSubmissions(\n jobList: SubmissionTypes.FormsAppJob[],\n) {\n // Get list of pending submissions, remove jobs that are in the pending queue\n return getPendingQueueSubmissions().then((submissions) => {\n const unprocessedJobs = jobList.filter(\n (job) => !submissions.some((sub) => sub.jobId === job.id),\n )\n return unprocessedJobs\n })\n}\n\nasync function tagDrafts(\n jobList: SubmissionTypes.FormsAppJob[],\n abortSignal?: AbortSignal,\n) {\n return getDrafts(abortSignal).then((drafts) =>\n jobList.map((job) => {\n const draft = drafts.find((draft) => draft.jobId === job.id)\n return {\n ...job,\n draft,\n }\n }),\n )\n}\n\n/**\n * Get Jobs for the current user. Jobs that are in the pending queue will be\n * filtered out and Jobs with drafts will include the `draft` property.\n *\n * #### Example\n *\n * ```js\n * const formsAppId = 1\n * const label = 'Applications'\n * const jobs = await jobService.getJobs(formsAppId, label)\n * ```\n *\n * @param formsAppId\n * @param jobsLabel\n * @param abortSignal - Signal to abort the requests\n * @returns\n */\nexport async function getJobs(\n formsAppId: number,\n jobsLabel: string,\n abortSignal?: AbortSignal,\n): Promise<SubmissionTypes.FormsAppJob[]> {\n if (!isLoggedIn()) {\n return []\n }\n\n return searchRequest<{ jobs: Array<SubmissionTypes.FormsAppJob> }>(\n `${tenants.current.apiOrigin}/forms-apps/${formsAppId}/jobs`,\n {\n isSubmitted: false,\n },\n )\n .then((data) => removePendingSubmissions(data.jobs))\n .then((jobs) => tagDrafts(jobs, abortSignal))\n .then((jobList) =>\n _orderBy(\n jobList,\n ['details.priority', (job) => Date.parse(job.createdAt)],\n ['asc', 'asc'],\n ),\n )\n .catch((error) => {\n Sentry.captureException(error)\n console.warn('Error retrieving Jobs for forms app', error)\n\n if (isOffline()) {\n throw new OneBlinkAppsError(\n 'You are currently offline and do not have a local copy of this app available, please connect to the internet and try again',\n {\n originalError: error,\n isOffline: true,\n },\n )\n }\n\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n `You need to log in to see your ${jobsLabel}. Please login and try again.`,\n {\n originalError: error,\n requiresLogin: true,\n httpStatusCode: error.status,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n `You have not been granted access to ${jobsLabel}. Please contact your administrator to gain the correct level of access.`,\n {\n originalError: error,\n requiresAccessRequest: true,\n httpStatusCode: error.status,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application you are looking for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Application',\n httpStatusCode: error.status,\n },\n )\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n httpStatusCode: error.status,\n },\n )\n }\n }\n })\n}\n\nexport { ensurePrefillFormDataExists }\n"]}
@@ -2,6 +2,6 @@ import { SubmissionTypes } from '@oneblink/types';
2
2
  import { DraftSubmission, ProgressListener } from '../../types/submissions';
3
3
  declare function uploadDraftData(draftSubmission: DraftSubmission, onProgress?: ProgressListener, abortSignal?: AbortSignal): Promise<import("@oneblink/storage/dist/http-handlers/types").OneBlinkResponse<SubmissionTypes.FormSubmissionDraftVersion>>;
4
4
  declare function getFormSubmissionDrafts(formsAppId: number, abortSignal?: AbortSignal): Promise<SubmissionTypes.FormSubmissionDraft[]>;
5
- declare function downloadDraftData(formSubmissionDraftVersionId: string, abortSignal?: AbortSignal): Promise<SubmissionTypes.S3SubmissionData>;
5
+ declare function downloadDraftData(formSubmissionDraft: SubmissionTypes.FormSubmissionDraft, latestFormSubmissionDraftVersion: SubmissionTypes.FormSubmissionDraftVersion, abortSignal?: AbortSignal): Promise<DraftSubmission | undefined>;
6
6
  declare function deleteFormSubmissionDraft(formSubmissionDraftId: string, abortSignal?: AbortSignal): Promise<void>;
7
7
  export { uploadDraftData, getFormSubmissionDrafts, downloadDraftData, deleteFormSubmissionDraft, };
@@ -122,24 +122,47 @@ async function getFormSubmissionDrafts(formsAppId, abortSignal) {
122
122
  }
123
123
  }
124
124
  }
125
- async function downloadDraftData(formSubmissionDraftVersionId, abortSignal) {
125
+ async function downloadDraftData(formSubmissionDraft, latestFormSubmissionDraftVersion, abortSignal) {
126
126
  try {
127
127
  console.log('Attempting to download draft form data:', {
128
- formSubmissionDraftVersionId,
128
+ formSubmissionDraftVersionId: latestFormSubmissionDraftVersion.id,
129
129
  });
130
130
  const oneblinkDownloader = generateOneBlinkDownloader();
131
- const data = await oneblinkDownloader.downloadDraftSubmission({
132
- formSubmissionDraftVersionId,
131
+ const s3SubmissionData = await oneblinkDownloader.downloadDraftSubmission({
132
+ formSubmissionDraftVersionId: latestFormSubmissionDraftVersion.id,
133
133
  abortSignal,
134
134
  });
135
- if (!data) {
136
- throw new OneBlinkAppsError("Data has been removed based on your administrator's draft data retention policy.", {
137
- title: 'Draft Data Unavailable',
138
- });
135
+ if (!s3SubmissionData) {
136
+ return undefined;
139
137
  }
140
- return data;
138
+ return {
139
+ definition: s3SubmissionData.definition,
140
+ submission: s3SubmissionData.submission,
141
+ lastElementUpdated: s3SubmissionData.lastElementUpdated,
142
+ // Drafts will always have a formsAppId, so we can safely cast to number
143
+ formsAppId: s3SubmissionData.formsAppId,
144
+ jobId: formSubmissionDraft.jobId,
145
+ externalId: formSubmissionDraft.externalId,
146
+ previousFormSubmissionApprovalId: formSubmissionDraft.previousFormSubmissionApprovalId,
147
+ taskCompletion: s3SubmissionData.task &&
148
+ s3SubmissionData.taskAction && {
149
+ task: s3SubmissionData.task,
150
+ taskAction: s3SubmissionData.taskAction,
151
+ taskGroup: s3SubmissionData.taskGroup,
152
+ taskGroupInstance: s3SubmissionData.taskGroupInstance,
153
+ redirectUrl: '',
154
+ },
155
+ title: latestFormSubmissionDraftVersion.title,
156
+ createdAt: latestFormSubmissionDraftVersion.createdAt,
157
+ formSubmissionDraftId: formSubmissionDraft.id,
158
+ sectionState: s3SubmissionData.sectionState,
159
+ previousElapsedDurationSeconds: s3SubmissionData.previousElapsedDurationSeconds,
160
+ };
141
161
  }
142
162
  catch (error) {
163
+ if (abortSignal === null || abortSignal === void 0 ? void 0 : abortSignal.aborted) {
164
+ return undefined;
165
+ }
143
166
  console.error('Error occurred while attempting to download draft data', error);
144
167
  if (error instanceof OneBlinkAppsError) {
145
168
  throw error;
@@ -1 +1 @@
1
- {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../../../src/apps/services/api/drafts.ts"],"names":[],"mappings":"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","sourcesContent":["import { SubmissionTypes } from '@oneblink/types'\nimport { getRequest, HTTPError, deleteRequest } from '../fetch'\nimport { isLoggedIn } from '../../auth-service'\nimport { getDeviceInformation } from '../getDeviceInformation'\nimport OneBlinkAppsError from '../errors/oneBlinkAppsError'\nimport tenants from '../../tenants'\nimport { getUserToken } from '../user-token'\nimport Sentry from '../../Sentry'\nimport prepareSubmissionData from '../prepareSubmissionData'\nimport { DraftSubmission, ProgressListener } from '../../types/submissions'\nimport generateOneBlinkUploader from '../generateOneBlinkUploader'\nimport { OneBlinkStorageError } from '@oneblink/storage'\nimport generateOneBlinkDownloader from '../generateOneBlinkDownloader'\n\nasync function uploadDraftData(\n draftSubmission: DraftSubmission,\n onProgress?: ProgressListener,\n abortSignal?: AbortSignal,\n) {\n try {\n const submission = await prepareSubmissionData(draftSubmission)\n const oneblinkUploader = generateOneBlinkUploader()\n const userToken = getUserToken()\n console.log('Attempting to upload draft data')\n return await oneblinkUploader.uploadFormSubmissionDraft({\n submission,\n definition: draftSubmission.definition,\n device: getDeviceInformation(),\n userToken: userToken || undefined,\n previousFormSubmissionApprovalId:\n draftSubmission.previousFormSubmissionApprovalId,\n jobId: draftSubmission.jobId,\n formsAppId: draftSubmission.formsAppId,\n externalId: draftSubmission.externalId,\n taskId: draftSubmission.taskCompletion?.task.taskId,\n taskActionId: draftSubmission.taskCompletion?.taskAction.taskActionId,\n taskGroupInstanceId:\n draftSubmission.taskCompletion?.taskGroupInstance?.taskGroupInstanceId,\n formSubmissionDraftId: draftSubmission.formSubmissionDraftId,\n createdAt: draftSubmission.createdAt,\n title: draftSubmission.title,\n lastElementUpdated: draftSubmission.lastElementUpdated,\n sectionState: draftSubmission.sectionState,\n previousElapsedDurationSeconds:\n draftSubmission.previousElapsedDurationSeconds,\n onProgress,\n abortSignal,\n })\n } catch (error) {\n console.warn('Error occurred while attempting to upload draft data', error)\n Sentry.captureException(error)\n if (error instanceof OneBlinkStorageError) {\n switch (error.httpStatusCode) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot save drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n requiresLogin: true,\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n requiresAccessRequest: true,\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application your attempting upload a draft for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Application',\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error instanceof Error ? error : undefined,\n },\n )\n }\n}\n\nasync function getFormSubmissionDrafts(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<SubmissionTypes.FormSubmissionDraft[]> {\n if (!isLoggedIn()) {\n console.log(\n 'Could not retrieve drafts from API as the current user is not logged in.',\n )\n return []\n }\n\n const url = new URL('/form-submission-drafts', tenants.current.apiOrigin)\n url.searchParams.append('formsAppId', formsAppId.toString())\n url.searchParams.append('isSubmitted', 'false')\n console.log('Attempting to retrieve drafts from API', url.href)\n\n try {\n const { formSubmissionDrafts } = await getRequest<{\n formSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n }>(url.href, abortSignal)\n return formSubmissionDrafts\n } catch (err) {\n console.warn(\n 'Error occurred while attempting to retrieve drafts from API',\n err,\n )\n if (err instanceof OneBlinkAppsError) {\n throw err\n }\n\n const error = err as HTTPError\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot retrieve your drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresAccessRequest: true,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application your attempting retrieve drafts for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Error Syncing Drafts',\n httpStatusCode: error.status,\n },\n )\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n },\n )\n }\n }\n }\n}\n\nasync function downloadDraftData(\n formSubmissionDraftVersionId: string,\n abortSignal?: AbortSignal,\n) {\n try {\n console.log('Attempting to download draft form data:', {\n formSubmissionDraftVersionId,\n })\n const oneblinkDownloader = generateOneBlinkDownloader()\n const data = await oneblinkDownloader.downloadDraftSubmission({\n formSubmissionDraftVersionId,\n abortSignal,\n })\n if (!data) {\n throw new OneBlinkAppsError(\n \"Data has been removed based on your administrator's draft data retention policy.\",\n {\n title: 'Draft Data Unavailable',\n },\n )\n }\n return data\n } catch (error) {\n console.error(\n 'Error occurred while attempting to download draft data',\n error,\n )\n\n if (error instanceof OneBlinkAppsError) {\n throw error\n }\n\n Sentry.captureException(error)\n\n if (error instanceof OneBlinkStorageError) {\n switch (error.httpStatusCode) {\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n originalError: error,\n title: 'Invalid Request',\n httpStatusCode: error.httpStatusCode,\n })\n }\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot retrieve draft data until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.httpStatusCode,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.httpStatusCode,\n requiresAccessRequest: true,\n },\n )\n }\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the draft your attempting retrieve. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Draft',\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n title: 'Unexpected Error',\n originalError: error instanceof Error ? error : undefined,\n httpStatusCode:\n error instanceof OneBlinkStorageError\n ? error.httpStatusCode\n : undefined,\n },\n )\n }\n}\n\nasync function deleteFormSubmissionDraft(\n formSubmissionDraftId: string,\n abortSignal?: AbortSignal,\n) {\n const url = `${tenants.current.apiOrigin}/form-submission-drafts/${formSubmissionDraftId}`\n console.log('Attempting to delete form submission draft remotely', url)\n try {\n await deleteRequest(url, abortSignal)\n } catch (error) {\n console.warn(\n 'Error occurred while attempting to delete a draft from API',\n error,\n )\n if (error instanceof OneBlinkAppsError) {\n throw error\n }\n\n Sentry.captureException(error)\n\n if (error instanceof HTTPError) {\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot delete drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresAccessRequest: true,\n },\n )\n }\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n originalError: error,\n title: 'Invalid Request',\n httpStatusCode: error.status,\n })\n }\n case 404: {\n console.warn(\n 'Remote draft does not exist, we will assume it has already been deleted.',\n formSubmissionDraftId,\n error,\n )\n return\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error as Error,\n },\n )\n }\n}\n\nexport {\n uploadDraftData,\n getFormSubmissionDrafts,\n downloadDraftData,\n deleteFormSubmissionDraft,\n}\n"]}
1
+ {"version":3,"file":"drafts.js","sourceRoot":"","sources":["../../../../src/apps/services/api/drafts.ts"],"names":[],"mappings":"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","sourcesContent":["import { SubmissionTypes } from '@oneblink/types'\nimport { getRequest, HTTPError, deleteRequest } from '../fetch'\nimport { isLoggedIn } from '../../auth-service'\nimport { getDeviceInformation } from '../getDeviceInformation'\nimport OneBlinkAppsError from '../errors/oneBlinkAppsError'\nimport tenants from '../../tenants'\nimport { getUserToken } from '../user-token'\nimport Sentry from '../../Sentry'\nimport prepareSubmissionData from '../prepareSubmissionData'\nimport { DraftSubmission, ProgressListener } from '../../types/submissions'\nimport generateOneBlinkUploader from '../generateOneBlinkUploader'\nimport { OneBlinkStorageError } from '@oneblink/storage'\nimport generateOneBlinkDownloader from '../generateOneBlinkDownloader'\n\nasync function uploadDraftData(\n draftSubmission: DraftSubmission,\n onProgress?: ProgressListener,\n abortSignal?: AbortSignal,\n) {\n try {\n const submission = await prepareSubmissionData(draftSubmission)\n const oneblinkUploader = generateOneBlinkUploader()\n const userToken = getUserToken()\n console.log('Attempting to upload draft data')\n return await oneblinkUploader.uploadFormSubmissionDraft({\n submission,\n definition: draftSubmission.definition,\n device: getDeviceInformation(),\n userToken: userToken || undefined,\n previousFormSubmissionApprovalId:\n draftSubmission.previousFormSubmissionApprovalId,\n jobId: draftSubmission.jobId,\n formsAppId: draftSubmission.formsAppId,\n externalId: draftSubmission.externalId,\n taskId: draftSubmission.taskCompletion?.task.taskId,\n taskActionId: draftSubmission.taskCompletion?.taskAction.taskActionId,\n taskGroupInstanceId:\n draftSubmission.taskCompletion?.taskGroupInstance?.taskGroupInstanceId,\n formSubmissionDraftId: draftSubmission.formSubmissionDraftId,\n createdAt: draftSubmission.createdAt,\n title: draftSubmission.title,\n lastElementUpdated: draftSubmission.lastElementUpdated,\n sectionState: draftSubmission.sectionState,\n previousElapsedDurationSeconds:\n draftSubmission.previousElapsedDurationSeconds,\n onProgress,\n abortSignal,\n })\n } catch (error) {\n console.warn('Error occurred while attempting to upload draft data', error)\n Sentry.captureException(error)\n if (error instanceof OneBlinkStorageError) {\n switch (error.httpStatusCode) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot save drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n requiresLogin: true,\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n requiresAccessRequest: true,\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application your attempting upload a draft for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Application',\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error instanceof Error ? error : undefined,\n },\n )\n }\n}\n\nasync function getFormSubmissionDrafts(\n formsAppId: number,\n abortSignal?: AbortSignal,\n): Promise<SubmissionTypes.FormSubmissionDraft[]> {\n if (!isLoggedIn()) {\n console.log(\n 'Could not retrieve drafts from API as the current user is not logged in.',\n )\n return []\n }\n\n const url = new URL('/form-submission-drafts', tenants.current.apiOrigin)\n url.searchParams.append('formsAppId', formsAppId.toString())\n url.searchParams.append('isSubmitted', 'false')\n console.log('Attempting to retrieve drafts from API', url.href)\n\n try {\n const { formSubmissionDrafts } = await getRequest<{\n formSubmissionDrafts: SubmissionTypes.FormSubmissionDraft[]\n }>(url.href, abortSignal)\n return formSubmissionDrafts\n } catch (err) {\n console.warn(\n 'Error occurred while attempting to retrieve drafts from API',\n err,\n )\n if (err instanceof OneBlinkAppsError) {\n throw err\n }\n\n const error = err as HTTPError\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot retrieve your drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresAccessRequest: true,\n },\n )\n }\n case 400:\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the application your attempting retrieve drafts for. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Error Syncing Drafts',\n httpStatusCode: error.status,\n },\n )\n }\n default: {\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error,\n },\n )\n }\n }\n }\n}\n\nasync function downloadDraftData(\n formSubmissionDraft: SubmissionTypes.FormSubmissionDraft,\n latestFormSubmissionDraftVersion: SubmissionTypes.FormSubmissionDraftVersion,\n abortSignal?: AbortSignal,\n): Promise<DraftSubmission | undefined> {\n try {\n console.log('Attempting to download draft form data:', {\n formSubmissionDraftVersionId: latestFormSubmissionDraftVersion.id,\n })\n const oneblinkDownloader = generateOneBlinkDownloader()\n const s3SubmissionData = await oneblinkDownloader.downloadDraftSubmission({\n formSubmissionDraftVersionId: latestFormSubmissionDraftVersion.id,\n abortSignal,\n })\n if (!s3SubmissionData) {\n return undefined\n }\n return {\n definition: s3SubmissionData.definition,\n submission: s3SubmissionData.submission,\n lastElementUpdated: s3SubmissionData.lastElementUpdated,\n // Drafts will always have a formsAppId, so we can safely cast to number\n formsAppId: s3SubmissionData.formsAppId as number,\n jobId: formSubmissionDraft.jobId,\n externalId: formSubmissionDraft.externalId,\n previousFormSubmissionApprovalId:\n formSubmissionDraft.previousFormSubmissionApprovalId,\n taskCompletion: s3SubmissionData.task &&\n s3SubmissionData.taskAction && {\n task: s3SubmissionData.task,\n taskAction: s3SubmissionData.taskAction,\n taskGroup: s3SubmissionData.taskGroup,\n taskGroupInstance: s3SubmissionData.taskGroupInstance,\n redirectUrl: '',\n },\n title: latestFormSubmissionDraftVersion.title,\n createdAt: latestFormSubmissionDraftVersion.createdAt,\n formSubmissionDraftId: formSubmissionDraft.id,\n sectionState: s3SubmissionData.sectionState,\n previousElapsedDurationSeconds:\n s3SubmissionData.previousElapsedDurationSeconds,\n }\n } catch (error) {\n if (abortSignal?.aborted) {\n return undefined\n }\n\n console.error(\n 'Error occurred while attempting to download draft data',\n error,\n )\n\n if (error instanceof OneBlinkAppsError) {\n throw error\n }\n\n Sentry.captureException(error)\n\n if (error instanceof OneBlinkStorageError) {\n switch (error.httpStatusCode) {\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n originalError: error,\n title: 'Invalid Request',\n httpStatusCode: error.httpStatusCode,\n })\n }\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot retrieve draft data until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.httpStatusCode,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.httpStatusCode,\n requiresAccessRequest: true,\n },\n )\n }\n case 404: {\n throw new OneBlinkAppsError(\n 'We could not find the draft your attempting retrieve. Please contact your administrator to ensure your application configuration has been completed successfully.',\n {\n originalError: error,\n title: 'Unknown Draft',\n httpStatusCode: error.httpStatusCode,\n },\n )\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n title: 'Unexpected Error',\n originalError: error instanceof Error ? error : undefined,\n httpStatusCode:\n error instanceof OneBlinkStorageError\n ? error.httpStatusCode\n : undefined,\n },\n )\n }\n}\n\nasync function deleteFormSubmissionDraft(\n formSubmissionDraftId: string,\n abortSignal?: AbortSignal,\n) {\n const url = `${tenants.current.apiOrigin}/form-submission-drafts/${formSubmissionDraftId}`\n console.log('Attempting to delete form submission draft remotely', url)\n try {\n await deleteRequest(url, abortSignal)\n } catch (error) {\n console.warn(\n 'Error occurred while attempting to delete a draft from API',\n error,\n )\n if (error instanceof OneBlinkAppsError) {\n throw error\n }\n\n Sentry.captureException(error)\n\n if (error instanceof HTTPError) {\n switch (error.status) {\n case 401: {\n throw new OneBlinkAppsError(\n 'You cannot delete drafts until you have logged in. Please login and try again.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresLogin: true,\n },\n )\n }\n case 403: {\n throw new OneBlinkAppsError(\n 'You do not have access to drafts for this application. Please contact your administrator to gain the correct level of access.',\n {\n originalError: error,\n httpStatusCode: error.status,\n requiresAccessRequest: true,\n },\n )\n }\n case 400: {\n throw new OneBlinkAppsError(error.message, {\n originalError: error,\n title: 'Invalid Request',\n httpStatusCode: error.status,\n })\n }\n case 404: {\n console.warn(\n 'Remote draft does not exist, we will assume it has already been deleted.',\n formSubmissionDraftId,\n error,\n )\n return\n }\n }\n }\n\n throw new OneBlinkAppsError(\n 'An unknown error has occurred. Please contact support if the problem persists.',\n {\n originalError: error as Error,\n },\n )\n }\n}\n\nexport {\n uploadDraftData,\n getFormSubmissionDrafts,\n downloadDraftData,\n deleteFormSubmissionDraft,\n}\n"]}
@@ -13,4 +13,4 @@ export declare function deleteDraftData(formSubmissionDraftId: string, abortSign
13
13
  hasDeletedRemoteDraft: boolean;
14
14
  }>;
15
15
  export declare function getLatestFormSubmissionDraftVersion(versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined): SubmissionTypes.FormSubmissionDraftVersion | undefined;
16
- export declare function getDraftSubmission(formSubmissionDraft: SubmissionTypes.FormSubmissionDraft, abortSignal?: AbortSignal): Promise<DraftSubmission | undefined>;
16
+ export declare function getDraftSubmission(formSubmissionDraft: SubmissionTypes.FormSubmissionDraft, abortSignal: AbortSignal | undefined): Promise<DraftSubmission | undefined>;
@@ -75,41 +75,23 @@ export function getLatestFormSubmissionDraftVersion(versions) {
75
75
  }
76
76
  export async function getDraftSubmission(formSubmissionDraft, abortSignal) {
77
77
  const latestFormSubmissionDraftVersion = getLatestFormSubmissionDraftVersion(formSubmissionDraft.versions);
78
- const draftSubmission = await getLocalDraftSubmission(formSubmissionDraft.id);
78
+ const localDraftSubmission = await getLocalDraftSubmission(formSubmissionDraft.id);
79
79
  // If there is local data and no server data, return local data.
80
80
  // Or if the latest server version of the draft is what
81
81
  // is currently saved locally, return local data.
82
- if (draftSubmission &&
82
+ if (localDraftSubmission &&
83
83
  (!latestFormSubmissionDraftVersion ||
84
- latestFormSubmissionDraftVersion.createdAt <= draftSubmission.createdAt)) {
85
- return draftSubmission;
84
+ latestFormSubmissionDraftVersion.createdAt <=
85
+ localDraftSubmission.createdAt)) {
86
+ return localDraftSubmission;
86
87
  }
87
88
  if (!latestFormSubmissionDraftVersion) {
88
89
  return undefined;
89
90
  }
90
- //drafts will always have a formsAppId
91
- const s3SubmissionData = (await downloadDraftData(latestFormSubmissionDraftVersion.id, abortSignal));
92
- return await setLocalDraftSubmission({
93
- definition: s3SubmissionData.definition,
94
- submission: s3SubmissionData.submission,
95
- lastElementUpdated: s3SubmissionData.lastElementUpdated,
96
- formsAppId: s3SubmissionData.formsAppId,
97
- jobId: formSubmissionDraft.jobId,
98
- externalId: formSubmissionDraft.externalId,
99
- previousFormSubmissionApprovalId: formSubmissionDraft.previousFormSubmissionApprovalId,
100
- taskCompletion: s3SubmissionData.task &&
101
- s3SubmissionData.taskAction && {
102
- task: s3SubmissionData.task,
103
- taskAction: s3SubmissionData.taskAction,
104
- taskGroup: s3SubmissionData.taskGroup,
105
- taskGroupInstance: s3SubmissionData.taskGroupInstance,
106
- redirectUrl: '',
107
- },
108
- title: latestFormSubmissionDraftVersion.title,
109
- createdAt: latestFormSubmissionDraftVersion.createdAt,
110
- formSubmissionDraftId: formSubmissionDraft.id,
111
- sectionState: s3SubmissionData.sectionState,
112
- previousElapsedDurationSeconds: s3SubmissionData.previousElapsedDurationSeconds,
113
- });
91
+ const draftSubmission = await downloadDraftData(formSubmissionDraft, latestFormSubmissionDraftVersion, abortSignal);
92
+ if (draftSubmission) {
93
+ await setLocalDraftSubmission(draftSubmission);
94
+ }
95
+ return draftSubmission;
114
96
  }
115
97
  //# sourceMappingURL=draft-data-store.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"draft-data-store.js","sourceRoot":"","sources":["../../../src/apps/services/draft-data-store.ts"],"names":[],"mappings":"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","sourcesContent":["import utilsService from './utils'\n\nimport {\n uploadDraftData,\n downloadDraftData,\n deleteFormSubmissionDraft,\n} from './api/drafts'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from '../Sentry'\nimport { DraftSubmission, ProgressListener } from '../types/submissions'\nimport { deleteAutoSaveData } from '../auto-save-service'\n\nfunction getLocalDraftSubmissionKey(formSubmissionDraftId: string) {\n return `DRAFT_SUBMISSION_${formSubmissionDraftId}`\n}\n\nexport async function getLocalDraftSubmission(\n formSubmissionDraftId: string | undefined,\n): Promise<DraftSubmission | null> {\n if (!formSubmissionDraftId) {\n return null\n }\n const key = getLocalDraftSubmissionKey(formSubmissionDraftId)\n return utilsService.getLocalForageItem(key)\n}\n\nasync function setLocalDraftSubmission(\n draftSubmission: DraftSubmission,\n): Promise<DraftSubmission> {\n const key = getLocalDraftSubmissionKey(draftSubmission.formSubmissionDraftId)\n return utilsService.setLocalForageItem(key, draftSubmission)\n}\n\nexport async function removeLocalDraftSubmission(\n formSubmissionDraftId: undefined | null | string,\n): Promise<void> {\n if (!formSubmissionDraftId) {\n return\n }\n const key = getLocalDraftSubmissionKey(formSubmissionDraftId)\n return utilsService.removeLocalForageItem(key)\n}\n\nexport async function saveDraftSubmission({\n draftSubmission,\n autoSaveKey,\n onProgress,\n abortSignal,\n skipUpload,\n}: {\n draftSubmission: DraftSubmission\n autoSaveKey: string | undefined\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n skipUpload?: boolean\n}): Promise<SubmissionTypes.FormSubmissionDraftVersion | undefined> {\n await setLocalDraftSubmission(draftSubmission)\n\n if (draftSubmission.backgroundUpload) {\n return\n }\n\n try {\n if (!skipUpload) {\n return await uploadDraftData(draftSubmission, onProgress, abortSignal)\n }\n } catch (error) {\n // Ignoring all errors here as we don't want draft submission data\n // being saved to the cloud to prevent drafts from being saved on the device\n console.warn('Could not upload Draft Data as JSON', error)\n Sentry.captureException(error)\n } finally {\n if (typeof autoSaveKey === 'string') {\n try {\n await deleteAutoSaveData(draftSubmission.definition.id, autoSaveKey)\n } catch (error) {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n }\n }\n }\n}\n\nexport async function deleteDraftData(\n formSubmissionDraftId: string,\n abortSignal?: AbortSignal,\n): Promise<{ hasDeletedRemoteDraft: boolean }> {\n try {\n await deleteFormSubmissionDraft(formSubmissionDraftId, abortSignal)\n return {\n hasDeletedRemoteDraft: true,\n }\n } catch (error) {\n console.warn(\n 'Could not delete remote draft, will attempt to delete again later.',\n error,\n )\n return {\n hasDeletedRemoteDraft: false,\n }\n }\n}\n\nexport function getLatestFormSubmissionDraftVersion(\n versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined,\n) {\n return versions?.reduce<\n SubmissionTypes.FormSubmissionDraftVersion | undefined\n >((memo, formSubmissionDraftVersion) => {\n if (!memo || formSubmissionDraftVersion.createdAt > memo.createdAt) {\n return formSubmissionDraftVersion\n }\n return memo\n }, undefined)\n}\n\nexport async function getDraftSubmission(\n formSubmissionDraft: SubmissionTypes.FormSubmissionDraft,\n abortSignal?: AbortSignal,\n): Promise<DraftSubmission | undefined> {\n const latestFormSubmissionDraftVersion = getLatestFormSubmissionDraftVersion(\n formSubmissionDraft.versions,\n )\n const draftSubmission = await getLocalDraftSubmission(formSubmissionDraft.id)\n\n // If there is local data and no server data, return local data.\n // Or if the latest server version of the draft is what\n // is currently saved locally, return local data.\n if (\n draftSubmission &&\n (!latestFormSubmissionDraftVersion ||\n latestFormSubmissionDraftVersion.createdAt <= draftSubmission.createdAt)\n ) {\n return draftSubmission\n }\n\n if (!latestFormSubmissionDraftVersion) {\n return undefined\n }\n\n //drafts will always have a formsAppId\n const s3SubmissionData = (await downloadDraftData(\n latestFormSubmissionDraftVersion.id,\n abortSignal,\n )) as Omit<SubmissionTypes.S3SubmissionData, 'formsAppId'> & {\n formsAppId: number\n }\n return await setLocalDraftSubmission({\n definition: s3SubmissionData.definition,\n submission: s3SubmissionData.submission,\n lastElementUpdated: s3SubmissionData.lastElementUpdated,\n formsAppId: s3SubmissionData.formsAppId,\n jobId: formSubmissionDraft.jobId,\n externalId: formSubmissionDraft.externalId,\n previousFormSubmissionApprovalId:\n formSubmissionDraft.previousFormSubmissionApprovalId,\n taskCompletion: s3SubmissionData.task &&\n s3SubmissionData.taskAction && {\n task: s3SubmissionData.task,\n taskAction: s3SubmissionData.taskAction,\n taskGroup: s3SubmissionData.taskGroup,\n taskGroupInstance: s3SubmissionData.taskGroupInstance,\n redirectUrl: '',\n },\n title: latestFormSubmissionDraftVersion.title,\n createdAt: latestFormSubmissionDraftVersion.createdAt,\n formSubmissionDraftId: formSubmissionDraft.id,\n sectionState: s3SubmissionData.sectionState,\n previousElapsedDurationSeconds:\n s3SubmissionData.previousElapsedDurationSeconds,\n })\n}\n"]}
1
+ {"version":3,"file":"draft-data-store.js","sourceRoot":"","sources":["../../../src/apps/services/draft-data-store.ts"],"names":[],"mappings":"AAAA,OAAO,YAAY,MAAM,SAAS,CAAA;AAElC,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,yBAAyB,GAC1B,MAAM,cAAc,CAAA;AAErB,OAAO,MAAM,MAAM,WAAW,CAAA;AAE9B,OAAO,EAAE,kBAAkB,EAAE,MAAM,sBAAsB,CAAA;AAEzD,SAAS,0BAA0B,CAAC,qBAA6B;IAC/D,OAAO,oBAAoB,qBAAqB,EAAE,CAAA;AACpD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAC3C,qBAAyC;IAEzC,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAO,IAAI,CAAA;IACb,CAAC;IACD,MAAM,GAAG,GAAG,0BAA0B,CAAC,qBAAqB,CAAC,CAAA;IAC7D,OAAO,YAAY,CAAC,kBAAkB,CAAC,GAAG,CAAC,CAAA;AAC7C,CAAC;AAED,KAAK,UAAU,uBAAuB,CACpC,eAAgC;IAEhC,MAAM,GAAG,GAAG,0BAA0B,CAAC,eAAe,CAAC,qBAAqB,CAAC,CAAA;IAC7E,OAAO,YAAY,CAAC,kBAAkB,CAAC,GAAG,EAAE,eAAe,CAAC,CAAA;AAC9D,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,0BAA0B,CAC9C,qBAAgD;IAEhD,IAAI,CAAC,qBAAqB,EAAE,CAAC;QAC3B,OAAM;IACR,CAAC;IACD,MAAM,GAAG,GAAG,0BAA0B,CAAC,qBAAqB,CAAC,CAAA;IAC7D,OAAO,YAAY,CAAC,qBAAqB,CAAC,GAAG,CAAC,CAAA;AAChD,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,mBAAmB,CAAC,EACxC,eAAe,EACf,WAAW,EACX,UAAU,EACV,WAAW,EACX,UAAU,GAOX;IACC,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IAE9C,IAAI,eAAe,CAAC,gBAAgB,EAAE,CAAC;QACrC,OAAM;IACR,CAAC;IAED,IAAI,CAAC;QACH,IAAI,CAAC,UAAU,EAAE,CAAC;YAChB,OAAO,MAAM,eAAe,CAAC,eAAe,EAAE,UAAU,EAAE,WAAW,CAAC,CAAA;QACxE,CAAC;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,kEAAkE;QAClE,4EAA4E;QAC5E,OAAO,CAAC,IAAI,CAAC,qCAAqC,EAAE,KAAK,CAAC,CAAA;QAC1D,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;IAChC,CAAC;YAAS,CAAC;QACT,IAAI,OAAO,WAAW,KAAK,QAAQ,EAAE,CAAC;YACpC,IAAI,CAAC;gBACH,MAAM,kBAAkB,CAAC,eAAe,CAAC,UAAU,CAAC,EAAE,EAAE,WAAW,CAAC,CAAA;YACtE,CAAC;YAAC,OAAO,KAAK,EAAE,CAAC;gBACf,OAAO,CAAC,IAAI,CAAC,iCAAiC,EAAE,KAAK,CAAC,CAAA;gBACtD,MAAM,CAAC,gBAAgB,CAAC,KAAK,CAAC,CAAA;YAChC,CAAC;QACH,CAAC;IACH,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,eAAe,CACnC,qBAA6B,EAC7B,WAAyB;IAEzB,IAAI,CAAC;QACH,MAAM,yBAAyB,CAAC,qBAAqB,EAAE,WAAW,CAAC,CAAA;QACnE,OAAO;YACL,qBAAqB,EAAE,IAAI;SAC5B,CAAA;IACH,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,CAAC,IAAI,CACV,oEAAoE,EACpE,KAAK,CACN,CAAA;QACD,OAAO;YACL,qBAAqB,EAAE,KAAK;SAC7B,CAAA;IACH,CAAC;AACH,CAAC;AAED,MAAM,UAAU,mCAAmC,CACjD,QAAkE;IAElE,OAAO,QAAQ,aAAR,QAAQ,uBAAR,QAAQ,CAAE,MAAM,CAErB,CAAC,IAAI,EAAE,0BAA0B,EAAE,EAAE;QACrC,IAAI,CAAC,IAAI,IAAI,0BAA0B,CAAC,SAAS,GAAG,IAAI,CAAC,SAAS,EAAE,CAAC;YACnE,OAAO,0BAA0B,CAAA;QACnC,CAAC;QACD,OAAO,IAAI,CAAA;IACb,CAAC,EAAE,SAAS,CAAC,CAAA;AACf,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,kBAAkB,CACtC,mBAAwD,EACxD,WAAoC;IAEpC,MAAM,gCAAgC,GAAG,mCAAmC,CAC1E,mBAAmB,CAAC,QAAQ,CAC7B,CAAA;IACD,MAAM,oBAAoB,GAAG,MAAM,uBAAuB,CACxD,mBAAmB,CAAC,EAAE,CACvB,CAAA;IAED,gEAAgE;IAChE,uDAAuD;IACvD,iDAAiD;IACjD,IACE,oBAAoB;QACpB,CAAC,CAAC,gCAAgC;YAChC,gCAAgC,CAAC,SAAS;gBACxC,oBAAoB,CAAC,SAAS,CAAC,EACnC,CAAC;QACD,OAAO,oBAAoB,CAAA;IAC7B,CAAC;IAED,IAAI,CAAC,gCAAgC,EAAE,CAAC;QACtC,OAAO,SAAS,CAAA;IAClB,CAAC;IAED,MAAM,eAAe,GAAG,MAAM,iBAAiB,CAC7C,mBAAmB,EACnB,gCAAgC,EAChC,WAAW,CACZ,CAAA;IACD,IAAI,eAAe,EAAE,CAAC;QACpB,MAAM,uBAAuB,CAAC,eAAe,CAAC,CAAA;IAChD,CAAC;IACD,OAAO,eAAe,CAAA;AACxB,CAAC","sourcesContent":["import utilsService from './utils'\n\nimport {\n uploadDraftData,\n downloadDraftData,\n deleteFormSubmissionDraft,\n} from './api/drafts'\nimport { SubmissionTypes } from '@oneblink/types'\nimport Sentry from '../Sentry'\nimport { DraftSubmission, ProgressListener } from '../types/submissions'\nimport { deleteAutoSaveData } from '../auto-save-service'\n\nfunction getLocalDraftSubmissionKey(formSubmissionDraftId: string) {\n return `DRAFT_SUBMISSION_${formSubmissionDraftId}`\n}\n\nexport async function getLocalDraftSubmission(\n formSubmissionDraftId: string | undefined,\n): Promise<DraftSubmission | null> {\n if (!formSubmissionDraftId) {\n return null\n }\n const key = getLocalDraftSubmissionKey(formSubmissionDraftId)\n return utilsService.getLocalForageItem(key)\n}\n\nasync function setLocalDraftSubmission(\n draftSubmission: DraftSubmission,\n): Promise<DraftSubmission> {\n const key = getLocalDraftSubmissionKey(draftSubmission.formSubmissionDraftId)\n return utilsService.setLocalForageItem(key, draftSubmission)\n}\n\nexport async function removeLocalDraftSubmission(\n formSubmissionDraftId: undefined | null | string,\n): Promise<void> {\n if (!formSubmissionDraftId) {\n return\n }\n const key = getLocalDraftSubmissionKey(formSubmissionDraftId)\n return utilsService.removeLocalForageItem(key)\n}\n\nexport async function saveDraftSubmission({\n draftSubmission,\n autoSaveKey,\n onProgress,\n abortSignal,\n skipUpload,\n}: {\n draftSubmission: DraftSubmission\n autoSaveKey: string | undefined\n onProgress?: ProgressListener\n abortSignal?: AbortSignal\n skipUpload?: boolean\n}): Promise<SubmissionTypes.FormSubmissionDraftVersion | undefined> {\n await setLocalDraftSubmission(draftSubmission)\n\n if (draftSubmission.backgroundUpload) {\n return\n }\n\n try {\n if (!skipUpload) {\n return await uploadDraftData(draftSubmission, onProgress, abortSignal)\n }\n } catch (error) {\n // Ignoring all errors here as we don't want draft submission data\n // being saved to the cloud to prevent drafts from being saved on the device\n console.warn('Could not upload Draft Data as JSON', error)\n Sentry.captureException(error)\n } finally {\n if (typeof autoSaveKey === 'string') {\n try {\n await deleteAutoSaveData(draftSubmission.definition.id, autoSaveKey)\n } catch (error) {\n console.warn('Error removing auto save data: ', error)\n Sentry.captureException(error)\n }\n }\n }\n}\n\nexport async function deleteDraftData(\n formSubmissionDraftId: string,\n abortSignal?: AbortSignal,\n): Promise<{ hasDeletedRemoteDraft: boolean }> {\n try {\n await deleteFormSubmissionDraft(formSubmissionDraftId, abortSignal)\n return {\n hasDeletedRemoteDraft: true,\n }\n } catch (error) {\n console.warn(\n 'Could not delete remote draft, will attempt to delete again later.',\n error,\n )\n return {\n hasDeletedRemoteDraft: false,\n }\n }\n}\n\nexport function getLatestFormSubmissionDraftVersion(\n versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined,\n) {\n return versions?.reduce<\n SubmissionTypes.FormSubmissionDraftVersion | undefined\n >((memo, formSubmissionDraftVersion) => {\n if (!memo || formSubmissionDraftVersion.createdAt > memo.createdAt) {\n return formSubmissionDraftVersion\n }\n return memo\n }, undefined)\n}\n\nexport async function getDraftSubmission(\n formSubmissionDraft: SubmissionTypes.FormSubmissionDraft,\n abortSignal: AbortSignal | undefined,\n): Promise<DraftSubmission | undefined> {\n const latestFormSubmissionDraftVersion = getLatestFormSubmissionDraftVersion(\n formSubmissionDraft.versions,\n )\n const localDraftSubmission = await getLocalDraftSubmission(\n formSubmissionDraft.id,\n )\n\n // If there is local data and no server data, return local data.\n // Or if the latest server version of the draft is what\n // is currently saved locally, return local data.\n if (\n localDraftSubmission &&\n (!latestFormSubmissionDraftVersion ||\n latestFormSubmissionDraftVersion.createdAt <=\n localDraftSubmission.createdAt)\n ) {\n return localDraftSubmission\n }\n\n if (!latestFormSubmissionDraftVersion) {\n return undefined\n }\n\n const draftSubmission = await downloadDraftData(\n formSubmissionDraft,\n latestFormSubmissionDraftVersion,\n abortSignal,\n )\n if (draftSubmission) {\n await setLocalDraftSubmission(draftSubmission)\n }\n return draftSubmission\n}\n"]}
@@ -86,14 +86,17 @@ export type LocalFormSubmissionDraft = Omit<SubmissionTypes.FormSubmissionDraft,
86
86
  * remotely yet.
87
87
  */
88
88
  versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined;
89
- /**
90
- * The draft submission data. `undefined` if it has not been downloaded
91
- * locally yet.
92
- */
93
- draftSubmission: DraftSubmission | undefined;
94
89
  /** `true` if the draft was created by a public user (not logged in). */
95
90
  isPublic?: boolean;
96
- };
91
+ } & ({
92
+ downloadStatus: 'PENDING' | 'DOWNLOADING' | 'NOT_AVAILABLE';
93
+ } | {
94
+ downloadStatus: 'ERROR';
95
+ downloadError: string;
96
+ } | {
97
+ downloadStatus: 'SUCCESS';
98
+ draftSubmission: DraftSubmission;
99
+ });
97
100
  export type FormSubmission = NewFormSubmission & BaseFormSubmission & {
98
101
  /** The id of the Forms App submitting for */
99
102
  formsAppId?: number;
@@ -1 +1 @@
1
- {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/apps/types/submissions.ts"],"names":[],"mappings":"","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n ScheduledTasksTypes,\n} from '@oneblink/types'\nimport { FormElement } from '@oneblink/types/typescript/forms'\n\nexport { ProgressListener, ProgressListenerEvent } from '@oneblink/storage'\n\nexport type BaseNewFormSubmission = {\n /** The submission data */\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** The form definition when the draft was saved */\n definition: FormTypes.Form\n}\n\nexport type NewDraftSubmission = BaseNewFormSubmission & {\n /**\n * Set to true if the submission should be uploaded in the background, false\n * or undefined if the submission should be uploaded immediately\n */\n backgroundUpload?: boolean\n /** The element that was last updated before the draft was saved */\n lastElementUpdated?: FormElement\n /** The state of sections before the draft was saved */\n sectionState?: SubmissionTypes.NewS3SubmissionData['sectionState']\n /**\n * The elapsed duration in seconds the user took to complete the submission\n * before the draft was saved\n */\n\n previousElapsedDurationSeconds?: SubmissionTypes.NewS3SubmissionData['previousElapsedDurationSeconds']\n}\n\nexport type NewFormSubmission = BaseNewFormSubmission & {\n /** The reCAPTCHA tokens to validate the submission */\n recaptchas?: Array<{\n /** The site key that was used to generate the reCAPTCHA token */\n siteKey: string\n /** A reCAPTCHA token */\n token: string\n }>\n}\n\nexport type BaseFormSubmission = {\n /** The id of the job to submit */\n jobId?: string\n /** The id of the Forms App submitting for */\n externalId?: string\n /**\n * The id of the previous form submission approval id. Only used when the form\n * submission is in response to `CLARIFICATION_REQUIRED` approval.\n */\n previousFormSubmissionApprovalId?: string\n /**\n * Will have a value if the user was attempting to complete a scheduled task\n * via a form submission\n */\n taskCompletion?: {\n /** The task */\n task: ScheduledTasksTypes.Task\n /** The task action */\n taskAction: ScheduledTasksTypes.TaskAction\n /** The task group */\n taskGroup: ScheduledTasksTypes.TaskGroup | undefined\n /** The task group instance */\n taskGroupInstance: ScheduledTasksTypes.TaskGroupInstance | undefined\n /**\n * The URL to redirect the user to after completing the task via form\n * submission\n */\n redirectUrl: string\n }\n}\n\nexport type DraftSubmissionInput = NewDraftSubmission &\n BaseFormSubmission & {\n /** The id of the Forms App submitting for */\n formsAppId: number\n /** The title input by a user to identify the draft. */\n title: string\n }\n\nexport type DraftSubmission = DraftSubmissionInput & {\n /**\n * The date and time (in ISO format) when this version of the draft was\n * created.\n */\n createdAt: string\n /**\n * The identifier for the parent draft record. Created client side to store\n * the draft locally for offline capability\n */\n formSubmissionDraftId: string\n}\n\nexport type LocalFormSubmissionDraft = Omit<\n SubmissionTypes.FormSubmissionDraft,\n 'id' | 'versions'\n> & {\n /**\n * The versions of the draft data. `undefined` if it has not been uploaded\n * remotely yet.\n */\n versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined\n /**\n * The draft submission data. `undefined` if it has not been downloaded\n * locally yet.\n */\n draftSubmission: DraftSubmission | undefined\n /** `true` if the draft was created by a public user (not logged in). */\n isPublic?: boolean\n}\n\nexport type FormSubmission = NewFormSubmission &\n BaseFormSubmission & {\n /** The id of the Forms App submitting for */\n formsAppId?: number\n /** The id of the draft to clean up after successful submission */\n formSubmissionDraftId?: string\n /** The id of the prefill data to clean up after successful submission */\n preFillFormDataId: string | null\n }\n\nexport type FormSubmissionResult = FormSubmission & {\n /**\n * The identifier that represents the submission. `null` if the form\n * submission was unsuccessful\n */\n submissionId: string | null\n /**\n * The timestamp the form was submitted, `null` if the form submission was\n * unsuccessful\n */\n submissionTimestamp: string | null\n /** `null` if the form submission does not require a payment */\n payment: {\n /** The amount required to pay */\n amount: number\n /** The URL to redirect the user to after payment to display a receipt */\n paymentReceiptUrl: string\n /**\n * The URL to redirect the user to to make a payment for a form hosted by\n * customer instead of payment provider\n */\n paymentFormUrl: string | undefined\n /** The URL to redirect the user to to complete the payment process */\n hostedFormUrl: string\n /** The payment submission event */\n submissionEvent: SubmissionEventTypes.FormPaymentEvent\n } | null\n /** `null` if the form submission does not require a booking */\n scheduling: {\n /** The URL to redirect the user to to complete the booking process */\n bookingUrl: string\n /** The scheduling submission event */\n submissionEvent: SubmissionEventTypes.FormSchedulingEvent\n } | null\n /**\n * `true` if the submission was not submitted yet and was added to the pending\n * queue\n */\n isInPendingQueue: boolean\n /** `true` if the submission was attempted offline */\n isOffline: boolean\n /** True if the submission was attempted whilst attachments were uploading */\n isUploadingAttachments: boolean\n /** Exists if the form allows PDF download */\n /**\n * @deprecated Only returned when legacy post submission download\n * configuration is in use. For non legacy configured forms, use\n * `downloadSubmissionPdfs` instead.\n */\n downloadSubmissionPdfUrl?: string\n\n downloadSubmissionPdfs?: Array<{\n id: string\n configuration: SubmissionEventTypes.PDFConfiguration\n url: string\n }>\n /** The access token to download post-submission attachment urls and metadata. */\n attachmentsAccessToken?: string\n}\n\nexport type PendingFormSubmission = FormSubmission & {\n /** The date and time (in ISO format) the submission was attempted */\n pendingTimestamp: string\n /** `true` if the submission is currently being processed by the pending queue */\n isSubmitting?: boolean\n /** `true` if the submission is currently being edited */\n isEditing?: boolean\n /**\n * An error message that might be set while attempting to process the\n * submission in the pending queue\n */\n error?: string\n}\n"]}
1
+ {"version":3,"file":"submissions.js","sourceRoot":"","sources":["../../../src/apps/types/submissions.ts"],"names":[],"mappings":"","sourcesContent":["import {\n FormTypes,\n SubmissionEventTypes,\n SubmissionTypes,\n ScheduledTasksTypes,\n} from '@oneblink/types'\nimport { FormElement } from '@oneblink/types/typescript/forms'\n\nexport { ProgressListener, ProgressListenerEvent } from '@oneblink/storage'\n\nexport type BaseNewFormSubmission = {\n /** The submission data */\n submission: SubmissionTypes.S3SubmissionData['submission']\n /** The form definition when the draft was saved */\n definition: FormTypes.Form\n}\n\nexport type NewDraftSubmission = BaseNewFormSubmission & {\n /**\n * Set to true if the submission should be uploaded in the background, false\n * or undefined if the submission should be uploaded immediately\n */\n backgroundUpload?: boolean\n /** The element that was last updated before the draft was saved */\n lastElementUpdated?: FormElement\n /** The state of sections before the draft was saved */\n sectionState?: SubmissionTypes.NewS3SubmissionData['sectionState']\n /**\n * The elapsed duration in seconds the user took to complete the submission\n * before the draft was saved\n */\n\n previousElapsedDurationSeconds?: SubmissionTypes.NewS3SubmissionData['previousElapsedDurationSeconds']\n}\n\nexport type NewFormSubmission = BaseNewFormSubmission & {\n /** The reCAPTCHA tokens to validate the submission */\n recaptchas?: Array<{\n /** The site key that was used to generate the reCAPTCHA token */\n siteKey: string\n /** A reCAPTCHA token */\n token: string\n }>\n}\n\nexport type BaseFormSubmission = {\n /** The id of the job to submit */\n jobId?: string\n /** The id of the Forms App submitting for */\n externalId?: string\n /**\n * The id of the previous form submission approval id. Only used when the form\n * submission is in response to `CLARIFICATION_REQUIRED` approval.\n */\n previousFormSubmissionApprovalId?: string\n /**\n * Will have a value if the user was attempting to complete a scheduled task\n * via a form submission\n */\n taskCompletion?: {\n /** The task */\n task: ScheduledTasksTypes.Task\n /** The task action */\n taskAction: ScheduledTasksTypes.TaskAction\n /** The task group */\n taskGroup: ScheduledTasksTypes.TaskGroup | undefined\n /** The task group instance */\n taskGroupInstance: ScheduledTasksTypes.TaskGroupInstance | undefined\n /**\n * The URL to redirect the user to after completing the task via form\n * submission\n */\n redirectUrl: string\n }\n}\n\nexport type DraftSubmissionInput = NewDraftSubmission &\n BaseFormSubmission & {\n /** The id of the Forms App submitting for */\n formsAppId: number\n /** The title input by a user to identify the draft. */\n title: string\n }\n\nexport type DraftSubmission = DraftSubmissionInput & {\n /**\n * The date and time (in ISO format) when this version of the draft was\n * created.\n */\n createdAt: string\n /**\n * The identifier for the parent draft record. Created client side to store\n * the draft locally for offline capability\n */\n formSubmissionDraftId: string\n}\n\nexport type LocalFormSubmissionDraft = Omit<\n SubmissionTypes.FormSubmissionDraft,\n 'id' | 'versions'\n> & {\n /**\n * The versions of the draft data. `undefined` if it has not been uploaded\n * remotely yet.\n */\n versions: SubmissionTypes.FormSubmissionDraftVersion[] | undefined\n /** `true` if the draft was created by a public user (not logged in). */\n isPublic?: boolean\n} & (\n | {\n downloadStatus: 'PENDING' | 'DOWNLOADING' | 'NOT_AVAILABLE'\n }\n | {\n downloadStatus: 'ERROR'\n downloadError: string\n }\n | {\n downloadStatus: 'SUCCESS'\n draftSubmission: DraftSubmission\n }\n )\n\nexport type FormSubmission = NewFormSubmission &\n BaseFormSubmission & {\n /** The id of the Forms App submitting for */\n formsAppId?: number\n /** The id of the draft to clean up after successful submission */\n formSubmissionDraftId?: string\n /** The id of the prefill data to clean up after successful submission */\n preFillFormDataId: string | null\n }\n\nexport type FormSubmissionResult = FormSubmission & {\n /**\n * The identifier that represents the submission. `null` if the form\n * submission was unsuccessful\n */\n submissionId: string | null\n /**\n * The timestamp the form was submitted, `null` if the form submission was\n * unsuccessful\n */\n submissionTimestamp: string | null\n /** `null` if the form submission does not require a payment */\n payment: {\n /** The amount required to pay */\n amount: number\n /** The URL to redirect the user to after payment to display a receipt */\n paymentReceiptUrl: string\n /**\n * The URL to redirect the user to to make a payment for a form hosted by\n * customer instead of payment provider\n */\n paymentFormUrl: string | undefined\n /** The URL to redirect the user to to complete the payment process */\n hostedFormUrl: string\n /** The payment submission event */\n submissionEvent: SubmissionEventTypes.FormPaymentEvent\n } | null\n /** `null` if the form submission does not require a booking */\n scheduling: {\n /** The URL to redirect the user to to complete the booking process */\n bookingUrl: string\n /** The scheduling submission event */\n submissionEvent: SubmissionEventTypes.FormSchedulingEvent\n } | null\n /**\n * `true` if the submission was not submitted yet and was added to the pending\n * queue\n */\n isInPendingQueue: boolean\n /** `true` if the submission was attempted offline */\n isOffline: boolean\n /** True if the submission was attempted whilst attachments were uploading */\n isUploadingAttachments: boolean\n /** Exists if the form allows PDF download */\n /**\n * @deprecated Only returned when legacy post submission download\n * configuration is in use. For non legacy configured forms, use\n * `downloadSubmissionPdfs` instead.\n */\n downloadSubmissionPdfUrl?: string\n\n downloadSubmissionPdfs?: Array<{\n id: string\n configuration: SubmissionEventTypes.PDFConfiguration\n url: string\n }>\n /** The access token to download post-submission attachment urls and metadata. */\n attachmentsAccessToken?: string\n}\n\nexport type PendingFormSubmission = FormSubmission & {\n /** The date and time (in ISO format) the submission was attempted */\n pendingTimestamp: string\n /** `true` if the submission is currently being processed by the pending queue */\n isSubmitting?: boolean\n /** `true` if the submission is currently being edited */\n isEditing?: boolean\n /**\n * An error message that might be set while attempting to process the\n * submission in the pending queue\n */\n error?: string\n}\n"]}
@@ -1,4 +1,4 @@
1
1
  import * as React from 'react';
2
- export declare function Clickable(props: React.ComponentProps<'div'> & {
2
+ export declare function Clickable({ disabled, onClick, ...props }: React.ComponentProps<'div'> & {
3
3
  disabled?: boolean;
4
4
  }): import("react/jsx-runtime").JSX.Element;
@@ -1,17 +1,19 @@
1
1
  import { jsx as _jsx } from "react/jsx-runtime";
2
2
  import * as React from 'react';
3
3
  import clsx from 'clsx';
4
- export function Clickable(props) {
4
+ export function Clickable({ disabled, onClick, ...props }) {
5
5
  const ref = React.useRef(null);
6
- return (_jsx("div", { ...props, role: "button", tabIndex: props.disabled ? -1 : 0, ref: ref, onKeyDown: (event) => {
7
- var _a, _b;
6
+ return (_jsx("div", { ...props, onClick: disabled ? undefined : onClick, role: "button", tabIndex: disabled ? -1 : 0, ref: ref, onKeyDown: (event) => {
7
+ var _a;
8
+ if (disabled)
9
+ return;
8
10
  if (ref.current === event.target &&
9
11
  (event.key === 'Enter' || event.key === ' ')) {
10
- (_a = props.onClick) === null || _a === void 0 ? void 0 : _a.call(props, event);
12
+ onClick === null || onClick === void 0 ? void 0 : onClick(event);
11
13
  }
12
- (_b = props.onKeyDown) === null || _b === void 0 ? void 0 : _b.call(props, event);
14
+ (_a = props.onKeyDown) === null || _a === void 0 ? void 0 : _a.call(props, event);
13
15
  }, className: clsx(props.className, {
14
- 'is-clickable': !props.disabled,
15
- }), "aria-disabled": props.disabled }));
16
+ 'is-clickable': !disabled,
17
+ }), "aria-disabled": disabled }));
16
18
  }
17
19
  //# sourceMappingURL=Clickable.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"Clickable.js","sourceRoot":"","sources":["../../src/components/Clickable.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,UAAU,SAAS,CACvB,KAEC;IAED,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAiB,IAAI,CAAC,CAAA;IAC9C,OAAO,CACL,iBACM,KAAK,EACT,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,KAAK,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EACjC,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;;YACnB,IACE,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM;gBAC5B,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAC5C,CAAC;gBACD,MAAA,KAAK,CAAC,OAAO,sDACX,KAAgE,CACjE,CAAA;YACH,CAAC;YACD,MAAA,KAAK,CAAC,SAAS,sDAAG,KAAK,CAAC,CAAA;QAC1B,CAAC,EACD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;YAC/B,cAAc,EAAE,CAAC,KAAK,CAAC,QAAQ;SAChC,CAAC,mBACa,KAAK,CAAC,QAAQ,GAC7B,CACH,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\n\nexport function Clickable(\n props: React.ComponentProps<'div'> & {\n disabled?: boolean\n },\n) {\n const ref = React.useRef<HTMLDivElement>(null)\n return (\n <div\n {...props}\n role=\"button\"\n tabIndex={props.disabled ? -1 : 0}\n ref={ref}\n onKeyDown={(event) => {\n if (\n ref.current === event.target &&\n (event.key === 'Enter' || event.key === ' ')\n ) {\n props.onClick?.(\n event as unknown as React.MouseEvent<HTMLDivElement, MouseEvent>,\n )\n }\n props.onKeyDown?.(event)\n }}\n className={clsx(props.className, {\n 'is-clickable': !props.disabled,\n })}\n aria-disabled={props.disabled}\n />\n )\n}\n"]}
1
+ {"version":3,"file":"Clickable.js","sourceRoot":"","sources":["../../src/components/Clickable.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,IAAI,MAAM,MAAM,CAAA;AAEvB,MAAM,UAAU,SAAS,CAAC,EACxB,QAAQ,EACR,OAAO,EACP,GAAG,KAAK,EAGT;IACC,MAAM,GAAG,GAAG,KAAK,CAAC,MAAM,CAAiB,IAAI,CAAC,CAAA;IAC9C,OAAO,CACL,iBACM,KAAK,EACT,OAAO,EAAE,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,CAAC,CAAC,OAAO,EACvC,IAAI,EAAC,QAAQ,EACb,QAAQ,EAAE,QAAQ,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,CAAC,EAC3B,GAAG,EAAE,GAAG,EACR,SAAS,EAAE,CAAC,KAAK,EAAE,EAAE;;YACnB,IAAI,QAAQ;gBAAE,OAAM;YACpB,IACE,GAAG,CAAC,OAAO,KAAK,KAAK,CAAC,MAAM;gBAC5B,CAAC,KAAK,CAAC,GAAG,KAAK,OAAO,IAAI,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,EAC5C,CAAC;gBACD,OAAO,aAAP,OAAO,uBAAP,OAAO,CACL,KAAgE,CACjE,CAAA;YACH,CAAC;YACD,MAAA,KAAK,CAAC,SAAS,sDAAG,KAAK,CAAC,CAAA;QAC1B,CAAC,EACD,SAAS,EAAE,IAAI,CAAC,KAAK,CAAC,SAAS,EAAE;YAC/B,cAAc,EAAE,CAAC,QAAQ;SAC1B,CAAC,mBACa,QAAQ,GACvB,CACH,CAAA;AACH,CAAC","sourcesContent":["import * as React from 'react'\nimport clsx from 'clsx'\n\nexport function Clickable({\n disabled,\n onClick,\n ...props\n}: React.ComponentProps<'div'> & {\n disabled?: boolean\n}) {\n const ref = React.useRef<HTMLDivElement>(null)\n return (\n <div\n {...props}\n onClick={disabled ? undefined : onClick}\n role=\"button\"\n tabIndex={disabled ? -1 : 0}\n ref={ref}\n onKeyDown={(event) => {\n if (disabled) return\n if (\n ref.current === event.target &&\n (event.key === 'Enter' || event.key === ' ')\n ) {\n onClick?.(\n event as unknown as React.MouseEvent<HTMLDivElement, MouseEvent>,\n )\n }\n props.onKeyDown?.(event)\n }}\n className={clsx(props.className, {\n 'is-clickable': !disabled,\n })}\n aria-disabled={disabled}\n />\n )\n}\n"]}
@@ -1,5 +1,6 @@
1
1
  import * as React from 'react';
2
2
  import { draftService } from '../apps';
3
+ import { PriorityFn } from '../apps/draft-service';
3
4
  /** The value returned from `useDrafts()` hook */
4
5
  export type DraftsContextValue = {
5
6
  /** `true` if drafts are currently loading for the first time. */
@@ -14,7 +15,10 @@ export type DraftsContextValue = {
14
15
  */
15
16
  lastSyncTime: Date | null;
16
17
  /** A function to trigger syncing of the drafts */
17
- syncDrafts: (abortSignal: AbortSignal | undefined) => Promise<void>;
18
+ syncDrafts: ({ abortSignal, priorityFn, }: {
19
+ abortSignal: AbortSignal | undefined;
20
+ priorityFn: PriorityFn | undefined;
21
+ }) => Promise<void>;
18
22
  /** An Error object if syncing drafts fails */
19
23
  syncError: Error | null;
20
24
  /** A function to clear Error object from syncing drafts */
@@ -64,7 +64,7 @@ children, }) {
64
64
  syncError: null,
65
65
  }));
66
66
  }, []);
67
- const syncDrafts = React.useCallback(async (abortSignal) => {
67
+ const syncDrafts = React.useCallback(async ({ abortSignal, priorityFn, }) => {
68
68
  if (!isDraftsEnabled || isUsingFormsKey) {
69
69
  return;
70
70
  }
@@ -79,6 +79,7 @@ children, }) {
79
79
  try {
80
80
  await draftService.syncDrafts({
81
81
  formsAppId,
82
+ priorityFn,
82
83
  throwError: true,
83
84
  abortSignal,
84
85
  });
@@ -121,7 +122,7 @@ children, }) {
121
122
  ]);
122
123
  React.useEffect(() => {
123
124
  const abortController = new AbortController();
124
- const unregisterPendingQueueListener = submissionService.registerPendingQueueListener(() => syncDrafts(undefined));
125
+ const unregisterPendingQueueListener = submissionService.registerPendingQueueListener(() => syncDrafts({ abortSignal: undefined, priorityFn: undefined }));
125
126
  const unregisterDraftsListener = draftService.registerDraftsListener(setDrafts);
126
127
  return () => {
127
128
  abortController.abort();
@@ -132,7 +133,7 @@ children, }) {
132
133
  React.useEffect(() => {
133
134
  if (!isOffline) {
134
135
  const abortController = new AbortController();
135
- syncDrafts(abortController.signal);
136
+ syncDrafts({ abortSignal: abortController.signal, priorityFn: undefined });
136
137
  return () => {
137
138
  abortController.abort();
138
139
  };
@@ -1 +1 @@
1
- {"version":3,"file":"useDrafts.js","sourceRoot":"","sources":["../../src/hooks/useDrafts.tsx"],"names":[],"mappings":";AAAA,OAAO,KAAK,KAAK,MAAM,OAAO,CAAA;AAC9B,OAAO,EAAE,YAAY,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAA;AACzD,OAAO,OAAO,MAAM,WAAW,CAAA;AAC/B,OAAO,YAAY,MAAM,gBAAgB,CAAA;AACzC,OAAO,YAAY,MAAM,gBAAgB,CAAA;AAyBzC,MAAM,aAAa,GAAG,KAAK,CAAC,aAAa,CACvC,SAAS,CACV,CAAA;AAED;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAkCG;AACH,MAAM,UAAU,qBAAqB,CAAC;AACpC,yEAAyE;AACzE,UAAU;AACV;;;GAGG;AACH,eAAe;AACf,kCAAkC;AAClC,QAAQ,GAKT;IACC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,SAAS,GAAG,YAAY,EAAE,CAAA;IAChC,MAAM,EAAE,eAAe,EAAE,GAAG,OAAO,EAAE,CAAA;IAErC,MAAM,CAAC,SAAS,EAAE,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAI7C;QACD,YAAY,EAAE,IAAI;QAClB,SAAS,EAAE,KAAK;QAChB,SAAS,EAAE,IAAI;KAChB,CAAC,CAAA;IACF,MAAM,cAAc,GAAG,KAAK,CAAC,WAAW,CAAC,GAAG,EAAE;QAC5C,YAAY,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;YAC9B,GAAG,YAAY;YACf,SAAS,EAAE,IAAI;SAChB,CAAC,CAAC,CAAA;IACL,CAAC,EAAE,EAAE,CAAC,CAAA;IACN,MAAM,UAAU,GAAG,KAAK,CAAC,WAAW,CAClC,KAAK,EAAE,WAAoC,EAAE,EAAE;QAC7C,IAAI,CAAC,eAAe,IAAI,eAAe,EAAE,CAAC;YACxC,OAAM;QACR,CAAC;QAED,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,YAAY,CAAC,CAAC,YAAY,EAAE,EAAE,CAAC,CAAC;gBAC9B,GAAG,YAAY;gBACf,SAAS,EAAE,IAAI;gBACf,SAAS,EAAE,IAAI;aAChB,CAAC,CAAC,CAAA;QACL,CAAC;QAED,IAAI,QAAQ,GAAG,IAAI,CAAA;QAEnB,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,UAAU,CAAC;gBAC5B,UAAU;gBACV,UAAU,EAAE,IAAI;gBAChB,WAAW;aACZ,CAAC,CAAA;QACJ,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,QAAQ,GAAG,KAAc,CAAA;QAC3B,CAAC;QAED,IAAI,SAAS,CAAC,OAAO,EAAE,CAAC;YACtB,YAAY,CAAC;gBACX,YAAY,EAAE,IAAI,IAAI,EAAE;gBACxB,SAAS,EAAE,KAAK;gBAChB,SAAS,EAAE,QAAQ;aACpB,CAAC,CAAA;QACJ,CAAC;IACH,CAAC,EACD,CAAC,UAAU,EAAE,eAAe,EAAE,SAAS,EAAE,eAAe,CAAC,CAC1D,CAAA;IAED,MAAM,CAAC,MAAM,EAAE,SAAS,CAAC,GAAG,KAAK,CAAC,QAAQ,CAExC,IAAI,CAAC,CAAA;IAEP,MAAM,WAAW,GAAG,KAAK,CAAC,WAAW,CACnC,CAAC,OAAe,EAAE,EAAE;QAClB,OAAO,YAAY,CAAC,WAAW,CAAC,OAAO,EAAE,UAAU,CAAC,CAAA;IACtD,CAAC,EACD,CAAC,UAAU,CAAC,CACb,CAAA;IAED,MAAM,KAAK,GAAG,KAAK,CAAC,OAAO,CACzB,GAAG,EAAE,CAAC,CAAC;QACL,OAAO;QACP,UAAU;QACV,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,SAAS,EAAE,SAAS,CAAC,SAAS;QAC9B,YAAY,EAAE,SAAS,CAAC,YAAY;QACpC,cAAc;QACd,OAAO;QACP,SAAS,EAAE,CAAC,MAAM;QAClB,MAAM,EAAE,MAAM,IAAI,EAAE;QACpB,UAAU;QACV,WAAW;KACZ,CAAC,EACF;QACE,UAAU;QACV,SAAS,CAAC,SAAS;QACnB,SAAS,CAAC,SAAS;QACnB,SAAS,CAAC,YAAY;QACtB,cAAc;QACd,MAAM;QACN,WAAW;KACZ,CACF,CAAA;IAED,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;QAC7C,MAAM,8BAA8B,GAClC,iBAAiB,CAAC,4BAA4B,CAAC,GAAG,EAAE,CAClD,UAAU,CAAC,SAAS,CAAC,CACtB,CAAA;QACH,MAAM,wBAAwB,GAC5B,YAAY,CAAC,sBAAsB,CAAC,SAAS,CAAC,CAAA;QAChD,OAAO,GAAG,EAAE;YACV,eAAe,CAAC,KAAK,EAAE,CAAA;YACvB,8BAA8B,EAAE,CAAA;YAChC,wBAAwB,EAAE,CAAA;QAC5B,CAAC,CAAA;IACH,CAAC,EAAE,CAAC,UAAU,CAAC,CAAC,CAAA;IAEhB,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;QACnB,IAAI,CAAC,SAAS,EAAE,CAAC;YACf,MAAM,eAAe,GAAG,IAAI,eAAe,EAAE,CAAA;YAC7C,UAAU,CAAC,eAAe,CAAC,MAAM,CAAC,CAAA;YAClC,OAAO,GAAG,EAAE;gBACV,eAAe,CAAC,KAAK,EAAE,CAAA;YACzB,CAAC,CAAA;QACH,CAAC;IACH,CAAC,EAAE,CAAC,SAAS,EAAE,UAAU,CAAC,CAAC,CAAA;IAE3B,OAAO,CACL,KAAC,aAAa,CAAC,QAAQ,IAAC,KAAK,EAAE,KAAK,YAAG,QAAQ,GAA0B,CAC1E,CAAA;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,OAAO,UAAU,SAAS;IAC/B,MAAM,KAAK,GAAG,KAAK,CAAC,UAAU,CAAC,aAAa,CAAC,CAAA;IAC7C,IAAI,CAAC,KAAK,EAAE,CAAC;QACX,MAAM,IAAI,KAAK,CACb,4FAA4F,CAC7F,CAAA;IACH,CAAC;IACD,OAAO,KAAK,CAAA;AACd,CAAC","sourcesContent":["import * as React from 'react'\nimport { draftService, submissionService } from '../apps'\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` if drafts are currently loading for the first time. */\n isLoading: boolean\n /** The incomplete submissions that were saved for later */\n drafts: draftService.LocalFormSubmissionDraft[]\n /** `true` drafts are syncing with other devices */\n isSyncing: boolean\n /**\n * The date when the sync process last completed successfully, will be `null`\n * until it has completed the first time.\n */\n lastSyncTime: Date | null\n /** A function to trigger syncing of the drafts */\n syncDrafts: (abortSignal: AbortSignal | undefined) => Promise<void>\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: (formSubmissionDraftId: string) => Promise<void>\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 { isUsingFormsKey } = useAuth()\n\n const [syncState, setSyncState] = React.useState<{\n lastSyncTime: Date | null\n isSyncing: boolean\n syncError: Error | null\n }>({\n lastSyncTime: null,\n isSyncing: false,\n syncError: null,\n })\n const clearSyncError = React.useCallback(() => {\n setSyncState((currentState) => ({\n ...currentState,\n syncError: null,\n }))\n }, [])\n const syncDrafts = React.useCallback(\n async (abortSignal: AbortSignal | undefined) => {\n if (!isDraftsEnabled || isUsingFormsKey) {\n return\n }\n\n if (isMounted.current) {\n setSyncState((currentState) => ({\n ...currentState,\n isSyncing: true,\n syncError: null,\n }))\n }\n\n let newError = null\n\n try {\n await draftService.syncDrafts({\n formsAppId,\n throwError: true,\n abortSignal,\n })\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setSyncState({\n lastSyncTime: new Date(),\n isSyncing: false,\n syncError: newError,\n })\n }\n },\n [formsAppId, isDraftsEnabled, isMounted, isUsingFormsKey],\n )\n\n const [drafts, setDrafts] = React.useState<\n draftService.LocalFormSubmissionDraft[] | null\n >(null)\n\n const deleteDraft = React.useCallback(\n (draftId: string) => {\n return draftService.deleteDraft(draftId, formsAppId)\n },\n [formsAppId],\n )\n\n const value = React.useMemo<DraftsContextValue>(\n () => ({\n // Sync\n syncDrafts,\n isSyncing: syncState.isSyncing,\n syncError: syncState.syncError,\n lastSyncTime: syncState.lastSyncTime,\n clearSyncError,\n // Load\n isLoading: !drafts,\n drafts: drafts || [],\n // Delete,\n deleteDraft,\n }),\n [\n syncDrafts,\n syncState.isSyncing,\n syncState.syncError,\n syncState.lastSyncTime,\n clearSyncError,\n drafts,\n deleteDraft,\n ],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n const unregisterPendingQueueListener =\n submissionService.registerPendingQueueListener(() =>\n syncDrafts(undefined),\n )\n const unregisterDraftsListener =\n draftService.registerDraftsListener(setDrafts)\n return () => {\n abortController.abort()\n unregisterPendingQueueListener()\n unregisterDraftsListener()\n }\n }, [syncDrafts])\n\n React.useEffect(() => {\n if (!isOffline) {\n const abortController = new AbortController()\n syncDrafts(abortController.signal)\n return () => {\n abortController.abort()\n }\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
+ {"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 '../apps'\nimport useAuth from './useAuth'\nimport useIsMounted from './useIsMounted'\nimport useIsOffline from './useIsOffline'\nimport { PriorityFn } from '../apps/draft-service'\n\n/** The value returned from `useDrafts()` hook */\nexport type DraftsContextValue = {\n /** `true` if drafts are currently loading for the first time. */\n isLoading: boolean\n /** The incomplete submissions that were saved for later */\n drafts: draftService.LocalFormSubmissionDraft[]\n /** `true` drafts are syncing with other devices */\n isSyncing: boolean\n /**\n * The date when the sync process last completed successfully, will be `null`\n * until it has completed the first time.\n */\n lastSyncTime: Date | null\n /** A function to trigger syncing of the drafts */\n syncDrafts: ({\n abortSignal,\n priorityFn,\n }: {\n abortSignal: AbortSignal | undefined\n priorityFn: PriorityFn | undefined\n }) => Promise<void>\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: (formSubmissionDraftId: string) => Promise<void>\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 { isUsingFormsKey } = useAuth()\n\n const [syncState, setSyncState] = React.useState<{\n lastSyncTime: Date | null\n isSyncing: boolean\n syncError: Error | null\n }>({\n lastSyncTime: null,\n isSyncing: false,\n syncError: null,\n })\n const clearSyncError = React.useCallback(() => {\n setSyncState((currentState) => ({\n ...currentState,\n syncError: null,\n }))\n }, [])\n const syncDrafts = React.useCallback(\n async ({\n abortSignal,\n priorityFn,\n }: {\n abortSignal: AbortSignal | undefined\n priorityFn: PriorityFn | undefined\n }) => {\n if (!isDraftsEnabled || isUsingFormsKey) {\n return\n }\n\n if (isMounted.current) {\n setSyncState((currentState) => ({\n ...currentState,\n isSyncing: true,\n syncError: null,\n }))\n }\n\n let newError = null\n\n try {\n await draftService.syncDrafts({\n formsAppId,\n priorityFn,\n throwError: true,\n abortSignal,\n })\n } catch (error) {\n newError = error as Error\n }\n\n if (isMounted.current) {\n setSyncState({\n lastSyncTime: new Date(),\n isSyncing: false,\n syncError: newError,\n })\n }\n },\n [formsAppId, isDraftsEnabled, isMounted, isUsingFormsKey],\n )\n\n const [drafts, setDrafts] = React.useState<\n draftService.LocalFormSubmissionDraft[] | null\n >(null)\n\n const deleteDraft = React.useCallback(\n (draftId: string) => {\n return draftService.deleteDraft(draftId, formsAppId)\n },\n [formsAppId],\n )\n\n const value = React.useMemo<DraftsContextValue>(\n () => ({\n // Sync\n syncDrafts,\n isSyncing: syncState.isSyncing,\n syncError: syncState.syncError,\n lastSyncTime: syncState.lastSyncTime,\n clearSyncError,\n // Load\n isLoading: !drafts,\n drafts: drafts || [],\n // Delete,\n deleteDraft,\n }),\n [\n syncDrafts,\n syncState.isSyncing,\n syncState.syncError,\n syncState.lastSyncTime,\n clearSyncError,\n drafts,\n deleteDraft,\n ],\n )\n\n React.useEffect(() => {\n const abortController = new AbortController()\n const unregisterPendingQueueListener =\n submissionService.registerPendingQueueListener(() =>\n syncDrafts({ abortSignal: undefined, priorityFn: undefined }),\n )\n const unregisterDraftsListener =\n draftService.registerDraftsListener(setDrafts)\n return () => {\n abortController.abort()\n unregisterPendingQueueListener()\n unregisterDraftsListener()\n }\n }, [syncDrafts])\n\n React.useEffect(() => {\n if (!isOffline) {\n const abortController = new AbortController()\n syncDrafts({ abortSignal: abortController.signal, priorityFn: undefined })\n return () => {\n abortController.abort()\n }\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"]}
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": "9.1.1-beta.1",
4
+ "version": "10.0.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"
@@ -13,7 +13,7 @@
13
13
  "@emotion/styled": "^11.14.1",
14
14
  "@nylas/react": "^3.1.2",
15
15
  "@oneblink/sdk-core": "^9.1.0-beta.3",
16
- "@oneblink/storage": "^5.0.0-beta.2",
16
+ "@oneblink/storage": "^6.0.0-beta.1",
17
17
  "@react-google-maps/api": "^2.20.8",
18
18
  "@react-input/mask": "^2.0.4",
19
19
  "@sentry/browser": "^10.38.0",