mirror of
https://github.com/mauriceboe/TREK.git
synced 2026-06-22 06:41:46 +00:00
feat: complete offline write support with mutation queue + runtime SW cache config
- Add offline CRUD to todoRepo, budgetRepo, reservationRepo, accommodationRepo, dayRepo, tripRepo, fileRepo with optimistic Dexie writes and mutation queue - Wire all store slices (todo, budget, reservations, files, dayNotes, assignments, tripStore) through repos for offline-aware writes - Cover archive/unarchive, file toggleStar/update/delete, assignment create/delete, day title/notes update offline paths - Migrate service worker from generateSW to injectManifest (custom sw.ts) with runtime-configurable api-data (7d/500) and map-tiles (30d/1000) cache policies - Add Settings → Offline cache configuration UI with save/reset and live SW postMessage - Extend mutationQueue flush to cover all writable Dexie tables
This commit is contained in:
@@ -1,5 +1,6 @@
|
||||
import { filesApi } from '../api/client'
|
||||
import { offlineDb, upsertTripFiles } from '../db/offlineDb'
|
||||
import { mutationQueue, generateUUID } from '../sync/mutationQueue'
|
||||
import type { TripFile } from '../types'
|
||||
|
||||
export const fileRepo = {
|
||||
@@ -15,4 +16,61 @@ export const fileRepo = {
|
||||
upsertTripFiles(result.files)
|
||||
return result
|
||||
},
|
||||
|
||||
async update(tripId: number | string, id: number, data: Record<string, unknown>): Promise<unknown> {
|
||||
if (!navigator.onLine) {
|
||||
const existing = await offlineDb.tripFiles.get(id)
|
||||
if (existing) await offlineDb.tripFiles.put({ ...existing, ...(data as Partial<TripFile>) })
|
||||
await mutationQueue.enqueue({
|
||||
id: generateUUID(),
|
||||
tripId: Number(tripId),
|
||||
method: 'PUT',
|
||||
url: `/trips/${tripId}/files/${id}`,
|
||||
body: data,
|
||||
resource: 'tripFiles',
|
||||
})
|
||||
return { success: true }
|
||||
}
|
||||
const result = await filesApi.update(tripId, id, data)
|
||||
const file = (result as { file?: TripFile }).file
|
||||
if (file) offlineDb.tripFiles.put(file)
|
||||
return result
|
||||
},
|
||||
|
||||
async toggleStar(tripId: number | string, id: number): Promise<unknown> {
|
||||
if (!navigator.onLine) {
|
||||
const existing = await offlineDb.tripFiles.get(id)
|
||||
if (existing) {
|
||||
await offlineDb.tripFiles.put({ ...existing, starred: existing.starred ? 0 : 1 })
|
||||
}
|
||||
await mutationQueue.enqueue({
|
||||
id: generateUUID(),
|
||||
tripId: Number(tripId),
|
||||
method: 'PATCH',
|
||||
url: `/trips/${tripId}/files/${id}/star`,
|
||||
body: undefined,
|
||||
})
|
||||
return { success: true }
|
||||
}
|
||||
return filesApi.toggleStar(tripId, id)
|
||||
},
|
||||
|
||||
async delete(tripId: number | string, id: number): Promise<unknown> {
|
||||
if (!navigator.onLine) {
|
||||
await offlineDb.tripFiles.delete(id)
|
||||
await mutationQueue.enqueue({
|
||||
id: generateUUID(),
|
||||
tripId: Number(tripId),
|
||||
method: 'DELETE',
|
||||
url: `/trips/${tripId}/files/${id}`,
|
||||
body: undefined,
|
||||
resource: 'tripFiles',
|
||||
entityId: id,
|
||||
})
|
||||
return { success: true }
|
||||
}
|
||||
const result = await filesApi.delete(tripId, id)
|
||||
offlineDb.tripFiles.delete(id)
|
||||
return result
|
||||
},
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user