hotsheet 0.6.1 → 0.6.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(()=>{var kn=Object.defineProperty;var wn=(e,t,n)=>t in e?kn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var ue=(e,t,n)=>wn(e,typeof t!="symbol"?t+"":t,n);var Re=!1;function H(){Re=!0}function kt(){let e=new Map;return document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t.dataset.id;e.set(n,t.getBoundingClientRect())}),e}function Te(e){if(Re){Re=!1;return}e.size!==0&&document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t,a=n.dataset.id,o=e.get(a);if(!o)return;let i=n.getBoundingClientRect(),l=o.left-i.left,c=o.top-i.top;if(Math.abs(l)<1&&Math.abs(c)<1)return;n.style.transform=`translate(${l}px, ${c}px)`,n.offsetHeight,n.style.transition="transform 200ms ease-out",n.style.transform="";let d=()=>{n.style.transition=""};n.addEventListener("transitionend",d,{once:!0}),setTimeout(d,250)})}function v(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function wt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function Et(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}var J=class{constructor(t){ue(this,"__html");this.__html=t}toString(){return this.__html}};function D(e){return new J(e)}var En=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function qe(e){return e==null||typeof e=="boolean"?"":e instanceof J?e.__html:typeof e=="string"?wt(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(qe).join(""):""}var Tn={className:"class",htmlFor:"for",httpEquiv:"http-equiv",acceptCharset:"accept-charset",accessKey:"accesskey",autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",colSpan:"colspan",contentEditable:"contenteditable",crossOrigin:"crossorigin",dateTime:"datetime",defaultChecked:"checked",defaultValue:"value",encType:"enctype",formAction:"formaction",formEncType:"formenctype",formMethod:"formmethod",formNoValidate:"formnovalidate",formTarget:"formtarget",hrefLang:"hreflang",inputMode:"inputmode",maxLength:"maxlength",minLength:"minlength",noModule:"nomodule",noValidate:"novalidate",readOnly:"readonly",referrerPolicy:"referrerpolicy",rowSpan:"rowspan",spellCheck:"spellcheck",srcDoc:"srcdoc",srcLang:"srclang",srcSet:"srcset",tabIndex:"tabindex",useMap:"usemap",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",fillOpacity:"fill-opacity",fillRule:"fill-rule",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",floodColor:"flood-color",floodOpacity:"flood-opacity",lightingColor:"lighting-color",stopColor:"stop-color",stopOpacity:"stop-opacity",shapeRendering:"shape-rendering",imageRendering:"image-rendering",textRendering:"text-rendering",pointerEvents:"pointer-events",vectorEffect:"vector-effect",paintOrder:"paint-order",fontFamily:"font-family",fontSize:"font-size",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",fontStretch:"font-stretch",textAnchor:"text-anchor",textDecoration:"text-decoration",dominantBaseline:"dominant-baseline",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",letterSpacing:"letter-spacing",wordSpacing:"word-spacing",writingMode:"writing-mode",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",markerStart:"marker-start",markerMid:"marker-mid",markerEnd:"marker-end",gradientUnits:"gradientUnits",gradientTransform:"gradientTransform",spreadMethod:"spreadMethod",patternUnits:"patternUnits",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",maskUnits:"maskUnits",maskContentUnits:"maskContentUnits",filterUnits:"filterUnits",primitiveUnits:"primitiveUnits",clipPathUnits:"clipPathUnits",xlinkHref:"xlink:href",xlinkShow:"xlink:show",xlinkActuate:"xlink:actuate",xlinkType:"xlink:type",xlinkRole:"xlink:role",xlinkTitle:"xlink:title",xlinkArcrole:"xlink:arcrole",xmlBase:"xml:base",xmlLang:"xml:lang",xmlSpace:"xml:space",xmlns:"xmlns",xmlnsXlink:"xmlns:xlink",stdDeviation:"stdDeviation",baseFrequency:"baseFrequency",numOctaves:"numOctaves",kernelMatrix:"kernelMatrix",surfaceScale:"surfaceScale",specularConstant:"specularConstant",specularExponent:"specularExponent",diffuseConstant:"diffuseConstant",pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",limitingConeAngle:"limitingConeAngle",tableValues:"tableValues"};function xn(e,t){let n=Tn[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${n}`;let a;return t instanceof J?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=Et(t):a="",` ${n}="${a}"`}function r(e,t){if(typeof e=="function")return e(t);let{children:n,...a}=t,o=Object.entries(a).map(([l,c])=>xn(l,c)).join("");if(En.has(e))return new J(`<${e}${o}>`);let i=n!=null?qe(n):"";return new J(`<${e}${o}>${i}</${e}>`)}function pe({children:e}){return new J(e!=null?qe(e):"")}function Tt(e){document.getElementById("network-error-popup")?.remove();let t=v(r("div",{id:"network-error-popup",className:"error-popup",children:r("div",{className:"error-popup-content",children:[r("strong",{children:"Connection Error"}),r("p",{children:e}),r("button",{children:"Dismiss"})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function f(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}async function xt(e,t){try{let n=new FormData;return n.append("file",t),(await fetch("/api"+e,{method:"POST",body:n})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}var Ln={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},s={tickets:[],customViews:[],categories:[{id:"issue",label:"Issue",shortLabel:"ISS",color:"#6b7280",shortcutKey:"i",description:""},{id:"bug",label:"Bug",shortLabel:"BUG",color:"#ef4444",shortcutKey:"b",description:""},{id:"feature",label:"Feature",shortLabel:"FEA",color:"#22c55e",shortcutKey:"f",description:""},{id:"requirement_change",label:"Req Change",shortLabel:"REQ",color:"#f97316",shortcutKey:"r",description:""},{id:"task",label:"Task",shortLabel:"TSK",color:"#3b82f6",shortcutKey:"k",description:""},{id:"investigation",label:"Investigation",shortLabel:"INV",color:"#8b5cf6",shortcutKey:"g",description:""}],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...Ln},backupPreview:null},In='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="m8 18 4 4 4-4"/><path d="m8 6 4-4 4 4"/></svg>',Cn={highest:"\u2B06\u2B06",high:"\u2B06",default:In,low:"\u2B07",lowest:"\u2B07\u2B07"},Sn={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Lt='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-7.5 7.5L13 16"/></svg>',Mn={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:Lt,backlog:"\u25A1",archive:"\u25A0"},Ue=Lt;function C(e){return s.categories.find(n=>n.id===e)?.color||"#6b7280"}function K(e){return s.categories.find(n=>n.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function A(e){return Cn[e]||"\u2014"}function P(e){return Sn[e]||"#6b7280"}function z(e){return Mn[e]||"\u25CB"}function V(e){if(!e||e==="[]")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim())}catch{}return[]}function ge(e,t){let n=document.getElementById("detail-tags");if(n){n.innerHTML="";for(let a of e){let o=v(r("span",{className:"tag-chip",children:[a,t?null:r("button",{className:"tag-chip-remove","data-tag":a,title:"Remove tag",children:"\xD7"})]}));t||o.querySelector(".tag-chip-remove").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let i=s.tickets.find(d=>d.id===s.activeTicketId);if(!i)return;let c=V(i.tags).filter(d=>d!==a);await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(c)}}),i.tags=JSON.stringify(c),ge(c,!1)}),n.appendChild(o)}}}var $n={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},Nn={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function fe(e){let t=document.getElementById("detail-category");t.dataset.value=e;let n=s.categories.find(o=>o.id===e),a=C(e);t.innerHTML=`<span class="cat-dot" style="background:${a}"></span> ${n?.label||e}`}function xe(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${P(e)}">${A(e)}</span> ${Nn[e]||e}`}function Le(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${z(e)}</span> ${$n[e]||e}`}function te(e){s.activeTicketId=e,Ve(e)}function St(){s.selectedIds.clear(),s.activeTicketId=null,ne();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ne(){let e=s.view==="trash",t=!!s.backupPreview?.active,n=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),o=document.getElementById("detail-header"),i=document.getElementById("detail-body"),l=document.getElementById("detail-placeholder"),c=document.getElementById("detail-placeholder-text");if(e){n.style.display="none",a&&(a.style.display="none"),s.activeTicketId=null;return}if(n.style.display="flex",a&&(a.style.display=""),s.selectedIds.size===1){let d=Array.from(s.selectedIds)[0];n.classList.remove("detail-disabled"),o.style.display="",i.style.display="",l.style.display="none",s.activeTicketId!==d&&(s.activeTicketId=d,t?Bn(d):Ve(d))}else s.activeTicketId=null,n.classList.add("detail-disabled"),o.style.display="none",i.style.display="none",l.style.display="",s.selectedIds.size===0?c.textContent="Nothing selected":c.textContent=`${s.selectedIds.size} items selected`}function Mt(e){let t=document.getElementById("detail-title"),n=document.getElementById("detail-details"),a=document.getElementById("detail-category"),o=document.getElementById("detail-priority"),i=document.getElementById("detail-status"),l=document.getElementById("detail-upnext"),c=document.querySelector(".upload-btn");t.readOnly=e,n.readOnly=e,a.disabled=e,o.disabled=e,i.disabled=e,l.disabled=e,c&&(c.style.display=e?"none":"")}function Bn(e){let t=s.backupPreview?.tickets.find(l=>l.id===e);if(!t||s.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,fe(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details,Mt(!0),document.getElementById("detail-attachments").innerHTML="",ge(V(t.tags),!0);let a=document.getElementById("detail-notes"),o=$t(t.notes);o.length>0?a.innerHTML=r(pe,{children:o.map(l=>r("div",{className:"note-entry",children:[l.created_at?r("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:l.text})]}))}).toString():a.innerHTML="";let i=document.getElementById("detail-meta");i.innerHTML=r(pe,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ye(){s.activeTicketId!=null&&Ve(s.activeTicketId)}async function Ve(e){let t=await f(`/tickets/${e}`);if(s.activeTicketId!==e)return;Mt(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,fe(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details;let a=document.getElementById("detail-attachments");t.attachments.length>0?a.innerHTML=r(pe,{children:t.attachments.map(i=>r("div",{className:"attachment-item",children:[r("span",{className:"attachment-name",children:i.original_filename}),r("button",{className:"attachment-reveal","data-att-id":String(i.id),title:"Show in file manager",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r("path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"})})}),r("button",{className:"attachment-delete","data-att-id":String(i.id),title:"Remove",children:"\xD7"})]}))}).toString():a.innerHTML="",ge(V(t.tags),!1),Oe(t.id,$t(t.notes));let o=document.getElementById("detail-meta");o.innerHTML=r(pe,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function It(e,t){let n=s.tickets.find(a=>a.id===e);n&&(n.notes=JSON.stringify(t))}function Oe(e,t){let n=document.getElementById("detail-notes");if(n){if(n.innerHTML="",t.length===0){n.innerHTML='<div class="notes-empty">No notes added</div>';return}for(let a of t){let o=v(r("div",{className:"note-entry",children:[a.created_at?r("div",{className:"note-timestamp",children:new Date(a.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:a.text})]}));o.addEventListener("click",()=>{let i=o.querySelector(".note-text");if(o.querySelector(".note-edit-area"))return;let l=document.createElement("textarea");l.className="note-edit-area",l.value=a.text,l.rows=3,i.style.display="none",o.appendChild(l),l.focus();let c=async()=>{let d=l.value.trim();if(d&&d!==a.text){let u=s.tickets.find(m=>m.id===e),p=t.map(m=>m.id===a.id?{...m,text:d}:m);u&&me(u,"Edit note",JSON.stringify(p)),await f(`/tickets/${e}/notes/${a.id}`,{method:"PATCH",body:{text:d}}),a.text=d,It(e,t)}Oe(e,t)};l.addEventListener("blur",()=>{c()}),l.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)&&(d.preventDefault(),c()),d.key==="Escape"&&(d.stopPropagation(),l.blur())})}),o.addEventListener("contextmenu",i=>{i.preventDefault(),document.querySelectorAll(".note-context-menu").forEach(c=>c.remove());let l=v(r("div",{className:"note-context-menu context-menu",style:`top:${i.clientY}px;left:${i.clientX}px`,children:r("div",{className:"context-menu-item danger",children:r("span",{className:"context-menu-label",children:"Delete Note"})})}));l.querySelector(".context-menu-item").addEventListener("click",async c=>{c.stopPropagation(),l.remove();let d=s.tickets.find(m=>m.id===e),u=t.filter(m=>m.id!==a.id);d&&me(d,"Delete note",JSON.stringify(u)),await f(`/tickets/${e}/notes/${a.id}`,{method:"DELETE"});let p=t.indexOf(a);p>=0&&t.splice(p,1),It(e,t),Oe(e,t)}),document.body.appendChild(l),setTimeout(()=>{let c=()=>{l.remove(),document.removeEventListener("click",c)};document.addEventListener("click",c)},0)}),n.appendChild(o)}}}var _n=0;function Ct(){return`cn_${Date.now().toString(36)}_${(_n++).toString(36)}`}function $t(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map(n=>({id:n.id||Ct(),text:n.text,created_at:n.created_at}))}catch{}return e.trim()?[{id:Ct(),text:e,created_at:""}]:[]}async function Ie(){try{let e=await f("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function Ke(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function ze(){let e=document.getElementById("detail-panel");s.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${s.settings.detail_height}px`):(e.style.height="",e.style.width=`${s.settings.detail_width}px`)}function Nt(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),n=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",o=>{o.preventDefault(),a=!0,document.body.style.cursor=s.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",o=>{if(!a)return;let i=n.getBoundingClientRect();if(s.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,i.bottom-o.clientY));s.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,i.right-o.clientX));s.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",s.settings.detail_position==="bottom"?f("/settings",{method:"PATCH",body:{detail_height:String(s.settings.detail_height)}}):f("/settings",{method:"PATCH",body:{detail_width:String(s.settings.detail_width)}}))})}var Fe=class{constructor(){ue(this,"undoStack",[]);ue(this,"redoStack",[])}push(t){console.log("[undo] push:",t.label,"stack depth:",this.undoStack.length+1,"before:",JSON.stringify(t.before),"after:",JSON.stringify(t.after)),this.undoStack.push(t),this.undoStack.length>1e3&&this.undoStack.shift(),this.redoStack=[]}coalesce(t){if(t.coalescingKey==null||t.coalescingKey==="")return!1;let n=this.peekUndo();return!n||n.coalescingKey!==t.coalescingKey||t.timestamp-n.timestamp>=5e3?!1:(n.after=t.after,!0)}popUndo(){let t=this.undoStack.pop();return t&&this.redoStack.push(t),t}popRedo(){let t=this.redoStack.pop();return t&&this.undoStack.push(t),t}peekUndo(){return this.undoStack[this.undoStack.length-1]}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}},M=new Fe;function F(e,t=!1){let n={id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next};return t&&(n.notes=e.notes),n}async function R(e,t,n){let a=F(e),o=await f(`/tickets/${e.id}`,{method:"PATCH",body:t}),i=F(o);return M.push({label:n,timestamp:Date.now(),before:[a],after:[i]}),o}function Ce(e,t,n){let a=`${e.id}:${t}`,o=Date.now(),i={...F(e),[t]:n},l={label:`Edit ${t}`,timestamp:o,before:[F(e)],after:[i],coalescingKey:a};M.coalesce(l)||M.push(l)}async function I(e,t,n){let a=e.map(i=>F(i));await f("/tickets/batch",{method:"POST",body:t});let o=a.map(i=>{let l={...i};return t.action==="category"?l.category=t.value:t.action==="priority"?l.priority=t.value:t.action==="status"?l.status=t.value:t.action==="up_next"?l.up_next=t.value:t.action==="delete"&&(l.status="deleted"),l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function We(e,t,n){let a=e.map(i=>F(i));for(let i of t)await f("/tickets/batch",{method:"POST",body:i});let o=a.map(i=>{let l={...i};for(let c of t)c.ids.includes(i.id)&&(c.action==="status"?l.status=c.value:c.action==="up_next"?l.up_next=c.value:c.action==="category"?l.category=c.value:c.action==="priority"?l.priority=c.value:c.action==="delete"&&(l.status="deleted"));return l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function Se(e){let t=F(e);await f(`/tickets/${e.id}`,{method:"DELETE"});let n={...t,status:"deleted"};M.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Bt(e){let t=F(e);await f(`/tickets/${e.id}/restore`,{method:"POST"});let n={...t,status:"not_started"};M.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[n]})}async function _t(e){for(let t of e)t.status==="deleted"?await f(`/tickets/${t.id}`,{method:"DELETE"}):(await f(`/tickets/${t.id}`,{method:"PATCH",body:{title:t.title,details:t.details,category:t.category,priority:t.priority,status:t.status,up_next:t.up_next}}),t.notes!==void 0&&await f(`/tickets/${t.id}/notes-bulk`,{method:"PUT",body:{notes:t.notes}}))}var Y=!1;async function Ht(){if(console.log("[undo] performUndo, inFlight:",Y,"canUndo:",M.canUndo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),Y=!0;try{await _t(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ye(),50)}finally{Y=!1}}async function Dt(){if(console.log("[undo] performRedo, inFlight:",Y,"canRedo:",M.canRedo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),Y=!0;try{await _t(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ye(),50)}finally{Y=!1}}function me(e,t,n){let a=F(e,!0),o={...F(e,!0),notes:n};M.push({label:t,timestamp:Date.now(),before:[a],after:[o]})}function At(){return M.canUndo()}function Pt(){return M.canRedo()}function Ye(e,t){e.preventDefault(),G(),s.selectedIds.has(t.id)||(s.selectedIds.clear(),s.selectedIds.add(t.id),s.lastClickedId=t.id,L());let n=v(r("div",{className:"context-menu",style:`top:${e.clientY}px;left:${e.clientX}px`}));je(n,"Category",s.categories.map(i=>({label:i.label,icon:`<span class="dropdown-dot" style="background-color:${i.color}"></span>`,active:t.category===i.id,action:()=>ae("category",i.id)}))),je(n,"Priority",[{value:"highest",label:"Highest"},{value:"high",label:"High"},{value:"default",label:"Default"},{value:"low",label:"Low"},{value:"lowest",label:"Lowest"}].map(i=>({label:i.label,icon:A(i.value),iconColor:P(i.value),active:t.priority===i.value,action:()=>ae("priority",i.value)}))),je(n,"Status",[{value:"not_started",label:"Not Started"},{value:"started",label:"Started"},{value:"completed",label:"Completed"},{value:"verified",label:"Verified"}].map(i=>({label:i.label,icon:z(i.value),active:t.status===i.value,action:()=>ae("status",i.value)}))),se(n,t.up_next?"\u2605 Up Next":"\u2606 Up Next",()=>{ae("up_next",!t.up_next)}),Je(n),se(n,"Tags...",()=>{document.dispatchEvent(new CustomEvent("hotsheet:show-tags-dialog"))}),se(n,"Duplicate",async()=>{let i=Array.from(s.selectedIds),l=await f("/tickets/duplicate",{method:"POST",body:{ids:i}});s.selectedIds.clear();for(let c of l)s.selectedIds.add(c.id);w()}),Je(n),se(n,"Move to Backlog",()=>ae("status","backlog")),se(n,"Archive",()=>ae("status","archive")),Je(n),se(n,"Delete",async()=>{if(s.selectedIds.size===1)await Se(t);else{let i=Array.from(s.selectedIds),l=s.tickets.filter(c=>s.selectedIds.has(c.id));await I(l,{ids:i,action:"delete"},"Delete")}s.selectedIds.clear(),w()},!0),document.body.appendChild(n),Hn(n),setTimeout(()=>{document.addEventListener("click",G),document.addEventListener("contextmenu",G)},0)}function G(){document.querySelectorAll(".context-menu").forEach(e=>e.remove()),document.removeEventListener("click",G),document.removeEventListener("contextmenu",G)}function Hn(e){let t=e.getBoundingClientRect();t.right>window.innerWidth-8&&(e.style.left=`${window.innerWidth-t.width-8}px`),t.bottom>window.innerHeight-8&&(e.style.top=`${window.innerHeight-t.height-8}px`)}async function ae(e,t){let n=Array.from(s.selectedIds),a=s.tickets.filter(o=>s.selectedIds.has(o.id));if(n.length===1){let o=a[0];await R(o,{[e]:t},`Change ${e}`)}else await I(a,{ids:n,action:e,value:t},`Change ${e}`);w()}function je(e,t,n){let a=v(r("div",{className:"context-menu-item has-submenu",children:[r("span",{className:"context-menu-label",children:t}),r("span",{className:"context-menu-arrow",children:"\u25B8"})]})),o=v(r("div",{className:"context-submenu"}));for(let i of n){let l=v(r("div",{className:`context-menu-item${i.active?" active":""}`,children:[i.icon?r("span",{className:"dropdown-icon",style:i.iconColor?`color:${i.iconColor}`:"",children:D(i.icon)}):null,r("span",{className:"context-menu-label",children:i.label})]}));l.addEventListener("click",c=>{c.stopPropagation(),i.action(),G()}),o.appendChild(l)}a.appendChild(o),e.appendChild(a)}function se(e,t,n,a=!1){let o=v(r("div",{className:`context-menu-item${a?" danger":""}`,children:r("span",{className:"context-menu-label",children:t})}));o.addEventListener("click",i=>{i.stopPropagation(),G(),n()}),e.appendChild(o)}function Je(e){e.appendChild(v(r("div",{className:"context-menu-separator"})))}function $(e,t){let n=t.getBoundingClientRect(),a=e.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight,l=n.left;l+a.width>o-8&&(l=n.right-a.width),l<8&&(l=8);let c=n.bottom+4;c+a.height>i-8&&(c=n.top-a.height-4),c<8&&(c=8),e.style.left=`${l}px`,e.style.top=`${c}px`}function N(e,t){let n=v(r("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(d=>d.separator?r("div",{className:"dropdown-separator"}):r("button",{className:`dropdown-item${d.active?" active":""}`,"data-key":d.key,children:[d.color?r("span",{className:"dropdown-dot",style:`background-color:${d.color}`}):null,d.icon?r("span",{className:"dropdown-icon",style:d.iconColor?`color:${d.iconColor}`:"",children:D(d.icon)}):null,r("span",{className:"dropdown-label",children:d.label}),d.shortcut?r("kbd",{className:"dropdown-kbd",children:d.shortcut}):null]}))})),a=t.filter(d=>!d.separator);n.querySelectorAll(".dropdown-item").forEach((d,u)=>{d.addEventListener("click",()=>{a[u].action(),n.remove()})});function i(d){let u=t.find(p=>d.key.toLowerCase()===p.key.toLowerCase());u?(d.preventDefault(),d.stopPropagation(),u.action(),l()):d.key==="Escape"&&(d.preventDefault(),l())}function l(){n.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",c)}function c(){l()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",c)},0),n}function B(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var oe=null;function Ze(){oe&&(clearTimeout(oe),oe=null)}var ve=!1,he=null,Xe="",U=[];function Me(){return s.categories.map(e=>({key:e.shortcutKey,value:e.id,label:e.label}))}var Ge=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function Dn(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let n=t.dataset.id;return n!==void 0&&n!==""?parseInt(n,10):null}function An(e){e!=null&&(ve=!0,e==="draft"?W():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),ve=!1)}function $e(){let e=s.view;return e.startsWith("custom:")?!0:e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function Ut(){return s.view==="up-next"||s.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:s.view==="non-verified"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"}]:[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"},{status:"verified",label:"Verified"}]}function L(){let e=kt(),t=!!s.backupPreview?.active;if(s.layout==="columns"&&$e()){if(t){Rn(),Te(e);return}Un(),Te(e);return}let n=s.view==="trash",a=t?null:Dn(),o=null;if(a!=null&&a!=="draft"){let c=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);c&&(o=c.value)}let i=document.getElementById("ticket-list"),l=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!n&&!t&&i.appendChild(zt()),s.tickets.length===0){let c=n?"Trash is empty":t?"No tickets match this view":"";c&&i.appendChild(v(r("div",{className:"ticket-list-empty",children:c})))}for(let c of s.tickets)t?i.appendChild(Pn(c)):n?i.appendChild(Fn(c)):i.appendChild(zn(c));if(i.scrollTop=l,t){let c=document.getElementById("batch-toolbar");c&&(c.style.display="none"),be(),ne()}else{let c=document.getElementById("batch-toolbar");if(c&&(c.style.display=""),a!=null&&a!=="draft"&&o!=null){let d=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);d&&d.value!==o&&(d.value=o)}An(a),ie()}Ie(),Te(e)}function Pn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)};cursor:default`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:D(a?Ue:z(e.status))}),r("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return o.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ne()}),o}function Ot(e){let t={scrollLeft:0,columns:{}},n=e.querySelector(".columns-container");return n&&(t.scrollLeft=n.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&(t.columns[o]=i.scrollTop)})),t}function Vt(e,t){let n=e.querySelector(".columns-container");n&&(n.scrollLeft=t.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&t.columns[o]!=null&&(i.scrollTop=t.columns[o])}))}function Rn(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns");let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let i of n){let l=s.tickets.filter(u=>u.status===i.status),c=v(r("div",{className:"column","data-status":i.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:i.label}),r("span",{className:"column-count",children:String(l.length)})]}),r("div",{className:"column-body"})]})),d=c.querySelector(".column-body");for(let u of l)d.appendChild(qn(u));a.appendChild(c)}e.appendChild(a),Vt(e,t);let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),Ie()}function qn(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]}));return n.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,Kt(),ne()}),n}function Un(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(zt());let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let o of n){let i=s.tickets.filter(d=>d.status===o.status),l=v(r("div",{className:"column","data-status":o.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:o.label}),r("span",{className:"column-count",children:String(i.length)})]}),r("div",{className:"column-body"})]})),c=l.querySelector(".column-body");for(let d of i)c.appendChild(On(d));c.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),c.addEventListener("dragleave",d=>{let u=d.relatedTarget;(!u||!c.contains(u))&&l.classList.remove("column-drop-target")}),c.addEventListener("drop",d=>{d.preventDefault(),l.classList.remove("column-drop-target");let u=U;if(U=[],u.length===0)return;let p=s.tickets.filter(m=>u.includes(m.id));H(),I(p,{ids:u,action:"status",value:o.status},"Change status").then(()=>{w()})}),a.appendChild(l)}e.appendChild(a),Vt(e,t),ie(),Ie()}function On(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]})),a=n.querySelector(".ticket-category-badge");a.addEventListener("click",i=>{i.stopPropagation(),Jt(a,e)});let o=n.querySelector(".ticket-priority-indicator");return o.addEventListener("click",i=>{i.stopPropagation(),Yt(o,e)}),n.querySelector(".ticket-star").addEventListener("click",i=>{i.stopPropagation(),jt(e)}),n.addEventListener("contextmenu",i=>{Ye(i,e)}),n.draggable=!0,n.addEventListener("dragstart",i=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],i.dataTransfer.setData("text/plain",JSON.stringify(U)),i.dataTransfer.effectAllowed="move"}),n.addEventListener("dragend",()=>{U=[]}),n.addEventListener("click",i=>{if(i.metaKey||i.ctrlKey)s.selectedIds.has(e.id)?s.selectedIds.delete(e.id):s.selectedIds.add(e.id),s.lastClickedId=e.id;else if(i.shiftKey&&s.lastClickedId!=null){let l=s.tickets.find(c=>c.id===s.lastClickedId);if(l&&l.status===e.status){let d=s.tickets.filter(m=>m.status===e.status).map(m=>m.id),u=d.indexOf(s.lastClickedId),p=d.indexOf(e.id);if(u!==-1&&p!==-1){let m=Math.min(u,p),g=Math.max(u,p);s.selectedIds.clear();for(let y=m;y<=g;y++)s.selectedIds.add(d[y])}}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id;Kt(),ie()}),n}function Kt(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);s.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function zt(){let e=Ft(),t=s.view.startsWith("category:"),n=v(r("div",{className:"ticket-row draft-row",children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),r("span",{className:"ticket-category-badge draft-badge",style:`background-color:${C(e)}${t?"":";cursor:pointer;opacity:1"}`,children:K(e)}),r("span",{className:"ticket-number draft-number"}),r("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:Xe}),r("span",{className:"ticket-priority-indicator draft-placeholder"}),r("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let o=n.querySelector(".ticket-category-badge");o.addEventListener("click",i=>{i.stopPropagation(),Kn(o)})}let a=n.querySelector(".draft-input");return a.addEventListener("input",()=>{Xe=a.value}),a.addEventListener("keydown",async o=>{if(o.key==="Enter"&&a.value.trim()){o.preventDefault();let i=a.value.trim();Xe="",a.value="";let l=Vn();he&&!s.view.startsWith("category:")&&(l.category=he);let c=await f("/tickets",{method:"POST",body:{title:i,defaults:l}});c&&(s.selectedIds.clear(),s.selectedIds.add(c.id)),await w(),W()}else o.key==="ArrowDown"&&(o.preventDefault(),s.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${s.tickets[0].id}"] .ticket-title-input`)?.focus())}),n}function W(){document.querySelector(".draft-row .draft-input")?.focus()}function Vn(){let e=s.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e==="backlog"?{status:"backlog"}:e==="archive"?{status:"archive"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function Ft(){if(he)return he;let e=s.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Kn(e){B();let n=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=Ft(),o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${n}${i.key.toUpperCase()}`,color:C(i.value),active:a===i.value,action:()=>{he=i.value,L(),W()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function zn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:D(a?Ue:z(e.status))}),r("input",{type:"text",className:"ticket-title-input",value:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));o.addEventListener("mousedown",u=>{let p=u.target;p.tagName!=="INPUT"&&p.tagName!=="BUTTON"&&(o.draggable=!0)}),o.addEventListener("mouseup",()=>{o.draggable=!1}),o.addEventListener("dragend",()=>{o.draggable=!1,U=[]}),o.addEventListener("contextmenu",u=>{Ye(u,e)}),o.addEventListener("dragstart",u=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],u.dataTransfer.setData("text/plain",JSON.stringify(U)),u.dataTransfer.effectAllowed="move"}),o.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),Wt(u,e)&&u.stopPropagation())});let i=o.querySelector(".ticket-checkbox");i.addEventListener("click",u=>u.stopPropagation()),i.addEventListener("change",()=>{i.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),o.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),Yn(e)});let l=o.querySelector(".ticket-category-badge");l.addEventListener("click",u=>{u.stopPropagation(),Jt(l,e)});let c=o.querySelector(".ticket-title-input");c.addEventListener("focus",()=>{ve||s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ie())}),c.addEventListener("input",()=>{Ce(e,"title",c.value),Gn(e.id,{title:c.value})}),c.addEventListener("keydown",u=>{Wn(u,e,c)});let d=o.querySelector(".ticket-priority-indicator");return d.addEventListener("click",u=>{u.stopPropagation(),Yt(d,e)}),o.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),jt(e)}),o}function Fn(e){let t=s.selectedIds.has(e.id),n=e.deleted_at?new Date(e.deleted_at):null,a=v(r("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),r("span",{className:"ticket-number",title:n?`Deleted: ${n.toLocaleString()}`:"",children:n?n.toLocaleDateString():""}),r("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",i=>{(i.metaKey||i.ctrlKey||i.shiftKey)&&(i.preventDefault(),Wt(i,e)&&i.stopPropagation())});let o=a.querySelector(".ticket-checkbox");return o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("change",()=>{o.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),a.querySelector(".trash-title").addEventListener("click",()=>{s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ie())}),a.querySelector(".btn").addEventListener("click",async i=>{i.stopPropagation(),await Bt(e),w()}),a}function Wt(e,t){let n=e.metaKey||e.ctrlKey,a=e.shiftKey;if(n)s.selectedIds.has(t.id)?s.selectedIds.delete(t.id):s.selectedIds.add(t.id),s.lastClickedId=t.id,L();else if(a&&s.lastClickedId!=null){let o=s.tickets.map(c=>c.id),i=o.indexOf(s.lastClickedId),l=o.indexOf(t.id);if(i!==-1&&l!==-1){let c=Math.min(i,l),d=Math.max(i,l);s.selectedIds.clear();for(let u=c;u<=d;u++)s.selectedIds.add(o[u])}L()}else return!1;return!0}function Wn(e,t,n){if(e.key==="Enter")e.preventDefault(),W();else if(e.key==="Backspace"&&n.value==="")e.preventDefault(),Xn(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),Rt(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),Rt(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),jn(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Jn(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Me().some(a=>a.key===e.key)){e.preventDefault();let a=Me().find(o=>o.key===e.key);qt(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&Ge.some(a=>a.key===e.key)){e.preventDefault();let a=Ge.find(o=>o.key===e.key);qt(t,"priority",a.value)}}function jn(e){let t=s.tickets.findIndex(n=>n.id===e);t<s.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${s.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Jn(e){let t=s.tickets.findIndex(n=>n.id===e);t>0?document.querySelector(`.ticket-row[data-id="${s.tickets[t-1].id}"] .ticket-title-input`)?.focus():W()}function Rt(e,t){let a=s.tickets.findIndex(l=>l.id===e)+t;if(a<0||a>=s.tickets.length)return;let o=s.tickets[a].id;s.selectedIds.add(e),s.selectedIds.has(o)?s.selectedIds.delete(e):s.selectedIds.add(o),ve=!0,document.querySelector(`.ticket-row[data-id="${o}"] .ticket-title-input`)?.focus(),ve=!1,be(),ie()}async function Yn(e){let n={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await R(e,{status:n},"Change status");Object.assign(e,a),L()}async function jt(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await R(e,{status:"not_started",up_next:!0},"Toggle up next"):await R(e,{up_next:!e.up_next},"Toggle up next"),w(),document.dispatchEvent(new CustomEvent("hotsheet:upnext-changed"))}async function qt(e,t,n){let a=await R(e,{[t]:n},`Change ${t}`);Object.assign(e,a),L()}async function Xn(e){let t=s.tickets.findIndex(a=>a.id===e),n=s.tickets.find(a=>a.id===e);if(n?await Se(n):await f(`/tickets/${e}`,{method:"DELETE"}),s.tickets=s.tickets.filter(a=>a.id!==e),s.selectedIds.delete(e),L(),t>0&&s.tickets.length>0){let a=Math.min(t-1,s.tickets.length-1);document.querySelector(`.ticket-row[data-id="${s.tickets[a].id}"] .ticket-title-input`)?.focus()}else W()}function Gn(e,t){oe&&clearTimeout(oe),oe=setTimeout(()=>{f(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Jt(e,t){B();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${a}${i.key.toUpperCase()}`,color:C(i.value),active:t.category===i.value,action:async()=>{let l=await R(t,{category:i.value},"Change category");Object.assign(t,l),L()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function Yt(e,t){B();let n=N(e,Ge.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,icon:A(a.value),iconColor:P(a.value),active:t.priority===a.value,action:async()=>{let o=await R(t,{priority:a.value},"Change priority");Object.assign(t,o),L()}})));document.body.appendChild(n),$(n,e),n.style.visibility=""}function be(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),n=e.querySelector(".ticket-checkbox");s.selectedIds.has(t)?(e.classList.add("selected"),n&&(n.checked=!0)):(e.classList.remove("selected"),n&&(n.checked=!1))})}function ie(){let e=s.selectedIds.size,t=s.tickets.length,n=e>0,a=s.view==="trash",o=document.getElementById("batch-select-all");o.checked=t>0&&e===t,o.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=n?`${e} selected`:"";let i=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let p of i){let m=document.getElementById(p);m.style.display=a?"none":"",a||(m.disabled=!n)}let l=document.getElementById("batch-restore"),c=document.getElementById("batch-empty-trash");if(a){let p=document.getElementById("batch-toolbar");l||(l=v(r("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),l.addEventListener("click",async()=>{await f("/tickets/batch",{method:"POST",body:{ids:Array.from(s.selectedIds),action:"restore"}}),s.selectedIds.clear(),w()}),p.insertBefore(l,document.getElementById("batch-count"))),l.disabled=!n,l.style.display="",c||(c=v(r("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),c.addEventListener("click",async()=>{await f("/trash/empty",{method:"POST"}),s.selectedIds.clear(),w()}),p.insertBefore(c,document.getElementById("batch-count"))),c.disabled=t===0,c.style.display=""}else l&&(l.style.display="none"),c&&(c.style.display="none");let d=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!a&&d&&n){let p=s.tickets.filter(y=>s.selectedIds.has(y.id)),m=p.every(y=>y.up_next),g=p.every(y=>!y.up_next);m?(d.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):g?(d.textContent="\u2606",u.classList.remove("active","mixed")):(d.innerHTML=r("span",{className:"star-mixed-wrap",children:[r("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),u.classList.remove("active"),u.classList.add("mixed"))}else d&&(d.textContent="\u2606",u.classList.remove("active","mixed"));ne()}async function w(){if(s.backupPreview?.active){Zn();return}if(s.view.startsWith("custom:")){let n=s.view.slice(7),a=s.customViews.find(o=>o.id===n);a?s.tickets=await f("/tickets/query",{method:"POST",body:{logic:a.logic,conditions:a.conditions,sort_by:s.sortBy,sort_dir:s.sortDir}}):s.tickets=[],L();return}let e=new URLSearchParams;s.view==="trash"?e.set("status","deleted"):s.view==="up-next"?e.set("up_next","true"):s.view==="open"?e.set("status","open"):s.view==="completed"?e.set("status","completed"):s.view==="non-verified"?e.set("status","non_verified"):s.view==="verified"?e.set("status","verified"):s.view==="backlog"?e.set("status","backlog"):s.view==="archive"?e.set("status","archive"):s.view.startsWith("category:")?e.set("category",s.view.split(":")[1]):s.view.startsWith("priority:")?e.set("priority",s.view.split(":")[1]):e.set("status","active"),s.search&&e.set("search",s.search),e.set("sort_by",s.sortBy),e.set("sort_dir",s.sortDir);let t=e.toString();s.tickets=await f(`/tickets${t?"?"+t:""}`),L()}function Zn(){let e=[...s.backupPreview?.tickets||[]];if(s.view==="trash")e=e.filter(t=>t.status==="deleted");else if(s.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(s.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(s.view==="completed")e=e.filter(t=>t.status==="completed");else if(s.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(s.view==="verified")e=e.filter(t=>t.status==="verified");else if(s.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(s.view==="archive")e=e.filter(t=>t.status==="archive");else if(s.view.startsWith("category:")){let t=s.view.split(":")[1];e=e.filter(n=>n.category===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else if(s.view.startsWith("priority:")){let t=s.view.split(":")[1];e=e.filter(n=>n.priority===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(s.search){let t=s.search.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.ticket_number.toLowerCase().includes(t)||n.details&&n.details.toLowerCase().includes(t))}s.tickets=e,L()}function Qn(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;let a=Math.floor(n/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function ea(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ta(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function Qe(){var t;let e=document.getElementById("backup-list");if(e)try{let n=await f("/backups");if(n.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let o of n.backups)(a[t=o.tier]||(a[t]=[])).push(o);e.innerHTML="";for(let o of["5min","hourly","daily"]){let i=a[o];if(!(!i||i.length===0)){e.appendChild(v(r("div",{className:"backup-tier-label",children:ta(o)})));for(let l of i){let c=v(r("div",{className:"backup-row","data-tier":l.tier,"data-filename":l.filename,children:[r("span",{className:"backup-row-time",children:Qn(l.createdAt)}),r("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",ea(l.sizeBytes)]})]}));c.addEventListener("click",()=>{na(l.tier,l.filename,l.createdAt)}),e.appendChild(c)}}}}catch{e.textContent="Failed to load backups."}}async function na(e,t,n){let a=document.getElementById("settings-overlay");a.style.display="none";let o=document.getElementById("backup-preview-banner"),i=document.getElementById("backup-preview-label");i.textContent="Loading backup preview...",o.style.display="flex";try{let l=await f(`/backups/preview/${e}/${t}`);s.backupPreview={active:!0,tickets:l.tickets,timestamp:n,tier:e,filename:t},s.selectedIds.clear(),s.activeTicketId=null,i.textContent=`Previewing backup from ${new Date(n).toLocaleString()} (${l.stats.total} tickets, ${l.stats.open} open) \u2014 read-only`,w()}catch{i.textContent="Failed to load backup preview.",setTimeout(()=>{o.style.display="none"},3e3)}}async function aa(){let e=document.getElementById("backup-preview-banner");e.style.display="none",s.backupPreview=null,s.selectedIds.clear(),s.activeTicketId=null,await f("/backups/preview/cleanup",{method:"POST"}),w()}async function sa(){if(!s.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await f("/backups/restore",{method:"POST",body:{tier:s.backupPreview.tier,filename:s.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Xt(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{aa()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{sa()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await f("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",Qe())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}var Be,Z=null;function Qt(e){Be=e,document.getElementById("add-custom-view-btn").addEventListener("click",t=>{t.stopPropagation(),nt()})}async function en(){try{let e=await f("/settings");if(e.custom_views){let t=JSON.parse(e.custom_views);Array.isArray(t)&&(s.customViews=t)}}catch{}et()}function et(){let e=document.getElementById("custom-views-container");if(e&&(e.innerHTML="",s.customViews.length!==0)){e.appendChild(v(r("div",{className:"sidebar-divider"})));for(let t=0;t<s.customViews.length;t++){let n=s.customViews[t],a=v(r("button",{className:`sidebar-item sidebar-custom-view${s.view===`custom:${n.id}`?" active":""}`,"data-view":`custom:${n.id}`,"data-cv-index":String(t),draggable:"true",children:n.name}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`custom:${n.id}`,s.selectedIds.clear(),H(),Be()}),a.addEventListener("dblclick",o=>{o.preventDefault(),nt(n)}),a.addEventListener("contextmenu",o=>{o.preventDefault(),ra(a,n)}),a.addEventListener("dragstart",o=>{Z=t,o.dataTransfer.setData("text/plain",String(t)),o.dataTransfer.effectAllowed="move",setTimeout(()=>a.classList.add("dragging"),0)}),a.addEventListener("dragend",()=>{a.classList.remove("dragging"),Z=null}),a.addEventListener("dragover",o=>{Z!==null&&(o.preventDefault(),o.dataTransfer.dropEffect="move",a.classList.add("drop-target"))}),a.addEventListener("dragleave",()=>{a.classList.remove("drop-target")}),a.addEventListener("drop",o=>{if(o.preventDefault(),a.classList.remove("drop-target"),Z===null||Z===t)return;let[i]=s.customViews.splice(Z,1);s.customViews.splice(t,0,i),Z=null,tt()}),e.appendChild(a)}}}var oa='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>',ia='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>';function ra(e,t){B();let n=N(e,[{label:"Edit",key:"e",icon:oa,action:()=>nt(t)},{label:"Delete",key:"d",icon:ia,action:()=>la(t.id)}]);document.body.appendChild(n),$(n,e),n.style.visibility=""}async function tt(){await f("/settings",{method:"PATCH",body:{custom_views:JSON.stringify(s.customViews)}}),et()}async function la(e){s.customViews=s.customViews.filter(t=>t.id!==e),s.view===`custom:${e}`&&(s.view="all",document.querySelectorAll(".sidebar-item").forEach(t=>{t.classList.toggle("active",t.dataset.view==="all")}),Be()),await tt()}var Ne=[{value:"category",label:"Category",type:"select"},{value:"priority",label:"Priority",type:"ordinal"},{value:"status",label:"Status",type:"ordinal"},{value:"title",label:"Title",type:"text"},{value:"details",label:"Details",type:"text"},{value:"up_next",label:"Up Next",type:"boolean"},{value:"tags",label:"Tags",type:"text"}];function Gt(e){return e==="ordinal"?[{value:"equals",label:"="},{value:"not_equals",label:"\u2260"},{value:"lt",label:"<"},{value:"lte",label:"\u2264"},{value:"gt",label:">"},{value:"gte",label:"\u2265"}]:e==="select"?[{value:"equals",label:"is"},{value:"not_equals",label:"is not"}]:e==="boolean"?[{value:"equals",label:"is"}]:[{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"}]}var ca=["highest","high","default","low","lowest"],da=["not_started","started","completed","verified","backlog","archive"];function Zt(e){return e==="category"?s.categories.map(t=>t.id):e==="priority"?ca:e==="status"?da:e==="up_next"?["true","false"]:null}function ua(e,t){return e==="category"?s.categories.find(a=>a.id===t)?.label||t:e==="status"?t.replace(/_/g," "):e==="up_next"?t==="true"?"Yes":"No":t}function nt(e){let t=!!e,n=e?e.conditions.map(d=>({...d})):[],a=e?.logic||"all",o=e?.name||"",i=v(r("div",{className:"custom-view-editor-overlay",children:r("div",{className:"custom-view-editor",children:[r("div",{className:"custom-view-editor-header",children:[r("span",{children:t?"Edit Custom View":"New Custom View"}),r("button",{className:"detail-close",id:"cv-editor-close",children:"\xD7"})]}),r("div",{className:"custom-view-editor-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"Name"}),r("input",{type:"text",id:"cv-name",value:o,placeholder:"View name..."})]}),r("div",{className:"cv-logic-row",children:[r("span",{children:"Match"}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"all",checked:a==="all"})," All of"]}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"any",checked:a==="any"})," Any of"]})]}),r("div",{id:"cv-conditions"}),r("button",{className:"btn btn-sm",id:"cv-add-condition",style:"margin-top:8px",children:"+ Add Condition"})]}),r("div",{className:"custom-view-editor-footer",children:[r("button",{className:"btn btn-sm",id:"cv-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"cv-save",children:"Save"})]})]})}));function l(){let d=i.querySelector("#cv-conditions");d.innerHTML="",n.forEach((u,p)=>{let m=Ne.find(T=>T.value===u.field)||Ne[0],g=Gt(m.type),y=Zt(u.field),b=v(r("div",{className:"cv-condition-row",children:[r("select",{className:"cv-field-select",children:Ne.map(T=>r("option",{value:T.value,selected:T.value===u.field,children:T.label}))}),r("select",{className:"cv-op-select",children:g.map(T=>r("option",{value:T.value,selected:T.value===u.operator,children:T.label}))}),y?r("select",{className:"cv-value-select",children:y.map(T=>r("option",{value:T,selected:T===u.value,children:ua(u.field,T)}))}):r("input",{type:"text",className:"cv-value-input",value:u.value,placeholder:"Value..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),E=b.querySelector(".cv-field-select"),x=b.querySelector(".cv-op-select"),k=b.querySelector(".cv-value-select")||b.querySelector(".cv-value-input");E.addEventListener("change",()=>{let T=E.value,_=Ne.find(ee=>ee.value===T),ce=Gt(_.type);n[p].field=T,n[p].operator=ce[0].value;let Q=Zt(T);n[p].value=Q?Q[0]:"",l()}),x.addEventListener("change",()=>{n[p].operator=x.value}),k.addEventListener("change",()=>{n[p].value=k.value}),k.tagName==="INPUT"&&k.addEventListener("input",()=>{n[p].value=k.value}),b.querySelector(".category-delete-btn").addEventListener("click",()=>{n.splice(p,1),l()}),d.appendChild(b)})}l(),document.body.appendChild(i),i.querySelector("#cv-name").focus(),i.querySelectorAll('input[name="cv-logic"]').forEach(d=>{d.addEventListener("change",()=>{a=d.value})}),i.querySelector("#cv-add-condition").addEventListener("click",()=>{n.push({field:"category",operator:"equals",value:s.categories[0]?.id||"issue"}),l()});let c=()=>i.remove();i.querySelector("#cv-editor-close").addEventListener("click",c),i.querySelector("#cv-cancel").addEventListener("click",c),i.addEventListener("click",d=>{d.target===i&&c()}),i.querySelector("#cv-save").addEventListener("click",async()=>{if(o=i.querySelector("#cv-name").value.trim(),!o){i.querySelector("#cv-name").focus();return}let d={id:e?.id||o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`view-${Date.now()}`,name:o,logic:a,conditions:n.filter(u=>u.value!=="")};if(t){let u=s.customViews.findIndex(p=>p.id===e.id);u>=0?s.customViews[u]=d:s.customViews.push(d)}else s.customViews.push(d);await tt(),document.querySelectorAll(".sidebar-item").forEach(u=>u.classList.remove("active")),s.view=`custom:${d.id}`,s.selectedIds.clear(),et(),Be(),c()})}var re=30;async function st(e){e.innerHTML='<div class="dashboard-loading">Loading dashboard...</div>';try{let t=await f(`/dashboard?days=${re}`);e.innerHTML="",e.appendChild(pa(t))}catch{e.innerHTML='<div class="dashboard-loading">Failed to load dashboard data.</div>'}}function pa(e){let t=v(r("div",{className:"dashboard"})),n=v(r("div",{className:"dashboard-range-bar",children:[r("button",{className:`btn btn-sm${re===7?" active":""}`,"data-days":"7",children:"7 days"}),r("button",{className:`btn btn-sm${re===30?" active":""}`,"data-days":"30",children:"30 days"}),r("button",{className:`btn btn-sm${re===90?" active":""}`,"data-days":"90",children:"90 days"})]}));n.querySelectorAll("button").forEach(m=>{m.addEventListener("click",()=>{re=parseInt(m.dataset.days,10);let g=document.getElementById("dashboard-container");g&&st(g)})}),t.appendChild(n);let a=e.kpi,o=a.completedLastWeek>0?Math.round((a.completedThisWeek-a.completedLastWeek)/a.completedLastWeek*100):0,i=o>0?"\u2191":o<0?"\u2193":"",l=a.createdThisWeek>0?(a.completedThisWeek/a.createdThisWeek).toFixed(1):"\u2014";t.appendChild(v(r("div",{className:"dashboard-kpi-row",children:[r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.completedThisWeek)}),r("div",{className:"kpi-label",children:"Completed this week"}),i?r("div",{className:`kpi-trend${o>0?" up":" down"}`,children:[i," ",Math.abs(o),"%"]}):null]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:a.medianCycleTimeDays!==null?`${a.medianCycleTimeDays}d`:"\u2014"}),r("div",{className:"kpi-label",children:"Median cycle time"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.wipCount)}),r("div",{className:"kpi-label",children:"In progress"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(l)}),r("div",{className:"kpi-label",children:"Completed / created"})]})]})));let c=v(r("div",{className:"dashboard-grid"})),d=ke("Throughput","Items completed per day. Shows your sustainable delivery pace.",ma(e.throughput));at(d,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#3b82f6",value:m.completed}]}))),c.appendChild(d);let u=ke("Created vs Completed","Compares items created (orange) vs completed (green) over time. When created outpaces completed, the backlog grows.",ga(e.throughput));at(u,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#22c55e",value:m.completed},{label:"Created",color:"#f97316",value:m.created}]}))),c.appendChild(u);let p=ke("Cumulative Flow","Stacked area showing ticket counts by status over time. Widening bands indicate bottlenecks. A healthy flow has consistent band widths.",fa(e.snapshots));return at(p,e.snapshots.map(m=>({date:m.date,lines:[{label:"Not Started",color:"#6b7280",value:m.data.not_started},{label:"Started",color:"#3b82f6",value:m.data.started},{label:"Completed",color:"#22c55e",value:m.data.completed},{label:"Verified",color:"#8b5cf6",value:m.data.verified}]}))),c.appendChild(p),c.appendChild(ke("Category Breakdown","Distribution of tickets by category. Left: currently open. Right: all tickets active in the selected time period.",ya(e.categoryBreakdown,e.categoryPeriod))),c.appendChild(ke("Cycle Time","Each dot is a completed ticket plotted by completion date and days to complete. Dashed lines show 50th and 85th percentile delivery times.",va(e.cycleTime))),t.appendChild(c),t}function ke(e,t,n){let a=v(r("div",{className:"dashboard-chart-card",children:[r("div",{className:"dashboard-chart-header",children:[r("span",{className:"dashboard-chart-title",children:e}),r("button",{className:"dashboard-info-btn",title:"About this chart",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r("circle",{cx:"12",cy:"12",r:"10"}),r("path",{d:"M12 16v-4"}),r("path",{d:"M12 8h.01"})]})})]}),r("div",{className:"dashboard-chart-info",style:"display:none",children:t}),r("div",{className:"dashboard-chart-body",children:D(n)})]})),o=a.querySelector(".dashboard-info-btn"),i=a.querySelector(".dashboard-chart-info");return o.addEventListener("click",l=>{l.stopPropagation(),i.style.display=i.style.display==="none"?"":"none"}),a}function at(e,t){let n=e.querySelector(".dashboard-chart-body");if(!n||t.length===0)return;let a=document.createElement("div");a.className="chart-cursor",a.style.display="none",n.style.position="relative",n.appendChild(a);let o=document.createElement("div");o.className="chart-tooltip",o.style.display="none",n.appendChild(o);let i=n.querySelector("svg");i&&(i.addEventListener("mousemove",l=>{let c=i.getBoundingClientRect(),d=n.getBoundingClientRect(),u=c.left-d.left,p=c.top-d.top,m=q/c.width,g=O/c.height,y=(l.clientX-c.left)*m,b=q-h.left-h.right,E=Math.max(0,Math.min(1,(y-h.left)/b)),x=Math.round(E*(t.length-1));if(x<0||x>=t.length)return;let k=h.left+x/Math.max(t.length-1,1)*b,T=u+k/m,_=p+h.top/g,ce=(O-h.top-h.bottom)/g;a.style.display="",a.style.left=`${T}px`,a.style.top=`${_}px`,a.style.height=`${ce}px`;let Q=t[x];o.style.display="",o.innerHTML=`<div class="chart-tooltip-date">${ot(Q.date)}</div>${Q.lines.map(de=>`<div class="chart-tooltip-row"><span class="chart-legend-dot" style="background:${de.color}"></span>${de.label}: <b>${de.value}</b></div>`).join("")}`;let ee=T+10;ee+120>d.width?o.style.left=`${T-120}px`:o.style.left=`${ee}px`,o.style.top=`${l.clientY-d.top-10}px`}),i.addEventListener("mouseleave",()=>{a.style.display="none",o.style.display="none"}))}var q=400,O=180,h={top:10,right:10,bottom:25,left:35};function ma(e){if(e.length===0)return'<div class="chart-empty">No data</div>';let t=e.map(c=>c.completed),n=Math.max(...t,1),a=q-h.left-h.right,o=O-h.top-h.bottom,i=Math.max(2,a/e.length-2),l="";for(let c=0;c<e.length;c++){let d=h.left+c/e.length*a,u=t[c]/n*o,p=h.top+o-u,m=ot(e[c].date);l+=`<rect x="${d}" y="${p}" width="${i}" height="${u}" fill="#3b82f6" rx="1" opacity="0.8" class="chart-hover"><title>${m}: ${t[c]} completed</title></rect>`}return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
|
|
1
|
+
"use strict";(()=>{var kn=Object.defineProperty;var wn=(e,t,n)=>t in e?kn(e,t,{enumerable:!0,configurable:!0,writable:!0,value:n}):e[t]=n;var pe=(e,t,n)=>wn(e,typeof t!="symbol"?t+"":t,n);var Re=!1;function H(){Re=!0}function kt(){let e=new Map;return document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t.dataset.id;e.set(n,t.getBoundingClientRect())}),e}function Te(e){if(Re){Re=!1;return}e.size!==0&&document.querySelectorAll(".ticket-row[data-id], .column-card[data-id]").forEach(t=>{let n=t,a=n.dataset.id,o=e.get(a);if(!o)return;let i=n.getBoundingClientRect(),l=o.left-i.left,c=o.top-i.top;if(Math.abs(l)<1&&Math.abs(c)<1)return;n.style.transform=`translate(${l}px, ${c}px)`,n.offsetHeight,n.style.transition="transform 200ms ease-out",n.style.transform="";let d=()=>{n.style.transition=""};n.addEventListener("transitionend",d,{once:!0}),setTimeout(d,250)})}function v(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function wt(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function Et(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}var J=class{constructor(t){pe(this,"__html");this.__html=t}toString(){return this.__html}};function D(e){return new J(e)}var En=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function qe(e){return e==null||typeof e=="boolean"?"":e instanceof J?e.__html:typeof e=="string"?wt(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(qe).join(""):""}var Tn={className:"class",htmlFor:"for",httpEquiv:"http-equiv",acceptCharset:"accept-charset",accessKey:"accesskey",autoCapitalize:"autocapitalize",autoComplete:"autocomplete",autoFocus:"autofocus",autoPlay:"autoplay",colSpan:"colspan",contentEditable:"contenteditable",crossOrigin:"crossorigin",dateTime:"datetime",defaultChecked:"checked",defaultValue:"value",encType:"enctype",formAction:"formaction",formEncType:"formenctype",formMethod:"formmethod",formNoValidate:"formnovalidate",formTarget:"formtarget",hrefLang:"hreflang",inputMode:"inputmode",maxLength:"maxlength",minLength:"minlength",noModule:"nomodule",noValidate:"novalidate",readOnly:"readonly",referrerPolicy:"referrerpolicy",rowSpan:"rowspan",spellCheck:"spellcheck",srcDoc:"srcdoc",srcLang:"srclang",srcSet:"srcset",tabIndex:"tabindex",useMap:"usemap",strokeWidth:"stroke-width",strokeLinecap:"stroke-linecap",strokeLinejoin:"stroke-linejoin",strokeDasharray:"stroke-dasharray",strokeDashoffset:"stroke-dashoffset",strokeMiterlimit:"stroke-miterlimit",strokeOpacity:"stroke-opacity",fillOpacity:"fill-opacity",fillRule:"fill-rule",clipPath:"clip-path",clipRule:"clip-rule",colorInterpolation:"color-interpolation",colorInterpolationFilters:"color-interpolation-filters",floodColor:"flood-color",floodOpacity:"flood-opacity",lightingColor:"lighting-color",stopColor:"stop-color",stopOpacity:"stop-opacity",shapeRendering:"shape-rendering",imageRendering:"image-rendering",textRendering:"text-rendering",pointerEvents:"pointer-events",vectorEffect:"vector-effect",paintOrder:"paint-order",fontFamily:"font-family",fontSize:"font-size",fontStyle:"font-style",fontVariant:"font-variant",fontWeight:"font-weight",fontStretch:"font-stretch",textAnchor:"text-anchor",textDecoration:"text-decoration",dominantBaseline:"dominant-baseline",alignmentBaseline:"alignment-baseline",baselineShift:"baseline-shift",letterSpacing:"letter-spacing",wordSpacing:"word-spacing",writingMode:"writing-mode",glyphOrientationHorizontal:"glyph-orientation-horizontal",glyphOrientationVertical:"glyph-orientation-vertical",markerStart:"marker-start",markerMid:"marker-mid",markerEnd:"marker-end",gradientUnits:"gradientUnits",gradientTransform:"gradientTransform",spreadMethod:"spreadMethod",patternUnits:"patternUnits",patternContentUnits:"patternContentUnits",patternTransform:"patternTransform",maskUnits:"maskUnits",maskContentUnits:"maskContentUnits",filterUnits:"filterUnits",primitiveUnits:"primitiveUnits",clipPathUnits:"clipPathUnits",xlinkHref:"xlink:href",xlinkShow:"xlink:show",xlinkActuate:"xlink:actuate",xlinkType:"xlink:type",xlinkRole:"xlink:role",xlinkTitle:"xlink:title",xlinkArcrole:"xlink:arcrole",xmlBase:"xml:base",xmlLang:"xml:lang",xmlSpace:"xml:space",xmlns:"xmlns",xmlnsXlink:"xmlns:xlink",stdDeviation:"stdDeviation",baseFrequency:"baseFrequency",numOctaves:"numOctaves",kernelMatrix:"kernelMatrix",surfaceScale:"surfaceScale",specularConstant:"specularConstant",specularExponent:"specularExponent",diffuseConstant:"diffuseConstant",pointsAtX:"pointsAtX",pointsAtY:"pointsAtY",pointsAtZ:"pointsAtZ",limitingConeAngle:"limitingConeAngle",tableValues:"tableValues"};function xn(e,t){let n=Tn[e]??e;if(t==null||t===!1)return"";if(t===!0)return` ${n}`;let a;return t instanceof J?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=Et(t):a="",` ${n}="${a}"`}function r(e,t){if(typeof e=="function")return e(t);let{children:n,...a}=t,o=Object.entries(a).map(([l,c])=>xn(l,c)).join("");if(En.has(e))return new J(`<${e}${o}>`);let i=n!=null?qe(n):"";return new J(`<${e}${o}>${i}</${e}>`)}function me({children:e}){return new J(e!=null?qe(e):"")}function Tt(e){document.getElementById("network-error-popup")?.remove();let t=v(r("div",{id:"network-error-popup",className:"error-popup",children:r("div",{className:"error-popup-content",children:[r("strong",{children:"Connection Error"}),r("p",{children:e}),r("button",{children:"Dismiss"})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function f(e,t={}){try{return(await fetch("/api"+e,{headers:t.body!==void 0?{"Content-Type":"application/json"}:{},method:t.method,body:t.body!==void 0?JSON.stringify(t.body):void 0})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}async function xt(e,t){try{let n=new FormData;return n.append("file",t),(await fetch("/api"+e,{method:"POST",body:n})).json()}catch(n){throw Tt("Unable to reach the server. It may have been stopped."),n}}var Ln={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},s={tickets:[],customViews:[],categories:[{id:"issue",label:"Issue",shortLabel:"ISS",color:"#6b7280",shortcutKey:"i",description:""},{id:"bug",label:"Bug",shortLabel:"BUG",color:"#ef4444",shortcutKey:"b",description:""},{id:"feature",label:"Feature",shortLabel:"FEA",color:"#22c55e",shortcutKey:"f",description:""},{id:"requirement_change",label:"Req Change",shortLabel:"REQ",color:"#f97316",shortcutKey:"r",description:""},{id:"task",label:"Task",shortLabel:"TSK",color:"#3b82f6",shortcutKey:"k",description:""},{id:"investigation",label:"Investigation",shortLabel:"INV",color:"#8b5cf6",shortcutKey:"g",description:""}],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...Ln},backupPreview:null},In='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="#9ca3af" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M12 2v20"/><path d="m8 18 4 4 4-4"/><path d="m8 6 4-4 4 4"/></svg>',Cn={highest:"\u2B06\u2B06",high:"\u2B06",default:In,low:"\u2B07",lowest:"\u2B07\u2B07"},Sn={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},Lt='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-7.5 7.5L13 16"/></svg>',Mn={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:Lt,backlog:"\u25A1",archive:"\u25A0"},Ue=Lt;function C(e){return s.categories.find(n=>n.id===e)?.color||"#6b7280"}function K(e){return s.categories.find(n=>n.id===e)?.shortLabel||e.slice(0,3).toUpperCase()}function A(e){return Cn[e]||"\u2014"}function P(e){return Sn[e]||"#6b7280"}function z(e){return Mn[e]||"\u25CB"}function V(e){if(!e||e==="[]")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.filter(n=>typeof n=="string"&&n.trim())}catch{}return[]}function fe(e,t){let n=document.getElementById("detail-tags");if(n){n.innerHTML="";for(let a of e){let o=v(r("span",{className:"tag-chip",children:[a,t?null:r("button",{className:"tag-chip-remove","data-tag":a,title:"Remove tag",children:"\xD7"})]}));t||o.querySelector(".tag-chip-remove").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let i=s.tickets.find(d=>d.id===s.activeTicketId);if(!i)return;let c=V(i.tags).filter(d=>d!==a);await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(c)}}),i.tags=JSON.stringify(c),fe(c,!1)}),n.appendChild(o)}}}var $n={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified",backlog:"Backlog",archive:"Archive"},Nn={highest:"Highest",high:"High",default:"Default",low:"Low",lowest:"Lowest"};function ye(e){let t=document.getElementById("detail-category");t.dataset.value=e;let n=s.categories.find(o=>o.id===e),a=C(e);t.innerHTML=`<span class="cat-dot" style="background:${a}"></span> ${n?.label||e}`}function xe(e){let t=document.getElementById("detail-priority");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon" style="color:${P(e)}">${A(e)}</span> ${Nn[e]||e}`}function Le(e){let t=document.getElementById("detail-status");t.dataset.value=e,t.innerHTML=`<span class="dropdown-icon">${z(e)}</span> ${$n[e]||e}`}function te(e){s.activeTicketId=e,Ve(e)}function St(){s.selectedIds.clear(),s.activeTicketId=null,ne();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function ne(){let e=s.view==="trash",t=!!s.backupPreview?.active,n=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),o=document.getElementById("detail-header"),i=document.getElementById("detail-body"),l=document.getElementById("detail-placeholder"),c=document.getElementById("detail-placeholder-text");if(e){n.style.display="none",a&&(a.style.display="none"),s.activeTicketId=null;return}if(n.style.display="flex",a&&(a.style.display=""),s.selectedIds.size===1){let d=Array.from(s.selectedIds)[0];n.classList.remove("detail-disabled"),o.style.display="",i.style.display="",l.style.display="none",s.activeTicketId!==d&&(s.activeTicketId=d,t?Bn(d):Ve(d))}else s.activeTicketId=null,n.classList.add("detail-disabled"),o.style.display="none",i.style.display="none",l.style.display="",s.selectedIds.size===0?c.textContent="Nothing selected":c.textContent=`${s.selectedIds.size} items selected`}function Mt(e){let t=document.getElementById("detail-title"),n=document.getElementById("detail-details"),a=document.getElementById("detail-category"),o=document.getElementById("detail-priority"),i=document.getElementById("detail-status"),l=document.getElementById("detail-upnext"),c=document.querySelector(".upload-btn");t.readOnly=e,n.readOnly=e,a.disabled=e,o.disabled=e,i.disabled=e,l.disabled=e,c&&(c.style.display=e?"none":"")}function Bn(e){let t=s.backupPreview?.tickets.find(l=>l.id===e);if(!t||s.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ye(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details,Mt(!0),document.getElementById("detail-attachments").innerHTML="",fe(V(t.tags),!0);let a=document.getElementById("detail-notes"),o=$t(t.notes);o.length>0?a.innerHTML=r(me,{children:o.map(l=>r("div",{className:"note-entry",children:[l.created_at?r("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:l.text})]}))}).toString():a.innerHTML="";let i=document.getElementById("detail-meta");i.innerHTML=r(me,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ae(){s.activeTicketId!=null&&Ve(s.activeTicketId)}async function Ve(e){let t=await f(`/tickets/${e}`);if(s.activeTicketId!==e)return;Mt(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,ye(t.category),xe(t.priority),Le(t.status);let n=document.getElementById("detail-upnext");n.textContent=t.up_next?"\u2605":"\u2606",n.classList.toggle("active",t.up_next),document.getElementById("detail-details").value=t.details;let a=document.getElementById("detail-attachments");t.attachments.length>0?a.innerHTML=r(me,{children:t.attachments.map(i=>r("div",{className:"attachment-item",children:[r("span",{className:"attachment-name",children:i.original_filename}),r("button",{className:"attachment-reveal","data-att-id":String(i.id),title:"Show in file manager",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"12",height:"12",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:r("path",{d:"M22 19a2 2 0 0 1-2 2H4a2 2 0 0 1-2-2V5a2 2 0 0 1 2-2h5l2 3h9a2 2 0 0 1 2 2z"})})}),r("button",{className:"attachment-delete","data-att-id":String(i.id),title:"Remove",children:"\xD7"})]}))}).toString():a.innerHTML="",fe(V(t.tags),!1),Oe(t.id,$t(t.notes));let o=document.getElementById("detail-meta");o.innerHTML=r(me,{children:[r("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),r("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?r("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?r("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function It(e,t){let n=s.tickets.find(a=>a.id===e);n&&(n.notes=JSON.stringify(t))}function Oe(e,t){let n=document.getElementById("detail-notes");if(n){if(n.innerHTML="",t.length===0){n.innerHTML='<div class="notes-empty">No notes added</div>';return}for(let a of t){let o=v(r("div",{className:"note-entry",children:[a.created_at?r("div",{className:"note-timestamp",children:new Date(a.created_at).toLocaleString()}):null,r("div",{className:"note-text",children:a.text})]}));o.addEventListener("click",()=>{let i=o.querySelector(".note-text");if(o.querySelector(".note-edit-area"))return;let l=document.createElement("textarea");l.className="note-edit-area",l.value=a.text,l.rows=3,i.style.display="none",o.appendChild(l),l.focus();let c=async()=>{let d=l.value.trim();if(d&&d!==a.text){let u=s.tickets.find(m=>m.id===e),p=t.map(m=>m.id===a.id?{...m,text:d}:m);u&&ge(u,"Edit note",JSON.stringify(p)),await f(`/tickets/${e}/notes/${a.id}`,{method:"PATCH",body:{text:d}}),a.text=d,It(e,t)}Oe(e,t)};l.addEventListener("blur",()=>{c()}),l.addEventListener("keydown",d=>{d.key==="Enter"&&(d.metaKey||d.ctrlKey)&&(d.preventDefault(),c()),d.key==="Escape"&&(d.stopPropagation(),l.blur())})}),o.addEventListener("contextmenu",i=>{i.preventDefault(),document.querySelectorAll(".note-context-menu").forEach(c=>c.remove());let l=v(r("div",{className:"note-context-menu context-menu",style:`top:${i.clientY}px;left:${i.clientX}px`,children:r("div",{className:"context-menu-item danger",children:r("span",{className:"context-menu-label",children:"Delete Note"})})}));l.querySelector(".context-menu-item").addEventListener("click",async c=>{c.stopPropagation(),l.remove();let d=s.tickets.find(m=>m.id===e),u=t.filter(m=>m.id!==a.id);d&&ge(d,"Delete note",JSON.stringify(u)),await f(`/tickets/${e}/notes/${a.id}`,{method:"DELETE"});let p=t.indexOf(a);p>=0&&t.splice(p,1),It(e,t),Oe(e,t)}),document.body.appendChild(l),setTimeout(()=>{let c=()=>{l.remove(),document.removeEventListener("click",c)};document.addEventListener("click",c)},0)}),n.appendChild(o)}}}var _n=0;function Ct(){return`cn_${Date.now().toString(36)}_${(_n++).toString(36)}`}function $t(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t.map(n=>({id:n.id||Ct(),text:n.text,created_at:n.created_at}))}catch{}return e.trim()?[{id:Ct(),text:e,created_at:""}]:[]}async function Ie(){try{let e=await f("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function Ke(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function ze(){let e=document.getElementById("detail-panel");s.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${s.settings.detail_height}px`):(e.style.height="",e.style.width=`${s.settings.detail_width}px`)}function Nt(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),n=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",o=>{o.preventDefault(),a=!0,document.body.style.cursor=s.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",o=>{if(!a)return;let i=n.getBoundingClientRect();if(s.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,i.bottom-o.clientY));s.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,i.right-o.clientX));s.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",s.settings.detail_position==="bottom"?f("/settings",{method:"PATCH",body:{detail_height:String(s.settings.detail_height)}}):f("/settings",{method:"PATCH",body:{detail_width:String(s.settings.detail_width)}}))})}var Fe=class{constructor(){pe(this,"undoStack",[]);pe(this,"redoStack",[])}push(t){console.log("[undo] push:",t.label,"stack depth:",this.undoStack.length+1,"before:",JSON.stringify(t.before),"after:",JSON.stringify(t.after)),this.undoStack.push(t),this.undoStack.length>1e3&&this.undoStack.shift(),this.redoStack=[]}coalesce(t){if(t.coalescingKey==null||t.coalescingKey==="")return!1;let n=this.peekUndo();return!n||n.coalescingKey!==t.coalescingKey||t.timestamp-n.timestamp>=5e3?!1:(n.after=t.after,!0)}popUndo(){let t=this.undoStack.pop();return t&&this.redoStack.push(t),t}popRedo(){let t=this.redoStack.pop();return t&&this.undoStack.push(t),t}peekUndo(){return this.undoStack[this.undoStack.length-1]}canUndo(){return this.undoStack.length>0}canRedo(){return this.redoStack.length>0}},M=new Fe;function F(e,t=!1){let n={id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next};return t&&(n.notes=e.notes),n}async function R(e,t,n){let a=F(e),o=await f(`/tickets/${e.id}`,{method:"PATCH",body:t}),i=F(o);return M.push({label:n,timestamp:Date.now(),before:[a],after:[i]}),o}function Ce(e,t,n){let a=`${e.id}:${t}`,o=Date.now(),i={...F(e),[t]:n},l={label:`Edit ${t}`,timestamp:o,before:[F(e)],after:[i],coalescingKey:a};M.coalesce(l)||M.push(l)}async function I(e,t,n){let a=e.map(i=>F(i));await f("/tickets/batch",{method:"POST",body:t});let o=a.map(i=>{let l={...i};return t.action==="category"?l.category=t.value:t.action==="priority"?l.priority=t.value:t.action==="status"?l.status=t.value:t.action==="up_next"?l.up_next=t.value:t.action==="delete"&&(l.status="deleted"),l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function We(e,t,n){let a=e.map(i=>F(i));for(let i of t)await f("/tickets/batch",{method:"POST",body:i});let o=a.map(i=>{let l={...i};for(let c of t)c.ids.includes(i.id)&&(c.action==="status"?l.status=c.value:c.action==="up_next"?l.up_next=c.value:c.action==="category"?l.category=c.value:c.action==="priority"?l.priority=c.value:c.action==="delete"&&(l.status="deleted"));return l});M.push({label:n,timestamp:Date.now(),before:a,after:o})}async function Se(e){let t=F(e);await f(`/tickets/${e.id}`,{method:"DELETE"});let n={...t,status:"deleted"};M.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[n]})}async function Bt(e){let t=F(e);await f(`/tickets/${e.id}/restore`,{method:"POST"});let n={...t,status:"not_started"};M.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[n]})}async function _t(e){for(let t of e)t.status==="deleted"?await f(`/tickets/${t.id}`,{method:"DELETE"}):(await f(`/tickets/${t.id}`,{method:"PATCH",body:{title:t.title,details:t.details,category:t.category,priority:t.priority,status:t.status,up_next:t.up_next}}),t.notes!==void 0&&await f(`/tickets/${t.id}/notes-bulk`,{method:"PUT",body:{notes:t.notes}}))}var Y=!1;async function Ht(){if(console.log("[undo] performUndo, inFlight:",Y,"canUndo:",M.canUndo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),Y=!0;try{await _t(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ae(),50)}finally{Y=!1}}async function Dt(){if(console.log("[undo] performRedo, inFlight:",Y,"canRedo:",M.canRedo()),Y){console.log("[undo] skipped \u2014 already in flight");return}let e=M.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),Y=!0;try{await _t(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await w(),setTimeout(()=>ae(),50)}finally{Y=!1}}function ge(e,t,n){let a=F(e,!0),o={...F(e,!0),notes:n};M.push({label:t,timestamp:Date.now(),before:[a],after:[o]})}function At(){return M.canUndo()}function Pt(){return M.canRedo()}function Ye(e,t){e.preventDefault(),G(),s.selectedIds.has(t.id)||(s.selectedIds.clear(),s.selectedIds.add(t.id),s.lastClickedId=t.id,L());let n=v(r("div",{className:"context-menu",style:`top:${e.clientY}px;left:${e.clientX}px`}));je(n,"Category",s.categories.map(i=>({label:i.label,icon:`<span class="dropdown-dot" style="background-color:${i.color}"></span>`,active:t.category===i.id,action:()=>se("category",i.id)}))),je(n,"Priority",[{value:"highest",label:"Highest"},{value:"high",label:"High"},{value:"default",label:"Default"},{value:"low",label:"Low"},{value:"lowest",label:"Lowest"}].map(i=>({label:i.label,icon:A(i.value),iconColor:P(i.value),active:t.priority===i.value,action:()=>se("priority",i.value)}))),je(n,"Status",[{value:"not_started",label:"Not Started"},{value:"started",label:"Started"},{value:"completed",label:"Completed"},{value:"verified",label:"Verified"}].map(i=>({label:i.label,icon:z(i.value),active:t.status===i.value,action:()=>se("status",i.value)}))),oe(n,t.up_next?"\u2605 Up Next":"\u2606 Up Next",()=>{se("up_next",!t.up_next)}),Je(n),oe(n,"Tags...",()=>{document.dispatchEvent(new CustomEvent("hotsheet:show-tags-dialog"))}),oe(n,"Duplicate",async()=>{let i=Array.from(s.selectedIds),l=await f("/tickets/duplicate",{method:"POST",body:{ids:i}});s.selectedIds.clear();for(let c of l)s.selectedIds.add(c.id);w()}),Je(n),oe(n,"Move to Backlog",()=>se("status","backlog")),oe(n,"Archive",()=>se("status","archive")),Je(n),oe(n,"Delete",async()=>{if(s.selectedIds.size===1)await Se(t);else{let i=Array.from(s.selectedIds),l=s.tickets.filter(c=>s.selectedIds.has(c.id));await I(l,{ids:i,action:"delete"},"Delete")}s.selectedIds.clear(),w()},!0),document.body.appendChild(n),Hn(n),setTimeout(()=>{document.addEventListener("click",G),document.addEventListener("contextmenu",G)},0)}function G(){document.querySelectorAll(".context-menu").forEach(e=>e.remove()),document.removeEventListener("click",G),document.removeEventListener("contextmenu",G)}function Hn(e){let t=e.getBoundingClientRect();t.right>window.innerWidth-8&&(e.style.left=`${window.innerWidth-t.width-8}px`),t.bottom>window.innerHeight-8&&(e.style.top=`${window.innerHeight-t.height-8}px`)}async function se(e,t){let n=Array.from(s.selectedIds),a=s.tickets.filter(o=>s.selectedIds.has(o.id));if(n.length===1){let o=a[0];await R(o,{[e]:t},`Change ${e}`)}else await I(a,{ids:n,action:e,value:t},`Change ${e}`);w()}function je(e,t,n){let a=v(r("div",{className:"context-menu-item has-submenu",children:[r("span",{className:"context-menu-label",children:t}),r("span",{className:"context-menu-arrow",children:"\u25B8"})]})),o=v(r("div",{className:"context-submenu"}));for(let i of n){let l=v(r("div",{className:`context-menu-item${i.active?" active":""}`,children:[i.icon?r("span",{className:"dropdown-icon",style:i.iconColor?`color:${i.iconColor}`:"",children:D(i.icon)}):null,r("span",{className:"context-menu-label",children:i.label})]}));l.addEventListener("click",c=>{c.stopPropagation(),i.action(),G()}),o.appendChild(l)}a.appendChild(o),e.appendChild(a)}function oe(e,t,n,a=!1){let o=v(r("div",{className:`context-menu-item${a?" danger":""}`,children:r("span",{className:"context-menu-label",children:t})}));o.addEventListener("click",i=>{i.stopPropagation(),G(),n()}),e.appendChild(o)}function Je(e){e.appendChild(v(r("div",{className:"context-menu-separator"})))}function $(e,t){let n=t.getBoundingClientRect(),a=e.getBoundingClientRect(),o=window.innerWidth,i=window.innerHeight,l=n.left;l+a.width>o-8&&(l=n.right-a.width),l<8&&(l=8);let c=n.bottom+4;c+a.height>i-8&&(c=n.top-a.height-4),c<8&&(c=8),e.style.left=`${l}px`,e.style.top=`${c}px`}function N(e,t){let n=v(r("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(d=>d.separator?r("div",{className:"dropdown-separator"}):r("button",{className:`dropdown-item${d.active?" active":""}`,"data-key":d.key,children:[d.color?r("span",{className:"dropdown-dot",style:`background-color:${d.color}`}):null,d.icon?r("span",{className:"dropdown-icon",style:d.iconColor?`color:${d.iconColor}`:"",children:D(d.icon)}):null,r("span",{className:"dropdown-label",children:d.label}),d.shortcut?r("kbd",{className:"dropdown-kbd",children:d.shortcut}):null]}))})),a=t.filter(d=>!d.separator);n.querySelectorAll(".dropdown-item").forEach((d,u)=>{d.addEventListener("click",()=>{a[u].action(),n.remove()})});function i(d){let u=t.find(p=>d.key.toLowerCase()===p.key.toLowerCase());u?(d.preventDefault(),d.stopPropagation(),u.action(),l()):d.key==="Escape"&&(d.preventDefault(),l())}function l(){n.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",c)}function c(){l()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",c)},0),n}function B(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var ie=null;function Ze(){ie&&(clearTimeout(ie),ie=null)}var ve=!1,he=null,Xe="",U=[];function Me(){return s.categories.map(e=>({key:e.shortcutKey,value:e.id,label:e.label}))}var Ge=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}];function Dn(){let e=document.activeElement;if(!e||!(e instanceof HTMLElement))return null;let t=e.closest(".ticket-row");if(!t)return null;if(t.classList.contains("draft-row"))return"draft";let n=t.dataset.id;return n!==void 0&&n!==""?parseInt(n,10):null}function An(e){e!=null&&(ve=!0,e==="draft"?W():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),ve=!1)}function $e(){let e=s.view;return e.startsWith("custom:")?!0:e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function Ut(){return s.view==="up-next"||s.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:s.view==="non-verified"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"}]:[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"},{status:"completed",label:"Completed"},{status:"verified",label:"Verified"}]}function L(){let e=kt(),t=!!s.backupPreview?.active;if(s.layout==="columns"&&$e()){if(t){Rn(),Te(e);return}Un(),Te(e);return}let n=s.view==="trash",a=t?null:Dn(),o=null;if(a!=null&&a!=="draft"){let c=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);c&&(o=c.value)}let i=document.getElementById("ticket-list"),l=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!n&&!t&&i.appendChild(zt()),s.tickets.length===0){let c=n?"Trash is empty":t?"No tickets match this view":"";c&&i.appendChild(v(r("div",{className:"ticket-list-empty",children:c})))}for(let c of s.tickets)t?i.appendChild(Pn(c)):n?i.appendChild(Fn(c)):i.appendChild(zn(c));if(i.scrollTop=l,t){let c=document.getElementById("batch-toolbar");c&&(c.style.display="none"),be(),ne()}else{let c=document.getElementById("batch-toolbar");if(c&&(c.style.display=""),a!=null&&a!=="draft"&&o!=null){let d=document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`);d&&d.value!==o&&(d.value=o)}An(a),re()}Ie(),Te(e)}function Pn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)};cursor:default`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:D(a?Ue:z(e.status))}),r("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return o.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),ne()}),o}function Ot(e){let t={scrollLeft:0,columns:{}},n=e.querySelector(".columns-container");return n&&(t.scrollLeft=n.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&(t.columns[o]=i.scrollTop)})),t}function Vt(e,t){let n=e.querySelector(".columns-container");n&&(n.scrollLeft=t.scrollLeft,n.querySelectorAll(".column[data-status]").forEach(a=>{let o=a.dataset.status,i=a.querySelector(".column-body");i&&t.columns[o]!=null&&(i.scrollTop=t.columns[o])}))}function Rn(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns");let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let i of n){let l=s.tickets.filter(u=>u.status===i.status),c=v(r("div",{className:"column","data-status":i.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:i.label}),r("span",{className:"column-count",children:String(l.length)})]}),r("div",{className:"column-body"})]})),d=c.querySelector(".column-body");for(let u of l)d.appendChild(qn(u));a.appendChild(c)}e.appendChild(a),Vt(e,t);let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),Ie()}function qn(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:D(A(e.priority))}),r("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]}));return n.addEventListener("click",()=>{s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,Kt(),ne()}),n}function Un(){let e=document.getElementById("ticket-list"),t=Ot(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(zt());let n=Ut(),a=v(r("div",{className:"columns-container"}));for(let o of n){let i=s.tickets.filter(d=>d.status===o.status),l=v(r("div",{className:"column","data-status":o.status,children:[r("div",{className:"column-header",children:[r("span",{className:"column-title",children:o.label}),r("span",{className:"column-count",children:String(i.length)})]}),r("div",{className:"column-body"})]})),c=l.querySelector(".column-body");for(let d of i)c.appendChild(On(d));c.addEventListener("dragover",d=>{d.preventDefault(),d.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),c.addEventListener("dragleave",d=>{let u=d.relatedTarget;(!u||!c.contains(u))&&l.classList.remove("column-drop-target")}),c.addEventListener("drop",d=>{d.preventDefault(),l.classList.remove("column-drop-target");let u=U;if(U=[],u.length===0)return;let p=s.tickets.filter(m=>u.includes(m.id));H(),I(p,{ids:u,action:"status",value:o.status},"Change status").then(()=>{w()})}),a.appendChild(l)}e.appendChild(a),Vt(e,t),re(),Ie()}function On(e){let t=s.selectedIds.has(e.id),n=v(r("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("div",{className:"column-card-header",children:[r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}),r("div",{className:"column-card-title",children:e.title})]})),a=n.querySelector(".ticket-category-badge");a.addEventListener("click",i=>{i.stopPropagation(),Jt(a,e)});let o=n.querySelector(".ticket-priority-indicator");return o.addEventListener("click",i=>{i.stopPropagation(),Yt(o,e)}),n.querySelector(".ticket-star").addEventListener("click",i=>{i.stopPropagation(),jt(e)}),n.addEventListener("contextmenu",i=>{Ye(i,e)}),n.draggable=!0,n.addEventListener("dragstart",i=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],i.dataTransfer.setData("text/plain",JSON.stringify(U)),i.dataTransfer.effectAllowed="move"}),n.addEventListener("dragend",()=>{U=[]}),n.addEventListener("click",i=>{if(i.metaKey||i.ctrlKey)s.selectedIds.has(e.id)?s.selectedIds.delete(e.id):s.selectedIds.add(e.id),s.lastClickedId=e.id;else if(i.shiftKey&&s.lastClickedId!=null){let l=s.tickets.find(c=>c.id===s.lastClickedId);if(l&&l.status===e.status){let d=s.tickets.filter(m=>m.status===e.status).map(m=>m.id),u=d.indexOf(s.lastClickedId),p=d.indexOf(e.id);if(u!==-1&&p!==-1){let m=Math.min(u,p),g=Math.max(u,p);s.selectedIds.clear();for(let y=m;y<=g;y++)s.selectedIds.add(d[y])}}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id}else s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id;Kt(),re()}),n}function Kt(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);s.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function zt(){let e=Ft(),t=s.view.startsWith("category:"),n=v(r("div",{className:"ticket-row draft-row",children:[r("span",{className:"ticket-checkbox-spacer"}),r("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),r("span",{className:"ticket-category-badge draft-badge",style:`background-color:${C(e)}${t?"":";cursor:pointer;opacity:1"}`,children:K(e)}),r("span",{className:"ticket-number draft-number"}),r("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:Xe}),r("span",{className:"ticket-priority-indicator draft-placeholder"}),r("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let o=n.querySelector(".ticket-category-badge");o.addEventListener("click",i=>{i.stopPropagation(),Kn(o)})}let a=n.querySelector(".draft-input");return a.addEventListener("input",()=>{Xe=a.value}),a.addEventListener("keydown",async o=>{if(o.key==="Enter"&&a.value.trim()){o.preventDefault();let i=a.value.trim();Xe="",a.value="";let l=Vn();he&&!s.view.startsWith("category:")&&(l.category=he);let c=await f("/tickets",{method:"POST",body:{title:i,defaults:l}});c&&(s.selectedIds.clear(),s.selectedIds.add(c.id)),await w(),W()}else o.key==="ArrowDown"&&(o.preventDefault(),s.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${s.tickets[0].id}"] .ticket-title-input`)?.focus())}),n}function W(){document.querySelector(".draft-row .draft-input")?.focus()}function Vn(){let e=s.view;return e==="up-next"?{up_next:!0}:e==="open"?{}:e==="completed"?{status:"completed"}:e==="backlog"?{status:"backlog"}:e==="archive"?{status:"archive"}:e.startsWith("category:")?{category:e.split(":")[1]}:e.startsWith("priority:")?{priority:e.split(":")[1]}:{}}function Ft(){if(he)return he;let e=s.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function Kn(e){B();let n=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=Ft(),o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${n}${i.key.toUpperCase()}`,color:C(i.value),active:a===i.value,action:()=>{he=i.value,L(),W()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function zn(e){let t=s.selectedIds.has(e.id),n=e.status==="completed"||e.status==="verified",a=e.status==="verified",o=v(r("div",{className:`ticket-row${t?" selected":""}${n?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,title:e.category,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:D(a?Ue:z(e.status))}),r("input",{type:"text",className:"ticket-title-input",value:e.title}),r("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:D(A(e.priority))}),r("button",{className:`ticket-star${e.up_next?" active":""}`,title:e.up_next?"Remove from Up Next":"Add to Up Next",children:e.up_next?"\u2605":"\u2606"})]}));o.addEventListener("mousedown",u=>{let p=u.target;p.tagName!=="INPUT"&&p.tagName!=="BUTTON"&&(o.draggable=!0)}),o.addEventListener("mouseup",()=>{o.draggable=!1}),o.addEventListener("dragend",()=>{o.draggable=!1,U=[]}),o.addEventListener("contextmenu",u=>{Ye(u,e)}),o.addEventListener("dragstart",u=>{s.selectedIds.has(e.id)&&s.selectedIds.size>1?U=Array.from(s.selectedIds):U=[e.id],u.dataTransfer.setData("text/plain",JSON.stringify(U)),u.dataTransfer.effectAllowed="move"}),o.addEventListener("mousedown",u=>{(u.metaKey||u.ctrlKey||u.shiftKey)&&(u.preventDefault(),Wt(u,e)&&u.stopPropagation())});let i=o.querySelector(".ticket-checkbox");i.addEventListener("click",u=>u.stopPropagation()),i.addEventListener("change",()=>{i.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),o.querySelector(".ticket-status-btn").addEventListener("click",u=>{u.stopPropagation(),Yn(e)});let l=o.querySelector(".ticket-category-badge");l.addEventListener("click",u=>{u.stopPropagation(),Jt(l,e)});let c=o.querySelector(".ticket-title-input");c.addEventListener("focus",()=>{ve||s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),re())}),c.addEventListener("input",()=>{Ce(e,"title",c.value),Gn(e.id,{title:c.value})}),c.addEventListener("keydown",u=>{Wn(u,e,c)});let d=o.querySelector(".ticket-priority-indicator");return d.addEventListener("click",u=>{u.stopPropagation(),Yt(d,e)}),o.querySelector(".ticket-star").addEventListener("click",u=>{u.stopPropagation(),jt(e)}),o}function Fn(e){let t=s.selectedIds.has(e.id),n=e.deleted_at?new Date(e.deleted_at):null,a=v(r("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[r("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),r("span",{className:"ticket-category-badge",style:`background-color:${C(e.category)}`,children:K(e.category)}),r("span",{className:"ticket-number",children:e.ticket_number}),r("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),r("span",{className:"ticket-number",title:n?`Deleted: ${n.toLocaleString()}`:"",children:n?n.toLocaleDateString():""}),r("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",i=>{(i.metaKey||i.ctrlKey||i.shiftKey)&&(i.preventDefault(),Wt(i,e)&&i.stopPropagation())});let o=a.querySelector(".ticket-checkbox");return o.addEventListener("click",i=>i.stopPropagation()),o.addEventListener("change",()=>{o.checked?s.selectedIds.add(e.id):s.selectedIds.delete(e.id),s.lastClickedId=e.id,L()}),a.querySelector(".trash-title").addEventListener("click",()=>{s.selectedIds.size===1&&s.selectedIds.has(e.id)||(s.selectedIds.clear(),s.selectedIds.add(e.id),s.lastClickedId=e.id,be(),re())}),a.querySelector(".btn").addEventListener("click",async i=>{i.stopPropagation(),await Bt(e),w()}),a}function Wt(e,t){let n=e.metaKey||e.ctrlKey,a=e.shiftKey;if(n)s.selectedIds.has(t.id)?s.selectedIds.delete(t.id):s.selectedIds.add(t.id),s.lastClickedId=t.id,L();else if(a&&s.lastClickedId!=null){let o=s.tickets.map(c=>c.id),i=o.indexOf(s.lastClickedId),l=o.indexOf(t.id);if(i!==-1&&l!==-1){let c=Math.min(i,l),d=Math.max(i,l);s.selectedIds.clear();for(let u=c;u<=d;u++)s.selectedIds.add(o[u])}L()}else return!1;return!0}function Wn(e,t,n){if(e.key==="Enter")e.preventDefault(),W();else if(e.key==="Backspace"&&n.value==="")e.preventDefault(),Xn(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),Rt(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),Rt(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),jn(t.id);else if(e.key==="ArrowUp")e.preventDefault(),Jn(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Me().some(a=>a.key===e.key)){e.preventDefault();let a=Me().find(o=>o.key===e.key);qt(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&Ge.some(a=>a.key===e.key)){e.preventDefault();let a=Ge.find(o=>o.key===e.key);qt(t,"priority",a.value)}}function jn(e){let t=s.tickets.findIndex(n=>n.id===e);t<s.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${s.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function Jn(e){let t=s.tickets.findIndex(n=>n.id===e);t>0?document.querySelector(`.ticket-row[data-id="${s.tickets[t-1].id}"] .ticket-title-input`)?.focus():W()}function Rt(e,t){let a=s.tickets.findIndex(l=>l.id===e)+t;if(a<0||a>=s.tickets.length)return;let o=s.tickets[a].id;s.selectedIds.add(e),s.selectedIds.has(o)?s.selectedIds.delete(e):s.selectedIds.add(o),ve=!0,document.querySelector(`.ticket-row[data-id="${o}"] .ticket-title-input`)?.focus(),ve=!1,be(),re()}async function Yn(e){let n={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await R(e,{status:n},"Change status");Object.assign(e,a),L()}async function jt(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await R(e,{status:"not_started",up_next:!0},"Toggle up next"):await R(e,{up_next:!e.up_next},"Toggle up next"),w(),document.dispatchEvent(new CustomEvent("hotsheet:upnext-changed"))}async function qt(e,t,n){let a=await R(e,{[t]:n},`Change ${t}`);Object.assign(e,a),L()}async function Xn(e){let t=s.tickets.findIndex(a=>a.id===e),n=s.tickets.find(a=>a.id===e);if(n?await Se(n):await f(`/tickets/${e}`,{method:"DELETE"}),s.tickets=s.tickets.filter(a=>a.id!==e),s.selectedIds.delete(e),L(),t>0&&s.tickets.length>0){let a=Math.min(t-1,s.tickets.length-1);document.querySelector(`.ticket-row[data-id="${s.tickets[a].id}"] .ticket-title-input`)?.focus()}else W()}function Gn(e,t){ie&&clearTimeout(ie),ie=setTimeout(()=>{f(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function Jt(e,t){B();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",o=N(e,Me().map(i=>({label:i.label,key:i.key,shortcut:`${a}${i.key.toUpperCase()}`,color:C(i.value),active:t.category===i.value,action:async()=>{let l=await R(t,{category:i.value},"Change category");Object.assign(t,l),L()}})));document.body.appendChild(o),$(o,e),o.style.visibility=""}function Yt(e,t){B();let n=N(e,Ge.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,icon:A(a.value),iconColor:P(a.value),active:t.priority===a.value,action:async()=>{let o=await R(t,{priority:a.value},"Change priority");Object.assign(t,o),L()}})));document.body.appendChild(n),$(n,e),n.style.visibility=""}function be(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),n=e.querySelector(".ticket-checkbox");s.selectedIds.has(t)?(e.classList.add("selected"),n&&(n.checked=!0)):(e.classList.remove("selected"),n&&(n.checked=!1))})}function re(){let e=s.selectedIds.size,t=s.tickets.length,n=e>0,a=s.view==="trash",o=document.getElementById("batch-select-all");o.checked=t>0&&e===t,o.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=n?`${e} selected`:"";let i=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let p of i){let m=document.getElementById(p);m.style.display=a?"none":"",a||(m.disabled=!n)}let l=document.getElementById("batch-restore"),c=document.getElementById("batch-empty-trash");if(a){let p=document.getElementById("batch-toolbar");l||(l=v(r("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),l.addEventListener("click",async()=>{await f("/tickets/batch",{method:"POST",body:{ids:Array.from(s.selectedIds),action:"restore"}}),s.selectedIds.clear(),w()}),p.insertBefore(l,document.getElementById("batch-count"))),l.disabled=!n,l.style.display="",c||(c=v(r("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),c.addEventListener("click",async()=>{await f("/trash/empty",{method:"POST"}),s.selectedIds.clear(),w()}),p.insertBefore(c,document.getElementById("batch-count"))),c.disabled=t===0,c.style.display=""}else l&&(l.style.display="none"),c&&(c.style.display="none");let d=document.querySelector(".batch-star-icon"),u=document.getElementById("batch-upnext");if(!a&&d&&n){let p=s.tickets.filter(y=>s.selectedIds.has(y.id)),m=p.every(y=>y.up_next),g=p.every(y=>!y.up_next);m?(d.textContent="\u2605",u.classList.add("active"),u.classList.remove("mixed")):g?(d.textContent="\u2606",u.classList.remove("active","mixed")):(d.innerHTML=r("span",{className:"star-mixed-wrap",children:[r("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),u.classList.remove("active"),u.classList.add("mixed"))}else d&&(d.textContent="\u2606",u.classList.remove("active","mixed"));ne()}async function w(){if(s.backupPreview?.active){Zn();return}if(s.view.startsWith("custom:")){let n=s.view.slice(7),a=s.customViews.find(o=>o.id===n);a?s.tickets=await f("/tickets/query",{method:"POST",body:{logic:a.logic,conditions:a.conditions,sort_by:s.sortBy,sort_dir:s.sortDir}}):s.tickets=[],L();return}let e=new URLSearchParams;s.view==="trash"?e.set("status","deleted"):s.view==="up-next"?e.set("up_next","true"):s.view==="open"?e.set("status","open"):s.view==="completed"?e.set("status","completed"):s.view==="non-verified"?e.set("status","non_verified"):s.view==="verified"?e.set("status","verified"):s.view==="backlog"?e.set("status","backlog"):s.view==="archive"?e.set("status","archive"):s.view.startsWith("category:")?e.set("category",s.view.split(":")[1]):s.view.startsWith("priority:")?e.set("priority",s.view.split(":")[1]):e.set("status","active"),s.search&&e.set("search",s.search),e.set("sort_by",s.sortBy),e.set("sort_dir",s.sortDir);let t=e.toString();s.tickets=await f(`/tickets${t?"?"+t:""}`),L()}function Zn(){let e=[...s.backupPreview?.tickets||[]];if(s.view==="trash")e=e.filter(t=>t.status==="deleted");else if(s.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(s.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(s.view==="completed")e=e.filter(t=>t.status==="completed");else if(s.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(s.view==="verified")e=e.filter(t=>t.status==="verified");else if(s.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(s.view==="archive")e=e.filter(t=>t.status==="archive");else if(s.view.startsWith("category:")){let t=s.view.split(":")[1];e=e.filter(n=>n.category===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else if(s.view.startsWith("priority:")){let t=s.view.split(":")[1];e=e.filter(n=>n.priority===t&&n.status!=="deleted"&&n.status!=="backlog"&&n.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(s.search){let t=s.search.toLowerCase();e=e.filter(n=>n.title.toLowerCase().includes(t)||n.ticket_number.toLowerCase().includes(t)||n.details&&n.details.toLowerCase().includes(t))}s.tickets=e,L()}function Qn(e){let t=Date.now()-new Date(e).getTime(),n=Math.floor(t/6e4);if(n<1)return"just now";if(n<60)return`${n}m ago`;let a=Math.floor(n/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function ea(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function ta(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function Qe(){var t;let e=document.getElementById("backup-list");if(e)try{let n=await f("/backups");if(n.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let o of n.backups)(a[t=o.tier]||(a[t]=[])).push(o);e.innerHTML="";for(let o of["5min","hourly","daily"]){let i=a[o];if(!(!i||i.length===0)){e.appendChild(v(r("div",{className:"backup-tier-label",children:ta(o)})));for(let l of i){let c=v(r("div",{className:"backup-row","data-tier":l.tier,"data-filename":l.filename,children:[r("span",{className:"backup-row-time",children:Qn(l.createdAt)}),r("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",ea(l.sizeBytes)]})]}));c.addEventListener("click",()=>{na(l.tier,l.filename,l.createdAt)}),e.appendChild(c)}}}}catch{e.textContent="Failed to load backups."}}async function na(e,t,n){let a=document.getElementById("settings-overlay");a.style.display="none";let o=document.getElementById("backup-preview-banner"),i=document.getElementById("backup-preview-label");i.textContent="Loading backup preview...",o.style.display="flex";try{let l=await f(`/backups/preview/${e}/${t}`);s.backupPreview={active:!0,tickets:l.tickets,timestamp:n,tier:e,filename:t},s.selectedIds.clear(),s.activeTicketId=null,i.textContent=`Previewing backup from ${new Date(n).toLocaleString()} (${l.stats.total} tickets, ${l.stats.open} open) \u2014 read-only`,w()}catch{i.textContent="Failed to load backup preview.",setTimeout(()=>{o.style.display="none"},3e3)}}async function aa(){let e=document.getElementById("backup-preview-banner");e.style.display="none",s.backupPreview=null,s.selectedIds.clear(),s.activeTicketId=null,await f("/backups/preview/cleanup",{method:"POST"}),w()}async function sa(){if(!s.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await f("/backups/restore",{method:"POST",body:{tier:s.backupPreview.tier,filename:s.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Xt(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{aa()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{sa()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await f("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",Qe())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}var Be,Z=null;function Qt(e){Be=e,document.getElementById("add-custom-view-btn").addEventListener("click",t=>{t.stopPropagation(),nt()})}async function en(){try{let e=await f("/settings");if(e.custom_views){let t=JSON.parse(e.custom_views);Array.isArray(t)&&(s.customViews=t)}}catch{}et()}function et(){let e=document.getElementById("custom-views-container");if(e&&(e.innerHTML="",s.customViews.length!==0)){e.appendChild(v(r("div",{className:"sidebar-divider"})));for(let t=0;t<s.customViews.length;t++){let n=s.customViews[t],a=v(r("button",{className:`sidebar-item sidebar-custom-view${s.view===`custom:${n.id}`?" active":""}`,"data-view":`custom:${n.id}`,"data-cv-index":String(t),draggable:"true",children:n.name}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`custom:${n.id}`,s.selectedIds.clear(),H(),Be()}),a.addEventListener("dblclick",o=>{o.preventDefault(),nt(n)}),a.addEventListener("contextmenu",o=>{o.preventDefault(),ra(a,n)}),a.addEventListener("dragstart",o=>{Z=t,o.dataTransfer.setData("text/plain",String(t)),o.dataTransfer.effectAllowed="move",setTimeout(()=>a.classList.add("dragging"),0)}),a.addEventListener("dragend",()=>{a.classList.remove("dragging"),Z=null}),a.addEventListener("dragover",o=>{Z!==null&&(o.preventDefault(),o.dataTransfer.dropEffect="move",a.classList.add("drop-target"))}),a.addEventListener("dragleave",()=>{a.classList.remove("drop-target")}),a.addEventListener("drop",o=>{if(o.preventDefault(),a.classList.remove("drop-target"),Z===null||Z===t)return;let[i]=s.customViews.splice(Z,1);s.customViews.splice(t,0,i),Z=null,tt()}),e.appendChild(a)}}}var oa='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21.174 6.812a1 1 0 0 0-3.986-3.987L3.842 16.174a2 2 0 0 0-.5.83l-1.321 4.352a.5.5 0 0 0 .623.622l4.353-1.32a2 2 0 0 0 .83-.497z"/><path d="m15 5 4 4"/></svg>',ia='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M3 6h18"/><path d="M19 6v14c0 1-1 2-2 2H7c-1 0-2-1-2-2V6"/><path d="M8 6V4c0-1 1-2 2-2h4c1 0 2 1 2 2v2"/></svg>';function ra(e,t){B();let n=N(e,[{label:"Edit",key:"e",icon:oa,action:()=>nt(t)},{label:"Delete",key:"d",icon:ia,action:()=>la(t.id)}]);document.body.appendChild(n),$(n,e),n.style.visibility=""}async function tt(){await f("/settings",{method:"PATCH",body:{custom_views:JSON.stringify(s.customViews)}}),et()}async function la(e){s.customViews=s.customViews.filter(t=>t.id!==e),s.view===`custom:${e}`&&(s.view="all",document.querySelectorAll(".sidebar-item").forEach(t=>{t.classList.toggle("active",t.dataset.view==="all")}),Be()),await tt()}var Ne=[{value:"category",label:"Category",type:"select"},{value:"priority",label:"Priority",type:"ordinal"},{value:"status",label:"Status",type:"ordinal"},{value:"title",label:"Title",type:"text"},{value:"details",label:"Details",type:"text"},{value:"up_next",label:"Up Next",type:"boolean"},{value:"tags",label:"Tags",type:"text"}];function Gt(e){return e==="ordinal"?[{value:"equals",label:"="},{value:"not_equals",label:"\u2260"},{value:"lt",label:"<"},{value:"lte",label:"\u2264"},{value:"gt",label:">"},{value:"gte",label:"\u2265"}]:e==="select"?[{value:"equals",label:"is"},{value:"not_equals",label:"is not"}]:e==="boolean"?[{value:"equals",label:"is"}]:[{value:"contains",label:"contains"},{value:"not_contains",label:"does not contain"}]}var ca=["highest","high","default","low","lowest"],da=["not_started","started","completed","verified","backlog","archive"];function Zt(e){return e==="category"?s.categories.map(t=>t.id):e==="priority"?ca:e==="status"?da:e==="up_next"?["true","false"]:null}function ua(e,t){return e==="category"?s.categories.find(a=>a.id===t)?.label||t:e==="status"?t.replace(/_/g," "):e==="up_next"?t==="true"?"Yes":"No":t}function nt(e){let t=!!e,n=e?e.conditions.map(d=>({...d})):[],a=e?.logic||"all",o=e?.name||"",i=v(r("div",{className:"custom-view-editor-overlay",children:r("div",{className:"custom-view-editor",children:[r("div",{className:"custom-view-editor-header",children:[r("span",{children:t?"Edit Custom View":"New Custom View"}),r("button",{className:"detail-close",id:"cv-editor-close",children:"\xD7"})]}),r("div",{className:"custom-view-editor-body",children:[r("div",{className:"settings-field",children:[r("label",{children:"Name"}),r("input",{type:"text",id:"cv-name",value:o,placeholder:"View name..."})]}),r("div",{className:"cv-logic-row",children:[r("span",{children:"Match"}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"all",checked:a==="all"})," All of"]}),r("label",{children:[r("input",{type:"radio",name:"cv-logic",value:"any",checked:a==="any"})," Any of"]})]}),r("div",{id:"cv-conditions"}),r("button",{className:"btn btn-sm",id:"cv-add-condition",style:"margin-top:8px",children:"+ Add Condition"})]}),r("div",{className:"custom-view-editor-footer",children:[r("button",{className:"btn btn-sm",id:"cv-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"cv-save",children:"Save"})]})]})}));function l(){let d=i.querySelector("#cv-conditions");d.innerHTML="",n.forEach((u,p)=>{let m=Ne.find(T=>T.value===u.field)||Ne[0],g=Gt(m.type),y=Zt(u.field),b=v(r("div",{className:"cv-condition-row",children:[r("select",{className:"cv-field-select",children:Ne.map(T=>r("option",{value:T.value,selected:T.value===u.field,children:T.label}))}),r("select",{className:"cv-op-select",children:g.map(T=>r("option",{value:T.value,selected:T.value===u.operator,children:T.label}))}),y?r("select",{className:"cv-value-select",children:y.map(T=>r("option",{value:T,selected:T===u.value,children:ua(u.field,T)}))}):r("input",{type:"text",className:"cv-value-input",value:u.value,placeholder:"Value..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),E=b.querySelector(".cv-field-select"),x=b.querySelector(".cv-op-select"),k=b.querySelector(".cv-value-select")||b.querySelector(".cv-value-input");E.addEventListener("change",()=>{let T=E.value,_=Ne.find(ee=>ee.value===T),de=Gt(_.type);n[p].field=T,n[p].operator=de[0].value;let Q=Zt(T);n[p].value=Q?Q[0]:"",l()}),x.addEventListener("change",()=>{n[p].operator=x.value}),k.addEventListener("change",()=>{n[p].value=k.value}),k.tagName==="INPUT"&&k.addEventListener("input",()=>{n[p].value=k.value}),b.querySelector(".category-delete-btn").addEventListener("click",()=>{n.splice(p,1),l()}),d.appendChild(b)})}l(),document.body.appendChild(i),i.querySelector("#cv-name").focus(),i.querySelectorAll('input[name="cv-logic"]').forEach(d=>{d.addEventListener("change",()=>{a=d.value})}),i.querySelector("#cv-add-condition").addEventListener("click",()=>{n.push({field:"category",operator:"equals",value:s.categories[0]?.id||"issue"}),l()});let c=()=>i.remove();i.querySelector("#cv-editor-close").addEventListener("click",c),i.querySelector("#cv-cancel").addEventListener("click",c),i.addEventListener("click",d=>{d.target===i&&c()}),i.querySelector("#cv-save").addEventListener("click",async()=>{if(o=i.querySelector("#cv-name").value.trim(),!o){i.querySelector("#cv-name").focus();return}let d={id:e?.id||o.toLowerCase().replace(/[^a-z0-9]+/g,"-").replace(/^-|-$/g,"")||`view-${Date.now()}`,name:o,logic:a,conditions:n.filter(u=>u.value!=="")};if(t){let u=s.customViews.findIndex(p=>p.id===e.id);u>=0?s.customViews[u]=d:s.customViews.push(d)}else s.customViews.push(d);await tt(),document.querySelectorAll(".sidebar-item").forEach(u=>u.classList.remove("active")),s.view=`custom:${d.id}`,s.selectedIds.clear(),et(),Be(),c()})}var le=30;async function st(e){e.innerHTML='<div class="dashboard-loading">Loading dashboard...</div>';try{let t=await f(`/dashboard?days=${le}`);e.innerHTML="",e.appendChild(pa(t))}catch{e.innerHTML='<div class="dashboard-loading">Failed to load dashboard data.</div>'}}function pa(e){let t=v(r("div",{className:"dashboard"})),n=v(r("div",{className:"dashboard-range-bar",children:[r("button",{className:`btn btn-sm${le===7?" active":""}`,"data-days":"7",children:"7 days"}),r("button",{className:`btn btn-sm${le===30?" active":""}`,"data-days":"30",children:"30 days"}),r("button",{className:`btn btn-sm${le===90?" active":""}`,"data-days":"90",children:"90 days"})]}));n.querySelectorAll("button").forEach(m=>{m.addEventListener("click",()=>{le=parseInt(m.dataset.days,10);let g=document.getElementById("dashboard-container");g&&st(g)})}),t.appendChild(n);let a=e.kpi,o=a.completedLastWeek>0?Math.round((a.completedThisWeek-a.completedLastWeek)/a.completedLastWeek*100):0,i=o>0?"\u2191":o<0?"\u2193":"",l=a.createdThisWeek>0?(a.completedThisWeek/a.createdThisWeek).toFixed(1):"\u2014";t.appendChild(v(r("div",{className:"dashboard-kpi-row",children:[r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.completedThisWeek)}),r("div",{className:"kpi-label",children:"Completed this week"}),i?r("div",{className:`kpi-trend${o>0?" up":" down"}`,children:[i," ",Math.abs(o),"%"]}):null]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:a.medianCycleTimeDays!==null?`${a.medianCycleTimeDays}d`:"\u2014"}),r("div",{className:"kpi-label",children:"Median cycle time"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(a.wipCount)}),r("div",{className:"kpi-label",children:"In progress"})]}),r("div",{className:"dashboard-kpi-card",children:[r("div",{className:"kpi-value",children:String(l)}),r("div",{className:"kpi-label",children:"Completed / created"})]})]})));let c=v(r("div",{className:"dashboard-grid"})),d=ke("Throughput","Items completed per day. Shows your sustainable delivery pace.",ma(e.throughput));at(d,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#3b82f6",value:m.completed}]}))),c.appendChild(d);let u=ke("Created vs Completed","Compares items created (orange) vs completed (green) over time. When created outpaces completed, the backlog grows.",ga(e.throughput));at(u,e.throughput.map(m=>({date:m.date,lines:[{label:"Completed",color:"#22c55e",value:m.completed},{label:"Created",color:"#f97316",value:m.created}]}))),c.appendChild(u);let p=ke("Cumulative Flow","Stacked area showing ticket counts by status over time. Widening bands indicate bottlenecks. A healthy flow has consistent band widths.",fa(e.snapshots));return at(p,e.snapshots.map(m=>({date:m.date,lines:[{label:"Not Started",color:"#6b7280",value:m.data.not_started},{label:"Started",color:"#3b82f6",value:m.data.started},{label:"Completed",color:"#22c55e",value:m.data.completed},{label:"Verified",color:"#8b5cf6",value:m.data.verified}]}))),c.appendChild(p),c.appendChild(ke("Category Breakdown","Distribution of tickets by category. Left: currently open. Right: all tickets active in the selected time period.",ya(e.categoryBreakdown,e.categoryPeriod))),c.appendChild(ke("Cycle Time","Each dot is a completed ticket plotted by completion date and days to complete. Dashed lines show 50th and 85th percentile delivery times.",va(e.cycleTime))),t.appendChild(c),t}function ke(e,t,n){let a=v(r("div",{className:"dashboard-chart-card",children:[r("div",{className:"dashboard-chart-header",children:[r("span",{className:"dashboard-chart-title",children:e}),r("button",{className:"dashboard-info-btn",title:"About this chart",children:r("svg",{xmlns:"http://www.w3.org/2000/svg",width:"14",height:"14",viewBox:"0 0 24 24",fill:"none",stroke:"currentColor",strokeWidth:"2",strokeLinecap:"round",strokeLinejoin:"round",children:[r("circle",{cx:"12",cy:"12",r:"10"}),r("path",{d:"M12 16v-4"}),r("path",{d:"M12 8h.01"})]})})]}),r("div",{className:"dashboard-chart-info",style:"display:none",children:t}),r("div",{className:"dashboard-chart-body",children:D(n)})]})),o=a.querySelector(".dashboard-info-btn"),i=a.querySelector(".dashboard-chart-info");return o.addEventListener("click",l=>{l.stopPropagation(),i.style.display=i.style.display==="none"?"":"none"}),a}function at(e,t){let n=e.querySelector(".dashboard-chart-body");if(!n||t.length===0)return;let a=document.createElement("div");a.className="chart-cursor",a.style.display="none",n.style.position="relative",n.appendChild(a);let o=document.createElement("div");o.className="chart-tooltip",o.style.display="none",n.appendChild(o);let i=n.querySelector("svg");i&&(i.addEventListener("mousemove",l=>{let c=i.getBoundingClientRect(),d=n.getBoundingClientRect(),u=c.left-d.left,p=c.top-d.top,m=q/c.width,g=O/c.height,y=(l.clientX-c.left)*m,b=q-h.left-h.right,E=Math.max(0,Math.min(1,(y-h.left)/b)),x=Math.round(E*(t.length-1));if(x<0||x>=t.length)return;let k=h.left+x/Math.max(t.length-1,1)*b,T=u+k/m,_=p+h.top/g,de=(O-h.top-h.bottom)/g;a.style.display="",a.style.left=`${T}px`,a.style.top=`${_}px`,a.style.height=`${de}px`;let Q=t[x];o.style.display="",o.innerHTML=`<div class="chart-tooltip-date">${ot(Q.date)}</div>${Q.lines.map(ue=>`<div class="chart-tooltip-row"><span class="chart-legend-dot" style="background:${ue.color}"></span>${ue.label}: <b>${ue.value}</b></div>`).join("")}`;let ee=T+10;ee+120>d.width?o.style.left=`${T-120}px`:o.style.left=`${ee}px`,o.style.top=`${l.clientY-d.top-10}px`}),i.addEventListener("mouseleave",()=>{a.style.display="none",o.style.display="none"}))}var q=400,O=180,h={top:10,right:10,bottom:25,left:35};function ma(e){if(e.length===0)return'<div class="chart-empty">No data</div>';let t=e.map(c=>c.completed),n=Math.max(...t,1),a=q-h.left-h.right,o=O-h.top-h.bottom,i=Math.max(2,a/e.length-2),l="";for(let c=0;c<e.length;c++){let d=h.left+c/e.length*a,u=t[c]/n*o,p=h.top+o-u,m=ot(e[c].date);l+=`<rect x="${d}" y="${p}" width="${i}" height="${u}" fill="#3b82f6" rx="1" opacity="0.8" class="chart-hover"><title>${m}: ${t[c]} completed</title></rect>`}return`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
|
|
2
2
|
${it(n,o)}
|
|
3
3
|
${l}
|
|
4
4
|
${_e(e.map(c=>c.date))}
|
|
@@ -10,7 +10,7 @@
|
|
|
10
10
|
</svg>`;return o+i}function fa(e){if(e.length<2)return'<div class="chart-empty">Not enough data</div>';let t=["verified","completed","started","not_started"],n={not_started:"#6b7280",started:"#3b82f6",completed:"#22c55e",verified:"#8b5cf6"},a={not_started:"Not Started",started:"Started",completed:"Completed",verified:"Verified"},o=`<div class="chart-legend">${t.map(g=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${n[g]}"></span>${a[g]}</span>`).join("")}</div>`,i=e.map(g=>{let y=0;return t.map(b=>(y+=g.data[b]||0,y))}),l=Math.max(...i.map(g=>g[g.length-1]),1),c=q-h.left-h.right,d=O-h.top-h.bottom,u=e.length,p="";for(let g=t.length-1;g>=0;g--){let y=i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g]/l*d;return`${k},${T}`}),b=g>0?i.map((E,x)=>{let k=h.left+x/(u-1)*c,T=h.top+d-E[g-1]/l*d;return`${k},${T}`}).reverse():[`${h.left+c},${h.top+d}`,`${h.left},${h.top+d}`];p+=`<polygon points="${y.join(" ")} ${b.join(" ")}" fill="${n[t[g]]}" opacity="0.6"/>`}let m=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">
|
|
11
11
|
${p}
|
|
12
12
|
${_e(e.map(g=>g.date))}
|
|
13
|
-
</svg>`;return o+m}function ya(e,t){let n=new Map;for(let c of[...e,...t])if(!n.has(c.category)){let d=s.categories.find(u=>u.id===c.category);n.set(c.category,{color:C(c.category),label:d?.label||c.category})}let a=`<div class="chart-legend">${Array.from(n.values()).map(c=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${c.color}"></span>${c.label}</span>`).join("")}</div>`,o=tn(e,"Open",90),i=tn(t,`${
|
|
13
|
+
</svg>`;return o+m}function ya(e,t){let n=new Map;for(let c of[...e,...t])if(!n.has(c.category)){let d=s.categories.find(u=>u.id===c.category);n.set(c.category,{color:C(c.category),label:d?.label||c.category})}let a=`<div class="chart-legend">${Array.from(n.values()).map(c=>`<span class="chart-legend-item"><span class="chart-legend-dot" style="background:${c.color}"></span>${c.label}</span>`).join("")}</div>`,o=tn(e,"Open",90),i=tn(t,`${le}d active`,290),l=`<svg viewBox="0 0 ${q} ${O}" class="dashboard-svg">${o}${i}</svg>`;return a+l}function tn(e,t,n){if(e.length===0)return`<text x="${n}" y="95" text-anchor="middle" fill="#9ca3af" font-size="11">No data</text>`;let a=e.reduce((u,p)=>u+p.count,0),o=95,i=60,l=38,c=-Math.PI/2,d="";for(let u of e){let p=u.count/a*Math.PI*2,m=n+i*Math.cos(c),g=o+i*Math.sin(c),y=n+i*Math.cos(c+p),b=o+i*Math.sin(c+p),E=n+l*Math.cos(c+p),x=o+l*Math.sin(c+p),k=n+l*Math.cos(c),T=o+l*Math.sin(c),_=p>Math.PI?1:0,de=C(u.category),ee=s.categories.find(ue=>ue.id===u.category)?.label||u.category;d+=`<path d="M ${m} ${g} A ${i} ${i} 0 ${_} 1 ${y} ${b} L ${E} ${x} A ${l} ${l} 0 ${_} 0 ${k} ${T} Z" fill="${de}" opacity="0.8" class="chart-hover"><title>${ee}: ${u.count}</title></path>`,c+=p}return d+=`<text x="${n}" y="${o+4}" text-anchor="middle" fill="currentColor" font-size="16" font-weight="600">${a}</text>`,d+=`<text x="${n}" y="${o+17}" text-anchor="middle" fill="#6b7280" font-size="9">${t}</text>`,d}function va(e){if(e.length===0)return'<div class="chart-empty">No completed tickets</div>';let t=Math.max(...e.map(E=>E.days),1),n=q-h.left-h.right,a=O-h.top-h.bottom,o=e.map(E=>new Date(E.completed_at).getTime()),i=Math.min(...o),c=Math.max(...o)-i||1,d="";for(let E of e){let x=h.left+(new Date(E.completed_at).getTime()-i)/c*n,k=h.top+a-E.days/t*a;d+=`<circle cx="${x}" cy="${k}" r="4" fill="#3b82f6" opacity="0.5" class="chart-hover"><title>${E.ticket_number}: ${E.title}
|
|
14
14
|
${E.days} days</title></circle>`}let u=e.map(E=>E.days).sort((E,x)=>E-x),p=u[Math.floor(u.length*.5)],m=u[Math.floor(u.length*.85)],g=h.top+a-p/t*a,y=h.top+a-m/t*a,b=`
|
|
15
15
|
<line x1="${h.left}" y1="${g}" x2="${h.left+n}" y2="${g}" stroke="#22c55e" stroke-dasharray="4,4" opacity="0.6"/>
|
|
16
16
|
<text x="${h.left+n+2}" y="${g+3}" fill="#22c55e" font-size="9">50% (${p}d)</text>
|
|
@@ -94,7 +94,7 @@ ${E.days} days</title></circle>`}let u=e.map(E=>E.days).sort((E,x)=>E-x),p=u[Mat
|
|
|
94
94
|
.chart-legend-item { display: inline-flex; align-items: center; gap: 4px; }
|
|
95
95
|
.chart-legend-dot { width: 8px; height: 8px; border-radius: 50%; }
|
|
96
96
|
@media print { body { padding: 0; } }
|
|
97
|
-
`}async function wa(){try{await Ea(),await Ta(),await en(),xa(),H(),await w(),Ha(),Na(),Ba(),Da(),Aa(),za(),Fa(),Ja(),La(),Xt(),Ma(),$a(),Qt(()=>{w()}),Nt(),Ya(),Ca(),document.addEventListener("hotsheet:render",()=>L()),document.addEventListener("hotsheet:show-tags-dialog",()=>{bn()}),document.addEventListener("hotsheet:upnext-changed",()=>ht()),document.getElementById("print-btn")?.addEventListener("click",rt),fn(),Ka(),W()}catch(e){console.error("Hot Sheet init failed:",e);let t=document.getElementById("ticket-list");t&&(t.innerHTML=`<div style="padding:20px;color:red">Init error: ${e}</div>`)}}async function Ea(){try{let e=await f("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(s.settings.detail_position=e.detail_position),e.detail_width&&(s.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(s.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(s.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(s.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(s.layout=e.layout)}catch{}Ke(s.settings.detail_position),ze()}async function Ta(){try{let e=await f("/categories");e.length>0&&(s.categories=e)}catch{}ft()}function ft(){let e=document.getElementById("sidebar-categories");if(e){let t=e.querySelector(".sidebar-label");e.innerHTML="",t&&e.appendChild(t);for(let n of s.categories){let a=v(r("button",{className:`sidebar-item${s.view===`category:${n.id}`?" active":""}`,"data-view":`category:${n.id}`,children:[r("span",{className:"cat-dot",style:`background:${n.color}`})," ",n.label]}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`category:${n.id}`,s.selectedIds.clear(),bt(),H(),w()}),e.appendChild(a)}}if(s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);t&&fe(t.category)}}async function xa(){try{let e=await f("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function La(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),n=document.getElementById("settings-btn"),a=document.querySelectorAll(".settings-tab"),o=document.querySelectorAll(".settings-tab-panel");a.forEach(k=>{k.addEventListener("click",()=>{let T=k.dataset.tab;a.forEach(_=>_.classList.remove("active")),o.forEach(_=>_.classList.remove("active")),k.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${T}"]`)?.classList.add("active")})}),n.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(s.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(s.settings.verified_cleanup_days),e.style.display="flex",Qe(),f("/file-settings").then(k=>{document.getElementById("settings-app-name").value=k.appName||"",document.getElementById("settings-backup-dir").value=k.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",k=>{k.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),l=null;i.addEventListener("input",()=>{l&&clearTimeout(l),l=setTimeout(()=>{let k=Math.max(1,parseInt(i.value,10)||3);i.value=String(k),s.settings.trash_cleanup_days=k,f("/settings",{method:"PATCH",body:{trash_cleanup_days:String(k)}})},500)});let c=document.getElementById("settings-verified-days"),d=null;c.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let k=Math.max(1,parseInt(c.value,10)||30);c.value=String(k),s.settings.verified_cleanup_days=k,f("/settings",{method:"PATCH",body:{verified_cleanup_days:String(k)}})},500)});let u=document.getElementById("settings-app-name"),p=document.getElementById("settings-app-name-hint"),m=null;u.addEventListener("input",()=>{m&&clearTimeout(m),m=setTimeout(()=>{let k=u.value.trim();f("/file-settings",{method:"PATCH",body:{appName:k}}).then(()=>{let T=k||"Hot Sheet";document.title=T;let _=document.querySelector(".app-title h1");_&&(_.textContent=T),p.textContent=k?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let g=document.getElementById("check-updates-btn"),y=document.getElementById("check-updates-status");g.addEventListener("click",async()=>{let k=yt();if(k){g.disabled=!0,g.textContent="Checking...",y.textContent="";try{let T=await k("check_for_update");T?(y.textContent=`Update available: v${T}`,document.getElementById("settings-overlay").style.display="none",mn(T)):y.textContent="Your software is up to date."}catch{y.textContent="Could not check for updates."}g.textContent="Check for Updates",g.disabled=!1}});let b=document.getElementById("settings-backup-dir"),E=document.getElementById("settings-backup-dir-hint"),x=null;b.addEventListener("input",()=>{x&&clearTimeout(x),x=setTimeout(()=>{let k=b.value.trim();f("/file-settings",{method:"PATCH",body:{backupDir:k}}).then(()=>{E.textContent=k?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)}),Pa(),Ia()}function De(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<s.categories.length;t++){let n=s.categories[t],a=v(r("div",{className:"category-row",children:[r("input",{type:"color",className:"category-color-input",value:n.color,title:"Color"}),r("input",{type:"text",className:"category-label-input",value:n.label,placeholder:"Label",title:"Display name"}),r("input",{type:"text",className:"category-short-input",value:n.shortLabel,placeholder:"ABR",title:"Short label (3 chars)",maxlength:"4"}),r("input",{type:"text",className:"category-key-input",value:n.shortcutKey,placeholder:"k",title:"Keyboard shortcut",maxlength:"1"}),r("input",{type:"text",className:"category-desc-input",value:n.description,placeholder:"Description...",title:"Description (for AI tools)"}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),o=a.querySelectorAll("input"),[i,l,c,d,u]=o,p=()=>{rn()};i.addEventListener("input",()=>{s.categories[t].color=i.value,p()}),l.addEventListener("input",()=>{s.categories[t].label=l.value,(!n.id||n.id==="")&&(s.categories[t].id=l.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),p()}),c.addEventListener("input",()=>{s.categories[t].shortLabel=c.value.toUpperCase(),p()}),d.addEventListener("input",()=>{let m=d.value.toLowerCase().slice(0,1);d.value=m,s.categories[t].shortcutKey=m,on(),p()}),u.addEventListener("input",()=>{s.categories[t].description=u.value,p()}),a.querySelector(".category-delete-btn").addEventListener("click",()=>{s.categories.splice(t,1),De(),rn()}),e.appendChild(a)}on()}function on(){let e=document.querySelectorAll(".category-key-input"),t=new Map;s.categories.forEach((n,a)=>{if(n.shortcutKey){let o=n.shortcutKey.toLowerCase();t.has(o)||t.set(o,[]),t.get(o).push(a)}}),e.forEach((n,a)=>{let o=s.categories[a]?.shortcutKey?.toLowerCase();o&&t.get(o).length>1?n.classList.add("category-key-conflict"):n.classList.remove("category-key-conflict")})}var ct=null;function rn(){ct&&clearTimeout(ct),ct=setTimeout(async()=>{await f("/categories",{method:"PUT",body:s.categories}),ft()},500)}function Ia(){document.getElementById("category-add-btn").addEventListener("click",()=>{s.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),De();let n=document.querySelectorAll(".category-row");n[n.length-1]?.querySelector(".category-label-input")?.focus()});let e=document.getElementById("category-preset-select");f("/category-presets").then(n=>{for(let a of n)e.appendChild(v(r("option",{value:a.id,children:a.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let a=(await f("/category-presets")).find(o=>o.id===e.value);a&&(s.categories=[...a.categories],await f("/categories",{method:"PUT",body:s.categories}),De(),ft()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{De()})}async function Ca(){let e=yt();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let n=document.getElementById("settings-tab-updates");n&&(n.style.display="");let a=[0,3e3,1e4];for(let o of a){o>0&&await new Promise(i=>setTimeout(i,o));try{let i=await e("get_pending_update");if(i){mn(i);return}}catch{return}}}function yt(){return window.__TAURI__?.core?.invoke??null}function mn(e){let t=document.getElementById("update-banner");if(!t)return;let n=document.getElementById("update-banner-label");n&&(n.textContent=`Update available: v${e}`),t.style.display="flex";let a=document.getElementById("update-install-btn");a?.addEventListener("click",async()=>{if(a){a.textContent="Installing...",a.disabled=!0;try{await yt()?.("install_update"),n&&(n.textContent="Update installed! Restart the app to apply."),a.style.display="none"}catch{a.textContent="Install Failed",a.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function Sa(){let e=document.getElementById("skills-banner");if(!e)return;e.style.display="flex",document.getElementById("skills-banner-dismiss")?.addEventListener("click",()=>{e.style.display="none"})}function Ma(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),n=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),o="";f("/worklist-info").then(i=>{o=i.prompt,e.style.display="",i.skillCreated&&Sa()}),t.addEventListener("click",()=>{o!==""&&navigator.clipboard.writeText(o).then(()=>{n.textContent="Copied!",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{n.textContent="Copy AI prompt",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function $a(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");f("/glassbox/status").then(({available:n})=>{n&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{f("/glassbox/launch",{method:"POST"})})}function pt(){let e=document.getElementById("layout-toggle"),t=$e(),n=e.querySelector('[data-layout="columns"]');n.disabled=!t,n.style.opacity=t?"":"0.3";let a=s.layout==="columns"&&!t?"list":s.layout;e.querySelectorAll(".layout-btn").forEach(o=>{o.classList.toggle("active",o.dataset.layout===a)})}function Na(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.layout;n==="columns"&&!$e()||(s.layout=n,H(),pt(),L(),f("/settings",{method:"PATCH",body:{layout:n}}))})}),pt()}function ln(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===s.settings.detail_position)})}function Ba(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.position;s.settings.detail_position=n,Ke(n),ze(),ln(),f("/settings",{method:"PATCH",body:{detail_position:n}})})}),ln()}function gn(e){return e==="up-next"?{action:"up_next",value:!0}:e==="open"?{action:"status",value:"not_started"}:e==="completed"?{action:"status",value:"completed"}:e==="verified"?{action:"status",value:"verified"}:e==="backlog"?{action:"status",value:"backlog"}:e==="archive"?{action:"status",value:"archive"}:e==="trash"?{action:"delete",value:null}:e.startsWith("category:")?{action:"category",value:e.split(":")[1]}:e.startsWith("priority:")?{action:"priority",value:e.split(":")[1]}:null}async function _a(e,t){let n=gn(e);if(!n)return;let a=s.tickets.filter(o=>t.includes(o.id));n.action==="delete"?await I(a,{ids:t,action:"delete"},"Delete tickets"):await I(a,{ids:t,action:n.action,value:n.value},`Change ${n.action}`),H(),w()}function Ha(){document.querySelectorAll(".sidebar-item[data-view]").forEach(t=>{t.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(a=>a.classList.remove("active")),t.classList.add("active"),s.view=t.dataset.view,s.selectedIds.clear(),bt(),H(),pt(),w()});let n=t.dataset.view;gn(n)&&(t.addEventListener("dragover",a=>{a.preventDefault(),a.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",a=>{a.preventDefault(),t.classList.remove("drop-target");let o=[...U];o.length!==0&&_a(n,o)}))})}function Da(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,n]=e.value.split(":");s.sortBy=t,s.sortDir=n,H(),w()})}var dt=null;function Aa(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{dt&&clearTimeout(dt),dt=setTimeout(()=>{s.search=e.value,H(),w()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",s.search="",H(),w())})}var X=[];function Pa(){let e=document.getElementById("settings-tab-experimental"),t=document.getElementById("settings-experimental-panel"),n=document.getElementById("settings-channel-enabled"),a=document.getElementById("settings-channel-hint"),o=document.getElementById("settings-channel-instructions"),i=document.getElementById("settings-channel-copy-btn"),l=document.getElementById("settings-channel-cmd"),c=document.getElementById("settings-custom-commands-section");document.getElementById("settings-btn").addEventListener("click",()=>{fetch("/api/channel/claude-check").then(d=>d.ok?d.json():null).then(d=>{if(!d||!d.installed){e.style.display="none",t.style.display="none";return}e.style.display="",t.style.display="",d.meetsMinimum?(a.textContent="Push worklist events to a running Claude Code session via MCP channels.",n.disabled=!1):(a.textContent=`Claude Code ${d.version||"unknown"} detected but v2.1.80+ is required. Please upgrade Claude Code.`,n.disabled=!0),mt()}).catch(()=>{e.style.display="none",t.style.display="none"})}),fetch("/api/channel/status").then(d=>d.ok?d.json():null).then(d=>{d&&(n.checked=d.enabled,d.enabled&&(o.style.display="",c.style.display=""))}).catch(()=>{}),f("/settings").then(d=>{if(d.custom_commands)try{X=JSON.parse(d.custom_commands)}catch{}Ae()}),n.addEventListener("change",async()=>{n.checked?(await f("/channel/enable",{method:"POST"}),o.style.display="",c.style.display=""):(await f("/channel/disable",{method:"POST"}),o.style.display="none",c.style.display="none"),fn(),Ae()}),i?.addEventListener("click",()=>{let d=l?.textContent||"";navigator.clipboard.writeText(d).then(()=>{i&&(i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy"},1500))})}),document.getElementById("settings-add-command-btn")?.addEventListener("click",()=>{X.push({name:"",prompt:""}),mt()})}function mt(){let e=document.getElementById("settings-commands-list");if(e){e.innerHTML="";for(let t=0;t<X.length;t++){let n=X[t],a=v(r("div",{className:"settings-command-row",children:[r("div",{className:"settings-command-row-header",children:[r("input",{type:"text",value:n.name,placeholder:"Button label..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]}),r("label",{children:"Prompt sent to Claude:"}),r("textarea",{placeholder:"Tell Claude what to do...",children:n.prompt})]})),o=a.querySelector("input"),i=a.querySelector("textarea"),l=()=>{X[t]={name:o.value,prompt:i.value},cn()};o.addEventListener("input",l),i.addEventListener("input",l),a.querySelector(".category-delete-btn").addEventListener("click",()=>{X.splice(t,1),mt(),cn()}),e.appendChild(a)}}}async function cn(){await f("/settings",{method:"PATCH",body:{custom_commands:JSON.stringify(X)}}),Ae()}function Ae(){let e=document.getElementById("channel-commands-container");if(!e)return;e.innerHTML="";let t=document.getElementById("channel-play-section");if(!(!t||t.style.display==="none"))for(let n of X){if(!n.name.trim()||!n.prompt.trim())continue;let a=v(r("button",{className:"channel-command-btn",children:n.name}));a.addEventListener("click",()=>{vt(n.prompt)}),e.appendChild(a)}}var we=null;function Ra(){we||(we=setInterval(async()=>{try{let e=await fetch("/api/channel/permission");if(!e.ok)return;let t=await e.json();t.pending&&Ua(t.pending)}catch{}},2e3))}function qa(){we&&(clearInterval(we),we=null)}function Ua(e){let t=document.getElementById("permission-overlay");if(!t||t.style.display!=="none")return;let n=document.getElementById("permission-overlay-detail");n&&(n.textContent=`${e.tool_name}: ${e.description}`),t.style.display="";function a(i){fetch("/api/channel/permission/respond",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({request_id:e.request_id,behavior:i})}),t.style.display="none"}function o(){fetch("/api/channel/permission/dismiss",{method:"POST"}),t.style.display="none"}document.getElementById("permission-allow-btn")?.addEventListener("click",()=>a("allow"),{once:!0}),document.getElementById("permission-deny-btn")?.addEventListener("click",()=>a("deny"),{once:!0}),document.getElementById("permission-dismiss-btn")?.addEventListener("click",o,{once:!0})}var Ee=!1,He=null,Pe=!1;function gt(e){Pe=e;let t=document.getElementById("channel-status-indicator");if(!t)return;let n=document.getElementById("channel-play-section");if(!n||n.style.display==="none"){t.style.display="none";return}e?(t.style.display="",t.className="channel-status-indicator busy",t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Claude working'):(t.style.display="",t.className="channel-status-indicator",t.innerHTML="\u2713 Claude idle",setTimeout(()=>{!Pe&&t&&(t.style.display="none")},5e3))}var le=null;function vt(e){gt(!0),f("/channel/trigger",{method:"POST",body:{message:e}}),le&&clearTimeout(le),le=setTimeout(()=>{Pe&>(!1)},12e4)}async function fn(){let e={enabled:!1,alive:!1};try{let l=await fetch("/api/channel/status");l.ok&&(e=await l.json())}catch{}let t=document.getElementById("channel-play-section"),n=document.getElementById("channel-play-btn"),a=document.getElementById("channel-play-icon"),o=document.getElementById("channel-auto-icon");if(!e.enabled){t.style.display="none",qa();return}t.style.display="",Ae(),Ra();let i=null;n.addEventListener("click",()=>{i?(clearTimeout(i),i=null,dn(n,a,o)):i=setTimeout(()=>{i=null,Ee?dn(n,a,o):(n.classList.add("pulsing"),setTimeout(()=>n.classList.remove("pulsing"),600),vt())},250)})}function dn(e,t,n){Ee=!Ee,Ee?(e.classList.add("auto-mode"),t.style.display="none",n.style.display=""):(e.classList.remove("auto-mode"),t.style.display="",n.style.display="none")}function ht(){Ee&&(He&&clearTimeout(He),He=setTimeout(()=>{He=null,vt()},5e3))}function bt(){let e=document.getElementById("dashboard-container");e&&(e.id="ticket-list",e.innerHTML="",Va())}var yn=["search-input","layout-toggle","sort-select","detail-position-toggle","glassbox-btn"];function Oa(){s.view="dashboard",document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active"));for(let o of yn){let i=document.getElementById(o);if(i){let l=i.closest(".search-box, .layout-toggle, .sort-controls")||i;l.style.display="none"}}let e=document.getElementById("batch-toolbar");e&&(e.style.display="none");let t=document.getElementById("detail-panel");t&&(t.style.display="none");let n=document.getElementById("detail-resize-handle");n&&(n.style.display="none");let a=document.getElementById("ticket-list");a.innerHTML="",a.id="dashboard-container",a.classList.remove("ticket-list-columns"),st(a)}function Va(){for(let e of yn){let t=document.getElementById(e);if(t){let n=t.closest(".search-box, .layout-toggle, .sort-controls")||t;n.style.display=""}}bt()}async function Ka(){let e=await an(),t=document.getElementById("stats-bar");t&&t.after(e),e.addEventListener("click",()=>Oa())}var vn=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}],hn=[{key:"n",value:"not_started",label:"Not Started"},{key:"s",value:"started",label:"Started"},{key:"c",value:"completed",label:"Completed"},{key:"v",value:"verified",label:"Verified"},{key:"b",value:"backlog",label:"Backlog"},{key:"a",value:"archive",label:"Archive"}];function za(){let e=document.getElementById("batch-category");e.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(e,s.categories.map(l=>({label:l.label,key:l.shortcutKey,color:l.color,action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"category",value:l.id},"Batch change category"),w()}})));document.body.appendChild(i),$(i,e),i.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(t,vn.map(l=>({label:l.label,key:l.key,icon:A(l.value),iconColor:P(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"priority",value:l.value},"Batch change priority"),w()}})));document.body.appendChild(i),$(i,t),i.style.visibility=""});let n=document.getElementById("batch-status");n.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(n,hn.map(l=>({label:l.label,key:l.key,icon:z(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"status",value:l.value},"Batch change status"),w()}})));document.body.appendChild(i),$(i,n),i.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){let u=[{ids:d.map(p=>p.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}];await We(o,u,"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!0},"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!1},"Batch toggle up next");w(),ht()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));await I(i,{ids:o,action:"delete"},"Batch delete"),s.selectedIds.clear(),w()});let a=document.getElementById("batch-more");a.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(a,[{label:"Tags...",key:"t",action:()=>{bn()}},{label:"Duplicate",key:"d",action:async()=>{let l=Array.from(s.selectedIds),c=await f("/tickets/duplicate",{method:"POST",body:{ids:l}});s.selectedIds.clear();for(let d of c)s.selectedIds.add(d.id);w()}},{label:"",key:"",separator:!0,action:()=>{}},{label:"Move to Backlog",key:"b",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"backlog"},"Move to backlog"),s.selectedIds.clear(),w()}},{label:"Archive",key:"a",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"archive"},"Archive"),s.selectedIds.clear(),w()}}]);document.body.appendChild(i),$(i,a),i.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",o=>{if(o.target.checked)for(let l of s.tickets)s.selectedIds.add(l.id);else s.selectedIds.clear();L()})}var j=null;function Fa(){document.getElementById("detail-close").addEventListener("click",St);let e=["detail-title","detail-details"];for(let u of e){let p=document.getElementById(u);p.addEventListener("input",()=>{let m=s.tickets.find(g=>g.id===s.activeTicketId);if(m){let g=u.replace("detail-","");Ce(m,g,p.value)}j&&clearTimeout(j),j=setTimeout(()=>{if(s.activeTicketId==null)return;let g=u.replace("detail-","");f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[g]:p.value}}).then(()=>{w()})},300)})}async function t(u,p){if(s.activeTicketId==null)return;let m=s.tickets.find(g=>g.id===s.activeTicketId);m?await R(m,{[u]:p},`Change ${u}`):await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[u]:p}}),w(),te(s.activeTicketId)}document.getElementById("detail-category").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,s.categories.map(y=>({label:y.label,key:y.shortcutKey,color:y.color,active:y.id===m,action:()=>{fe(y.id),t("category",y.id)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,vn.map(y=>({label:y.label,key:y.key,icon:A(y.value),iconColor:P(y.value),active:y.value===m,action:()=>{xe(y.value),t("priority",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,hn.map(y=>({label:y.label,key:y.key,icon:z(y.value),active:y.value===m,action:()=>{Le(y.value),t("status",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);u?!u.up_next&&(u.status==="completed"||u.status==="verified")?await R(u,{status:"not_started",up_next:!0},"Toggle up next"):await R(u,{up_next:!u.up_next},"Toggle up next"):await f(`/tickets/${s.activeTicketId}/up-next`,{method:"POST"}),w(),ht(),te(s.activeTicketId)}),document.getElementById("detail-add-note-btn")?.addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);if(u){let p=u.notes;await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{notes:"(new note)"}});let m=await f(`/tickets/${s.activeTicketId}`);me({...u,notes:p},"Add note",m.notes),u.notes=m.notes}te(s.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async u=>{let p=u.target,m=p.files?.[0];!m||s.activeTicketId==null||(await xt(`/tickets/${s.activeTicketId}/attachments`,m),p.value="",te(s.activeTicketId),w())}),document.getElementById("detail-attachments").addEventListener("click",async u=>{let p=u.target,m=p.closest(".attachment-reveal");if(m){let b=m.dataset.attId;b&&f(`/attachments/${b}/reveal`,{method:"POST"});return}let g=p.closest(".attachment-delete");if(g===null)return;let y=g.dataset.attId;y===void 0||y===""||(await f(`/attachments/${y}`,{method:"DELETE"}),s.activeTicketId!=null&&te(s.activeTicketId))});let n=document.getElementById("detail-tag-input"),a=null,o=-1,i=[];f("/tags").then(u=>{i=u});function l(){a?.remove(),a=null,o=-1}function c(){l();let u=n.value.trim().toLowerCase();if(!u)return;let p=s.tickets.find(b=>b.id===s.activeTicketId),m=p?V(p.tags):[],g=i.filter(b=>b.toLowerCase().includes(u)&&!m.includes(b));if(g.length===0)return;a=v(r("div",{className:"tag-autocomplete"}));for(let b=0;b<g.length;b++){let E=v(r("div",{className:"tag-autocomplete-item",children:g[b]}));E.addEventListener("mousedown",x=>{x.preventDefault(),n.value=g[b],l(),d()}),a.appendChild(E)}let y=n.getBoundingClientRect();a.style.position="fixed",a.style.left=`${y.left}px`,a.style.top=`${y.bottom+2}px`,a.style.width=`${y.width}px`,document.body.appendChild(a)}async function d(){let u=n.value.trim();if(!u||s.activeTicketId==null)return;let p=s.tickets.find(y=>y.id===s.activeTicketId);if(!p)return;let m=V(p.tags);if(m.includes(u)){n.value="";return}let g=[...m,u];n.value="",l(),await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(g)}}),p.tags=JSON.stringify(g),ge(g,!1),i.includes(u)||i.push(u)}n.addEventListener("input",()=>{c()}),n.addEventListener("blur",()=>{l()}),n.addEventListener("keydown",u=>{if(u.key==="Enter"){if(u.preventDefault(),a&&o>=0){let p=a.querySelectorAll(".tag-autocomplete-item");n.value=p[o]?.textContent||n.value}l(),d()}else if(u.key==="Escape")l();else if(u.key==="ArrowDown"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.min(o+1,p.length-1),p.forEach((m,g)=>m.classList.toggle("active",g===o))}else if(u.key==="ArrowUp"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.max(o-1,0),p.forEach((m,g)=>m.classList.toggle("active",g===o))}})}async function bn(){let e=s.tickets.filter(p=>s.selectedIds.has(p.id));if(e.length===0)return;let t=await f("/tags");for(let p of e)for(let m of V(p.tags))t.includes(m)||t.push(m);t.sort();let n=new Map;for(let p of t){let m=e.filter(g=>V(g.tags).includes(p)).length;m===e.length?n.set(p,"checked"):m===0?n.set(p,"unchecked"):n.set(p,"mixed")}let a=new Map(n),o=new Map(n),i=v(r("div",{className:"tags-dialog-overlay",children:r("div",{className:"tags-dialog",children:[r("div",{className:"tags-dialog-header",children:[r("span",{children:"Tags"}),r("button",{className:"detail-close",id:"tags-dialog-close",children:"\xD7"})]}),r("div",{className:"tags-dialog-body",id:"tags-dialog-body"}),r("div",{className:"tags-dialog-new",children:[r("input",{type:"text",id:"tags-dialog-new-input",placeholder:"New tag..."}),r("button",{className:"btn btn-sm",id:"tags-dialog-add-btn",children:"Add"})]}),r("div",{className:"tags-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"tags-dialog-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"tags-dialog-done",children:"Done"})]})]})}));function l(){let p=i.querySelector("#tags-dialog-body");p.innerHTML="";for(let m of t){let g=o.get(m),y=v(r("label",{className:"tags-dialog-row",children:[r("input",{type:"checkbox",checked:g==="checked"}),r("span",{children:m})]})),b=y.querySelector("input");g==="mixed"&&(b.indeterminate=!0),b.addEventListener("change",()=>{o.set(m,b.checked?"checked":"unchecked")}),p.appendChild(y)}t.length===0&&(p.innerHTML='<div style="padding:12px 16px;color:var(--text-muted);font-size:13px">No tags yet. Create one below.</div>')}l(),document.body.appendChild(i);let c=i.querySelector("#tags-dialog-new-input"),d=()=>{let p=c.value.trim();if(!p||t.includes(p)){c.value="";return}t.push(p),t.sort(),o.set(p,"checked"),a.set(p,"unchecked"),c.value="",l()};i.querySelector("#tags-dialog-add-btn").addEventListener("click",d),c.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),d())});let u=()=>i.remove();i.querySelector("#tags-dialog-close").addEventListener("click",u),i.querySelector("#tags-dialog-cancel").addEventListener("click",u),i.addEventListener("click",p=>{p.target===i&&u()}),i.querySelector("#tags-dialog-done").addEventListener("click",async()=>{let p=[],m=[];for(let g of t){let y=a.get(g),b=o.get(g);y!==b&&(b==="checked"?p.push(g):b==="unchecked"&&m.push(g))}if(p.length>0||m.length>0){for(let g of e){let y=V(g.tags),b=[...y];for(let E of p)b.includes(E)||b.push(E);for(let E of m)b=b.filter(x=>x!==E);JSON.stringify(b)!==JSON.stringify(y)&&await f(`/tickets/${g.id}`,{method:"PATCH",body:{tags:JSON.stringify(b)}})}w(),ye()}u()})}function Wa(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function ja(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let n=Wa(e.notes);if(n.length>0){t.push("");for(let a of n)t.push(`- ${a.text}`)}return t.join(`
|
|
98
|
-
`)}function un(){console.log("[undo] triggerUndo called, canUndo:",At()),j&&(clearTimeout(j),j=null),Ze(),Ht().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function pn(){console.log("[undo] triggerRedo called, canRedo:",Pt()),j&&(clearTimeout(j),j=null),Ze(),Dt().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function
|
|
97
|
+
`}async function wa(){try{await Ea(),await Ta(),await en(),xa(),H(),await w(),Ha(),Na(),Ba(),Da(),Aa(),Wa(),ja(),Xa(),La(),Xt(),Ma(),$a(),Qt(()=>{w()}),Nt(),Ga(),Ca(),document.addEventListener("hotsheet:render",()=>L()),document.addEventListener("hotsheet:show-tags-dialog",()=>{bn()}),document.addEventListener("hotsheet:upnext-changed",()=>ht()),document.getElementById("print-btn")?.addEventListener("click",rt),fn(),Fa(),W()}catch(e){console.error("Hot Sheet init failed:",e);let t=document.getElementById("ticket-list");t&&(t.innerHTML=`<div style="padding:20px;color:red">Init error: ${e}</div>`)}}async function Ea(){try{let e=await f("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(s.settings.detail_position=e.detail_position),e.detail_width&&(s.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(s.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(s.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(s.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(s.layout=e.layout)}catch{}Ke(s.settings.detail_position),ze()}async function Ta(){try{let e=await f("/categories");e.length>0&&(s.categories=e)}catch{}ft()}function ft(){let e=document.getElementById("sidebar-categories");if(e){let t=e.querySelector(".sidebar-label");e.innerHTML="",t&&e.appendChild(t);for(let n of s.categories){let a=v(r("button",{className:`sidebar-item${s.view===`category:${n.id}`?" active":""}`,"data-view":`category:${n.id}`,children:[r("span",{className:"cat-dot",style:`background:${n.color}`})," ",n.label]}));a.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active")),a.classList.add("active"),s.view=`category:${n.id}`,s.selectedIds.clear(),bt(),H(),w()}),e.appendChild(a)}}if(s.activeTicketId!=null){let t=s.tickets.find(n=>n.id===s.activeTicketId);t&&ye(t.category)}}async function xa(){try{let e=await f("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function La(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close"),n=document.getElementById("settings-btn"),a=document.querySelectorAll(".settings-tab"),o=document.querySelectorAll(".settings-tab-panel");a.forEach(k=>{k.addEventListener("click",()=>{let T=k.dataset.tab;a.forEach(_=>_.classList.remove("active")),o.forEach(_=>_.classList.remove("active")),k.classList.add("active"),document.querySelector(`.settings-tab-panel[data-panel="${T}"]`)?.classList.add("active")})}),n.addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(s.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(s.settings.verified_cleanup_days),e.style.display="flex",Qe(),f("/file-settings").then(k=>{document.getElementById("settings-app-name").value=k.appName||"",document.getElementById("settings-backup-dir").value=k.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",k=>{k.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),l=null;i.addEventListener("input",()=>{l&&clearTimeout(l),l=setTimeout(()=>{let k=Math.max(1,parseInt(i.value,10)||3);i.value=String(k),s.settings.trash_cleanup_days=k,f("/settings",{method:"PATCH",body:{trash_cleanup_days:String(k)}})},500)});let c=document.getElementById("settings-verified-days"),d=null;c.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let k=Math.max(1,parseInt(c.value,10)||30);c.value=String(k),s.settings.verified_cleanup_days=k,f("/settings",{method:"PATCH",body:{verified_cleanup_days:String(k)}})},500)});let u=document.getElementById("settings-app-name"),p=document.getElementById("settings-app-name-hint"),m=null;u.addEventListener("input",()=>{m&&clearTimeout(m),m=setTimeout(()=>{let k=u.value.trim();f("/file-settings",{method:"PATCH",body:{appName:k}}).then(()=>{let T=k||"Hot Sheet";document.title=T;let _=document.querySelector(".app-title h1");_&&(_.textContent=T),p.textContent=k?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let g=document.getElementById("check-updates-btn"),y=document.getElementById("check-updates-status");g.addEventListener("click",async()=>{let k=yt();if(k){g.disabled=!0,g.textContent="Checking...",y.textContent="";try{let T=await k("check_for_update");T?(y.textContent=`Update available: v${T}`,document.getElementById("settings-overlay").style.display="none",mn(T)):y.textContent="Your software is up to date."}catch{y.textContent="Could not check for updates."}g.textContent="Check for Updates",g.disabled=!1}});let b=document.getElementById("settings-backup-dir"),E=document.getElementById("settings-backup-dir-hint"),x=null;b.addEventListener("input",()=>{x&&clearTimeout(x),x=setTimeout(()=>{let k=b.value.trim();f("/file-settings",{method:"PATCH",body:{backupDir:k}}).then(()=>{E.textContent=k?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)}),Pa(),Ia()}function De(){let e=document.getElementById("category-list");e.innerHTML="";for(let t=0;t<s.categories.length;t++){let n=s.categories[t],a=v(r("div",{className:"category-row",children:[r("input",{type:"color",className:"category-color-input",value:n.color,title:"Color"}),r("input",{type:"text",className:"category-label-input",value:n.label,placeholder:"Label",title:"Display name"}),r("input",{type:"text",className:"category-short-input",value:n.shortLabel,placeholder:"ABR",title:"Short label (3 chars)",maxlength:"4"}),r("input",{type:"text",className:"category-key-input",value:n.shortcutKey,placeholder:"k",title:"Keyboard shortcut",maxlength:"1"}),r("input",{type:"text",className:"category-desc-input",value:n.description,placeholder:"Description...",title:"Description (for AI tools)"}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]})),o=a.querySelectorAll("input"),[i,l,c,d,u]=o,p=()=>{rn()};i.addEventListener("input",()=>{s.categories[t].color=i.value,p()}),l.addEventListener("input",()=>{s.categories[t].label=l.value,(!n.id||n.id==="")&&(s.categories[t].id=l.value.toLowerCase().replace(/[^a-z0-9]+/g,"_").replace(/^_|_$/g,"")),p()}),c.addEventListener("input",()=>{s.categories[t].shortLabel=c.value.toUpperCase(),p()}),d.addEventListener("input",()=>{let m=d.value.toLowerCase().slice(0,1);d.value=m,s.categories[t].shortcutKey=m,on(),p()}),u.addEventListener("input",()=>{s.categories[t].description=u.value,p()}),a.querySelector(".category-delete-btn").addEventListener("click",()=>{s.categories.splice(t,1),De(),rn()}),e.appendChild(a)}on()}function on(){let e=document.querySelectorAll(".category-key-input"),t=new Map;s.categories.forEach((n,a)=>{if(n.shortcutKey){let o=n.shortcutKey.toLowerCase();t.has(o)||t.set(o,[]),t.get(o).push(a)}}),e.forEach((n,a)=>{let o=s.categories[a]?.shortcutKey?.toLowerCase();o&&t.get(o).length>1?n.classList.add("category-key-conflict"):n.classList.remove("category-key-conflict")})}var ct=null;function rn(){ct&&clearTimeout(ct),ct=setTimeout(async()=>{await f("/categories",{method:"PUT",body:s.categories}),ft()},500)}function Ia(){document.getElementById("category-add-btn").addEventListener("click",()=>{s.categories.push({id:"",label:"",shortLabel:"",color:"#6b7280",shortcutKey:"",description:""}),De();let n=document.querySelectorAll(".category-row");n[n.length-1]?.querySelector(".category-label-input")?.focus()});let e=document.getElementById("category-preset-select");f("/category-presets").then(n=>{for(let a of n)e.appendChild(v(r("option",{value:a.id,children:a.name})))}),e.addEventListener("change",async()=>{if(!e.value)return;let a=(await f("/category-presets")).find(o=>o.id===e.value);a&&(s.categories=[...a.categories],await f("/categories",{method:"PUT",body:s.categories}),De(),ft()),e.value=""}),document.getElementById("settings-btn").addEventListener("click",()=>{De()})}async function Ca(){let e=yt();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let n=document.getElementById("settings-tab-updates");n&&(n.style.display="");let a=[0,3e3,1e4];for(let o of a){o>0&&await new Promise(i=>setTimeout(i,o));try{let i=await e("get_pending_update");if(i){mn(i);return}}catch{return}}}function yt(){return window.__TAURI__?.core?.invoke??null}function mn(e){let t=document.getElementById("update-banner");if(!t)return;let n=document.getElementById("update-banner-label");n&&(n.textContent=`Update available: v${e}`),t.style.display="flex";let a=document.getElementById("update-install-btn");a?.addEventListener("click",async()=>{if(a){a.textContent="Installing...",a.disabled=!0;try{await yt()?.("install_update"),n&&(n.textContent="Update installed! Restart the app to apply."),a.style.display="none"}catch{a.textContent="Install Failed",a.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function Sa(){let e=document.getElementById("skills-banner");if(!e)return;e.style.display="flex",document.getElementById("skills-banner-dismiss")?.addEventListener("click",()=>{e.style.display="none"})}function Ma(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),n=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),o="";f("/worklist-info").then(i=>{o=i.prompt,e.style.display="",i.skillCreated&&Sa()}),t.addEventListener("click",()=>{o!==""&&navigator.clipboard.writeText(o).then(()=>{n.textContent="Copied!",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M20 6L9 17l-5-5"/></svg>',setTimeout(()=>{n.textContent="Copy AI prompt",a.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="13" height="13" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><rect x="9" y="9" width="13" height="13" rx="2"/><path d="M5 15H4a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h9a2 2 0 0 1 2 2v1"/></svg>'},1500)})})}function $a(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");f("/glassbox/status").then(({available:n})=>{n&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{f("/glassbox/launch",{method:"POST"})})}function pt(){let e=document.getElementById("layout-toggle"),t=$e(),n=e.querySelector('[data-layout="columns"]');n.disabled=!t,n.style.opacity=t?"":"0.3";let a=s.layout==="columns"&&!t?"list":s.layout;e.querySelectorAll(".layout-btn").forEach(o=>{o.classList.toggle("active",o.dataset.layout===a)})}function Na(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.layout;n==="columns"&&!$e()||(s.layout=n,H(),pt(),L(),f("/settings",{method:"PATCH",body:{layout:n}}))})}),pt()}function ln(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===s.settings.detail_position)})}function Ba(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let n=t.dataset.position;s.settings.detail_position=n,Ke(n),ze(),ln(),f("/settings",{method:"PATCH",body:{detail_position:n}})})}),ln()}function gn(e){return e==="up-next"?{action:"up_next",value:!0}:e==="open"?{action:"status",value:"not_started"}:e==="completed"?{action:"status",value:"completed"}:e==="verified"?{action:"status",value:"verified"}:e==="backlog"?{action:"status",value:"backlog"}:e==="archive"?{action:"status",value:"archive"}:e==="trash"?{action:"delete",value:null}:e.startsWith("category:")?{action:"category",value:e.split(":")[1]}:e.startsWith("priority:")?{action:"priority",value:e.split(":")[1]}:null}async function _a(e,t){let n=gn(e);if(!n)return;let a=s.tickets.filter(o=>t.includes(o.id));n.action==="delete"?await I(a,{ids:t,action:"delete"},"Delete tickets"):await I(a,{ids:t,action:n.action,value:n.value},`Change ${n.action}`),H(),w()}function Ha(){document.querySelectorAll(".sidebar-item[data-view]").forEach(t=>{t.addEventListener("click",()=>{document.querySelectorAll(".sidebar-item").forEach(a=>a.classList.remove("active")),t.classList.add("active"),s.view=t.dataset.view,s.selectedIds.clear(),bt(),H(),pt(),w()});let n=t.dataset.view;gn(n)&&(t.addEventListener("dragover",a=>{a.preventDefault(),a.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",a=>{a.preventDefault(),t.classList.remove("drop-target");let o=[...U];o.length!==0&&_a(n,o)}))})}function Da(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,n]=e.value.split(":");s.sortBy=t,s.sortDir=n,H(),w()})}var dt=null;function Aa(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{dt&&clearTimeout(dt),dt=setTimeout(()=>{s.search=e.value,H(),w()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",s.search="",H(),w())})}var X=[];function Pa(){let e=document.getElementById("settings-tab-experimental"),t=document.getElementById("settings-experimental-panel"),n=document.getElementById("settings-channel-enabled"),a=document.getElementById("settings-channel-hint"),o=document.getElementById("settings-channel-instructions"),i=document.getElementById("settings-channel-copy-btn"),l=document.getElementById("settings-channel-cmd"),c=document.getElementById("settings-custom-commands-section");document.getElementById("settings-btn").addEventListener("click",()=>{fetch("/api/channel/claude-check").then(d=>d.ok?d.json():null).then(d=>{if(!d||!d.installed){e.style.display="none",t.style.display="none";return}e.style.display="",t.style.display="",d.meetsMinimum?(a.textContent="Push worklist events to a running Claude Code session via MCP channels.",n.disabled=!1):(a.textContent=`Claude Code ${d.version||"unknown"} detected but v2.1.80+ is required. Please upgrade Claude Code.`,n.disabled=!0),mt()}).catch(()=>{e.style.display="none",t.style.display="none"})}),fetch("/api/channel/status").then(d=>d.ok?d.json():null).then(d=>{d&&(n.checked=d.enabled,d.enabled&&(o.style.display="",c.style.display=""))}).catch(()=>{}),f("/settings").then(d=>{if(d.custom_commands)try{X=JSON.parse(d.custom_commands)}catch{}Ae()}),n.addEventListener("change",async()=>{n.checked?(await f("/channel/enable",{method:"POST"}),o.style.display="",c.style.display=""):(await f("/channel/disable",{method:"POST"}),o.style.display="none",c.style.display="none"),fn(),Ae()}),i?.addEventListener("click",()=>{let d=l?.textContent||"";navigator.clipboard.writeText(d).then(()=>{i&&(i.textContent="Copied!",setTimeout(()=>{i.textContent="Copy"},1500))})}),document.getElementById("settings-add-command-btn")?.addEventListener("click",()=>{X.push({name:"",prompt:""}),mt()})}function mt(){let e=document.getElementById("settings-commands-list");if(e){e.innerHTML="";for(let t=0;t<X.length;t++){let n=X[t],a=v(r("div",{className:"settings-command-row",children:[r("div",{className:"settings-command-row-header",children:[r("input",{type:"text",value:n.name,placeholder:"Button label..."}),r("button",{className:"category-delete-btn",title:"Remove",children:"\xD7"})]}),r("label",{children:"Prompt sent to Claude:"}),r("textarea",{placeholder:"Tell Claude what to do...",children:n.prompt})]})),o=a.querySelector("input"),i=a.querySelector("textarea"),l=()=>{X[t]={name:o.value,prompt:i.value},cn()};o.addEventListener("input",l),i.addEventListener("input",l),a.querySelector(".category-delete-btn").addEventListener("click",()=>{X.splice(t,1),mt(),cn()}),e.appendChild(a)}}}async function cn(){await f("/settings",{method:"PATCH",body:{custom_commands:JSON.stringify(X)}}),Ae()}function Ae(){let e=document.getElementById("channel-commands-container");if(!e)return;e.innerHTML="";let t=document.getElementById("channel-play-section");if(!(!t||t.style.display==="none"))for(let n of X){if(!n.name.trim()||!n.prompt.trim())continue;let a=v(r("button",{className:"channel-command-btn",children:n.name}));a.addEventListener("click",()=>{vt(n.prompt)}),e.appendChild(a)}}var we=null;function Ra(){we||(we=setInterval(async()=>{try{let e=await fetch("/api/channel/permission");if(!e.ok)return;let t=await e.json();t.pending&&Ua(t.pending)}catch{}},2e3))}function qa(){we&&(clearInterval(we),we=null)}function Ua(e){let t=document.getElementById("permission-overlay");if(!t||t.style.display!=="none")return;let n=document.getElementById("permission-overlay-detail");if(n){let i=`<div class="permission-tool">${e.tool_name}: ${e.description}</div>`;e.input_preview&&(i+=`<pre class="permission-preview">${e.input_preview.replace(/&/g,"&").replace(/</g,"<")}</pre>`),n.innerHTML=i}t.style.display="";function a(i){fetch("/api/channel/permission/respond",{method:"POST",headers:{"Content-Type":"application/json"},body:JSON.stringify({request_id:e.request_id,behavior:i})}),t.style.display="none"}function o(){fetch("/api/channel/permission/dismiss",{method:"POST"}),t.style.display="none"}document.getElementById("permission-allow-btn")?.addEventListener("click",()=>a("allow"),{once:!0}),document.getElementById("permission-deny-btn")?.addEventListener("click",()=>a("deny"),{once:!0}),document.getElementById("permission-dismiss-btn")?.addEventListener("click",o,{once:!0})}var Ee=!1,He=null,Pe=!1;function gt(e){Pe=e;let t=document.getElementById("channel-status-indicator");if(!t)return;let n=document.getElementById("channel-play-section");if(!n||n.style.display==="none"){t.style.display="none";return}e?(t.style.display="",t.className="channel-status-indicator busy",t.innerHTML='<svg xmlns="http://www.w3.org/2000/svg" width="12" height="12" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2" stroke-linecap="round" stroke-linejoin="round"><path d="M21 12a9 9 0 1 1-6.219-8.56"/></svg> Claude working'):(t.style.display="",t.className="channel-status-indicator",t.innerHTML="\u2713 Claude idle",setTimeout(()=>{!Pe&&t&&(t.style.display="none")},5e3))}var ce=null;function vt(e){gt(!0),f("/channel/trigger",{method:"POST",body:{message:e}}),ce&&clearTimeout(ce),ce=setTimeout(()=>{Pe&>(!1)},12e4)}async function Oa(e){try{if((await f("/stats")).up_next===0){Va();return}}catch{}e.classList.add("pulsing"),setTimeout(()=>e.classList.remove("pulsing"),600),vt()}function Va(){let e=document.getElementById("no-upnext-alert");e&&e.remove();let t=v(r("div",{id:"no-upnext-alert",className:"no-upnext-alert",children:[r("span",{children:"No Up Next items to process"}),r("button",{className:"no-upnext-dismiss",children:"\xD7"})]}));t.querySelector(".no-upnext-dismiss").addEventListener("click",()=>t.remove()),setTimeout(()=>t.remove(),4e3);let n=document.getElementById("channel-play-section");n&&n.after(t)}async function fn(){let e={enabled:!1,alive:!1};try{let l=await fetch("/api/channel/status");l.ok&&(e=await l.json())}catch{}let t=document.getElementById("channel-play-section"),n=document.getElementById("channel-play-btn"),a=document.getElementById("channel-play-icon"),o=document.getElementById("channel-auto-icon");if(!e.enabled){t.style.display="none",qa();return}t.style.display="",Ae(),Ra();let i=null;n.addEventListener("click",()=>{i?(clearTimeout(i),i=null,dn(n,a,o)):i=setTimeout(()=>{i=null,Ee?dn(n,a,o):Oa(n)},250)})}function dn(e,t,n){Ee=!Ee,Ee?(e.classList.add("auto-mode"),t.style.display="none",n.style.display=""):(e.classList.remove("auto-mode"),t.style.display="",n.style.display="none")}function ht(){Ee&&(He&&clearTimeout(He),He=setTimeout(()=>{He=null,vt()},5e3))}function bt(){let e=document.getElementById("dashboard-container");e&&(e.id="ticket-list",e.innerHTML="",za())}var yn=["search-input","layout-toggle","sort-select","detail-position-toggle","glassbox-btn"];function Ka(){s.view="dashboard",document.querySelectorAll(".sidebar-item").forEach(o=>o.classList.remove("active"));for(let o of yn){let i=document.getElementById(o);if(i){let l=i.closest(".search-box, .layout-toggle, .sort-controls")||i;l.style.display="none"}}let e=document.getElementById("batch-toolbar");e&&(e.style.display="none");let t=document.getElementById("detail-panel");t&&(t.style.display="none");let n=document.getElementById("detail-resize-handle");n&&(n.style.display="none");let a=document.getElementById("ticket-list");a.innerHTML="",a.id="dashboard-container",a.classList.remove("ticket-list-columns"),st(a)}function za(){for(let e of yn){let t=document.getElementById(e);if(t){let n=t.closest(".search-box, .layout-toggle, .sort-controls")||t;n.style.display=""}}bt()}async function Fa(){let e=await an(),t=document.getElementById("stats-bar");t&&t.after(e),e.addEventListener("click",()=>Ka())}var vn=[{key:"1",value:"highest",label:"Highest"},{key:"2",value:"high",label:"High"},{key:"3",value:"default",label:"Default"},{key:"4",value:"low",label:"Low"},{key:"5",value:"lowest",label:"Lowest"}],hn=[{key:"n",value:"not_started",label:"Not Started"},{key:"s",value:"started",label:"Started"},{key:"c",value:"completed",label:"Completed"},{key:"v",value:"verified",label:"Verified"},{key:"b",value:"backlog",label:"Backlog"},{key:"a",value:"archive",label:"Archive"}];function Wa(){let e=document.getElementById("batch-category");e.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(e,s.categories.map(l=>({label:l.label,key:l.shortcutKey,color:l.color,action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"category",value:l.id},"Batch change category"),w()}})));document.body.appendChild(i),$(i,e),i.style.visibility=""});let t=document.getElementById("batch-priority");t.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(t,vn.map(l=>({label:l.label,key:l.key,icon:A(l.value),iconColor:P(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"priority",value:l.value},"Batch change priority"),w()}})));document.body.appendChild(i),$(i,t),i.style.visibility=""});let n=document.getElementById("batch-status");n.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(n,hn.map(l=>({label:l.label,key:l.key,icon:z(l.value),action:async()=>{let c=Array.from(s.selectedIds),d=s.tickets.filter(u=>s.selectedIds.has(u.id));await I(d,{ids:c,action:"status",value:l.value},"Batch change status"),w()}})));document.body.appendChild(i),$(i,n),i.style.visibility=""}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){let u=[{ids:d.map(p=>p.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}];await We(o,u,"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!0},"Batch toggle up next")}else await I(o,{ids:c,action:"up_next",value:!1},"Batch toggle up next");w(),ht()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));await I(i,{ids:o,action:"delete"},"Batch delete"),s.selectedIds.clear(),w()});let a=document.getElementById("batch-more");a.addEventListener("click",o=>{o.stopPropagation(),B();let i=N(a,[{label:"Tags...",key:"t",action:()=>{bn()}},{label:"Duplicate",key:"d",action:async()=>{let l=Array.from(s.selectedIds),c=await f("/tickets/duplicate",{method:"POST",body:{ids:l}});s.selectedIds.clear();for(let d of c)s.selectedIds.add(d.id);w()}},{label:"",key:"",separator:!0,action:()=>{}},{label:"Move to Backlog",key:"b",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"backlog"},"Move to backlog"),s.selectedIds.clear(),w()}},{label:"Archive",key:"a",action:async()=>{let l=Array.from(s.selectedIds),c=s.tickets.filter(d=>s.selectedIds.has(d.id));await I(c,{ids:l,action:"status",value:"archive"},"Archive"),s.selectedIds.clear(),w()}}]);document.body.appendChild(i),$(i,a),i.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",o=>{if(o.target.checked)for(let l of s.tickets)s.selectedIds.add(l.id);else s.selectedIds.clear();L()})}var j=null;function ja(){document.getElementById("detail-close").addEventListener("click",St);let e=["detail-title","detail-details"];for(let u of e){let p=document.getElementById(u);p.addEventListener("input",()=>{let m=s.tickets.find(g=>g.id===s.activeTicketId);if(m){let g=u.replace("detail-","");Ce(m,g,p.value)}j&&clearTimeout(j),j=setTimeout(()=>{if(s.activeTicketId==null)return;let g=u.replace("detail-","");f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[g]:p.value}}).then(()=>{w()})},300)})}async function t(u,p){if(s.activeTicketId==null)return;let m=s.tickets.find(g=>g.id===s.activeTicketId);m?await R(m,{[u]:p},`Change ${u}`):await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{[u]:p}}),w(),te(s.activeTicketId)}document.getElementById("detail-category").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,s.categories.map(y=>({label:y.label,key:y.shortcutKey,color:y.color,active:y.id===m,action:()=>{ye(y.id),t("category",y.id)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-priority").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,vn.map(y=>({label:y.label,key:y.key,icon:A(y.value),iconColor:P(y.value),active:y.value===m,action:()=>{xe(y.value),t("priority",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-status").addEventListener("click",u=>{u.stopPropagation();let p=u.currentTarget;if(p.disabled)return;B();let m=p.dataset.value||"",g=N(p,hn.map(y=>({label:y.label,key:y.key,icon:z(y.value),active:y.value===m,action:()=>{Le(y.value),t("status",y.value)}})));document.body.appendChild(g),$(g,p),g.style.visibility=""}),document.getElementById("detail-upnext").addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);u?!u.up_next&&(u.status==="completed"||u.status==="verified")?await R(u,{status:"not_started",up_next:!0},"Toggle up next"):await R(u,{up_next:!u.up_next},"Toggle up next"):await f(`/tickets/${s.activeTicketId}/up-next`,{method:"POST"}),w(),ht(),te(s.activeTicketId)}),document.getElementById("detail-add-note-btn")?.addEventListener("click",async()=>{if(s.activeTicketId==null)return;let u=s.tickets.find(p=>p.id===s.activeTicketId);if(u){let p=u.notes;await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{notes:"(new note)"}});let m=await f(`/tickets/${s.activeTicketId}`);ge({...u,notes:p},"Add note",m.notes),u.notes=m.notes}te(s.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async u=>{let p=u.target,m=p.files?.[0];!m||s.activeTicketId==null||(await xt(`/tickets/${s.activeTicketId}/attachments`,m),p.value="",te(s.activeTicketId),w())}),document.getElementById("detail-attachments").addEventListener("click",async u=>{let p=u.target,m=p.closest(".attachment-reveal");if(m){let b=m.dataset.attId;b&&f(`/attachments/${b}/reveal`,{method:"POST"});return}let g=p.closest(".attachment-delete");if(g===null)return;let y=g.dataset.attId;y===void 0||y===""||(await f(`/attachments/${y}`,{method:"DELETE"}),s.activeTicketId!=null&&te(s.activeTicketId))});let n=document.getElementById("detail-tag-input"),a=null,o=-1,i=[];f("/tags").then(u=>{i=u});function l(){a?.remove(),a=null,o=-1}function c(){l();let u=n.value.trim().toLowerCase();if(!u)return;let p=s.tickets.find(b=>b.id===s.activeTicketId),m=p?V(p.tags):[],g=i.filter(b=>b.toLowerCase().includes(u)&&!m.includes(b));if(g.length===0)return;a=v(r("div",{className:"tag-autocomplete"}));for(let b=0;b<g.length;b++){let E=v(r("div",{className:"tag-autocomplete-item",children:g[b]}));E.addEventListener("mousedown",x=>{x.preventDefault(),n.value=g[b],l(),d()}),a.appendChild(E)}let y=n.getBoundingClientRect();a.style.position="fixed",a.style.left=`${y.left}px`,a.style.top=`${y.bottom+2}px`,a.style.width=`${y.width}px`,document.body.appendChild(a)}async function d(){let u=n.value.trim();if(!u||s.activeTicketId==null)return;let p=s.tickets.find(y=>y.id===s.activeTicketId);if(!p)return;let m=V(p.tags);if(m.includes(u)){n.value="";return}let g=[...m,u];n.value="",l(),await f(`/tickets/${s.activeTicketId}`,{method:"PATCH",body:{tags:JSON.stringify(g)}}),p.tags=JSON.stringify(g),fe(g,!1),i.includes(u)||i.push(u)}n.addEventListener("input",()=>{c()}),n.addEventListener("blur",()=>{l()}),n.addEventListener("keydown",u=>{if(u.key==="Enter"){if(u.preventDefault(),a&&o>=0){let p=a.querySelectorAll(".tag-autocomplete-item");n.value=p[o]?.textContent||n.value}l(),d()}else if(u.key==="Escape")l();else if(u.key==="ArrowDown"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.min(o+1,p.length-1),p.forEach((m,g)=>m.classList.toggle("active",g===o))}else if(u.key==="ArrowUp"&&a){u.preventDefault();let p=a.querySelectorAll(".tag-autocomplete-item");o=Math.max(o-1,0),p.forEach((m,g)=>m.classList.toggle("active",g===o))}})}async function bn(){let e=s.tickets.filter(p=>s.selectedIds.has(p.id));if(e.length===0)return;let t=await f("/tags");for(let p of e)for(let m of V(p.tags))t.includes(m)||t.push(m);t.sort();let n=new Map;for(let p of t){let m=e.filter(g=>V(g.tags).includes(p)).length;m===e.length?n.set(p,"checked"):m===0?n.set(p,"unchecked"):n.set(p,"mixed")}let a=new Map(n),o=new Map(n),i=v(r("div",{className:"tags-dialog-overlay",children:r("div",{className:"tags-dialog",children:[r("div",{className:"tags-dialog-header",children:[r("span",{children:"Tags"}),r("button",{className:"detail-close",id:"tags-dialog-close",children:"\xD7"})]}),r("div",{className:"tags-dialog-body",id:"tags-dialog-body"}),r("div",{className:"tags-dialog-new",children:[r("input",{type:"text",id:"tags-dialog-new-input",placeholder:"New tag..."}),r("button",{className:"btn btn-sm",id:"tags-dialog-add-btn",children:"Add"})]}),r("div",{className:"tags-dialog-footer",children:[r("button",{className:"btn btn-sm",id:"tags-dialog-cancel",children:"Cancel"}),r("button",{className:"btn btn-sm btn-accent",id:"tags-dialog-done",children:"Done"})]})]})}));function l(){let p=i.querySelector("#tags-dialog-body");p.innerHTML="";for(let m of t){let g=o.get(m),y=v(r("label",{className:"tags-dialog-row",children:[r("input",{type:"checkbox",checked:g==="checked"}),r("span",{children:m})]})),b=y.querySelector("input");g==="mixed"&&(b.indeterminate=!0),b.addEventListener("change",()=>{o.set(m,b.checked?"checked":"unchecked")}),p.appendChild(y)}t.length===0&&(p.innerHTML='<div style="padding:12px 16px;color:var(--text-muted);font-size:13px">No tags yet. Create one below.</div>')}l(),document.body.appendChild(i);let c=i.querySelector("#tags-dialog-new-input"),d=()=>{let p=c.value.trim();if(!p||t.includes(p)){c.value="";return}t.push(p),t.sort(),o.set(p,"checked"),a.set(p,"unchecked"),c.value="",l()};i.querySelector("#tags-dialog-add-btn").addEventListener("click",d),c.addEventListener("keydown",p=>{p.key==="Enter"&&(p.preventDefault(),d())});let u=()=>i.remove();i.querySelector("#tags-dialog-close").addEventListener("click",u),i.querySelector("#tags-dialog-cancel").addEventListener("click",u),i.addEventListener("click",p=>{p.target===i&&u()}),i.querySelector("#tags-dialog-done").addEventListener("click",async()=>{let p=[],m=[];for(let g of t){let y=a.get(g),b=o.get(g);y!==b&&(b==="checked"?p.push(g):b==="unchecked"&&m.push(g))}if(p.length>0||m.length>0){for(let g of e){let y=V(g.tags),b=[...y];for(let E of p)b.includes(E)||b.push(E);for(let E of m)b=b.filter(x=>x!==E);JSON.stringify(b)!==JSON.stringify(y)&&await f(`/tickets/${g.id}`,{method:"PATCH",body:{tags:JSON.stringify(b)}})}w(),ae()}u()})}function Ja(e){if(!e||e==="")return[];try{let t=JSON.parse(e);if(Array.isArray(t))return t}catch{}return e.trim()?[{text:e,created_at:""}]:[]}function Ya(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let n=Ja(e.notes);if(n.length>0){t.push("");for(let a of n)t.push(`- ${a.text}`)}return t.join(`
|
|
98
|
+
`)}function un(){console.log("[undo] triggerUndo called, canUndo:",At()),j&&(clearTimeout(j),j=null),Ze(),Ht().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function pn(){console.log("[undo] triggerRedo called, canRedo:",Pt()),j&&(clearTimeout(j),j=null),Ze(),Dt().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function Xa(){window.addEventListener("app:undo",un),window.addEventListener("app:redo",pn),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?pn():un())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,n=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",a=document.getElementById("settings-overlay");if(e.key==="Escape"&&a.style.display!=="none"){a.style.display="none";return}if(e.key==="Escape"){let o=document.activeElement;if(o&&(o.tagName==="INPUT"||o.tagName==="TEXTAREA")&&o.closest(".detail-panel, .detail-body")){o.blur();return}s.selectedIds.size>0&&(s.selectedIds.clear(),L());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!n){e.preventDefault(),s.selectedIds.clear();for(let o of s.tickets)s.selectedIds.add(o.id);L();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(s.selectedIds.size>0){e.preventDefault();let o=s.tickets.filter(d=>s.selectedIds.has(d.id)),l=!o.every(d=>d.up_next),c=Array.from(s.selectedIds);if(l){let d=o.filter(u=>u.status==="completed"||u.status==="verified");if(d.length>0){We(o,[{ids:d.map(u=>u.id),action:"status",value:"not_started"},{ids:c,action:"up_next",value:!0}],"Toggle up next").then(()=>{w()});return}}I(o,{ids:c,action:"up_next",value:l},"Toggle up next").then(()=>{w()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&s.selectedIds.size>0&&!(n&&!e.altKey)){let o=!e.altKey&&window.getSelection();if(!(o&&!o.isCollapsed&&o.toString().trim()!=="")){e.preventDefault();let l=s.tickets.filter(c=>s.selectedIds.has(c.id)).map(Ya).join(`
|
|
99
99
|
|
|
100
|
-
`);navigator.clipboard.writeText(l);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),W();return}if((e.metaKey||e.ctrlKey)&&e.key==="p"){e.preventDefault(),rt();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!n){e.preventDefault(),W();return}if((e.key==="Delete"||e.key==="Backspace")&&!n&&s.selectedIds.size>0){e.preventDefault();let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));I(i,{ids:o,action:"delete"},"Delete").then(()=>{s.selectedIds.clear(),w()});return}})}var ut=0;function
|
|
100
|
+
`);navigator.clipboard.writeText(l);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),W();return}if((e.metaKey||e.ctrlKey)&&e.key==="p"){e.preventDefault(),rt();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!n){e.preventDefault(),W();return}if((e.key==="Delete"||e.key==="Backspace")&&!n&&s.selectedIds.size>0){e.preventDefault();let o=Array.from(s.selectedIds),i=s.tickets.filter(l=>s.selectedIds.has(l.id));I(i,{ids:o,action:"delete"},"Delete").then(()=>{s.selectedIds.clear(),w()});return}})}var ut=0;function Ga(){async function e(){try{let t=await f(`/poll?version=${ut}`);t.version>ut&&(ut=t.version,s.backupPreview?.active||(w(),ae()),Pe&&fetch("/api/channel/status").then(n=>n.ok?n.json():null).then(n=>{n?.done&&(gt(!1),ce&&(clearTimeout(ce),ce=null))}).catch(()=>{}))}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}wa();})();
|
package/dist/client/styles.css
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}:root{--bg: #ffffff;--bg-secondary: #f9fafb;--bg-hover: #f3f4f6;--bg-selected: #eff6ff;--border: #e5e7eb;--text: #111827;--text-secondary: #6b7280;--text-muted: #9ca3af;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--star: #eab308;--radius: 6px;--shadow: 0 1px 3px rgba(0,0,0,0.08)}html,body{height:100%;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;line-height:1.5;color:var(--text);background:var(--bg)}button{cursor:pointer;border:none;background:none;font:inherit;color:inherit}input,select,textarea{font:inherit;color:inherit}.app{display:flex;flex-direction:column;height:100vh}.app-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-bottom:1px solid var(--border);background:var(--bg);gap:16px;flex-shrink:0}.app-header h1{font-size:18px;font-weight:700;white-space:nowrap}.header-controls{display:flex;align-items:center;gap:12px;flex:1;max-width:500px}.search-box{flex:1}.search-box input{width:100%;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-secondary);outline:none}.search-box input:focus{border-color:var(--accent);background:var(--bg)}.layout-toggle{display:flex;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex-shrink:0}.layout-btn{display:flex;align-items:center;justify-content:center;padding:4px 8px;color:var(--text-secondary);background:var(--bg);border:none;border-right:1px solid var(--border);cursor:pointer}.layout-btn:last-child{border-right:none}.layout-btn:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.layout-btn.active{background:var(--bg-selected);color:var(--accent)}.layout-btn:disabled{cursor:default}.sort-controls select{padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.print-btn{margin-left:auto}.settings-btn{font-size:18px;color:var(--text-muted);padding:4px;border-radius:var(--radius);flex-shrink:0}.settings-btn:hover{color:var(--text);background:var(--bg-hover)}.glassbox-btn{padding:0;border:1px solid var(--border);border-radius:var(--radius);flex-shrink:0;cursor:pointer;overflow:hidden;line-height:0}.glassbox-btn img{height:28px;width:28px;display:block}.glassbox-btn:hover{border-color:var(--accent)}.app-body{display:flex;flex:1;overflow:hidden}.content-area{flex:1;display:flex;overflow:hidden;min-width:0}.content-area.detail-side{flex-direction:row}.content-area.detail-bottom{flex-direction:column}.sidebar{width:180px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;flex-shrink:0;padding:8px 0}.sidebar-channel-play{padding:8px 10px 4px}.channel-play-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:8px;background:#22c55e;color:#fff;border-radius:var(--radius);cursor:pointer;transition:background .15s;position:relative}.channel-play-btn:hover{background:#16a34a}.channel-play-btn:active{background:#15803d}.channel-play-btn.pulsing{animation:play-pulse .6s ease-out}.channel-play-btn.auto-mode{background:#16a34a}.channel-play-icon{display:flex;align-items:center;justify-content:center}.channel-auto-icon{display:flex;align-items:center;justify-content:center}.channel-command-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:6px 8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text);border-radius:var(--radius);cursor:pointer;font-size:12px;transition:background .15s}.channel-command-btn:hover{background:var(--bg-hover);border-color:var(--accent)}#channel-commands-container{display:flex;flex-direction:column;gap:4px;padding:0 10px 4px}.settings-commands-list{display:flex;flex-direction:column;gap:8px}.settings-command-row{display:flex;flex-direction:column;gap:4px;padding:10px;background:var(--bg-secondary);border-radius:var(--radius);border:1px solid var(--border)}.settings-command-row .settings-command-row-header{display:flex;align-items:center;gap:6px}.settings-command-row input[type=text]{flex:1;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.settings-command-row input[type=text]:focus{border-color:var(--accent)}.settings-command-row textarea{width:100%;padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:11px;font-family:"SF Mono",Monaco,"Cascadia Code",monospace;resize:vertical;min-height:48px;outline:none}.settings-command-row textarea:focus{border-color:var(--accent)}.settings-command-row label{font-size:11px;color:var(--text-muted)}@keyframes play-pulse{0%{transform:scale(1)}50%{transform:scale(0.95);opacity:.7}100%{transform:scale(1);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}.settings-checkbox-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:13px !important}.settings-checkbox-label input[type=checkbox]{width:auto;accent-color:var(--accent)}.settings-experimental-heading{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}.settings-channel-command{display:flex;align-items:center;gap:8px;margin-top:6px;padding:8px 10px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius)}.settings-channel-command code{flex:1;font-size:11px;font-family:"SF Mono",Monaco,"Cascadia Code",monospace;word-break:break-all;color:var(--text)}.sidebar-copy-prompt{padding:8px 10px 4px}.copy-prompt-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 8px;font-size:12px;color:var(--text-secondary);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all .15s}.copy-prompt-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--bg-selected)}.copy-prompt-icon{display:flex;align-items:center;flex-shrink:0}.sidebar-section{margin-bottom:8px}.sidebar-label{display:flex;align-items:center;gap:4px;padding:8px 16px 4px;font-size:11px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.sidebar-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 16px;text-align:left;font-size:13px;color:var(--text-secondary);border-radius:0}.sidebar-item:hover{background:var(--bg-hover);color:var(--text)}.sidebar-item.active{background:var(--bg-selected);color:var(--accent);font-weight:500}.sidebar-item.drop-target{background:var(--bg-selected);color:var(--accent);outline:2px dashed var(--accent);outline-offset:-2px}.sidebar-divider{height:1px;background:var(--border);margin:6px 16px}.cat-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.sidebar-stats{padding:12px 16px;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;min-height:0}.batch-toolbar{display:flex;align-items:center;gap:8px;padding:6px 16px 6px 19px;background:var(--bg-secondary);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap;min-height:36px}.batch-toolbar select:disabled,.batch-toolbar .btn:disabled{opacity:.4;cursor:default;pointer-events:none}.batch-toolbar select{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px}.batch-select-all{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}.batch-star-btn{font-size:16px;color:var(--text-muted);padding:2px 6px;border-radius:var(--radius);line-height:1}.batch-star-btn:hover:not(:disabled){color:var(--star);background:var(--bg-hover)}.batch-star-btn.active{color:var(--star)}.batch-star-btn.mixed{color:var(--star)}.batch-star-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.star-mixed-wrap{position:relative;display:inline-block}.star-mixed-fill{position:absolute;left:0;top:0;overflow:hidden;width:50%}.batch-delete-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;border:none;background:none}.batch-more-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px}.batch-count{font-size:12px;color:var(--text-muted);margin-left:auto;white-space:nowrap}.btn{padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;cursor:pointer}.btn:hover{background:var(--bg-hover)}.btn-sm{padding:3px 8px;font-size:11px}.btn-danger{color:var(--danger)}.btn-danger:hover:not(:disabled){background:#fef2f2}.ticket-list{flex:1;overflow-y:auto;padding:4px 0}.ticket-list-empty,.ticket-list-loading{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:14px}.ticket-row{display:flex;align-items:center;gap:8px;padding:4px 16px;border-bottom:1px solid rgba(0,0,0,0);border-left:3px solid rgba(0,0,0,0);min-height:36px;-webkit-user-select:none;user-select:none}.ticket-row:hover{background:var(--bg-hover)}.ticket-row.selected{background:var(--bg-selected)}.ticket-row.completed .ticket-title-input{text-decoration:line-through;color:var(--text-muted)}.ticket-row.up-next{border-left:3px solid var(--star)}.ticket-checkbox{flex-shrink:0;width:14px;height:14px;cursor:pointer;accent-color:var(--accent)}.ticket-status-btn{flex-shrink:0;width:20px;height:20px;font-size:14px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:var(--text-secondary)}.ticket-status-btn:hover{background:var(--bg-hover)}.ticket-status-btn.verified{color:#22c55e}.ticket-category-badge{flex-shrink:0;width:4em;padding:1px 0;border-radius:3px;font-size:10px;font-weight:600;color:#fff;text-transform:uppercase;text-align:center;cursor:pointer;letter-spacing:.3px}.ticket-category-badge:hover{opacity:.85}.ticket-number{flex-shrink:0;font-size:11px;color:var(--text-muted);font-family:"SF Mono",Monaco,"Cascadia Code",monospace;min-width:5em}.ticket-title-input{flex:1;border:none;background:rgba(0,0,0,0);padding:2px 0;outline:none;min-width:0;-webkit-user-select:text;user-select:text}.ticket-title-input:focus{border-bottom:1px solid var(--accent)}.ticket-title-input::placeholder{color:var(--text-muted)}.ticket-priority-indicator{flex-shrink:0;font-size:12px;cursor:pointer;padding:2px 4px;border-radius:3px;min-width:24px;text-align:center}.ticket-priority-indicator:hover{background:var(--bg-hover)}.ticket-star{flex-shrink:0;font-size:16px;color:var(--text-muted);padding:0}.ticket-star.active{color:var(--star)}.ticket-star:hover{color:var(--star)}.trash-row .trash-title{flex:1;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-row .btn{flex-shrink:0}.draft-row{border-bottom:1px dashed var(--border) !important;background:var(--bg-secondary)}.draft-row:hover{background:var(--bg-secondary)}.draft-row .draft-placeholder{opacity:.35;pointer-events:none}.draft-row .draft-badge{opacity:.35}.draft-row .draft-input::placeholder{color:var(--text-muted);font-style:italic}.ticket-checkbox-spacer{width:14px;flex-shrink:0}.detail-resize-handle{flex-shrink:0;background:rgba(0,0,0,0);position:relative;z-index:10}.detail-resize-handle:hover,.detail-resize-handle:active{background:var(--accent);opacity:.3}.detail-side .detail-resize-handle{width:4px;cursor:col-resize}.detail-bottom .detail-resize-handle{height:4px;cursor:row-resize}.detail-panel{border-left:1px solid var(--border);background:var(--bg);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden}.detail-side .detail-panel{width:360px;border-left:1px solid var(--border);border-top:none}.detail-bottom .detail-panel{height:300px;width:auto;border-left:none;border-top:1px solid var(--border)}.detail-panel.detail-disabled{background:var(--bg-secondary)}.detail-placeholder{display:flex;align-items:center;justify-content:center;flex:1}.detail-placeholder-text{color:var(--text-muted);font-size:14px}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600}.detail-ticket-number{font-family:"SF Mono",Monaco,"Cascadia Code",monospace;font-size:13px;color:var(--accent)}.detail-close{font-size:20px;color:var(--text-muted);padding:0 4px}.detail-close:hover{color:var(--text)}.detail-body{flex:1;overflow-y:auto;padding:16px}.detail-fields-row{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px;margin-bottom:16px}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{grid-template-columns:repeat(4, 1fr);width:100%}.detail-bottom .detail-body .detail-field-full{width:100%;flex-basis:100%}.detail-field{margin-bottom:16px}.detail-field label{display:block;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.detail-field input[type=text],.detail-field textarea,.detail-field select{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.detail-field input[type=text]:focus,.detail-field textarea:focus,.detail-field select:focus{border-color:var(--accent)}.detail-field textarea{resize:vertical;min-height:80px}.detail-dropdown-btn{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);text-align:left;font-size:inherit;cursor:pointer}.detail-dropdown-btn:hover:not(:disabled){border-color:var(--accent)}.detail-dropdown-btn:disabled{opacity:.6;cursor:default}.batch-dropdown-btn.btn{font-size:12px}.detail-upnext-label{display:flex !important;align-items:center;gap:6px;cursor:pointer;font-size:13px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-star{font-size:18px;padding:2px 6px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.detail-upnext-star:hover:not(:disabled){border-color:var(--accent)}.detail-upnext-star:disabled{opacity:.6;cursor:default}.detail-attachments{margin-bottom:8px}.detail-tags{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:6px}.tag-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;background:var(--bg-selected);border:1px solid var(--border);border-radius:12px;font-size:12px;color:var(--text)}.tag-chip-remove{font-size:14px;color:var(--text-muted);padding:0;line-height:1}.tag-chip-remove:hover{color:var(--danger)}.detail-tag-input{width:100%;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.detail-tag-input:focus{border-color:var(--accent)}.tag-autocomplete{position:absolute;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);max-height:120px;overflow-y:auto;font-size:12px}.tag-autocomplete-item{padding:4px 10px;cursor:pointer}.tag-autocomplete-item:hover,.tag-autocomplete-item.active{background:var(--bg-hover)}.tags-dialog-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.tags-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:320px;max-width:90vw;max-height:60vh;display:flex;flex-direction:column;overflow:hidden}.tags-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.tags-dialog-body{flex:1;overflow-y:auto;padding:8px 0}.tags-dialog-row{display:flex;align-items:center;gap:8px;padding:6px 16px;font-size:13px;cursor:pointer}.tags-dialog-row:hover{background:var(--bg-hover)}.tags-dialog-row input[type=checkbox]{width:14px;height:14px;accent-color:var(--accent)}.tags-dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.tags-dialog-new{display:flex;gap:6px;padding:8px 16px;border-top:1px solid var(--border)}.tags-dialog-new input{flex:1;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);font-size:12px;outline:none}.tags-dialog-new input:focus{border-color:var(--accent)}.attachment-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--bg-secondary);border-radius:var(--radius);margin-bottom:4px;font-size:12px}.attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-reveal{color:var(--text-muted);padding:0 4px;cursor:pointer;border:none;background:none;display:flex;align-items:center}.attachment-reveal:hover{color:var(--accent)}.attachment-delete{color:var(--text-muted);font-size:16px;padding:0 4px;cursor:pointer;border:none;background:none}.attachment-delete:hover{color:var(--danger)}.upload-btn{cursor:pointer;display:inline-flex;align-items:center;gap:4px;margin-top:4px}.detail-meta{padding-top:12px;border-top:1px solid var(--border);font-size:11px;color:var(--text-muted)}.detail-meta div{margin-bottom:2px}.dropdown-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:4px 0;min-width:140px}.dropdown-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px;text-align:left;font-size:13px;text-transform:capitalize}.dropdown-item:hover{background:var(--bg-hover)}.dropdown-item.active{color:var(--accent);font-weight:500}.dropdown-separator{height:1px;background:var(--border);margin:4px 0}.dropdown-icon{font-size:12px;min-width:20px;text-align:center;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.dropdown-icon svg{vertical-align:middle}.dropdown-label{flex:1}.dropdown-kbd{font-size:11px;color:var(--text-muted);padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg-secondary);font-family:inherit;flex-shrink:0}.dropdown-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.print-dialog-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.print-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:360px;max-width:90vw}.print-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.print-dialog-body{padding:16px}.print-dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.permission-overlay{position:fixed;inset:0;z-index:5000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.6);-webkit-backdrop-filter:blur(12px) saturate(120%);backdrop-filter:blur(12px) saturate(120%);animation:permission-fade-in .3s ease-out}@keyframes permission-fade-in{from{opacity:0}to{opacity:1}}.permission-overlay-content{text-align:center;max-width:480px;padding:40px}.permission-overlay-text{font-size:28px;font-weight:700;color:#fff;margin-bottom:12px;text-shadow:0 2px 8px rgba(0,0,0,.3)}.permission-overlay-detail{font-size:14px;color:hsla(0,0%,100%,.7);margin-bottom:24px;line-height:1.5}.permission-overlay-actions{display:flex;gap:12px;justify-content:center}.permission-overlay-btn{padding:10px 24px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:1px solid hsla(0,0%,100%,.2);transition:all .15s}.permission-overlay-btn.permission-allow{background:#22c55e;color:#fff;border-color:#22c55e}.permission-overlay-btn.permission-allow:hover{background:#16a34a}.permission-overlay-btn.permission-deny{background:#ef4444;color:#fff;border-color:#ef4444}.permission-overlay-btn.permission-deny:hover{background:#dc2626}.permission-overlay-btn.permission-dismiss{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.permission-overlay-btn.permission-dismiss:hover{background:hsla(0,0%,100%,.2)}.context-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 4px 16px rgba(0,0,0,.12);padding:4px 0;min-width:180px;font-size:13px}.context-menu-item{display:flex;align-items:center;gap:8px;padding:6px 12px;cursor:pointer;position:relative}.context-menu-item:hover{background:var(--bg-hover)}.context-menu-item:hover>.context-submenu{display:block}.context-menu-item.active{color:var(--accent);font-weight:500}.context-menu-item.danger{color:var(--danger)}.context-menu-item.has-submenu{padding-right:24px}.context-menu-label{flex:1}.context-menu-arrow{position:absolute;right:8px;font-size:10px;color:var(--text-muted)}.context-menu-separator{height:1px;background:var(--border);margin:4px 0}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 4px 16px rgba(0,0,0,.12);padding:4px 0;min-width:160px;z-index:1001}.settings-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.settings-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:540px;max-width:90vw;max-height:85vh;display:flex;flex-direction:column;overflow:hidden}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0}.settings-header h2{font-size:16px;font-weight:600}.settings-tabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;padding:0 12px;gap:2px}.settings-tab{display:flex;flex-direction:column;align-items:center;gap:4px;padding:12px 16px 10px;font-size:11px;color:var(--text-muted);border-bottom:2px solid rgba(0,0,0,0);margin-bottom:-1px;transition:color .15s}.settings-tab svg{flex-shrink:0}.settings-tab:hover{color:var(--text)}.settings-tab.active{color:var(--accent);border-bottom-color:var(--accent)}.settings-body{padding:20px;overflow-y:auto;flex:1;min-height:0}.settings-tab-panel{display:none}.settings-tab-panel.active{display:block}.settings-field{margin-bottom:16px}.settings-field:last-child{margin-bottom:0}.settings-field label{display:block;font-size:13px;font-weight:500;color:var(--text-secondary);margin-bottom:6px}.settings-field select,.settings-field input[type=number],.settings-field input[type=text]{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.settings-field select:focus,.settings-field input[type=number]:focus,.settings-field input[type=text]:focus{border-color:var(--accent)}.settings-hint{display:block;font-size:11px;color:var(--text-secondary);margin-top:4px}.skills-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 20px;background:#dbeafe;border-bottom:2px solid #3b82f6;font-size:13px;color:#1e3a5f;flex-shrink:0}@media(prefers-color-scheme: dark){.skills-banner{background:#1e293b;border-bottom-color:#3b82f6;color:#93c5fd}}.update-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 20px;background:#dcfce7;border-bottom:2px solid #22c55e;font-size:13px;color:#166534;flex-shrink:0}@media(prefers-color-scheme: dark){.update-banner{background:#14532d;border-bottom-color:#22c55e;color:#86efac}}.update-banner-actions{display:flex;gap:8px;flex-shrink:0}.btn-accent{color:#fff;background:#22c55e;border-color:#22c55e}.btn-accent:hover:not(:disabled){background:#16a34a}.btn-accent:disabled{opacity:.7;cursor:default}.backup-preview-banner{display:flex;align-items:center;justify-content:space-between;padding:8px 20px;background:#fef3c7;border-bottom:2px solid #f59e0b;font-size:13px;font-weight:500;color:#92400e;flex-shrink:0}@media(prefers-color-scheme: dark){.backup-preview-banner{background:#451a03;border-bottom-color:#d97706;color:#fbbf24}}.backup-preview-actions{display:flex;gap:8px;flex-shrink:0}.settings-section{margin-top:20px;padding-top:16px;border-top:1px solid var(--border)}.settings-section h3{font-size:14px;font-weight:600;margin-bottom:12px}.settings-section-header{display:flex;align-items:center;justify-content:space-between}.settings-section-header h3{margin-bottom:0}.settings-section-header{margin-bottom:12px}.category-list{display:flex;flex-direction:column;gap:6px}.category-row{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--bg-secondary);border-radius:var(--radius)}.category-row input[type=text]{padding:3px 6px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.category-row input[type=text]:focus{border-color:var(--accent)}.category-color-input{width:28px;height:24px;border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;padding:1px;flex-shrink:0}.category-label-input{width:100px;flex-shrink:0}.category-short-input{width:42px;flex-shrink:0}.category-key-input{width:28px;text-align:center;flex-shrink:0}.category-desc-input{flex:1;min-width:0}.category-delete-btn{color:var(--text-muted);font-size:16px;padding:0 4px;flex-shrink:0}.category-delete-btn:hover{color:var(--danger)}.category-preset-controls select{padding:3px 8px;font-size:11px}.category-key-conflict{border-color:var(--danger) !important}.backup-list{max-height:300px;overflow-y:auto;font-size:13px;color:var(--text-muted)}.backup-tier-label{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;padding:8px 0 4px;border-bottom:1px solid var(--border);margin-bottom:2px}.backup-tier-label:first-child{padding-top:0}.backup-row{display:flex;align-items:center;justify-content:space-between;padding:5px 8px;border-radius:var(--radius);cursor:pointer}.backup-row:hover{background:var(--bg-hover)}.backup-row-time{color:var(--text);font-weight:500}.backup-row-meta{font-size:11px;color:var(--text-muted)}.custom-view-editor-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.custom-view-editor{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:520px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;overflow:hidden}.custom-view-editor-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.custom-view-editor-body{flex:1;overflow-y:auto;padding:16px}.custom-view-editor-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.cv-logic-row{display:flex;align-items:center;gap:12px;margin-bottom:12px;font-size:13px}.cv-logic-row label{display:flex;align-items:center;gap:4px;cursor:pointer}.cv-condition-row{display:flex;align-items:center;gap:6px;margin-bottom:6px}.cv-condition-row select,.cv-condition-row input[type=text]{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.cv-condition-row select:focus,.cv-condition-row input[type=text]:focus{border-color:var(--accent)}.cv-field-select{width:100px;flex-shrink:0}.cv-op-select{width:120px;flex-shrink:0}.cv-value-select,.cv-value-input{flex:1;min-width:0}.sidebar-custom-view.dragging{opacity:.4}.sidebar-add-view-btn{font-size:14px;font-weight:400;color:var(--text-muted);padding:0 4px;line-height:1;margin-left:4px;vertical-align:middle}.sidebar-add-view-btn:hover{color:var(--accent)}.dashboard-loading{padding:40px 20px;text-align:center;color:var(--text-muted)}.dashboard{padding:20px;overflow-y:auto;height:100%}.dashboard-range-bar{display:flex;gap:6px;margin-bottom:16px}.dashboard-range-bar .btn.active{background:var(--bg-selected);color:var(--accent);border-color:var(--accent)}.dashboard-kpi-row{display:grid;grid-template-columns:repeat(4, 1fr);gap:12px;margin-bottom:20px}.dashboard-kpi-card{padding:16px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);text-align:center}.kpi-value{font-size:28px;font-weight:700;color:var(--text);line-height:1.2}.kpi-label{font-size:12px;color:var(--text-muted);margin-top:4px}.kpi-trend{font-size:12px;margin-top:4px}.kpi-trend.up{color:#22c55e}.kpi-trend.down{color:#ef4444}.dashboard-grid{display:grid;grid-template-columns:repeat(2, 1fr);gap:16px}.dashboard-chart-card{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.dashboard-chart-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--border)}.dashboard-chart-title{font-size:13px;font-weight:600;color:var(--text-secondary)}.dashboard-info-btn{color:var(--text-muted);padding:2px;border-radius:var(--radius);display:flex;align-items:center}.dashboard-info-btn:hover{color:var(--accent);background:var(--bg-hover)}.dashboard-chart-info{padding:8px 14px;font-size:12px;color:var(--text-secondary);background:var(--bg-secondary);border-bottom:1px solid var(--border);line-height:1.5}.dashboard-chart-body{padding:12px}.dashboard-svg{width:100%;height:auto;color:var(--text)}.chart-legend{display:flex;flex-wrap:wrap;gap:8px 16px;padding:0 0 8px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--text-secondary)}.chart-legend-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.chart-hover{transition:opacity .15s}.chart-hover:hover{opacity:1 !important;filter:brightness(1.1)}.chart-cursor{position:absolute;width:1px;background:#000;pointer-events:none;z-index:1}.chart-tooltip{position:absolute;z-index:2;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:6px 10px;pointer-events:none;font-size:11px;white-space:nowrap}.chart-tooltip-date{font-weight:600;margin-bottom:2px;color:var(--text)}.chart-tooltip-row{display:flex;align-items:center;gap:5px;color:var(--text-secondary)}.chart-tooltip-row b{color:var(--text);font-weight:600}.chart-empty{padding:30px;text-align:center;color:var(--text-muted);font-size:13px}.sidebar-dashboard-widget{padding:8px 16px 12px;cursor:pointer}.sidebar-dashboard-widget:hover{background:var(--bg-hover)}.sidebar-widget-spark{margin-bottom:4px}.sidebar-widget-stats{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text)}.sidebar-widget-value{font-weight:500}.sidebar-widget-trend{font-size:11px}.sidebar-widget-trend.up{color:#22c55e}.sidebar-widget-trend.down{color:#ef4444}.sidebar-widget-wip{font-size:11px;color:var(--text-muted);margin-top:2px}.app-footer{display:flex;align-items:center;justify-content:space-between;padding:6px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);font-size:12px;color:var(--text-muted);flex-shrink:0}.keyboard-hints{display:flex;gap:16px}.keyboard-hints kbd{display:inline-block;padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg);font-family:inherit;font-size:11px}.status-bar-right{display:flex;align-items:center;gap:10px}.status-bar{font-size:12px}.channel-status-indicator{font-size:11px;display:flex;align-items:center;gap:4px;color:var(--text-muted)}.channel-status-indicator.busy{color:var(--accent)}.channel-status-indicator svg{width:12px;height:12px}.channel-status-indicator.busy svg{animation:spin 1.2s linear infinite}.ticket-list-columns{display:flex;flex-direction:column;overflow:hidden}.ticket-list-columns .draft-row{flex-shrink:0}.columns-container{display:flex;flex:1;gap:1px;background:var(--border);overflow-x:auto;min-height:0}.column{flex:1;min-width:180px;display:flex;flex-direction:column;background:var(--bg-secondary);overflow:hidden}.column.column-drop-target{background:var(--bg-selected)}.column.column-drop-target .column-body{outline:2px dashed var(--accent);outline-offset:-2px}.column-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;font-size:12px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.3px;border-bottom:1px solid var(--border);background:var(--bg);flex-shrink:0}.column-count{font-size:11px;font-weight:500;color:var(--text-muted);background:var(--bg-secondary);padding:1px 6px;border-radius:10px}.column-body{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:6px}.column-card{padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:grab;box-shadow:var(--shadow);-webkit-user-select:none;user-select:none}.column-card:hover{border-color:var(--accent)}.column-card.selected{border-color:var(--accent);background:var(--bg-selected)}.column-card.up-next{border-left:3px solid var(--star)}.column-card:active{cursor:grabbing}.column-card-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.column-card-header .ticket-number{flex:1}.column-card{container-type:inline-size}@container (max-width: 150px){.column-card-header .ticket-priority-indicator{display:none}}.column-card-title{font-size:13px;line-height:1.4;word-break:break-word}@media(max-width: 768px){.sidebar{width:140px}.detail-side .detail-panel{width:280px}.keyboard-hints{display:none}}@media(max-width: 600px){.sidebar{display:none}}.error-popup{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:3000}.error-popup-content{background:var(--bg);border:1px solid var(--danger);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);padding:24px;max-width:360px;text-align:center}.error-popup-content strong{display:block;font-size:16px;margin-bottom:8px;color:var(--danger)}.error-popup-content p{font-size:14px;color:var(--text-secondary);margin-bottom:16px}.error-popup-content button{padding:6px 16px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:13px;cursor:pointer}.error-popup-content button:hover{background:var(--bg-hover)}.detail-notes{display:flex;flex-direction:column;gap:8px}.note-entry{padding:8px 10px;background:var(--bg-secondary);border-radius:var(--radius);border-left:3px solid var(--accent);cursor:pointer}.note-entry:hover{background:var(--bg-hover)}.notes-empty{font-size:12px;color:var(--text-muted);padding:8px 0}.note-edit-area{width:100%;padding:4px 6px;border:1px solid var(--accent);border-radius:var(--radius);background:var(--bg);font-size:13px;font-family:inherit;resize:vertical;min-height:50px;outline:none;margin-top:4px}.detail-notes-label{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.note-timestamp{font-size:11px;color:var(--text-muted);margin-bottom:2px}.note-text{font-size:13px;color:var(--text);white-space:pre-wrap}
|
|
1
|
+
*,*::before,*::after{box-sizing:border-box;margin:0;padding:0}:root{--bg: #ffffff;--bg-secondary: #f9fafb;--bg-hover: #f3f4f6;--bg-selected: #eff6ff;--border: #e5e7eb;--text: #111827;--text-secondary: #6b7280;--text-muted: #9ca3af;--accent: #3b82f6;--accent-hover: #2563eb;--danger: #ef4444;--star: #eab308;--radius: 6px;--shadow: 0 1px 3px rgba(0,0,0,0.08)}html,body{height:100%;font-family:-apple-system,BlinkMacSystemFont,"Segoe UI",Roboto,sans-serif;font-size:14px;line-height:1.5;color:var(--text);background:var(--bg)}button{cursor:pointer;border:none;background:none;font:inherit;color:inherit}input,select,textarea{font:inherit;color:inherit}.app{display:flex;flex-direction:column;height:100vh}.app-header{display:flex;align-items:center;justify-content:space-between;padding:12px 20px;border-bottom:1px solid var(--border);background:var(--bg);gap:16px;flex-shrink:0}.app-header h1{font-size:18px;font-weight:700;white-space:nowrap}.header-controls{display:flex;align-items:center;gap:12px;flex:1;max-width:500px}.search-box{flex:1}.search-box input{width:100%;padding:6px 12px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg-secondary);outline:none}.search-box input:focus{border-color:var(--accent);background:var(--bg)}.layout-toggle{display:flex;border:1px solid var(--border);border-radius:var(--radius);overflow:hidden;flex-shrink:0}.layout-btn{display:flex;align-items:center;justify-content:center;padding:4px 8px;color:var(--text-secondary);background:var(--bg);border:none;border-right:1px solid var(--border);cursor:pointer}.layout-btn:last-child{border-right:none}.layout-btn:hover:not(:disabled){background:var(--bg-hover);color:var(--text)}.layout-btn.active{background:var(--bg-selected);color:var(--accent)}.layout-btn:disabled{cursor:default}.sort-controls select{padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.print-btn{margin-left:auto}.settings-btn{font-size:18px;color:var(--text-muted);padding:4px;border-radius:var(--radius);flex-shrink:0}.settings-btn:hover{color:var(--text);background:var(--bg-hover)}.glassbox-btn{padding:0;border:1px solid var(--border);border-radius:var(--radius);flex-shrink:0;cursor:pointer;overflow:hidden;line-height:0}.glassbox-btn img{height:28px;width:28px;display:block}.glassbox-btn:hover{border-color:var(--accent)}.app-body{display:flex;flex:1;overflow:hidden}.content-area{flex:1;display:flex;overflow:hidden;min-width:0}.content-area.detail-side{flex-direction:row}.content-area.detail-bottom{flex-direction:column}.sidebar{width:180px;border-right:1px solid var(--border);background:var(--bg-secondary);overflow-y:auto;flex-shrink:0;padding:8px 0}.sidebar-channel-play{padding:8px 10px 4px}.channel-play-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:8px;background:#22c55e;color:#fff;border-radius:var(--radius);cursor:pointer;transition:background .15s;position:relative}.channel-play-btn:hover{background:#16a34a}.channel-play-btn:active{background:#15803d}.channel-play-btn.pulsing{animation:play-pulse .6s ease-out}.channel-play-btn.auto-mode{background:#16a34a}.channel-play-icon{display:flex;align-items:center;justify-content:center}.channel-auto-icon{display:flex;align-items:center;justify-content:center}.no-upnext-alert{display:flex;align-items:center;justify-content:space-between;gap:6px;margin:4px 10px;padding:6px 10px;background:#fef3c7;border:1px solid #f59e0b;border-radius:var(--radius);font-size:12px;color:#92400e;animation:permission-fade-in .2s ease-out}.no-upnext-dismiss{color:#92400e;font-size:14px;padding:0 2px;line-height:1}.no-upnext-dismiss:hover{color:#78350f}.channel-command-btn{display:flex;align-items:center;justify-content:center;width:100%;padding:6px 8px;background:var(--bg-secondary);border:1px solid var(--border);color:var(--text);border-radius:var(--radius);cursor:pointer;font-size:12px;transition:background .15s}.channel-command-btn:hover{background:var(--bg-hover);border-color:var(--accent)}#channel-commands-container{display:flex;flex-direction:column;gap:4px;padding:0 10px 4px}.settings-commands-list{display:flex;flex-direction:column;gap:8px}.settings-command-row{display:flex;flex-direction:column;gap:4px;padding:10px;background:var(--bg-secondary);border-radius:var(--radius);border:1px solid var(--border)}.settings-command-row .settings-command-row-header{display:flex;align-items:center;gap:6px}.settings-command-row input[type=text]{flex:1;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.settings-command-row input[type=text]:focus{border-color:var(--accent)}.settings-command-row textarea{width:100%;padding:6px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:11px;font-family:"SF Mono",Monaco,"Cascadia Code",monospace;resize:vertical;min-height:48px;outline:none}.settings-command-row textarea:focus{border-color:var(--accent)}.settings-command-row label{font-size:11px;color:var(--text-muted)}@keyframes play-pulse{0%{transform:scale(1)}50%{transform:scale(0.95);opacity:.7}100%{transform:scale(1);opacity:1}}@keyframes spin{to{transform:rotate(360deg)}}.settings-checkbox-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:13px !important}.settings-checkbox-label input[type=checkbox]{width:auto;accent-color:var(--accent)}.settings-experimental-heading{font-size:11px;font-weight:600;text-transform:uppercase;letter-spacing:.5px;color:var(--text-muted);margin-bottom:12px;padding-bottom:8px;border-bottom:1px solid var(--border)}.settings-channel-command{display:flex;align-items:center;gap:8px;margin-top:6px;padding:8px 10px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius)}.settings-channel-command code{flex:1;font-size:11px;font-family:"SF Mono",Monaco,"Cascadia Code",monospace;word-break:break-all;color:var(--text)}.sidebar-copy-prompt{padding:8px 10px 4px}.copy-prompt-btn{display:flex;align-items:center;gap:6px;width:100%;padding:6px 8px;font-size:12px;color:var(--text-secondary);background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;transition:all .15s}.copy-prompt-btn:hover{color:var(--accent);border-color:var(--accent);background:var(--bg-selected)}.copy-prompt-icon{display:flex;align-items:center;flex-shrink:0}.sidebar-section{margin-bottom:8px}.sidebar-label{display:flex;align-items:center;gap:4px;padding:8px 16px 4px;font-size:11px;font-weight:600;text-transform:uppercase;color:var(--text-muted);letter-spacing:.5px}.sidebar-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 16px;text-align:left;font-size:13px;color:var(--text-secondary);border-radius:0}.sidebar-item:hover{background:var(--bg-hover);color:var(--text)}.sidebar-item.active{background:var(--bg-selected);color:var(--accent);font-weight:500}.sidebar-item.drop-target{background:var(--bg-selected);color:var(--accent);outline:2px dashed var(--accent);outline-offset:-2px}.sidebar-divider{height:1px;background:var(--border);margin:6px 16px}.cat-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.sidebar-stats{padding:12px 16px;font-size:12px;color:var(--text-muted);border-top:1px solid var(--border)}.main-content{flex:1;display:flex;flex-direction:column;overflow:hidden;min-width:0;min-height:0}.batch-toolbar{display:flex;align-items:center;gap:8px;padding:6px 16px 6px 19px;background:var(--bg-secondary);border-bottom:1px solid var(--border);flex-shrink:0;flex-wrap:wrap;min-height:36px}.batch-toolbar select:disabled,.batch-toolbar .btn:disabled{opacity:.4;cursor:default;pointer-events:none}.batch-toolbar select{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px}.batch-select-all{width:14px;height:14px;cursor:pointer;accent-color:var(--accent);flex-shrink:0}.batch-star-btn{font-size:16px;color:var(--text-muted);padding:2px 6px;border-radius:var(--radius);line-height:1}.batch-star-btn:hover:not(:disabled){color:var(--star);background:var(--bg-hover)}.batch-star-btn.active{color:var(--star)}.batch-star-btn.mixed{color:var(--star)}.batch-star-btn:disabled{opacity:.4;cursor:default;pointer-events:none}.star-mixed-wrap{position:relative;display:inline-block}.star-mixed-fill{position:absolute;left:0;top:0;overflow:hidden;width:50%}.batch-delete-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px;border:none;background:none}.batch-more-btn.btn{display:inline-flex;align-items:center;justify-content:center;padding:4px 6px}.batch-count{font-size:12px;color:var(--text-muted);margin-left:auto;white-space:nowrap}.btn{padding:4px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;cursor:pointer}.btn:hover{background:var(--bg-hover)}.btn-sm{padding:3px 8px;font-size:11px}.btn-danger{color:var(--danger)}.btn-danger:hover:not(:disabled){background:#fef2f2}.ticket-list{flex:1;overflow-y:auto;padding:4px 0}.ticket-list-empty,.ticket-list-loading{padding:40px 20px;text-align:center;color:var(--text-muted);font-size:14px}.ticket-row{display:flex;align-items:center;gap:8px;padding:4px 16px;border-bottom:1px solid rgba(0,0,0,0);border-left:3px solid rgba(0,0,0,0);min-height:36px;-webkit-user-select:none;user-select:none}.ticket-row:hover{background:var(--bg-hover)}.ticket-row.selected{background:var(--bg-selected)}.ticket-row.completed .ticket-title-input{text-decoration:line-through;color:var(--text-muted)}.ticket-row.up-next{border-left:3px solid var(--star)}.ticket-checkbox{flex-shrink:0;width:14px;height:14px;cursor:pointer;accent-color:var(--accent)}.ticket-status-btn{flex-shrink:0;width:20px;height:20px;font-size:14px;display:flex;align-items:center;justify-content:center;border-radius:50%;color:var(--text-secondary)}.ticket-status-btn:hover{background:var(--bg-hover)}.ticket-status-btn.verified{color:#22c55e}.ticket-category-badge{flex-shrink:0;width:4em;padding:1px 0;border-radius:3px;font-size:10px;font-weight:600;color:#fff;text-transform:uppercase;text-align:center;cursor:pointer;letter-spacing:.3px}.ticket-category-badge:hover{opacity:.85}.ticket-number{flex-shrink:0;font-size:11px;color:var(--text-muted);font-family:"SF Mono",Monaco,"Cascadia Code",monospace;min-width:5em}.ticket-title-input{flex:1;border:none;background:rgba(0,0,0,0);padding:2px 0;outline:none;min-width:0;-webkit-user-select:text;user-select:text}.ticket-title-input:focus{border-bottom:1px solid var(--accent)}.ticket-title-input::placeholder{color:var(--text-muted)}.ticket-priority-indicator{flex-shrink:0;font-size:12px;cursor:pointer;padding:2px 4px;border-radius:3px;min-width:24px;text-align:center}.ticket-priority-indicator:hover{background:var(--bg-hover)}.ticket-star{flex-shrink:0;font-size:16px;color:var(--text-muted);padding:0}.ticket-star.active{color:var(--star)}.ticket-star:hover{color:var(--star)}.trash-row .trash-title{flex:1;color:var(--text-muted);min-width:0;overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.trash-row .btn{flex-shrink:0}.draft-row{border-bottom:1px dashed var(--border) !important;background:var(--bg-secondary)}.draft-row:hover{background:var(--bg-secondary)}.draft-row .draft-placeholder{opacity:.35;pointer-events:none}.draft-row .draft-badge{opacity:.35}.draft-row .draft-input::placeholder{color:var(--text-muted);font-style:italic}.ticket-checkbox-spacer{width:14px;flex-shrink:0}.detail-resize-handle{flex-shrink:0;background:rgba(0,0,0,0);position:relative;z-index:10}.detail-resize-handle:hover,.detail-resize-handle:active{background:var(--accent);opacity:.3}.detail-side .detail-resize-handle{width:4px;cursor:col-resize}.detail-bottom .detail-resize-handle{height:4px;cursor:row-resize}.detail-panel{border-left:1px solid var(--border);background:var(--bg);flex-shrink:0;display:flex;flex-direction:column;overflow:hidden}.detail-side .detail-panel{width:360px;border-left:1px solid var(--border);border-top:none}.detail-bottom .detail-panel{height:300px;width:auto;border-left:none;border-top:1px solid var(--border)}.detail-panel.detail-disabled{background:var(--bg-secondary)}.detail-placeholder{display:flex;align-items:center;justify-content:center;flex:1}.detail-placeholder-text{color:var(--text-muted);font-size:14px}.detail-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600}.detail-ticket-number{font-family:"SF Mono",Monaco,"Cascadia Code",monospace;font-size:13px;color:var(--accent)}.detail-close{font-size:20px;color:var(--text-muted);padding:0 4px}.detail-close:hover{color:var(--text)}.detail-body{flex:1;overflow-y:auto;padding:16px}.detail-fields-row{display:grid;grid-template-columns:1fr 1fr;gap:12px 16px;margin-bottom:16px}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{grid-template-columns:repeat(4, 1fr);width:100%}.detail-bottom .detail-body .detail-field-full{width:100%;flex-basis:100%}.detail-field{margin-bottom:16px}.detail-field label{display:block;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.detail-field input[type=text],.detail-field textarea,.detail-field select{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.detail-field input[type=text]:focus,.detail-field textarea:focus,.detail-field select:focus{border-color:var(--accent)}.detail-field textarea{resize:vertical;min-height:80px}.detail-dropdown-btn{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);text-align:left;font-size:inherit;cursor:pointer}.detail-dropdown-btn:hover:not(:disabled){border-color:var(--accent)}.detail-dropdown-btn:disabled{opacity:.6;cursor:default}.batch-dropdown-btn.btn{font-size:12px}.detail-upnext-label{display:flex !important;align-items:center;gap:6px;cursor:pointer;font-size:13px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-star{font-size:18px;padding:2px 6px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);cursor:pointer}.detail-upnext-star:hover:not(:disabled){border-color:var(--accent)}.detail-upnext-star:disabled{opacity:.6;cursor:default}.detail-attachments{margin-bottom:8px}.detail-tags{display:flex;flex-wrap:wrap;gap:4px;margin-bottom:6px}.tag-chip{display:inline-flex;align-items:center;gap:4px;padding:2px 8px;background:var(--bg-selected);border:1px solid var(--border);border-radius:12px;font-size:12px;color:var(--text)}.tag-chip-remove{font-size:14px;color:var(--text-muted);padding:0;line-height:1}.tag-chip-remove:hover{color:var(--danger)}.detail-tag-input{width:100%;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.detail-tag-input:focus{border-color:var(--accent)}.tag-autocomplete{position:absolute;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);max-height:120px;overflow-y:auto;font-size:12px}.tag-autocomplete-item{padding:4px 10px;cursor:pointer}.tag-autocomplete-item:hover,.tag-autocomplete-item.active{background:var(--bg-hover)}.tags-dialog-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.tags-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:320px;max-width:90vw;max-height:60vh;display:flex;flex-direction:column;overflow:hidden}.tags-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.tags-dialog-body{flex:1;overflow-y:auto;padding:8px 0}.tags-dialog-row{display:flex;align-items:center;gap:8px;padding:6px 16px;font-size:13px;cursor:pointer}.tags-dialog-row:hover{background:var(--bg-hover)}.tags-dialog-row input[type=checkbox]{width:14px;height:14px;accent-color:var(--accent)}.tags-dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.tags-dialog-new{display:flex;gap:6px;padding:8px 16px;border-top:1px solid var(--border)}.tags-dialog-new input{flex:1;padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);font-size:12px;outline:none}.tags-dialog-new input:focus{border-color:var(--accent)}.attachment-item{display:flex;align-items:center;justify-content:space-between;padding:4px 8px;background:var(--bg-secondary);border-radius:var(--radius);margin-bottom:4px;font-size:12px}.attachment-name{overflow:hidden;text-overflow:ellipsis;white-space:nowrap}.attachment-reveal{color:var(--text-muted);padding:0 4px;cursor:pointer;border:none;background:none;display:flex;align-items:center}.attachment-reveal:hover{color:var(--accent)}.attachment-delete{color:var(--text-muted);font-size:16px;padding:0 4px;cursor:pointer;border:none;background:none}.attachment-delete:hover{color:var(--danger)}.upload-btn{cursor:pointer;display:inline-flex;align-items:center;gap:4px;margin-top:4px}.detail-meta{padding-top:12px;border-top:1px solid var(--border);font-size:11px;color:var(--text-muted)}.detail-meta div{margin-bottom:2px}.dropdown-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:4px 0;min-width:140px}.dropdown-item{display:flex;align-items:center;gap:8px;width:100%;padding:6px 12px;text-align:left;font-size:13px;text-transform:capitalize}.dropdown-item:hover{background:var(--bg-hover)}.dropdown-item.active{color:var(--accent);font-weight:500}.dropdown-separator{height:1px;background:var(--border);margin:4px 0}.dropdown-icon{font-size:12px;min-width:20px;text-align:center;flex-shrink:0;display:inline-flex;align-items:center;justify-content:center}.dropdown-icon svg{vertical-align:middle}.dropdown-label{flex:1}.dropdown-kbd{font-size:11px;color:var(--text-muted);padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg-secondary);font-family:inherit;flex-shrink:0}.dropdown-dot{display:inline-block;width:8px;height:8px;border-radius:50%;flex-shrink:0}.print-dialog-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.print-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:360px;max-width:90vw}.print-dialog-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.print-dialog-body{padding:16px}.print-dialog-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.permission-overlay{position:fixed;inset:0;z-index:5000;display:flex;align-items:center;justify-content:center;background:rgba(0,0,0,.6);-webkit-backdrop-filter:blur(12px) saturate(120%);backdrop-filter:blur(12px) saturate(120%);animation:permission-fade-in .3s ease-out}@keyframes permission-fade-in{from{opacity:0}to{opacity:1}}.permission-overlay-content{text-align:center;max-width:480px;padding:40px}.permission-overlay-text{font-size:28px;font-weight:700;color:#fff;margin-bottom:12px;text-shadow:0 2px 8px rgba(0,0,0,.3)}.permission-overlay-detail{font-size:14px;color:hsla(0,0%,100%,.7);margin-bottom:24px;line-height:1.5}.permission-tool{margin-bottom:12px}.permission-preview{text-align:left;background:rgba(0,0,0,.4);border:1px solid hsla(0,0%,100%,.15);border-radius:8px;padding:12px 16px;font-family:"SF Mono",Monaco,"Cascadia Code",monospace;font-size:12px;color:hsla(0,0%,100%,.85);white-space:pre-wrap;word-break:break-all;max-height:200px;overflow-y:auto}.permission-overlay-actions{display:flex;gap:12px;justify-content:center}.permission-overlay-btn{padding:10px 24px;border-radius:8px;font-size:14px;font-weight:600;cursor:pointer;border:1px solid hsla(0,0%,100%,.2);transition:all .15s}.permission-overlay-btn.permission-allow{background:#22c55e;color:#fff;border-color:#22c55e}.permission-overlay-btn.permission-allow:hover{background:#16a34a}.permission-overlay-btn.permission-deny{background:#ef4444;color:#fff;border-color:#ef4444}.permission-overlay-btn.permission-deny:hover{background:#dc2626}.permission-overlay-btn.permission-dismiss{background:hsla(0,0%,100%,.1);color:hsla(0,0%,100%,.8)}.permission-overlay-btn.permission-dismiss:hover{background:hsla(0,0%,100%,.2)}.context-menu{position:fixed;z-index:1000;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 4px 16px rgba(0,0,0,.12);padding:4px 0;min-width:180px;font-size:13px}.context-menu-item{display:flex;align-items:center;gap:8px;padding:6px 12px;cursor:pointer;position:relative}.context-menu-item:hover{background:var(--bg-hover)}.context-menu-item:hover>.context-submenu{display:block}.context-menu-item.active{color:var(--accent);font-weight:500}.context-menu-item.danger{color:var(--danger)}.context-menu-item.has-submenu{padding-right:24px}.context-menu-label{flex:1}.context-menu-arrow{position:absolute;right:8px;font-size:10px;color:var(--text-muted)}.context-menu-separator{height:1px;background:var(--border);margin:4px 0}.context-submenu{display:none;position:absolute;left:100%;top:-4px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:0 4px 16px rgba(0,0,0,.12);padding:4px 0;min-width:160px;z-index:1001}.settings-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.settings-dialog{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:540px;max-width:90vw;max-height:85vh;display:flex;flex-direction:column;overflow:hidden}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border);flex-shrink:0}.settings-header h2{font-size:16px;font-weight:600}.settings-tabs{display:flex;border-bottom:1px solid var(--border);flex-shrink:0;padding:0 12px;gap:2px}.settings-tab{display:flex;flex-direction:column;align-items:center;gap:4px;padding:12px 16px 10px;font-size:11px;color:var(--text-muted);border-bottom:2px solid rgba(0,0,0,0);margin-bottom:-1px;transition:color .15s}.settings-tab svg{flex-shrink:0}.settings-tab:hover{color:var(--text)}.settings-tab.active{color:var(--accent);border-bottom-color:var(--accent)}.settings-body{padding:20px;overflow-y:auto;flex:1;min-height:0}.settings-tab-panel{display:none}.settings-tab-panel.active{display:block}.settings-field{margin-bottom:16px}.settings-field:last-child{margin-bottom:0}.settings-field label{display:block;font-size:13px;font-weight:500;color:var(--text-secondary);margin-bottom:6px}.settings-field select,.settings-field input[type=number],.settings-field input[type=text]{width:100%;padding:6px 10px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);outline:none}.settings-field select:focus,.settings-field input[type=number]:focus,.settings-field input[type=text]:focus{border-color:var(--accent)}.settings-hint{display:block;font-size:11px;color:var(--text-secondary);margin-top:4px}.skills-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 20px;background:#dbeafe;border-bottom:2px solid #3b82f6;font-size:13px;color:#1e3a5f;flex-shrink:0}@media(prefers-color-scheme: dark){.skills-banner{background:#1e293b;border-bottom-color:#3b82f6;color:#93c5fd}}.update-banner{display:flex;align-items:center;justify-content:space-between;gap:12px;padding:8px 20px;background:#dcfce7;border-bottom:2px solid #22c55e;font-size:13px;color:#166534;flex-shrink:0}@media(prefers-color-scheme: dark){.update-banner{background:#14532d;border-bottom-color:#22c55e;color:#86efac}}.update-banner-actions{display:flex;gap:8px;flex-shrink:0}.btn-accent{color:#fff;background:#22c55e;border-color:#22c55e}.btn-accent:hover:not(:disabled){background:#16a34a}.btn-accent:disabled{opacity:.7;cursor:default}.backup-preview-banner{display:flex;align-items:center;justify-content:space-between;padding:8px 20px;background:#fef3c7;border-bottom:2px solid #f59e0b;font-size:13px;font-weight:500;color:#92400e;flex-shrink:0}@media(prefers-color-scheme: dark){.backup-preview-banner{background:#451a03;border-bottom-color:#d97706;color:#fbbf24}}.backup-preview-actions{display:flex;gap:8px;flex-shrink:0}.settings-section{margin-top:20px;padding-top:16px;border-top:1px solid var(--border)}.settings-section h3{font-size:14px;font-weight:600;margin-bottom:12px}.settings-section-header{display:flex;align-items:center;justify-content:space-between}.settings-section-header h3{margin-bottom:0}.settings-section-header{margin-bottom:12px}.category-list{display:flex;flex-direction:column;gap:6px}.category-row{display:flex;align-items:center;gap:6px;padding:6px 8px;background:var(--bg-secondary);border-radius:var(--radius)}.category-row input[type=text]{padding:3px 6px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.category-row input[type=text]:focus{border-color:var(--accent)}.category-color-input{width:28px;height:24px;border:1px solid var(--border);border-radius:var(--radius);cursor:pointer;padding:1px;flex-shrink:0}.category-label-input{width:100px;flex-shrink:0}.category-short-input{width:42px;flex-shrink:0}.category-key-input{width:28px;text-align:center;flex-shrink:0}.category-desc-input{flex:1;min-width:0}.category-delete-btn{color:var(--text-muted);font-size:16px;padding:0 4px;flex-shrink:0}.category-delete-btn:hover{color:var(--danger)}.category-preset-controls select{padding:3px 8px;font-size:11px}.category-key-conflict{border-color:var(--danger) !important}.backup-list{max-height:300px;overflow-y:auto;font-size:13px;color:var(--text-muted)}.backup-tier-label{font-size:11px;font-weight:600;color:var(--text-muted);text-transform:uppercase;letter-spacing:.5px;padding:8px 0 4px;border-bottom:1px solid var(--border);margin-bottom:2px}.backup-tier-label:first-child{padding-top:0}.backup-row{display:flex;align-items:center;justify-content:space-between;padding:5px 8px;border-radius:var(--radius);cursor:pointer}.backup-row:hover{background:var(--bg-hover)}.backup-row-time{color:var(--text);font-weight:500}.backup-row-meta{font-size:11px;color:var(--text-muted)}.custom-view-editor-overlay{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:2000}.custom-view-editor{background:var(--bg);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);width:520px;max-width:90vw;max-height:80vh;display:flex;flex-direction:column;overflow:hidden}.custom-view-editor-header{display:flex;align-items:center;justify-content:space-between;padding:12px 16px;border-bottom:1px solid var(--border);font-weight:600;font-size:14px}.custom-view-editor-body{flex:1;overflow-y:auto;padding:16px}.custom-view-editor-footer{display:flex;justify-content:flex-end;gap:8px;padding:12px 16px;border-top:1px solid var(--border)}.cv-logic-row{display:flex;align-items:center;gap:12px;margin-bottom:12px;font-size:13px}.cv-logic-row label{display:flex;align-items:center;gap:4px;cursor:pointer}.cv-condition-row{display:flex;align-items:center;gap:6px;margin-bottom:6px}.cv-condition-row select,.cv-condition-row input[type=text]{padding:4px 8px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:12px;outline:none}.cv-condition-row select:focus,.cv-condition-row input[type=text]:focus{border-color:var(--accent)}.cv-field-select{width:100px;flex-shrink:0}.cv-op-select{width:120px;flex-shrink:0}.cv-value-select,.cv-value-input{flex:1;min-width:0}.sidebar-custom-view.dragging{opacity:.4}.sidebar-add-view-btn{font-size:14px;font-weight:400;color:var(--text-muted);padding:0 4px;line-height:1;margin-left:4px;vertical-align:middle}.sidebar-add-view-btn:hover{color:var(--accent)}.dashboard-loading{padding:40px 20px;text-align:center;color:var(--text-muted)}.dashboard{padding:20px;overflow-y:auto;height:100%}.dashboard-range-bar{display:flex;gap:6px;margin-bottom:16px}.dashboard-range-bar .btn.active{background:var(--bg-selected);color:var(--accent);border-color:var(--accent)}.dashboard-kpi-row{display:grid;grid-template-columns:repeat(4, 1fr);gap:12px;margin-bottom:20px}.dashboard-kpi-card{padding:16px;background:var(--bg-secondary);border:1px solid var(--border);border-radius:var(--radius);text-align:center}.kpi-value{font-size:28px;font-weight:700;color:var(--text);line-height:1.2}.kpi-label{font-size:12px;color:var(--text-muted);margin-top:4px}.kpi-trend{font-size:12px;margin-top:4px}.kpi-trend.up{color:#22c55e}.kpi-trend.down{color:#ef4444}.dashboard-grid{display:grid;grid-template-columns:repeat(2, 1fr);gap:16px}.dashboard-chart-card{background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);overflow:hidden}.dashboard-chart-header{display:flex;align-items:center;justify-content:space-between;padding:10px 14px;border-bottom:1px solid var(--border)}.dashboard-chart-title{font-size:13px;font-weight:600;color:var(--text-secondary)}.dashboard-info-btn{color:var(--text-muted);padding:2px;border-radius:var(--radius);display:flex;align-items:center}.dashboard-info-btn:hover{color:var(--accent);background:var(--bg-hover)}.dashboard-chart-info{padding:8px 14px;font-size:12px;color:var(--text-secondary);background:var(--bg-secondary);border-bottom:1px solid var(--border);line-height:1.5}.dashboard-chart-body{padding:12px}.dashboard-svg{width:100%;height:auto;color:var(--text)}.chart-legend{display:flex;flex-wrap:wrap;gap:8px 16px;padding:0 0 8px}.chart-legend-item{display:inline-flex;align-items:center;gap:5px;font-size:11px;color:var(--text-secondary)}.chart-legend-dot{width:8px;height:8px;border-radius:50%;flex-shrink:0}.chart-hover{transition:opacity .15s}.chart-hover:hover{opacity:1 !important;filter:brightness(1.1)}.chart-cursor{position:absolute;width:1px;background:#000;pointer-events:none;z-index:1}.chart-tooltip{position:absolute;z-index:2;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);box-shadow:var(--shadow);padding:6px 10px;pointer-events:none;font-size:11px;white-space:nowrap}.chart-tooltip-date{font-weight:600;margin-bottom:2px;color:var(--text)}.chart-tooltip-row{display:flex;align-items:center;gap:5px;color:var(--text-secondary)}.chart-tooltip-row b{color:var(--text);font-weight:600}.chart-empty{padding:30px;text-align:center;color:var(--text-muted);font-size:13px}.sidebar-dashboard-widget{padding:8px 16px 12px;cursor:pointer}.sidebar-dashboard-widget:hover{background:var(--bg-hover)}.sidebar-widget-spark{margin-bottom:4px}.sidebar-widget-stats{display:flex;align-items:center;gap:6px;font-size:12px;color:var(--text)}.sidebar-widget-value{font-weight:500}.sidebar-widget-trend{font-size:11px}.sidebar-widget-trend.up{color:#22c55e}.sidebar-widget-trend.down{color:#ef4444}.sidebar-widget-wip{font-size:11px;color:var(--text-muted);margin-top:2px}.app-footer{display:flex;align-items:center;justify-content:space-between;padding:6px 20px;border-top:1px solid var(--border);background:var(--bg-secondary);font-size:12px;color:var(--text-muted);flex-shrink:0}.keyboard-hints{display:flex;gap:16px}.keyboard-hints kbd{display:inline-block;padding:1px 5px;border:1px solid var(--border);border-radius:3px;background:var(--bg);font-family:inherit;font-size:11px}.status-bar-right{display:flex;align-items:center;gap:10px}.status-bar{font-size:12px}.channel-status-indicator{font-size:11px;display:flex;align-items:center;gap:4px;color:var(--text-muted)}.channel-status-indicator.busy{color:var(--accent)}.channel-status-indicator svg{width:12px;height:12px}.channel-status-indicator.busy svg{animation:spin 1.2s linear infinite}.ticket-list-columns{display:flex;flex-direction:column;overflow:hidden}.ticket-list-columns .draft-row{flex-shrink:0}.columns-container{display:flex;flex:1;gap:1px;background:var(--border);overflow-x:auto;min-height:0}.column{flex:1;min-width:180px;display:flex;flex-direction:column;background:var(--bg-secondary);overflow:hidden}.column.column-drop-target{background:var(--bg-selected)}.column.column-drop-target .column-body{outline:2px dashed var(--accent);outline-offset:-2px}.column-header{display:flex;align-items:center;justify-content:space-between;padding:8px 12px;font-size:12px;font-weight:600;color:var(--text-secondary);text-transform:uppercase;letter-spacing:.3px;border-bottom:1px solid var(--border);background:var(--bg);flex-shrink:0}.column-count{font-size:11px;font-weight:500;color:var(--text-muted);background:var(--bg-secondary);padding:1px 6px;border-radius:10px}.column-body{flex:1;overflow-y:auto;padding:8px;display:flex;flex-direction:column;gap:6px}.column-card{padding:8px 10px;background:var(--bg);border:1px solid var(--border);border-radius:var(--radius);cursor:grab;box-shadow:var(--shadow);-webkit-user-select:none;user-select:none}.column-card:hover{border-color:var(--accent)}.column-card.selected{border-color:var(--accent);background:var(--bg-selected)}.column-card.up-next{border-left:3px solid var(--star)}.column-card:active{cursor:grabbing}.column-card-header{display:flex;align-items:center;gap:6px;margin-bottom:4px}.column-card-header .ticket-number{flex:1}.column-card{container-type:inline-size}@container (max-width: 150px){.column-card-header .ticket-priority-indicator{display:none}}.column-card-title{font-size:13px;line-height:1.4;word-break:break-word}@media(max-width: 768px){.sidebar{width:140px}.detail-side .detail-panel{width:280px}.keyboard-hints{display:none}}@media(max-width: 600px){.sidebar{display:none}}.error-popup{position:fixed;inset:0;background:rgba(0,0,0,.3);display:flex;align-items:center;justify-content:center;z-index:3000}.error-popup-content{background:var(--bg);border:1px solid var(--danger);border-radius:8px;box-shadow:0 8px 32px rgba(0,0,0,.15);padding:24px;max-width:360px;text-align:center}.error-popup-content strong{display:block;font-size:16px;margin-bottom:8px;color:var(--danger)}.error-popup-content p{font-size:14px;color:var(--text-secondary);margin-bottom:16px}.error-popup-content button{padding:6px 16px;border:1px solid var(--border);border-radius:var(--radius);background:var(--bg);font-size:13px;cursor:pointer}.error-popup-content button:hover{background:var(--bg-hover)}.detail-notes{display:flex;flex-direction:column;gap:8px}.note-entry{padding:8px 10px;background:var(--bg-secondary);border-radius:var(--radius);border-left:3px solid var(--accent);cursor:pointer}.note-entry:hover{background:var(--bg-hover)}.notes-empty{font-size:12px;color:var(--text-muted);padding:8px 0}.note-edit-area{width:100%;padding:4px 6px;border:1px solid var(--accent);border-radius:var(--radius);background:var(--bg);font-size:13px;font-family:inherit;resize:vertical;min-height:50px;outline:none;margin-top:4px}.detail-notes-label{display:flex;align-items:center;gap:4px;font-size:12px;font-weight:500;color:var(--text-secondary);margin-bottom:4px}.note-timestamp{font-size:11px;color:var(--text-muted);margin-bottom:2px}.note-text{font-size:13px;color:var(--text);white-space:pre-wrap}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "hotsheet",
|
|
3
|
-
"version": "0.6.
|
|
3
|
+
"version": "0.6.2",
|
|
4
4
|
"description": "A lightweight local project management tool. Create, categorize, and prioritize tickets with a fast bullet-list interface, then export an Up Next worklist for AI tools.",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "MIT",
|