Files
integration/website/public/widgets/dist/lagaufre.js
Sylvain Zimmer 720ee9f4f0 (widgets) import widgets code from Messages and setup Docker workflow (#33)
This adds Gaufre v2 with source, documentation, examples and built artefacts.
Also includes the feedback widget from Messages.
2025-11-19 15:18:21 +01:00

2 lines
8.5 KiB
JavaScript

(function(){"use strict";const F="#wrapper{display:flex;flex-direction:column;font-family:inherit}.wrapper-dialog{position:fixed;top:60px;right:60px;z-index:1000;width:340px;max-height:480px;background:#fff;border-radius:.25rem;box-shadow:0 0 6px #0000911a;border:1px solid #e5e5e5;overflow:hidden}#header{display:flex;justify-content:center;align-items:center;padding:4px 16px;background:transparent;border-bottom:1px solid #dfe2ea;min-height:48px;position:relative}#header-logo{height:25px;width:auto;object-fit:contain;display:block;margin:0 auto}#close{position:absolute;right:16px}#close{background:none;border:none;color:#64748b;cursor:pointer;font-size:36px;width:36px;height:36px;display:flex;align-items:center;justify-content:center;border-radius:4px;transition:background-color .2s}#close:hover{background-color:#f0f0f0}#close:focus{outline:2px solid #0a76f6}#footer{display:flex;padding:16px;background:transparent;border-top:1px solid #dfe2ea;justify-content:flex-end}#ok-button{background:#3e5de7;color:#fff;border:none;border-radius:6px;padding:8px 16px;font-size:14px;font-weight:600;cursor:pointer;transition:background-color .2s;min-width:60px}#ok-button:hover{background:#1d4ed8}#ok-button:focus{outline:2px solid #0a76f6}#content{flex:1;padding:16px;display:flex;flex-direction:column;overflow-y:auto;min-height:0}#loading{display:flex;align-items:center;justify-content:center;padding:40px 20px;color:#666;font-size:14px}#error{display:flex;align-items:center;justify-content:center;padding:40px 20px;color:#dc3545;font-size:14px;text-align:center}#services-grid{grid-template-columns:repeat(3,1fr);gap:4px;justify-items:center;list-style:none;padding:0;margin:0}.service-card{background:transparent;text-align:center;transition:all .2s ease;position:relative;display:flex;flex-direction:column;align-items:center;width:100%;list-style:none;padding:0;margin:0}.service-card:hover{background-color:#eef1f4;border-radius:6px}.service-card a{position:relative;padding:8px;width:100%;text-decoration:none;display:block}.service-logo{width:42px;height:42px;object-fit:contain}.maturity-badge{position:absolute;top:40px;left:50%;transform:translate(-50%);background:#eef1f4;color:#2845c1;border-radius:12px;padding:2px 4px;font-size:9px;line-height:9px;font-weight:700;text-transform:uppercase;letter-spacing:.3px;white-space:nowrap}.service-info{display:flex;flex-direction:column;align-items:center;width:100%;padding-top:4px}.service-name{font-weight:600;font-size:14px;color:#1e40af;margin-bottom:2px;line-height:1.2;text-align:center}@media (max-width: 480px){#wrapper{width:100%;inset:0!important;border-radius:0;max-height:100vh;position:fixed!important}#header{height:40px;display:flex}#header-logo{height:35px}#footer{display:flex}#services-grid{grid-template-columns:repeat(3,1fr);gap:12px}.service-card{width:70px;padding:6px}.service-logo,.service-logo-placeholder{width:40px;height:40px}.service-name{font-size:11px}}#content::-webkit-scrollbar{width:4px}#content::-webkit-scrollbar-track{background:transparent}#content::-webkit-scrollbar-thumb{background:#cbd5e1;border-radius:2px}#content::-webkit-scrollbar-thumb:hover{background:#94a3b8}";function D(e,t,n){const s=`lasuite-widget-${e}-shadow`,d=document.getElementById(s);d&&d.remove();const l=document.createElement("div");l.id=s;const r=l.attachShadow({mode:"open"}),p=document.createElement("style");p.textContent=n;const u=document.createElement("div");return u.innerHTML=t,r.appendChild(p),r.appendChild(u),l}const C="lasuite-widget",c=(e,t,n,s)=>document.dispatchEvent(new CustomEvent(`${C}-${e}-${t}`,n?{detail:n}:void 0)),m=(e,t,n,s,d)=>{const l=p=>d(p.detail),r=e?`${C}-${e}-${t}`:t;return(n||document).addEventListener(r,l,s?{once:!0}:void 0),()=>(n||document).removeEventListener(r,l,s?{once:!0}:void 0)},v=2,$=e=>window._lasuite_widget?._loaded?.[e],W=(e,t)=>{window._lasuite_widget?._loaded&&(window._lasuite_widget._loaded[e]=t)},B=e=>{window._lasuite_widget||(window._lasuite_widget=[]);const t=window._lasuite_widget;if(t._loaded||(t._loaded={}),$(e)!==v){t.push=(...n)=>{for(const s of n)$(s[0])===v?c(s[0],s[1],s[2]):t[t.length]=s;return t.length},W(e,v);for(const n of t.splice(0,t.length))t.push(n)}c(e,"loaded")},H=e=>e.offsetWidth>0&&e.offsetHeight>0,K=(e,t,n)=>{const s=d=>{if(d.key!=="Tab")return;const l=Array.from(t.querySelectorAll(n)).filter(u=>H(u));if(l.length===0)return;const r=l[0],p=l[l.length-1];d.shiftKey&&e.activeElement===r?(d.preventDefault(),p.focus()):!d.shiftKey&&e.activeElement===p&&(d.preventDefault(),r.focus())};return t.addEventListener("keydown",s),()=>{t.removeEventListener("keydown",s)}},M=e=>{const t=n=>{n.key==="Escape"&&(n.preventDefault(),e())};return document.addEventListener("keydown",t),()=>{document.removeEventListener("keydown",t)}},i="lagaufre";let w=!1;m(i,"init",null,!1,async e=>{if(!e.api&&!e.data){console.error("Missing API URL");return}w&&(c(i,"destroy"),await new Promise(o=>setTimeout(o,10)));const t=[];let n=!1;const s='<div id="wrapper" role="dialog" aria-modal="true" tabindex="-1">'+(e.headerLogo&&e.headerUrl?`<div id="header"><a href="${e.headerUrl}" target="_blank"><img src="${e.headerLogo}" id="header-logo"></a><button type="button" id="close">&times;</button></div>`:"")+'<div id="content"><div id="loading">Loading...</div><ul role="list" id="services-grid" style="display: none;"></ul><div id="error" style="display: none;"></div></div>'+(e.showFooter?'<div id="footer"><button id="ok-button">OK</button></div>':"")+"</div>",d=D(i,s,F),l=d.shadowRoot,r=l.querySelector("#wrapper"),p=l.querySelector("#loading"),u=l.querySelector("#services-grid"),k=l.querySelector("#error"),x=l.querySelector("#close"),q=l.querySelector("#ok-button"),z=l.querySelector("#header-logo"),E=o=>{const a=["top","bottom","left","right"],f=h=>{a.forEach(b=>{r.style[b]=typeof h[b]=="number"?`${h[b]}px`:"unset"})};if(a.every(h=>o[h]===void 0)||f(o),o.position)if(typeof o.position=="function"){const h=o.position();r.style.position=h.position,f(h)}else r.style.position=o.position;o.fontFamily&&(r.style.fontFamily=o.fontFamily),o.background&&(r.style.background=o.background);const g=o.label||"Services",y=o.closeLabel||"Close";p.textContent=o.loadingText||"Loading…",r.setAttribute("aria-label",g),x&&x.setAttribute("aria-label",y),z&&(z.alt=(o.headerLabel||"About LaSuite")+(o.newWindowLabelSuffix||""))};E(e),t.push(m("","resize",window,!1,()=>{E(e)})),r.style.display="none";const L=o=>{p.style.display="none",u.style.display="none",k.style.display="block",k.textContent=o},T=o=>{u.innerHTML="",o.services.forEach(a=>{if(!a.logo)return;a.maturity=="stable"&&delete a.maturity;const f=document.createElement("li");f.className="service-card",f.innerHTML=`<a target="_blank"><img alt="" class="service-logo" onerror="this.style.display='none'"><div class="service-info"><div class="service-name"></div></div></a>`;const g=f.querySelector("a"),y=f.querySelector("img"),h=f.querySelector(".service-name");if(a.maturity){const b=document.createElement("div");b.className="maturity-badge",b.textContent=a.maturity,g.insertBefore(b,y.nextSibling)}g.setAttribute("aria-label",a.name+(a.maturity?` (${a.maturity})`:"")+(e.newWindowLabelSuffix||"")),g.href=a.url,y.src=a.logo,h.textContent=a.name,u.appendChild(f)}),p.style.display="none",k.style.display="none",u.style.display="grid"};if(e.data)T(e.data);else try{const a=await(await fetch(e.api,{method:"GET"})).json();a.error?L(`Error: ${JSON.stringify(a.error)}`):a.services&&a.services.length>0?T(a):L("No services found")}catch(o){L(`Failed to load services: ${o instanceof Error?o.message:"Unknown error"}`)}const j=o=>{e.dialogElement||d.contains(o.target)||c(i,"close")};let S=null,_=null;t.push(m(i,"open",null,!1,()=>{r.style.display="block",setTimeout(()=>{n=!0,document.addEventListener("click",j),r.focus()},200),S=K(l,r,"a,button"),e.dialogElement||(_=M(()=>{c(i,"close")})),e.buttonElement&&e.buttonElement.setAttribute("aria-expanded","true"),c(i,"opened")})),t.push(m(i,"close",null,!1,()=>{S&&S(),_&&_(),n&&(r.style.display="none",n=!1,e.buttonElement&&(e.buttonElement.focus(),e.buttonElement.setAttribute("aria-expanded","false")),document.removeEventListener("click",j),c(i,"closed"))})),t.push(m(i,"toggle",null,!1,()=>{n?c(i,"close"):c(i,"open")})),t.push(m(i,"configure",null,!1,E)),q&&q.addEventListener("click",()=>{c(i,"close")}),x&&x.addEventListener("click",()=>{c(i,"close")}),e.buttonElement&&t.push(m("","click",e.buttonElement,!1,()=>{c(i,"toggle")})),e.dialogElement?e.dialogElement.appendChild(d):(r.className="wrapper-dialog",document.body.appendChild(d)),m(i,"destroy",null,!0,()=>{c(i,"close"),w=!1,d.remove(),t.forEach(o=>o())}),w=!0,c(i,"initialized"),e.open&&c(i,"open")}),B(i)})();