Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0

## [Unreleased]

### Changed

- individual draft data can be optionally downloaded during a sync

## [9.1.0] - 2026-02-23

### Added
Expand Down
65 changes: 41 additions & 24 deletions src/apps/draft-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -131,6 +131,7 @@ async function generatePublicLocalFormSubmissionDraftsFromStorage(

async function generateLocalFormSubmissionDraftsFromStorage(
localDraftsStorage: LocalDraftsStorage,
metaOnly: boolean,
): Promise<LocalFormSubmissionDraft[]> {
const pendingSubmissionsDraftIds = await getPendingSubmissionsDraftIds()
const deletedDraftIds = new Set(
Expand All @@ -153,15 +154,15 @@ async function generateLocalFormSubmissionDraftsFromStorage(
// Remove any drafts deleted while offline
!deletedDraftIds.has(formSubmissionDraft.id)
) {
const draftSubmission = await getDraftSubmission(
formSubmissionDraft,
).catch((err) => {
console.warn(
`Could not fetch draft submission for draft: ${formSubmissionDraft.id}`,
err,
)
return undefined
})
const draftSubmission = metaOnly
? undefined
: await getDraftSubmission(formSubmissionDraft).catch((err) => {
console.warn(
`Could not fetch draft submission for draft: ${formSubmissionDraft.id}`,
err,
)
return undefined
})
localFormSubmissionDraftsMap.set(formSubmissionDraft.id, {
...formSubmissionDraft,
draftSubmission,
Expand Down Expand Up @@ -454,9 +455,14 @@ async function getPublicDraftsFromStorage(): Promise<DraftSubmission[]> {
*
* @returns
*/
async function getDrafts(): Promise<LocalFormSubmissionDraft[]> {
async function getDrafts(
metaOnly?: boolean,
): Promise<LocalFormSubmissionDraft[]> {
const localDraftsStorage = await getLocalDraftsFromStorage()
return await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage)
return await generateLocalFormSubmissionDraftsFromStorage(
localDraftsStorage,
metaOnly ?? false,
)
}

/**
Expand Down Expand Up @@ -509,6 +515,7 @@ async function getDraftAndData(
formsAppId: number,
formSubmissionDraftId: string | undefined | null,
abortSignal: AbortSignal | undefined,
metaOnly?: boolean,
): Promise<DraftSubmission | undefined> {
if (!formSubmissionDraftId) {
return
Expand All @@ -523,7 +530,9 @@ async function getDraftAndData(
const localDraftsStorage = await getLocalDraftsFromStorage()
if (formSubmissionDrafts) {
localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts
await setAndBroadcastDrafts(localDraftsStorage)
if (!metaOnly) {
await setAndBroadcastDrafts(localDraftsStorage)
}
} else {
formSubmissionDrafts = localDraftsStorage.syncedFormSubmissionDrafts
}
Expand Down Expand Up @@ -671,7 +680,10 @@ async function setAndBroadcastDrafts(

console.log('Drafts have been updated', localDraftsStorage)
const localFormSubmissionDrafts =
await generateLocalFormSubmissionDraftsFromStorage(localDraftsStorage)
await generateLocalFormSubmissionDraftsFromStorage(
localDraftsStorage,
false,
)
await executeDraftsListeners(localFormSubmissionDrafts)
}

Expand All @@ -697,12 +709,15 @@ let _isSyncingDrafts = false
async function syncDrafts({
formsAppId,
throwError,
metaOnly,
abortSignal,
}: {
/** The id of the OneBlink Forms App to sync drafts with */
formsAppId: number
/** `true` to throw errors while syncing */
throwError?: boolean
/** `true` to only sync draft metadata */
metaOnly?: boolean
/** Signal to abort the requests */
abortSignal?: AbortSignal
}): Promise<void> {
Expand Down Expand Up @@ -800,19 +815,21 @@ async function syncDrafts({
localDraftsStorage.syncedFormSubmissionDrafts = formSubmissionDrafts
}

await setAndBroadcastDrafts(localDraftsStorage)
if (!metaOnly) {
await setAndBroadcastDrafts(localDraftsStorage)

if (localDraftsStorage.syncedFormSubmissionDrafts.length) {
console.log(
'Ensuring all draft data is available for offline use for synced drafts',
localDraftsStorage.syncedFormSubmissionDrafts,
)
for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {
await getDraftSubmission(formSubmissionDraft, abortSignal).catch(
(error) => {
console.warn('Could not download Draft Data as JSON', error)
},
if (localDraftsStorage.syncedFormSubmissionDrafts.length) {
console.log(
'Ensuring all draft data is available for offline use for synced drafts',
localDraftsStorage.syncedFormSubmissionDrafts,
)
for (const formSubmissionDraft of localDraftsStorage.syncedFormSubmissionDrafts) {
await getDraftSubmission(formSubmissionDraft, abortSignal).catch(
(error) => {
console.warn('Could not download Draft Data as JSON', error)
},
)
}
}
}

Expand Down
2 changes: 1 addition & 1 deletion src/apps/job-service.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ async function removePendingSubmissions(
}

async function tagDrafts(jobList: SubmissionTypes.FormsAppJob[]) {
return getDrafts().then((drafts) =>
return getDrafts(true).then((drafts) =>
jobList.map((job) => {
const draft = drafts.find((draft) => draft.jobId === job.id)
return {
Expand Down
8 changes: 6 additions & 2 deletions src/hooks/useDrafts.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ export type DraftsContextValue = {
*/
lastSyncTime: Date | null
/** A function to trigger syncing of the drafts */
syncDrafts: (abortSignal: AbortSignal | undefined) => Promise<void>
syncDrafts: (
abortSignal: AbortSignal | undefined,
metaOnly?: boolean,
) => Promise<void>
/** An Error object if syncing drafts fails */
syncError: Error | null
/** A function to clear Error object from syncing drafts */
Expand Down Expand Up @@ -101,7 +104,7 @@ export function DraftsContextProvider({
}))
}, [])
const syncDrafts = React.useCallback(
async (abortSignal: AbortSignal | undefined) => {
async (abortSignal: AbortSignal | undefined, metaOnly?: boolean) => {
if (!isDraftsEnabled || isUsingFormsKey) {
return
}
Expand All @@ -121,6 +124,7 @@ export function DraftsContextProvider({
formsAppId,
throwError: true,
abortSignal,
metaOnly,
})
} catch (error) {
newError = error as Error
Expand Down