Add a single-page A4 preview and PDF for all selected banquet dishes or a ready-menu selection, with company branding and optional costs. Preserve draft/order state and saved line prices, enforce access and tenant scope, and fail clearly rather than clipping oversized menus. Nineteen targeted browser scenarios passed twice and the generated iPhone PDF was visually checked. Full main QA must pass before the existing automatic production promotion; production verification includes the new renderer and real-asset client menu export.
64 lines
5.2 KiB
JavaScript
64 lines
5.2 KiB
JavaScript
const CACHE='sun-catering-pwa-v110-20260918-ui-stability-20260919-client-menu-support-bot-training-catalog-banquet-onepage';
|
|
const VERSION='20260918-ui-stability';
|
|
const CORE=[
|
|
'./core/banquet-client-menu.js?v=20260920-onepage',
|
|
'./core/training-catalog.js?v=20260920-training',
|
|
'./core/catalog-pricing.js?v=20260919-client-menu','./core/client-menu.css?v=20260919-client-menu',
|
|
'./vendor/supabase-2.112.4.min.js',
|
|
`./core/help-center.js?v=${VERSION}`,`./core/help-center.css?v=${VERSION}`,`./help/knowledge-v1.json?v=${VERSION}`,
|
|
'./','./index.html',`./core/mobile-order.js?v=${VERSION}`,`./core/proposal-layout.js?v=${VERSION}`,'./fonts/Manrope.ttf','./fonts/PlayfairDisplay.ttf','./fonts/PlayfairDisplay-Italic.ttf',`./core/trial-demo.js?v=${VERSION}`,`./core/cloud-transport.js?v=${VERSION}`,`./core/banquet-menu.js?v=${VERSION}`,`./core/access-policy.js?v=${VERSION}`,`./core/import-archive.js?v=${VERSION}`,`./core/company-branding.js?v=${VERSION}`,`./core/signature-offer-pdf-v18.js?v=${VERSION}`,`./core/brand-theme.js?v=${VERSION}`,
|
|
`./core/sun-safe.js?v=${VERSION}`,`./core/performance.js?v=${VERSION}`,`./core/account-center-v1780.js?v=${VERSION}`,`./core/login-signature-v1776.js?v=${VERSION}`,`./core/login-signature-v1776.css?v=${VERSION}`,`./core/data-layer-v1773.js?v=${VERSION}`,`./core/server-automation-v1770.js?v=${VERSION}`,`./core/hotfix-v1763.js?v=${VERSION}`,`./core/ops-ux-v1762.js?v=${VERSION}`,`./core/ux-fixes-v1764.js?v=${VERSION}`,`./core/pdf-engine.js?v=${VERSION}`,`./core/classic-offer-pdf-v1767.js?v=${VERSION}`,`./core/developer-console-v1768.js?v=${VERSION}`,`./core/offer-workspace-v1769.js?v=${VERSION}`,`./core/auth-security-v1774.js?v=${VERSION}`,`./core/order-enhancements-v1775.js?v=${VERSION}`,`./legacy/bootstrap.js?v=${VERSION}`,`./app-runtime.js?v=${VERSION}`,
|
|
'./offer-gallery/001.jpg','./offer-gallery/002.jpg',
|
|
'./catalog/001.jpg','./catalog/002.jpg','./catalog/003.jpg',
|
|
'./sun-logo.png','./caterium-login-logo.png','./caterium-mark-light.svg','./pwa-icon-192.png','./pwa-icon-512.png','./manifest.webmanifest',
|
|
'./offer-templates/thumb-light.jpg','./offer-templates/thumb-editorial-grid.jpg','./offer-templates/thumb-midnight-glass.jpg','./offer-templates/thumb-emerald-gold.jpg'
|
|
];
|
|
const CRITICAL_FRESH=new Set([
|
|
'/core/banquet-client-menu.js',
|
|
'/core/training-catalog.js',
|
|
'/core/catalog-pricing.js','/core/client-menu.css',
|
|
'/core/help-center.js','/core/help-center.css','/help/knowledge-v1.json',
|
|
'/core/mobile-order.js','/core/cloud-transport.js','/core/trial-demo.js','/core/proposal-layout.js',
|
|
'/core/banquet-menu.js','/core/access-policy.js','/core/import-archive.js','/core/company-branding.js','/core/brand-theme.js','/core/sun-safe.js','/core/performance.js','/core/account-center-v1780.js','/core/login-signature-v1776.js','/core/login-signature-v1776.css','/core/auth-security-v1774.js','/legacy/bootstrap.js','/app-runtime.js'
|
|
]);
|
|
self.addEventListener('install',event=>{
|
|
event.waitUntil(caches.open(CACHE).then(cache=>cache.addAll(CORE)).then(()=>self.skipWaiting()));
|
|
});
|
|
self.addEventListener('activate',event=>{
|
|
event.waitUntil(caches.keys().then(keys=>Promise.all(keys.filter(k=>k.startsWith('sun-catering-pwa-')&&k!==CACHE).map(k=>caches.delete(k)))).then(()=>self.clients.claim()));
|
|
});
|
|
function cachePut(req,res){
|
|
if(res&&res.ok){const clone=res.clone();caches.open(CACHE).then(c=>c.put(req,clone)).catch(()=>{});}return res;
|
|
}
|
|
function networkFirst(req,fallback){
|
|
return fetch(req,{cache:'no-store'}).then(res=>cachePut(req,res)).catch(()=>caches.match(req).then(hit=>hit||caches.match(fallback||req)));
|
|
}
|
|
function forceFresh(req){
|
|
const url=new URL(req.url);url.searchParams.set('__caterium_release',VERSION);
|
|
return fetch(url.toString(),{cache:'no-store',credentials:'same-origin'}).then(res=>cachePut(req,res)).catch(()=>caches.match(req));
|
|
}
|
|
self.addEventListener('fetch',event=>{
|
|
const req=event.request;if(req.method!=='GET')return;
|
|
const url=new URL(req.url);if(url.origin!==self.location.origin||url.pathname.startsWith('/api/'))return;
|
|
// Static PNGs can bypass Apache rewrites on the production host. Resolve old
|
|
// catalog/editor/document URLs here too, before checking the original cache.
|
|
if(/^\/demo\/images\/(?:berry-dessert|bruschetta-tomato|caprese|cheese-fruit|chicken-sandwich|meat-assortment|mushroom-tartlet|salmon-cream|turkey-wrap|vegetables-hummus)\.png$/.test(url.pathname)){
|
|
url.pathname=url.pathname.replace(/\.png$/,'.webp');
|
|
const optimized=new Request(url.toString(),{credentials:'same-origin'});
|
|
event.respondWith(caches.match(optimized).then(hit=>hit||fetch(optimized).then(res=>res.ok?cachePut(optimized,res):fetch(req))));
|
|
return;
|
|
}
|
|
if(req.mode==='navigate'){
|
|
event.respondWith(
|
|
fetch(req,{cache:'no-store'})
|
|
.then(res=>{const clone=res.clone();caches.open(CACHE).then(c=>c.put('./index.html',clone)).catch(()=>{});return res;})
|
|
.catch(()=>caches.match('./index.html'))
|
|
);
|
|
return;
|
|
}
|
|
if(CRITICAL_FRESH.has(url.pathname)){event.respondWith(forceFresh(req));return;}
|
|
const freshAsset=/\.(?:js|css|webmanifest)$/i.test(url.pathname);
|
|
if(freshAsset){event.respondWith(networkFirst(req));return;}
|
|
event.respondWith(caches.match(req).then(cached=>cached||fetch(req,{cache:'no-store'}).then(res=>cachePut(req,res))));
|
|
});
|