Mode2Test/AuthAndToken: assume tokens always fresh with background refresh; fix jobs API to use correct collection; align Home UI to Mode1 (exact fields, styling, strict Active dot); add full-field IndexedDB cache w/ pagination; remove progress bar; dev TLS bypass; rebuild bundles
This commit is contained in:
@@ -0,0 +1,129 @@
|
||||
// job-cache.ts
|
||||
var DB_NAME = "JobInfoCache";
|
||||
var DB_VERSION = 2;
|
||||
var JOBS_STORE = "jobs";
|
||||
var META_STORE = "metadata";
|
||||
var CACHE_TTL = 5 * 60 * 1000;
|
||||
var PAGE_SIZE = 500;
|
||||
|
||||
class JobCache {
|
||||
db = null;
|
||||
async initialize() {
|
||||
return new Promise((resolve, reject) => {
|
||||
const request = indexedDB.open(DB_NAME, DB_VERSION);
|
||||
request.onerror = () => reject(request.error);
|
||||
request.onsuccess = () => {
|
||||
this.db = request.result;
|
||||
resolve();
|
||||
};
|
||||
request.onupgradeneeded = (event) => {
|
||||
const db = event.target.result;
|
||||
if (!db.objectStoreNames.contains(JOBS_STORE)) {
|
||||
db.createObjectStore(JOBS_STORE, { keyPath: "Job_Number" });
|
||||
}
|
||||
if (!db.objectStoreNames.contains(META_STORE)) {
|
||||
db.createObjectStore(META_STORE);
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
async getCachedJobs() {
|
||||
if (!this.db)
|
||||
throw new Error("Database not initialized");
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([JOBS_STORE], "readonly");
|
||||
const store = transaction.objectStore(JOBS_STORE);
|
||||
const request = store.getAll();
|
||||
request.onsuccess = () => resolve(request.result);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
async isCacheValid() {
|
||||
if (!this.db)
|
||||
return false;
|
||||
try {
|
||||
const metadata = await this.getMetadata();
|
||||
if (!metadata || !metadata.lastUpdated)
|
||||
return false;
|
||||
const age = Date.now() - metadata.lastUpdated;
|
||||
return age < CACHE_TTL;
|
||||
} catch {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
async saveJobs(jobs) {
|
||||
if (!this.db)
|
||||
throw new Error("Database not initialized");
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([JOBS_STORE, META_STORE], "readwrite");
|
||||
const jobsStore = transaction.objectStore(JOBS_STORE);
|
||||
const metaStore = transaction.objectStore(META_STORE);
|
||||
jobsStore.clear();
|
||||
jobs.forEach((job) => jobsStore.add(job));
|
||||
const metadata = {
|
||||
lastUpdated: Date.now(),
|
||||
version: DB_VERSION
|
||||
};
|
||||
metaStore.put(metadata, "main");
|
||||
transaction.oncomplete = () => resolve();
|
||||
transaction.onerror = () => reject(transaction.error);
|
||||
});
|
||||
}
|
||||
async refreshJobs() {
|
||||
try {
|
||||
let page = 1;
|
||||
let all = [];
|
||||
let totalPages = 1;
|
||||
while (page <= totalPages) {
|
||||
const url = `/api/jobs?page=${page}&perPage=${PAGE_SIZE}&sort=-Job_Number`;
|
||||
const response = await fetch(url);
|
||||
if (!response.ok) {
|
||||
throw new Error(`Failed to fetch jobs (status ${response.status})`);
|
||||
}
|
||||
const data = await response.json();
|
||||
const items = data.items || [];
|
||||
const reportedTotalPages = data.totalPages || 1;
|
||||
all = all.concat(items);
|
||||
totalPages = Math.max(totalPages, reportedTotalPages);
|
||||
page += 1;
|
||||
}
|
||||
await this.saveJobs(all);
|
||||
return all;
|
||||
} catch (err) {
|
||||
console.error("Failed to refresh jobs cache:", err);
|
||||
throw err;
|
||||
}
|
||||
}
|
||||
async getMetadata() {
|
||||
if (!this.db)
|
||||
return null;
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([META_STORE], "readonly");
|
||||
const store = transaction.objectStore(META_STORE);
|
||||
const request = store.get("main");
|
||||
request.onsuccess = () => resolve(request.result || null);
|
||||
request.onerror = () => reject(request.error);
|
||||
});
|
||||
}
|
||||
async clearCache() {
|
||||
if (!this.db)
|
||||
throw new Error("Database not initialized");
|
||||
return new Promise((resolve, reject) => {
|
||||
const transaction = this.db.transaction([JOBS_STORE, META_STORE], "readwrite");
|
||||
transaction.objectStore(JOBS_STORE).clear();
|
||||
transaction.objectStore(META_STORE).clear();
|
||||
transaction.oncomplete = () => resolve();
|
||||
transaction.onerror = () => reject(transaction.error);
|
||||
});
|
||||
}
|
||||
async getCacheAge() {
|
||||
const metadata = await this.getMetadata();
|
||||
if (!metadata || !metadata.lastUpdated)
|
||||
return null;
|
||||
return Date.now() - metadata.lastUpdated;
|
||||
}
|
||||
}
|
||||
var jobCache = new JobCache;
|
||||
export {
|
||||
jobCache
|
||||
};
|
||||
Reference in New Issue
Block a user