All checks were successful
ci/woodpecker/push/ci Pipeline was successful
- Add 3-column header layout (Buyer | Seller | Document Info) to: - Order create page (new) - Invoice create page (updated) - Order show page (updated with units/cases, item comments) - Invoice show page (updated with seller info, units/cases) - Quote show page (updated with seller info, units/cases) - Add seller-initiated order creation: - New /orders/create route and view - Orders track created_by (buyer/seller) - New Order button on orders index - Add ping pong order flow feature: - ping_pong_enabled on businesses table - is_ping_pong toggle per order - Admin toggle in Business > Suite Settings - Add item comments per line item: - item_comment field on order_items, crm_invoice_items, crm_quote_items - Inline edit UI on order show page - UI improvements: - Units/cases display (X UNITS / Y CASES) - Live totals in document headers - Consistent styling across all document types
115 lines
3.4 KiB
JavaScript
115 lines
3.4 KiB
JavaScript
// Cannabrands Hub Service Worker
|
|
// Uses Workbox for caching strategies and update detection
|
|
|
|
// LOCALHOST SELF-DESTRUCT: Unregister immediately on localhost to avoid dev issues
|
|
if (self.location.hostname === 'localhost' || self.location.hostname === '127.0.0.1') {
|
|
self.addEventListener('install', () => self.skipWaiting());
|
|
self.addEventListener('activate', () => {
|
|
self.registration.unregister().then(() => {
|
|
console.log('SW self-destructed on localhost');
|
|
});
|
|
});
|
|
throw new Error('SW disabled on localhost'); // Stop execution here
|
|
}
|
|
|
|
importScripts('https://storage.googleapis.com/workbox-cdn/releases/7.0.0/workbox-sw.js');
|
|
|
|
// Cache version - update this to trigger a new SW install
|
|
const CACHE_VERSION = 'v2';
|
|
const OFFLINE_URL = '/offline.html';
|
|
|
|
if (workbox) {
|
|
console.log('Workbox loaded successfully');
|
|
|
|
// Precache the offline page immediately
|
|
workbox.precaching.precacheAndRoute([
|
|
{ url: OFFLINE_URL, revision: CACHE_VERSION }
|
|
]);
|
|
|
|
// Cache CSS/JS assets with StaleWhileRevalidate
|
|
workbox.routing.registerRoute(
|
|
({ request }) => request.destination === 'style' || request.destination === 'script',
|
|
new workbox.strategies.StaleWhileRevalidate({
|
|
cacheName: 'assets-' + CACHE_VERSION,
|
|
})
|
|
);
|
|
|
|
// Cache images with CacheFirst (they don't change often)
|
|
workbox.routing.registerRoute(
|
|
({ request }) => request.destination === 'image',
|
|
new workbox.strategies.CacheFirst({
|
|
cacheName: 'images-' + CACHE_VERSION,
|
|
plugins: [
|
|
new workbox.expiration.ExpirationPlugin({
|
|
maxEntries: 100,
|
|
maxAgeSeconds: 30 * 24 * 60 * 60, // 30 days
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
|
|
// Cache fonts with CacheFirst
|
|
workbox.routing.registerRoute(
|
|
({ request }) => request.destination === 'font',
|
|
new workbox.strategies.CacheFirst({
|
|
cacheName: 'fonts-' + CACHE_VERSION,
|
|
plugins: [
|
|
new workbox.expiration.ExpirationPlugin({
|
|
maxEntries: 20,
|
|
maxAgeSeconds: 365 * 24 * 60 * 60, // 1 year
|
|
}),
|
|
],
|
|
})
|
|
);
|
|
|
|
// Network-first for HTML pages with offline fallback
|
|
const networkFirstHandler = new workbox.strategies.NetworkFirst({
|
|
cacheName: 'pages-' + CACHE_VERSION,
|
|
plugins: [
|
|
new workbox.expiration.ExpirationPlugin({
|
|
maxEntries: 50,
|
|
}),
|
|
],
|
|
});
|
|
|
|
// Custom handler for navigation requests with offline fallback
|
|
workbox.routing.registerRoute(
|
|
({ request }) => request.mode === 'navigate',
|
|
async ({ event }) => {
|
|
try {
|
|
return await networkFirstHandler.handle({ event, request: event.request });
|
|
} catch (error) {
|
|
console.log('Network failed, returning offline page');
|
|
return caches.match(OFFLINE_URL);
|
|
}
|
|
}
|
|
);
|
|
|
|
} else {
|
|
console.log('Workbox failed to load');
|
|
}
|
|
|
|
// Handle the "skip waiting" message from the client
|
|
self.addEventListener('message', (event) => {
|
|
if (event.data && event.data.type === 'SKIP_WAITING') {
|
|
self.skipWaiting();
|
|
}
|
|
});
|
|
|
|
// Notify clients when a new SW takes over
|
|
self.addEventListener('activate', (event) => {
|
|
event.waitUntil(
|
|
(async () => {
|
|
// Clean up old caches
|
|
const cacheNames = await caches.keys();
|
|
await Promise.all(
|
|
cacheNames
|
|
.filter((name) => !name.endsWith(CACHE_VERSION) && !name.startsWith('workbox-precache'))
|
|
.map((name) => caches.delete(name))
|
|
);
|
|
// Take control of all clients
|
|
await self.clients.claim();
|
|
})()
|
|
);
|
|
});
|