Remove temporary v17.6.6 patcher
This commit is contained in:
parent
2abcebe09a
commit
afa93ceab4
79
.github/scripts/patch-v1766-offers2.mjs
vendored
79
.github/scripts/patch-v1766-offers2.mjs
vendored
@ -1,79 +0,0 @@
|
|||||||
import fs from 'node:fs';
|
|
||||||
|
|
||||||
const VERSION='17.6.6';
|
|
||||||
const RELEASE='20260908-v17-6-6-offer-templates';
|
|
||||||
const read=f=>fs.readFileSync(f,'utf8');
|
|
||||||
const write=(f,s)=>fs.writeFileSync(f,s);
|
|
||||||
function exact(s,a,b,label){const n=s.split(a).length-1;if(n!==1)throw new Error(`${label}: expected 1 match, got ${n}`);return s.replace(a,b)}
|
|
||||||
function between(s,start,end,replacement,label){const a=s.indexOf(start);if(a<0)throw new Error(`${label}: start not found`);const b=s.indexOf(end,a+start.length);if(b<0)throw new Error(`${label}: end not found`);return s.slice(0,a)+replacement+s.slice(b)}
|
|
||||||
|
|
||||||
let runtime=read('public/app-runtime.js');
|
|
||||||
runtime=exact(runtime,
|
|
||||||
" const prepared=await preparedSnapshot(snapshot);prepared.offerTemplateId=offerTemplateId();",
|
|
||||||
" const prepared=await preparedSnapshot(snapshot);const explicitTemplate=String(snapshot?.offerTemplateId||prepared?.offerTemplateId||'').trim();prepared.offerTemplateId=OFFER_TEMPLATE_IDS.has(explicitTemplate)?explicitTemplate:offerTemplateId();",
|
|
||||||
'per-offer template');
|
|
||||||
runtime=exact(runtime,
|
|
||||||
" newPage();brandHeader();hero();sellingBlock();drawItems();summary();if(id==='editorial-grid'){pricing();infoCards()}else{infoCards();pricing()}footerNoteBlock();finalGalleryFill();",
|
|
||||||
" newPage();\n if(id==='editorial-grid'){brandHeader();hero();drawItems();summary();pricing();sellingBlock();infoCards();finalGalleryFill();footerNoteBlock();}\n else if(id==='midnight-glass'){brandHeader();hero();sellingBlock();summary();infoCards();drawItems();pricing();finalGalleryFill();footerNoteBlock();}\n else if(id==='emerald-gold'){brandHeader();hero();summary();sellingBlock();infoCards();pricing();drawItems();footerNoteBlock();finalGalleryFill();}\n else{brandHeader();hero();sellingBlock();drawItems();summary();infoCards();pricing();footerNoteBlock();finalGalleryFill();}",
|
|
||||||
'PDF layout sequence');
|
|
||||||
runtime=exact(runtime,
|
|
||||||
" {id:'light',name:'Светлый фирменный',desc:'Белый фон, фирменный зелёный и золото. Основной дизайн.',thumb:'offer-templates/thumb-light.jpg'},\n {id:'editorial-grid',name:'Солнце Editorial',desc:'Макет по референсу: крупный первый экран, компактное меню, фотосетка и итоги на одной визуальной системе.',thumb:'offer-templates/thumb-editorial-grid.jpg'},\n {id:'midnight-glass',name:'Midnight Glass',desc:'Двухколоночный макет: меню списком слева, реальные фото боксов мозаикой справа.',thumb:'offer-templates/thumb-midnight-glass.jpg'},\n {id:'emerald-gold',name:'Emerald Gold',desc:'Премиальная композиция: золотой итог в первом экране, меню слева и фотоколлаж справа.',thumb:'offer-templates/thumb-emerald-gold.jpg'}",
|
|
||||||
" {id:'light',name:'Светлый фирменный',desc:'Классическая A4-композиция: обложка, карточки меню, итог и условия.',thumb:'offer-templates/thumb-light.jpg'},\n {id:'editorial-grid',name:'Солнце Editorial',desc:'Журнальная композиция: крупный первый экран, меню-сетка, фотоблоки и редакционная подача.',thumb:'offer-templates/thumb-editorial-grid.jpg'},\n {id:'midnight-glass',name:'Midnight Glass',desc:'Тёмная презентация: стеклянные панели, итог до меню и контрастная двухколоночная композиция.',thumb:'offer-templates/thumb-midnight-glass.jpg'},\n {id:'emerald-gold',name:'Emerald Gold',desc:'Премиальный буклет: золотой итог на первом экране, условия и меню как финальная часть.',thumb:'offer-templates/thumb-emerald-gold.jpg'}",
|
|
||||||
'template descriptions');
|
|
||||||
|
|
||||||
const miniHelper=` function offerTemplateMini(id){\n if(id==='editorial-grid')return '<i class="mini-head"></i><i class="mini-editorial-hero"></i><i class="mini-editorial-stack a"></i><i class="mini-editorial-stack b"></i><i class="mini-editorial-grid"></i>';\n if(id==='midnight-glass')return '<i class="mini-head"></i><i class="mini-midnight-hero"></i><i class="mini-midnight-total"></i><i class="mini-midnight-left"></i><i class="mini-midnight-right"></i>';\n if(id==='emerald-gold')return '<i class="mini-head"></i><i class="mini-emerald-hero"></i><i class="mini-emerald-gold"></i><i class="mini-emerald-info"></i><i class="mini-emerald-menu"></i>';\n return '<i class="mini-head"></i><i class="mini-light-hero"></i><i class="mini-light-row a"></i><i class="mini-light-row b"></i><i class="mini-light-row c"></i><i class="mini-light-total"></i>';\n }\n`;
|
|
||||||
runtime=exact(runtime," function cardHtml(){\n const cur=selected();",miniHelper+" function cardHtml(){\n const cur=selected();",'settings mini helper');
|
|
||||||
runtime=exact(runtime,"<img class=\"sun-offer-template-thumb\" src=\"${esc(t.thumb)}\" alt=\"${esc(t.name)}\">","<div class=\"sun-offer-template-thumb sun-offer-template-mini sun-offer-template-mini-${esc(t.id)}\" data-template-mini=\"${esc(t.id)}\" aria-hidden=\"true\">${offerTemplateMini(t.id)}</div>",'settings mini preview');
|
|
||||||
write('public/app-runtime.js',runtime);
|
|
||||||
|
|
||||||
let ux=read('public/core/ux-fixes-v1764.js');
|
|
||||||
ux=exact(ux," const VERSION='17.6.4';"," const VERSION='17.6.6';",'ux version');
|
|
||||||
const pickerStart=" function pickerHtml(){";
|
|
||||||
const pickerEnd=" function ensureOfferPicker(){";
|
|
||||||
const pickerReplacement=` function offerTemplateMini(id){\n if(id==='editorial-grid')return '<i class="mini-head"></i><i class="mini-editorial-hero"></i><i class="mini-editorial-stack a"></i><i class="mini-editorial-stack b"></i><i class="mini-editorial-grid"></i>';\n if(id==='midnight-glass')return '<i class="mini-head"></i><i class="mini-midnight-hero"></i><i class="mini-midnight-total"></i><i class="mini-midnight-left"></i><i class="mini-midnight-right"></i>';\n if(id==='emerald-gold')return '<i class="mini-head"></i><i class="mini-emerald-hero"></i><i class="mini-emerald-gold"></i><i class="mini-emerald-info"></i><i class="mini-emerald-menu"></i>';\n return '<i class="mini-head"></i><i class="mini-light-hero"></i><i class="mini-light-row a"></i><i class="mini-light-row b"></i><i class="mini-light-row c"></i><i class="mini-light-total"></i>';\n }\n function pickerHtml(){\n const current=activeTemplateId();return \`<div class="sun-v1764-offer-template-head"><div><b>Оформление PDF</b><small>Шаблон закрепляется за этим предложением. Миниатюра повторяет структуру PDF.</small></div></div><div class="sun-v1764-offer-template-grid">\${templateList().map(t=>\`<button type="button" data-v1764-offer-template="\${esc(t.id)}" class="\${t.id===current?'on':''}"><div class="sun-offer-template-mini sun-offer-template-mini-\${esc(t.id)}" data-template-mini="\${esc(t.id)}" aria-hidden="true">\${offerTemplateMini(t.id)}</div><span>\${esc(t.name||t.id)}</span></button>\`).join('')}</div>\`;\n }\n`;
|
|
||||||
ux=between(ux,pickerStart,pickerEnd,pickerReplacement+pickerEnd,'offer picker');
|
|
||||||
|
|
||||||
const styleAnchor=" #sunOrderCards .sun-order-card[data-sun-auto-completed=\"1\"]{opacity:.88}";
|
|
||||||
const newCss=` header nav .nav-menu{--sun-icon:url("data:image/svg+xml,%3Csvg%20xmlns%3D%22http%3A%2F%2Fwww.w3.org%2F2000%2Fsvg%22%20viewBox%3D%220%200%2024%2024%22%20fill%3D%22none%22%20stroke%3D%22black%22%20stroke-width%3D%221.9%22%20stroke-linecap%3D%22round%22%20stroke-linejoin%3D%22round%22%3E%3Cpath%20d%3D%22M4%2018h16M6%2017a6%206%200%200%201%2012%200M12%2011V8M10.5%208h3M3%2020h18%22%2F%3E%3C%2Fsvg%3E")!important;display:flex!important;align-items:center!important;gap:0!important}\n .sun-enterprise-sidebar header nav .nav-menu>.sun-v1764-menu-icon{display:none!important}\n .sun-offer-template-mini{position:relative;display:block;width:100%;aspect-ratio:16/10;overflow:hidden;border-radius:8px;background:#fff;border:1px solid #e3e5e7;box-sizing:border-box}.sun-offer-template-mini i{position:absolute;display:block;border-radius:2px}.sun-offer-template-mini .mini-head{left:7%;right:7%;top:7%;height:6%;background:#c8b17a}.sun-offer-template-mini-light{background:#fbfaf6}.mini-light-hero{left:7%;right:7%;top:18%;height:24%;background:linear-gradient(90deg,#e9eee7 0 45%,#bdc8bb 45%)}.mini-light-row{left:7%;right:7%;height:10%;background:#eff1ed;border:1px solid #d8dcd5}.mini-light-row.a{top:47%}.mini-light-row.b{top:59%}.mini-light-row.c{top:71%}.mini-light-total{left:55%;right:7%;bottom:7%;height:12%;background:#d7e4d5}\n .sun-offer-template-mini-editorial-grid{background:#fbfaf6}.mini-editorial-hero{left:7%;top:18%;width:45%;height:35%;background:#dfe8df}.mini-editorial-stack{left:55%;right:7%;height:16%;background:#b8c9b7}.mini-editorial-stack.a{top:18%}.mini-editorial-stack.b{top:37%}.mini-editorial-grid{left:7%;right:7%;bottom:8%;height:32%;background:repeating-linear-gradient(90deg,#ece7dc 0 22%,transparent 22% 26%)}\n .sun-offer-template-mini-midnight-glass{background:#071621;border-color:#294a5b}.sun-offer-template-mini-midnight-glass .mini-head{background:#d5aa56}.mini-midnight-hero{left:7%;right:7%;top:18%;height:30%;background:linear-gradient(90deg,#12313b 0 57%,#31515b 57%)}.mini-midnight-total{left:7%;right:7%;top:53%;height:12%;background:#d5aa56}.mini-midnight-left{left:7%;width:54%;bottom:8%;height:22%;background:#0b2633;border:1px solid #315263}.mini-midnight-right{right:7%;width:27%;bottom:8%;height:22%;background:repeating-linear-gradient(0deg,#284856 0 30%,#102735 30% 34%)}\n .sun-offer-template-mini-emerald-gold{background:#061318;border-color:#314a4c}.sun-offer-template-mini-emerald-gold .mini-head{background:#d7ac55}.mini-emerald-hero{left:7%;right:7%;top:18%;height:38%;background:linear-gradient(90deg,#0c2d29 0 60%,#31534b 60%)}.mini-emerald-gold{left:10%;width:42%;top:43%;height:10%;background:#d7ac55}.mini-emerald-info{left:7%;right:57%;bottom:8%;height:27%;background:#0b2526;border:1px solid #67572f}.mini-emerald-menu{left:46%;right:7%;bottom:8%;height:27%;background:repeating-linear-gradient(0deg,#102c2d 0 17%,#67572f 17% 19%)}\n .sun-offer-template-option .sun-offer-template-mini{width:100%;aspect-ratio:16/9;border-radius:10px}.sun-offer-template-thumb.sun-offer-template-mini{height:auto;object-fit:initial}\n`;
|
|
||||||
ux=exact(ux,styleAnchor,newCss+styleAnchor,'insert template/menu css');
|
|
||||||
const decoStart=" function decorateMenuIcon(){";
|
|
||||||
const decoEnd=" let maintainTimer=0;";
|
|
||||||
const decoReplacement=` function decorateMenuIcon(){\n let changed=false;\n qa('header nav button.nav-menu,header nav button[data-nav-label="Меню"]').forEach(button=>{\n button.dataset.sunMenuIconV1766='1';button.querySelectorAll('.sun-v1764-menu-icon').forEach(x=>x.remove());\n let label=button.querySelector('span');if(!label){label=document.createElement('span');label.textContent='Меню';button.textContent='';button.appendChild(label)}else label.textContent='Меню';changed=true;\n });\n qa('#new .catalog-head button').filter(b=>String(b.textContent||'').trim()==='Меню').forEach(button=>{if(button.dataset.sunMenuIconV1764==='1')return;button.dataset.sunMenuIconV1764='1';button.classList.add('sun-v1764-menu-action');button.innerHTML=\`\${menuSvg}<span>Меню</span>\`;changed=true});\n return changed;\n }\n\n`;
|
|
||||||
ux=between(ux,decoStart,decoEnd,decoReplacement+decoEnd,'menu decorator');
|
|
||||||
write('public/core/ux-fixes-v1764.js',ux);
|
|
||||||
|
|
||||||
let perf=read('public/core/performance.js');
|
|
||||||
perf=exact(perf," const VERSION='17.6.5';\n const RELEASE='20260908-v17-6-5-stability';",` const VERSION='${VERSION}';\n const RELEASE='${RELEASE}';`,'performance version');
|
|
||||||
write('public/core/performance.js',perf);
|
|
||||||
|
|
||||||
let index=read('public/index.html');
|
|
||||||
const oldToken='20260908-v17-6-5-stability';if(!index.includes(oldToken))throw new Error('index old cache token missing');index=index.split(oldToken).join(RELEASE);write('public/index.html',index);
|
|
||||||
let sw=read('public/service-worker.js');
|
|
||||||
if(!/const CACHE='sun-catering-pwa-v\d+-[^']+';\nconst VERSION='[^']+';/.test(sw))throw new Error('service worker version header missing');sw=sw.replace(/const CACHE='sun-catering-pwa-v\d+-[^']+';\nconst VERSION='[^']+';/,`const CACHE='sun-catering-pwa-v71-${RELEASE}';\nconst VERSION='${RELEASE}';`);write('public/service-worker.js',sw);
|
|
||||||
|
|
||||||
const pkg=JSON.parse(read('package.json'));pkg.version=VERSION;write('package.json',JSON.stringify(pkg,null,2)+'\n');
|
|
||||||
const lock=JSON.parse(read('package-lock.json'));lock.version=VERSION;if(lock.packages?.[''])lock.packages[''].version=VERSION;write('package-lock.json',JSON.stringify(lock,null,2)+'\n');
|
|
||||||
|
|
||||||
let security=read('tests/static-security.mjs');
|
|
||||||
security=security.replaceAll('v17-6-5-stability','v17-6-6-offer-templates').replaceAll('20260908-v17-6-5-stability',RELEASE).replace("else ok('PWA cache updated to v17.6.5')","else ok('PWA cache updated to v17.6.6')");
|
|
||||||
security=security.replace("if(!performance.includes('ux-fixes-v1764.js')||!performance.includes('SunUXFixV1764'))fail('v17.6.4 UX fix loader missing');else ok('v17.6.4 UX fix loader present');","if(!performance.includes('ux-fixes-v1764.js')||!performance.includes('SunUXFixV1764'))fail('UX fix loader missing');else ok('UX fix loader present');");
|
|
||||||
security=security.replace("if(!hotfix.includes('checkPlatformAdmin?.(false)')||!hotfix.includes('},10000);'))fail('Developer fallback polling is still aggressive');else ok('Developer fallback polling is throttled');","if(!hotfix.includes('checkPlatformAdmin?.(false)')||!hotfix.includes('},10000);'))fail('Developer fallback polling is still aggressive');else ok('Developer fallback polling is throttled');\nif(!ux.includes('sunMenuIconV1766')||!ux.includes('sun-offer-template-mini-editorial-grid')||!runtime.includes('explicitTemplate'))fail('v17.6.6 proposal/menu markers missing');else ok('v17.6.6 proposal/menu markers present');");
|
|
||||||
write('tests/static-security.mjs',security);
|
|
||||||
|
|
||||||
let releaseCheck=read('tests/release-check.mjs');
|
|
||||||
releaseCheck=releaseCheck.replace("check(sw.includes('v17-6-5-stability')&&sw.includes('ux-fixes-v1764.js'),'service worker cache is v17.6.5');",`check(sw.includes('v17-6-6-offer-templates')&&sw.includes('ux-fixes-v1764.js'),'service worker cache is v17.6.6');`)
|
|
||||||
.replace("check(index.includes('20260908-v17-6-5-stability')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.6.5');",`check(index.includes('${RELEASE}')&&!index.includes('20260907-v17-6-0-stability-security'),'index cache-busting points to v17.6.6');`)
|
|
||||||
.replace("check(ux.includes('sun-v1764-menu-icon')&&ux.includes('<svg'),'menu uses a styled SVG icon');","check(ux.includes('sunMenuIconV1766')&&ux.includes('--sun-icon:url('),'menu uses the native sidebar mask icon without a duplicate square');")
|
|
||||||
.replace("check(String(releaseManifest.pwaCache||'').includes('v17-6-5'),'release manifest points to current PWA cache');","check(String(releaseManifest.pwaCache||'').includes('v17-6-6'),'release manifest points to current PWA cache');")
|
|
||||||
.replace("check(['17.6.2','17.6.3','17.6.4','17.6.5'].every(v=>fs.existsSync(path.join(root,`docs/releases/V${v}-CHANGES.txt`))),'release notes exist through v17.6.5');","check(['17.6.2','17.6.3','17.6.4','17.6.5','17.6.6'].every(v=>fs.existsSync(path.join(root,`docs/releases/V${v}-CHANGES.txt`))),'release notes exist through v17.6.6');");
|
|
||||||
releaseCheck=releaseCheck.replace("if(bad)process.exit(1);",`check(runtime.includes('explicitTemplate')&&runtime.includes("OFFER_TEMPLATE_IDS.has(explicitTemplate)"),'per-order proposal template survives render and PDF');\ncheck(runtime.includes("else if(id==='midnight-glass')")&&runtime.includes("else if(id==='emerald-gold')")&&runtime.includes("if(id==='editorial-grid')"),'four proposal templates use distinct PDF layout sequences');\ncheck(runtime.includes('data-template-mini')&&ux.includes('data-template-mini'),'global and per-offer selectors show structural PDF previews');\nif(bad)process.exit(1);`);
|
|
||||||
write('tests/release-check.mjs',releaseCheck);
|
|
||||||
|
|
||||||
let spec=read('tests/app.spec.mjs');
|
|
||||||
spec=spec.replace("expect(result.version).toBe('17.6.5');","expect(result.version).toBe('17.6.6');");
|
|
||||||
spec += `\n\ntest('v17.6.6 Menu sidebar icon uses native mask and has no duplicate inline SVG', async ({ page }) => {\n await page.goto('/index.html',{waitUntil:'domcontentloaded'});\n await page.evaluate(()=>{let nav=document.querySelector('header nav');if(!nav){const h=document.createElement('header');nav=document.createElement('nav');h.appendChild(nav);document.body.prepend(h)}let b=nav.querySelector('.nav-menu');if(!b){b=document.createElement('button');b.className='sun-nav-button nav-menu';b.dataset.navLabel='Меню';b.textContent='Меню';nav.appendChild(b)}document.body.classList.add('sun-enterprise-sidebar')});\n await injectCore(page,'ux-fixes-v1764.js','SunUXFixV1764');\n const r=await page.evaluate(()=>{const b=document.querySelector('.nav-menu'),p=getComputedStyle(b,'::before');return {inline:b.querySelectorAll('.sun-v1764-menu-icon').length,mask:p.maskImage||p.webkitMaskImage,width:parseFloat(p.width),height:parseFloat(p.height)}});\n expect(r.inline).toBe(0);expect(r.mask).not.toBe('none');expect(r.width).toBeLessThanOrEqual(22);expect(r.height).toBeLessThanOrEqual(22);\n});\n\ntest('v17.6.6 proposal templates preserve selection and expose four structural previews', async () => {\n const runtimeSource=fs.readFileSync(path.join(process.cwd(),'public','app-runtime.js'),'utf8');\n const uxSource=fs.readFileSync(path.join(process.cwd(),'public','core','ux-fixes-v1764.js'),'utf8');\n expect(runtimeSource).toContain("OFFER_TEMPLATE_IDS.has(explicitTemplate)");\n for(const marker of ['mini-light-hero','mini-editorial-hero','mini-midnight-total','mini-emerald-gold'])expect(runtimeSource+uxSource).toContain(marker);\n});\n`;
|
|
||||||
write('tests/app.spec.mjs',spec);
|
|
||||||
|
|
||||||
const manifestPath='docs/release-manifest.json';const manifest=JSON.parse(read(manifestPath));Object.assign(manifest,{version:'v17.6.6',channel:'production',pwaCache:`v71-${RELEASE}`,release:RELEASE,offerTemplates:4,offerTemplatePerOrder:true,offerTemplateStructuralPreviews:true,offerPdfDistinctLayouts:true,menuNavMaskFixed:true,notes:'Four proposal templates now keep the per-order choice and use distinct PDF compositions. Menu sidebar icon uses the native mask system without the yellow square.'});write(manifestPath,JSON.stringify(manifest,null,2)+'\n');
|
|
||||||
write('docs/releases/V17.6.6-CHANGES.txt',`Caterium v17.6.6 — Proposal templates and Menu icon\nDate: 2026-09-08\n\n- Removed the yellow square and duplicate icon next to Menu. The item now uses the same 20px masked sidebar icon system as Stock and Routes.\n- Fixed per-order proposal template selection being overwritten by the global template during rendering.\n- Four PDF templates now use different section composition, not only different colors.\n- Template pickers use structural mini-previews matching the intended PDF hierarchy.\n- PWA cache v71 / ${RELEASE}.\n`);
|
|
||||||
console.log('Applied Caterium v17.6.6');
|
|
||||||
Loading…
Reference in New Issue
Block a user