Persist uploaded order CSVs across app restarts

Uploaded CSVs previously lived only in memory; reloading the app reset the
order list to the embedded SEED_ORDERS_CSV. Now every upload is written to a
new IndexedDB store so inspectors keep their order list after closing/reopening
the PWA.

- db.js: bump DB_VERSION to 4, add object store `ordersCsv` (keyPath 'id'),
  saveOrdersCsv(csvText) and loadOrdersCsv().
- csvLoader.js: loadOrdersFromUpload returns { text, orders } so the handler
  can persist the raw text alongside the parsed result.
- main.js: init() prefers the stored CSV, falls back to SEED_ORDERS_CSV. The
  upload handler persists the CSV before re-rendering.
This commit is contained in:
Randy Fischer 2026-04-15 15:47:15 +02:00
parent e86aa5bae2
commit 92ad6a92e3
3 changed files with 29 additions and 4 deletions

View File

@ -33,7 +33,9 @@
document.getElementById('csvFileInput').addEventListener('change', async (e) => { document.getElementById('csvFileInput').addEventListener('change', async (e) => {
const file = e.target.files[0]; const file = e.target.files[0];
if (!file) return; if (!file) return;
A.state.orders = await I.loadOrdersFromUpload(file); const { text, orders } = await I.loadOrdersFromUpload(file);
await I.saveOrdersCsv(text);
A.state.orders = orders;
A.renderOverviewScreen(openOrder); A.renderOverviewScreen(openOrder);
e.target.value = ''; e.target.value = '';
}); });
@ -91,7 +93,8 @@
async function init() { async function init() {
await I.openDB(); await I.openDB();
A.state.orders = D.parseCSV(I.SEED_ORDERS_CSV); const stored = await I.loadOrdersCsv();
A.state.orders = D.parseCSV(stored ? stored.csv : I.SEED_ORDERS_CSV);
A.state.orderStatuses = await I.loadAllOrderStatuses(); A.state.orderStatuses = await I.loadAllOrderStatuses();
wireOverviewToolbar(); wireOverviewToolbar();

View File

@ -1,6 +1,6 @@
(function (I, D) { (function (I, D) {
I.loadOrdersFromUpload = async function (file) { I.loadOrdersFromUpload = async function (file) {
const text = await file.text(); const text = await file.text();
return D.parseCSV(text); return { text, orders: D.parseCSV(text) };
}; };
})(window.App.Infrastructure, window.App.Domain); })(window.App.Infrastructure, window.App.Domain);

View File

@ -1,6 +1,6 @@
(function (I) { (function (I) {
const DB_NAME = 'DuimstokInspecties'; const DB_NAME = 'DuimstokInspecties';
const DB_VERSION = 3; const DB_VERSION = 4;
let db = null; let db = null;
I.openDB = function () { I.openDB = function () {
@ -12,6 +12,8 @@
d.createObjectStore('inspections', { keyPath: 'orderNr' }); d.createObjectStore('inspections', { keyPath: 'orderNr' });
if (!d.objectStoreNames.contains('orderStatuses')) if (!d.objectStoreNames.contains('orderStatuses'))
d.createObjectStore('orderStatuses', { keyPath: 'orderKey' }); d.createObjectStore('orderStatuses', { keyPath: 'orderKey' });
if (!d.objectStoreNames.contains('ordersCsv'))
d.createObjectStore('ordersCsv', { keyPath: 'id' });
}; };
req.onsuccess = (e) => { db = e.target.result; resolve(db); }; req.onsuccess = (e) => { db = e.target.result; resolve(db); };
req.onerror = (e) => reject(e); req.onerror = (e) => reject(e);
@ -53,6 +55,26 @@
}); });
}; };
I.saveOrdersCsv = async function (csvText) {
const d = await ensureDb();
return new Promise((resolve, reject) => {
const tx = d.transaction('ordersCsv', 'readwrite');
tx.objectStore('ordersCsv').put({ id: 'current', csv: csvText, uploadedAt: new Date().toISOString() });
tx.oncomplete = resolve;
tx.onerror = reject;
});
};
I.loadOrdersCsv = async function () {
const d = await ensureDb();
return new Promise((resolve, reject) => {
const tx = d.transaction('ordersCsv', 'readonly');
const req = tx.objectStore('ordersCsv').get('current');
req.onsuccess = () => resolve(req.result || null);
req.onerror = reject;
});
};
I.loadAllOrderStatuses = async function () { I.loadAllOrderStatuses = async function () {
const d = await ensureDb(); const d = await ensureDb();
return new Promise((resolve, reject) => { return new Promise((resolve, reject) => {