hotsheet 0.2.11 → 0.2.12
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.
- package/dist/cli.js +34 -0
- package/dist/client/app.global.js +3 -3
- package/dist/client/styles.css +1 -1
- package/package.json +1 -1
package/dist/cli.js
CHANGED
|
@@ -596,6 +596,32 @@ async function getTickets(filters = {}) {
|
|
|
596
596
|
);
|
|
597
597
|
return result.rows;
|
|
598
598
|
}
|
|
599
|
+
async function duplicateTickets(ids) {
|
|
600
|
+
const db2 = await getDb();
|
|
601
|
+
const allTitles = await db2.query(`SELECT title FROM tickets WHERE status != 'deleted'`);
|
|
602
|
+
const existingTitles = new Set(allTitles.rows.map((r) => r.title));
|
|
603
|
+
const created = [];
|
|
604
|
+
for (const id of ids) {
|
|
605
|
+
const ticket = await getTicket(id);
|
|
606
|
+
if (!ticket) continue;
|
|
607
|
+
const baseTitle = ticket.title;
|
|
608
|
+
let copyTitle = `${baseTitle} - Copy`;
|
|
609
|
+
if (existingTitles.has(copyTitle)) {
|
|
610
|
+
let n = 2;
|
|
611
|
+
while (existingTitles.has(`${baseTitle} - Copy ${n}`)) n++;
|
|
612
|
+
copyTitle = `${baseTitle} - Copy ${n}`;
|
|
613
|
+
}
|
|
614
|
+
existingTitles.add(copyTitle);
|
|
615
|
+
const newTicket = await createTicket(copyTitle, {
|
|
616
|
+
category: ticket.category,
|
|
617
|
+
priority: ticket.priority,
|
|
618
|
+
details: ticket.details,
|
|
619
|
+
up_next: ticket.up_next
|
|
620
|
+
});
|
|
621
|
+
created.push(newTicket);
|
|
622
|
+
}
|
|
623
|
+
return created;
|
|
624
|
+
}
|
|
599
625
|
async function batchUpdateTickets(ids, updates) {
|
|
600
626
|
for (const id of ids) {
|
|
601
627
|
await updateTicket(id, updates);
|
|
@@ -2137,6 +2163,13 @@ apiRoutes.post("/tickets/batch", async (c) => {
|
|
|
2137
2163
|
notifyChange();
|
|
2138
2164
|
return c.json({ ok: true });
|
|
2139
2165
|
});
|
|
2166
|
+
apiRoutes.post("/tickets/duplicate", async (c) => {
|
|
2167
|
+
const body = await c.req.json();
|
|
2168
|
+
const created = await duplicateTickets(body.ids);
|
|
2169
|
+
scheduleAllSync();
|
|
2170
|
+
notifyChange();
|
|
2171
|
+
return c.json(created, 201);
|
|
2172
|
+
});
|
|
2140
2173
|
apiRoutes.post("/tickets/:id/restore", async (c) => {
|
|
2141
2174
|
const id = parseInt(c.req.param("id"), 10);
|
|
2142
2175
|
const ticket = await restoreTicket(id);
|
|
@@ -2592,6 +2625,7 @@ pageRoutes.get("/", (c) => {
|
|
|
2592
2625
|
] }),
|
|
2593
2626
|
/* @__PURE__ */ jsx("button", { id: "batch-upnext", className: "batch-star-btn", title: "Toggle Up Next", disabled: true, children: raw('<span class="batch-star-icon">☆</span>') }),
|
|
2594
2627
|
/* @__PURE__ */ jsx("button", { id: "batch-delete", className: "btn btn-sm btn-danger batch-delete-btn", title: "Delete selected", disabled: true, children: raw('<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"/><line x1="10" y1="11" x2="10" y2="17"/><line x1="14" y1="11" x2="14" y2="17"/></svg>') }),
|
|
2628
|
+
/* @__PURE__ */ jsx("button", { id: "batch-more", className: "btn btn-sm batch-more-btn", title: "More actions", disabled: true, children: raw('<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"><circle cx="12" cy="12" r="1"/><circle cx="19" cy="12" r="1"/><circle cx="5" cy="12" r="1"/></svg>') }),
|
|
2595
2629
|
/* @__PURE__ */ jsx("span", { className: "batch-count", id: "batch-count" })
|
|
2596
2630
|
] }),
|
|
2597
2631
|
/* @__PURE__ */ jsx("div", { className: "ticket-list", id: "ticket-list", children: raw('<div class="ticket-list-loading">Loading...</div>') })
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
"use strict";(()=>{var Ge=Object.defineProperty;var Ye=(e,t,s)=>t in e?Ge(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var U=(e,t,s)=>Ye(e,typeof t!="symbol"?t+"":t,s);function ve(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function he(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}var S=class{constructor(t){U(this,"__html");this.__html=t}toString(){return this.__html}};function _(e){return new S(e)}var Xe=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function Z(e){return e==null||typeof e=="boolean"?"":e instanceof S?e.__html:typeof e=="string"?ve(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(Z).join(""):""}function Qe(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let s=e==="className"?"class":e==="htmlFor"?"for":e,a;return t instanceof S?a=t.__html:typeof t=="number"?a=String(t):typeof t=="string"?a=he(t):a="",` ${s}="${a}"`}function c(e,t){if(typeof e=="function")return e(t);let{children:s,...a}=t,i=Object.entries(a).map(([l,r])=>Qe(l,r)).join("");if(Xe.has(e))return new S(`<${e}${i}>`);let o=s!=null?Z(s):"";return new S(`<${e}${i}>${o}</${e}>`)}function D({children:e}){return new S(e!=null?Z(e):"")}function y(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function be(e){document.getElementById("network-error-popup")?.remove();let t=y(c("div",{id:"network-error-popup",className:"error-popup",children:c("div",{className:"error-popup-content",children:[c("strong",{children:"Connection Error"}),c("p",{children:e}),c("button",{children:_("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function p(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(s){throw be("Unable to reach the server. It may have been stopped."),s}}async function ke(e,t){try{let s=new FormData;return s.append("file",t),(await fetch("/api"+e,{method:"POST",body:s})).json()}catch(s){throw be("Unable to reach the server. It may have been stopped."),s}}var Ze={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...Ze},backupPreview:null},et={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},tt={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},nt={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},st={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},at={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg",backlog:"\u25A1",archive:"\u25A0"},ee='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function w(e){return et[e]||"#6b7280"}function H(e){return tt[e]||"ISS"}function q(e){return nt[e]||"\u2014"}function P(e){return st[e]||"#6b7280"}function te(e){return at[e]||"\u25CB"}function z(e){n.activeTicketId=e,se(e)}function Ee(){n.selectedIds.clear(),n.activeTicketId=null,A();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function A(){let e=n.view==="trash",t=!!n.backupPreview?.active,s=document.getElementById("detail-panel"),a=document.getElementById("detail-resize-handle"),i=document.getElementById("detail-header"),o=document.getElementById("detail-body"),l=document.getElementById("detail-placeholder"),r=document.getElementById("detail-placeholder-text");if(e){s.style.display="none",a&&(a.style.display="none"),n.activeTicketId=null;return}if(s.style.display="flex",a&&(a.style.display=""),n.selectedIds.size===1){let u=Array.from(n.selectedIds)[0];s.classList.remove("detail-disabled"),i.style.display="",o.style.display="",l.style.display="none",n.activeTicketId!==u&&(n.activeTicketId=u,t?it(u):se(u))}else n.activeTicketId=null,s.classList.add("detail-disabled"),i.style.display="none",o.style.display="none",l.style.display="",n.selectedIds.size===0?r.textContent="Nothing selected":r.textContent=`${n.selectedIds.size} items selected`}function Te(e){let t=document.getElementById("detail-title"),s=document.getElementById("detail-details"),a=document.getElementById("detail-category"),i=document.getElementById("detail-priority"),o=document.getElementById("detail-status"),l=document.getElementById("detail-upnext"),r=document.querySelector(".upload-btn");t.readOnly=e,s.readOnly=e,a.disabled=e,i.disabled=e,o.disabled=e,l.disabled=e,r&&(r.style.display=e?"none":"")}function it(e){let t=n.backupPreview?.tickets.find(l=>l.id===e);if(!t||n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details,Te(!0),document.getElementById("detail-attachments").innerHTML="";let s=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),i=Ie(t.notes);i.length>0?(s.style.display="",a.innerHTML=c(D,{children:i.map(l=>c("div",{className:"note-entry",children:[l.created_at?c("div",{className:"note-timestamp",children:new Date(l.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:l.text})]}))}).toString()):(s.style.display="none",a.innerHTML="");let o=document.getElementById("detail-meta");o.innerHTML=c(D,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ne(){n.activeTicketId!=null&&se(n.activeTicketId)}async function se(e){let t=await p(`/tickets/${e}`);if(n.activeTicketId!==e)return;Te(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let s=document.getElementById("detail-attachments");t.attachments.length>0?s.innerHTML=c(D,{children:t.attachments.map(r=>c("div",{className:"attachment-item",children:[c("span",{className:"attachment-name",children:r.original_filename}),c("button",{className:"attachment-reveal","data-att-id":String(r.id),title:"Show in file manager",children:_('<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="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"/></svg>')}),c("button",{className:"attachment-delete","data-att-id":String(r.id),title:"Remove",children:_("×")})]}))}).toString():s.innerHTML="";let a=document.getElementById("detail-notes-section"),i=document.getElementById("detail-notes"),o=Ie(t.notes);o.length>0?(a.style.display="",i.innerHTML=c(D,{children:o.map(r=>c("div",{className:"note-entry",children:[r.created_at?c("div",{className:"note-timestamp",children:new Date(r.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:r.text})]}))}).toString()):(a.style.display="none",i.innerHTML="");let l=document.getElementById("detail-meta");l.innerHTML=c(D,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function Ie(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:""}]:[]}async function V(){try{let e=await p("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function ae(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function ie(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function we(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),s=document.getElementById("content-area"),a=!1;e.addEventListener("mousedown",i=>{i.preventDefault(),a=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",i=>{if(!a)return;let o=s.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let l=Math.max(150,Math.min(500,o.bottom-i.clientY));n.settings.detail_height=l,t.style.height=`${l}px`}else{let l=Math.max(250,Math.min(600,o.right-i.clientX));n.settings.detail_width=l,t.style.width=`${l}px`}}),document.addEventListener("mouseup",()=>{a&&(a=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?p("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):p("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function j(e,t){let s=t.getBoundingClientRect(),a=e.getBoundingClientRect(),i=window.innerWidth,o=window.innerHeight,l=s.left;l+a.width>i-8&&(l=s.right-a.width),l<8&&(l=8);let r=s.bottom+4;r+a.height>o-8&&(r=s.top-a.height-4),r<8&&(r=8),e.style.left=`${l}px`,e.style.top=`${r}px`}function W(e,t){let s=y(c("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(r=>c("button",{className:`dropdown-item${r.active?" active":""}`,"data-key":r.key,children:[r.color?c("span",{className:"dropdown-dot",style:`background-color:${r.color}`}):null,c("span",{className:"dropdown-label",children:r.label}),r.shortcut?c("kbd",{className:"dropdown-kbd",children:r.shortcut}):null]}))}));s.querySelectorAll(".dropdown-item").forEach((r,u)=>{r.addEventListener("click",()=>{t[u].action(),s.remove()})});function i(r){let u=t.find(d=>r.key.toLowerCase()===d.key.toLowerCase());u?(r.preventDefault(),r.stopPropagation(),u.action(),o()):r.key==="Escape"&&(r.preventDefault(),o())}function o(){s.remove(),document.removeEventListener("keydown",i,!0),document.removeEventListener("click",l)}function l(){o()}return document.addEventListener("keydown",i,!0),setTimeout(()=>{document.addEventListener("click",l)},0),s}function J(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var oe=class{constructor(){U(this,"undoStack",[]);U(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 s=this.peekUndo();return!s||s.coalescingKey!==t.coalescingKey||t.timestamp-s.timestamp>=5e3?!1:(s.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}},h=new oe;function B(e){return{id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next}}async function T(e,t,s){let a=B(e),i=await p(`/tickets/${e.id}`,{method:"PATCH",body:t}),o=B(i);return h.push({label:s,timestamp:Date.now(),before:[a],after:[o]}),i}function G(e,t,s){let a=`${e.id}:${t}`,i=Date.now(),o={...B(e),[t]:s},l={label:`Edit ${t}`,timestamp:i,before:[B(e)],after:[o],coalescingKey:a};h.coalesce(l)||h.push(l)}async function k(e,t,s){let a=e.map(B);await p("/tickets/batch",{method:"POST",body:t});let i=a.map(o=>{let l={...o};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});h.push({label:s,timestamp:Date.now(),before:a,after:i})}async function le(e,t,s){let a=e.map(B);for(let o of t)await p("/tickets/batch",{method:"POST",body:o});let i=a.map(o=>{let l={...o};for(let r of t)r.ids.includes(o.id)&&(r.action==="status"?l.status=r.value:r.action==="up_next"?l.up_next=r.value:r.action==="category"?l.category=r.value:r.action==="priority"?l.priority=r.value:r.action==="delete"&&(l.status="deleted"));return l});h.push({label:s,timestamp:Date.now(),before:a,after:i})}async function Le(e){let t=B(e);await p(`/tickets/${e.id}`,{method:"DELETE"});let s={...t,status:"deleted"};h.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[s]})}async function xe(e){let t=B(e);await p(`/tickets/${e.id}/restore`,{method:"POST"});let s={...t,status:"not_started"};h.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[s]})}async function Se(e){for(let t of e)t.status==="deleted"?await p(`/tickets/${t.id}`,{method:"DELETE"}):await p(`/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}})}var C=!1;async function _e(){if(console.log("[undo] performUndo, inFlight:",C,"canUndo:",h.canUndo()),C){console.log("[undo] skipped \u2014 already in flight");return}let e=h.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),C=!0;try{await Se(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await m(),ne()}finally{C=!1}}async function Ce(){if(console.log("[undo] performRedo, inFlight:",C,"canRedo:",h.canRedo()),C){console.log("[undo] skipped \u2014 already in flight");return}let e=h.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),C=!0;try{await Se(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await m(),ne()}finally{C=!1}}function Be(){return h.canUndo()}function Me(){return h.canRedo()}var $=null;function de(){$&&(clearTimeout($),$=null)}var K=!1,O=null,re="",E=[],Y=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],ce=[{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 ot(){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 s=t.dataset.id;return s!==void 0&&s!==""?parseInt(s,10):null}function lt(e){e!=null&&(K=!0,e==="draft"?I():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),K=!1)}function X(){let e=n.view;return e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function De(){return n.view==="up-next"||n.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:n.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 v(){let e=!!n.backupPreview?.active;if(n.layout==="columns"&&X()){if(e){ct();return}ut();return}let t=n.view==="trash",s=e?null:ot(),a=null;if(s!=null&&s!=="draft"){let l=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);l&&(a=l.value)}let i=document.getElementById("ticket-list"),o=i.scrollTop;if(i.innerHTML="",i.classList.remove("ticket-list-columns"),!t&&!e&&i.appendChild(Re()),n.tickets.length===0){let l=t?"Trash is empty":e?"No tickets match this view":"";l&&i.appendChild(y(c("div",{className:"ticket-list-empty",children:l})))}for(let l of n.tickets)e?i.appendChild(rt(l)):t?i.appendChild(yt(l)):i.appendChild(gt(l));if(i.scrollTop=o,e){let l=document.getElementById("batch-toolbar");l&&(l.style.display="none"),F(),A()}else{let l=document.getElementById("batch-toolbar");if(l&&(l.style.display=""),s!=null&&s!=="draft"&&a!=null){let r=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);r&&r.value!==a&&(r.value=a)}lt(s),R()}V()}function rt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",a=e.status==="verified",i=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:`ticket-status-btn${a?" verified":""}`,style:"cursor:default",children:a?_(ee):te(e.status)}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)};cursor:default`,title:e.category,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:q(e.priority)}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return i.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,F(),A()}),i}function Pe(e){let t={scrollLeft:0,columns:{}},s=e.querySelector(".columns-container");return s&&(t.scrollLeft=s.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(a=>{let i=a.dataset.status,o=a.querySelector(".column-body");o&&(t.columns[i]=o.scrollTop)})),t}function Ae(e,t){let s=e.querySelector(".columns-container");s&&(s.scrollLeft=t.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(a=>{let i=a.dataset.status,o=a.querySelector(".column-body");o&&t.columns[i]!=null&&(o.scrollTop=t.columns[i])}))}function ct(){let e=document.getElementById("ticket-list"),t=Pe(e);e.innerHTML="",e.classList.add("ticket-list-columns");let s=De(),a=y(c("div",{className:"columns-container"}));for(let o of s){let l=n.tickets.filter(d=>d.status===o.status),r=y(c("div",{className:"column","data-status":o.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:o.label}),c("span",{className:"column-count",children:String(l.length)})]}),c("div",{className:"column-body"})]})),u=r.querySelector(".column-body");for(let d of l)u.appendChild(dt(d));a.appendChild(r)}e.appendChild(a),Ae(e,t);let i=document.getElementById("batch-toolbar");i&&(i.style.display="none"),V()}function dt(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:q(e.priority)}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),c("div",{className:"column-card-title",children:e.title})]}));return s.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,$e(),A()}),s}function ut(){let e=document.getElementById("ticket-list"),t=Pe(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(Re());let s=De(),a=y(c("div",{className:"columns-container"}));for(let i of s){let o=n.tickets.filter(u=>u.status===i.status),l=y(c("div",{className:"column","data-status":i.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:i.label}),c("span",{className:"column-count",children:String(o.length)})]}),c("div",{className:"column-body"})]})),r=l.querySelector(".column-body");for(let u of o)r.appendChild(pt(u));r.addEventListener("dragover",u=>{u.preventDefault(),u.dataTransfer.dropEffect="move",l.classList.add("column-drop-target")}),r.addEventListener("dragleave",u=>{let d=u.relatedTarget;(!d||!r.contains(d))&&l.classList.remove("column-drop-target")}),r.addEventListener("drop",u=>{u.preventDefault(),l.classList.remove("column-drop-target");let d=E;if(E=[],d.length===0)return;let f=n.tickets.filter(b=>d.includes(b.id));k(f,{ids:d,action:"status",value:i.status},"Change status").then(()=>{m()})}),a.appendChild(l)}e.appendChild(a),Ae(e,t),R(),V()}function pt(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:q(e.priority)}),c("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"})]}),c("div",{className:"column-card-title",children:e.title})]})),a=s.querySelector(".ticket-priority-indicator");return a.addEventListener("click",i=>{i.stopPropagation(),Oe(a,e)}),s.querySelector(".ticket-star").addEventListener("click",i=>{i.stopPropagation(),Ke(e)}),s.draggable=!0,s.addEventListener("dragstart",i=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?E=Array.from(n.selectedIds):E=[e.id],i.dataTransfer.setData("text/plain",JSON.stringify(E)),i.dataTransfer.effectAllowed="move"}),s.addEventListener("dragend",()=>{E=[]}),s.addEventListener("click",i=>{if(i.metaKey||i.ctrlKey)n.selectedIds.has(e.id)?n.selectedIds.delete(e.id):n.selectedIds.add(e.id),n.lastClickedId=e.id;else if(i.shiftKey&&n.lastClickedId!=null){let o=n.tickets.find(l=>l.id===n.lastClickedId);if(o&&o.status===e.status){let r=n.tickets.filter(f=>f.status===e.status).map(f=>f.id),u=r.indexOf(n.lastClickedId),d=r.indexOf(e.id);if(u!==-1&&d!==-1){let f=Math.min(u,d),b=Math.max(u,d);n.selectedIds.clear();for(let x=f;x<=b;x++)n.selectedIds.add(r[x])}}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id;$e(),R()}),s}function $e(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);n.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function Re(){let e=Ue(),t=n.view.startsWith("category:"),s=y(c("div",{className:"ticket-row draft-row",children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),c("span",{className:"ticket-category-badge draft-badge",style:`background-color:${w(e)}${t?"":";cursor:pointer;opacity:1"}`,children:H(e)}),c("span",{className:"ticket-number draft-number"}),c("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:re}),c("span",{className:"ticket-priority-indicator draft-placeholder"}),c("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let i=s.querySelector(".ticket-category-badge");i.addEventListener("click",o=>{o.stopPropagation(),ft(i)})}let a=s.querySelector(".draft-input");return a.addEventListener("input",()=>{re=a.value}),a.addEventListener("keydown",async i=>{if(i.key==="Enter"&&a.value.trim()){i.preventDefault();let o=a.value.trim();re="",a.value="";let l=mt();O&&!n.view.startsWith("category:")&&(l.category=O);let r=await p("/tickets",{method:"POST",body:{title:o,defaults:l}});r&&(n.selectedIds.clear(),n.selectedIds.add(r.id)),await m(),I()}else i.key==="ArrowDown"&&(i.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),s}function I(){document.querySelector(".draft-row .draft-input")?.focus()}function mt(){let e=n.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 Ue(){if(O)return O;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function ft(e){J();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=Ue(),i=W(e,Y.map(o=>({label:o.label,key:o.key,shortcut:`${s}${o.key.toUpperCase()}`,color:w(o.value),active:a===o.value,action:()=>{O=o.value,v(),I()}})));document.body.appendChild(i),j(i,e),i.style.visibility=""}function gt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",a=e.status==="verified",i=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("button",{className:`ticket-status-btn${a?" verified":""}`,title:e.status.replace("_"," "),children:a?_(ee):te(e.status)}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,title:e.category,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("input",{type:"text",className:"ticket-title-input",value:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:q(e.priority)}),c("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"})]}));i.addEventListener("mousedown",d=>{let f=d.target;f.tagName!=="INPUT"&&f.tagName!=="BUTTON"&&(i.draggable=!0)}),i.addEventListener("mouseup",()=>{i.draggable=!1}),i.addEventListener("dragend",()=>{i.draggable=!1,E=[]}),i.addEventListener("dragstart",d=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?E=Array.from(n.selectedIds):E=[e.id],d.dataTransfer.setData("text/plain",JSON.stringify(E)),d.dataTransfer.effectAllowed="move"}),i.addEventListener("mousedown",d=>{(d.metaKey||d.ctrlKey||d.shiftKey)&&(d.preventDefault(),qe(d,e)&&d.stopPropagation())});let o=i.querySelector(".ticket-checkbox");o.addEventListener("click",d=>d.stopPropagation()),o.addEventListener("change",()=>{o.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,v()}),i.querySelector(".ticket-status-btn").addEventListener("click",d=>{d.stopPropagation(),kt(e)});let l=i.querySelector(".ticket-category-badge");l.addEventListener("click",d=>{d.stopPropagation(),It(l,e)});let r=i.querySelector(".ticket-title-input");r.addEventListener("focus",()=>{K||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,F(),R())}),r.addEventListener("input",()=>{G(e,"title",r.value),Tt(e.id,{title:r.value})}),r.addEventListener("keydown",d=>{vt(d,e,r)});let u=i.querySelector(".ticket-priority-indicator");return u.addEventListener("click",d=>{d.stopPropagation(),Oe(u,e)}),i.querySelector(".ticket-star").addEventListener("click",d=>{d.stopPropagation(),Ke(e)}),i}function yt(e){let t=n.selectedIds.has(e.id),s=e.deleted_at?new Date(e.deleted_at):null,a=y(c("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),c("span",{className:"ticket-number",title:s?`Deleted: ${s.toLocaleString()}`:"",children:s?s.toLocaleDateString():""}),c("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));a.addEventListener("mousedown",o=>{(o.metaKey||o.ctrlKey||o.shiftKey)&&(o.preventDefault(),qe(o,e)&&o.stopPropagation())});let i=a.querySelector(".ticket-checkbox");return i.addEventListener("click",o=>o.stopPropagation()),i.addEventListener("change",()=>{i.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,v()}),a.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,F(),R())}),a.querySelector(".btn").addEventListener("click",async o=>{o.stopPropagation(),await xe(e),m()}),a}function qe(e,t){let s=e.metaKey||e.ctrlKey,a=e.shiftKey;if(s)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,v();else if(a&&n.lastClickedId!=null){let i=n.tickets.map(r=>r.id),o=i.indexOf(n.lastClickedId),l=i.indexOf(t.id);if(o!==-1&&l!==-1){let r=Math.min(o,l),u=Math.max(o,l);n.selectedIds.clear();for(let d=r;d<=u;d++)n.selectedIds.add(i[d])}v()}else return!1;return!0}function vt(e,t,s){if(e.key==="Enter")e.preventDefault(),I();else if(e.key==="Backspace"&&s.value==="")e.preventDefault(),Et(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),He(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),He(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),ht(t.id);else if(e.key==="ArrowUp")e.preventDefault(),bt(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Y.some(a=>a.key===e.key)){e.preventDefault();let a=Y.find(i=>i.key===e.key);Ne(t,"category",a.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&ce.some(a=>a.key===e.key)){e.preventDefault();let a=ce.find(i=>i.key===e.key);Ne(t,"priority",a.value)}}function ht(e){let t=n.tickets.findIndex(s=>s.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function bt(e){let t=n.tickets.findIndex(s=>s.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():I()}function He(e,t){let a=n.tickets.findIndex(l=>l.id===e)+t;if(a<0||a>=n.tickets.length)return;let i=n.tickets[a].id;n.selectedIds.add(e),n.selectedIds.has(i)?n.selectedIds.delete(e):n.selectedIds.add(i),K=!0,document.querySelector(`.ticket-row[data-id="${i}"] .ticket-title-input`)?.focus(),K=!1,F(),R()}async function kt(e){let s={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",a=await T(e,{status:s},"Change status");Object.assign(e,a),v()}async function Ke(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await T(e,{status:"not_started",up_next:!0},"Toggle up next"):await T(e,{up_next:!e.up_next},"Toggle up next"),m()}async function Ne(e,t,s){let a=await T(e,{[t]:s},`Change ${t}`);Object.assign(e,a),v()}async function Et(e){let t=n.tickets.findIndex(a=>a.id===e),s=n.tickets.find(a=>a.id===e);if(s?await Le(s):await p(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(a=>a.id!==e),n.selectedIds.delete(e),v(),t>0&&n.tickets.length>0){let a=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[a].id}"] .ticket-title-input`)?.focus()}else I()}function Tt(e,t){$&&clearTimeout($),$=setTimeout(()=>{p(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function It(e,t){J();let a=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",i=W(e,Y.map(o=>({label:o.label,key:o.key,shortcut:`${a}${o.key.toUpperCase()}`,color:w(o.value),active:t.category===o.value,action:async()=>{let l=await T(t,{category:o.value},"Change category");Object.assign(t,l),v()}})));document.body.appendChild(i),j(i,e),i.style.visibility=""}function Oe(e,t){J();let s=W(e,ce.map(a=>({label:a.label,key:a.key,shortcut:`Alt+${a.key}`,color:P(a.value),active:t.priority===a.value,action:async()=>{let i=await T(t,{priority:a.value},"Change priority");Object.assign(t,i),v()}})));document.body.appendChild(s),j(s,e),s.style.visibility=""}function F(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),s=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),s&&(s.checked=!0)):(e.classList.remove("selected"),s&&(s.checked=!1))})}function R(){let e=n.selectedIds.size,t=n.tickets.length,s=e>0,a=n.view==="trash",i=document.getElementById("batch-select-all");i.checked=t>0&&e===t,i.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=s?`${e} selected`:"";let o=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete"];for(let f of o){let b=document.getElementById(f);b.style.display=a?"none":"",a||(b.disabled=!s)}let l=document.getElementById("batch-restore"),r=document.getElementById("batch-empty-trash");if(a){let f=document.getElementById("batch-toolbar");l||(l=y(c("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),l.addEventListener("click",async()=>{await p("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),m()}),f.insertBefore(l,document.getElementById("batch-count"))),l.disabled=!s,l.style.display="",r||(r=y(c("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),r.addEventListener("click",async()=>{await p("/trash/empty",{method:"POST"}),n.selectedIds.clear(),m()}),f.insertBefore(r,document.getElementById("batch-count"))),r.disabled=t===0,r.style.display=""}else l&&(l.style.display="none"),r&&(r.style.display="none");let u=document.querySelector(".batch-star-icon"),d=document.getElementById("batch-upnext");if(!a&&u&&s){let f=n.tickets.filter(M=>n.selectedIds.has(M.id)),b=f.every(M=>M.up_next),x=f.every(M=>!M.up_next);b?(u.textContent="\u2605",d.classList.add("active"),d.classList.remove("mixed")):x?(u.textContent="\u2606",d.classList.remove("active","mixed")):(u.innerHTML=c("span",{className:"star-mixed-wrap",children:[c("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),d.classList.remove("active"),d.classList.add("mixed"))}else u&&(u.textContent="\u2606",d.classList.remove("active","mixed"));A()}async function m(){if(n.backupPreview?.active){wt();return}let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="non-verified"?e.set("status","non_verified"):n.view==="verified"?e.set("status","verified"):n.view==="backlog"?e.set("status","backlog"):n.view==="archive"?e.set("status","archive"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")?e.set("priority",n.view.split(":")[1]):e.set("status","active"),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await p(`/tickets${t?"?"+t:""}`),v()}function wt(){let e=[...n.backupPreview?.tickets||[]];if(n.view==="trash")e=e.filter(t=>t.status==="deleted");else if(n.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(n.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(n.view==="completed")e=e.filter(t=>t.status==="completed");else if(n.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(n.view==="verified")e=e.filter(t=>t.status==="verified");else if(n.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(n.view==="archive")e=e.filter(t=>t.status==="archive");else if(n.view.startsWith("category:")){let t=n.view.split(":")[1];e=e.filter(s=>s.category===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else if(n.view.startsWith("priority:")){let t=n.view.split(":")[1];e=e.filter(s=>s.priority===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(n.search){let t=n.search.toLowerCase();e=e.filter(s=>s.title.toLowerCase().includes(t)||s.ticket_number.toLowerCase().includes(t)||s.details&&s.details.toLowerCase().includes(t))}n.tickets=e,v()}function Lt(e){let t=Date.now()-new Date(e).getTime(),s=Math.floor(t/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;let a=Math.floor(s/60);return a<24?`${a}h ago`:`${Math.floor(a/24)}d ago`}function xt(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function St(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function ue(){var t;let e=document.getElementById("backup-list");if(e)try{let s=await p("/backups");if(s.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let a={};for(let i of s.backups)(a[t=i.tier]||(a[t]=[])).push(i);e.innerHTML="";for(let i of["5min","hourly","daily"]){let o=a[i];if(!(!o||o.length===0)){e.appendChild(y(c("div",{className:"backup-tier-label",children:St(i)})));for(let l of o){let r=y(c("div",{className:"backup-row","data-tier":l.tier,"data-filename":l.filename,children:[c("span",{className:"backup-row-time",children:Lt(l.createdAt)}),c("span",{className:"backup-row-meta",children:[new Date(l.createdAt).toLocaleString()," \xB7 ",xt(l.sizeBytes)]})]}));r.addEventListener("click",()=>{_t(l.tier,l.filename,l.createdAt)}),e.appendChild(r)}}}}catch{e.textContent="Failed to load backups."}}async function _t(e,t,s){let a=document.getElementById("settings-overlay");a.style.display="none";let i=document.getElementById("backup-preview-banner"),o=document.getElementById("backup-preview-label");o.textContent="Loading backup preview...",i.style.display="flex";try{let l=await p(`/backups/preview/${e}/${t}`);n.backupPreview={active:!0,tickets:l.tickets,timestamp:s,tier:e,filename:t},n.selectedIds.clear(),n.activeTicketId=null,o.textContent=`Previewing backup from ${new Date(s).toLocaleString()} (${l.stats.total} tickets, ${l.stats.open} open) \u2014 read-only`,m()}catch{o.textContent="Failed to load backup preview.",setTimeout(()=>{i.style.display="none"},3e3)}}async function Ct(){let e=document.getElementById("backup-preview-banner");e.style.display="none",n.backupPreview=null,n.selectedIds.clear(),n.activeTicketId=null,await p("/backups/preview/cleanup",{method:"POST"}),m()}async function Bt(){if(!n.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await p("/backups/restore",{method:"POST",body:{tier:n.backupPreview.tier,filename:n.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Fe(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{Ct()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{Bt()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await p("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",ue())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}async function Mt(){await Ht(),Nt(),await m(),Ot(),Ut(),qt(),Ft(),zt(),Vt(),jt(),Gt(),Dt(),Fe(),$t(),Rt(),we(),Yt(),Pt(),document.addEventListener("hotsheet:render",()=>v()),I()}async function Ht(){try{let e=await p("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(n.layout=e.layout)}catch{}ae(n.settings.detail_position),ie()}async function Nt(){try{let e=await p("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function Dt(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex",ue(),p("/file-settings").then(g=>{document.getElementById("settings-app-name").value=g.appName||"",document.getElementById("settings-backup-dir").value=g.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",g=>{g.target===e&&(e.style.display="none")});let a=document.getElementById("settings-trash-days"),i=null;a.addEventListener("input",()=>{i&&clearTimeout(i),i=setTimeout(()=>{let g=Math.max(1,parseInt(a.value,10)||3);a.value=String(g),n.settings.trash_cleanup_days=g,p("/settings",{method:"PATCH",body:{trash_cleanup_days:String(g)}})},500)});let o=document.getElementById("settings-verified-days"),l=null;o.addEventListener("input",()=>{l&&clearTimeout(l),l=setTimeout(()=>{let g=Math.max(1,parseInt(o.value,10)||30);o.value=String(g),n.settings.verified_cleanup_days=g,p("/settings",{method:"PATCH",body:{verified_cleanup_days:String(g)}})},500)});let r=document.getElementById("settings-app-name"),u=document.getElementById("settings-app-name-hint"),d=null;r.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let g=r.value.trim();p("/file-settings",{method:"PATCH",body:{appName:g}}).then(()=>{let N=g||"Hot Sheet";document.title=N;let ye=document.querySelector(".app-title h1");ye&&(ye.textContent=N),u.textContent=g?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let f=document.getElementById("check-updates-btn"),b=document.getElementById("check-updates-status");f.addEventListener("click",async()=>{let g=ge();if(g){f.disabled=!0,f.textContent="Checking...",b.textContent="";try{let N=await g("check_for_update");N?(b.textContent=`Update available: v${N}`,document.getElementById("settings-overlay").style.display="none",We(N)):b.textContent="Your software is up to date."}catch{b.textContent="Could not check for updates."}f.textContent="Check for Updates",f.disabled=!1}});let x=document.getElementById("settings-backup-dir"),M=document.getElementById("settings-backup-dir-hint"),Q=null;x.addEventListener("input",()=>{Q&&clearTimeout(Q),Q=setTimeout(()=>{let g=x.value.trim();p("/file-settings",{method:"PATCH",body:{backupDir:g}}).then(()=>{M.textContent=g?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)})}async function Pt(){let e=ge();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let s=[0,3e3,1e4];for(let a of s){a>0&&await new Promise(i=>setTimeout(i,a));try{let i=await e("get_pending_update");if(i){We(i);return}}catch{return}}}function ge(){return window.__TAURI__?.core?.invoke??null}function We(e){let t=document.getElementById("update-banner");if(!t)return;let s=document.getElementById("update-banner-label");s&&(s.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 ge()?.("install_update"),s&&(s.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 At(){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 $t(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),s=document.getElementById("copy-prompt-label"),a=document.getElementById("copy-prompt-icon"),i="";p("/worklist-info").then(o=>{i=o.prompt,e.style.display="",o.skillCreated&&At()}),t.addEventListener("click",()=>{i!==""&&navigator.clipboard.writeText(i).then(()=>{s.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(()=>{s.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 Rt(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");p("/glassbox/status").then(({available:s})=>{s&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{p("/glassbox/launch",{method:"POST"})})}function fe(){let e=document.getElementById("layout-toggle"),t=X(),s=e.querySelector('[data-layout="columns"]');s.disabled=!t,s.style.opacity=t?"":"0.3";let a=n.layout==="columns"&&!t?"list":n.layout;e.querySelectorAll(".layout-btn").forEach(i=>{i.classList.toggle("active",i.dataset.layout===a)})}function Ut(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.layout;s==="columns"&&!X()||(n.layout=s,fe(),v(),p("/settings",{method:"PATCH",body:{layout:s}}))})}),fe()}function ze(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===n.settings.detail_position)})}function qt(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.position;n.settings.detail_position=s,ae(s),ie(),ze(),p("/settings",{method:"PATCH",body:{detail_position:s}})})}),ze()}function Je(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 Kt(e,t){let s=Je(e);if(!s)return;let a=n.tickets.filter(i=>t.includes(i.id));s.action==="delete"?await k(a,{ids:t,action:"delete"},"Delete tickets"):await k(a,{ids:t,action:s.action,value:s.value},`Change ${s.action}`),m()}function Ot(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(a=>{a.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),fe(),m()});let s=t.dataset.view;Je(s)&&(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 i=[...E];i.length!==0&&Kt(s,i)}))})}function Ft(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,s]=e.value.split(":");n.sortBy=t,n.sortDir=s,m()})}var pe=null;function zt(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{pe&&clearTimeout(pe),pe=setTimeout(()=>{n.search=e.value,m()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",m())})}function Vt(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{if(!e.value)return;let a=Array.from(n.selectedIds),i=n.tickets.filter(o=>n.selectedIds.has(o.id));await k(i,{ids:a,action:"category",value:e.value},"Batch change category"),e.value="",m()});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{if(!t.value)return;let a=Array.from(n.selectedIds),i=n.tickets.filter(o=>n.selectedIds.has(o.id));await k(i,{ids:a,action:"priority",value:t.value},"Batch change priority"),t.value="",m()});let s=document.getElementById("batch-status");s.addEventListener("change",async()=>{if(!s.value)return;let a=Array.from(n.selectedIds),i=n.tickets.filter(o=>n.selectedIds.has(o.id));await k(i,{ids:a,action:"status",value:s.value},"Batch change status"),s.value="",m()}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let a=n.tickets.filter(r=>n.selectedIds.has(r.id)),o=!a.every(r=>r.up_next),l=Array.from(n.selectedIds);if(o){let r=a.filter(u=>u.status==="completed"||u.status==="verified");if(r.length>0){let u=[{ids:r.map(d=>d.id),action:"status",value:"not_started"},{ids:l,action:"up_next",value:!0}];await le(a,u,"Batch toggle up next")}else await k(a,{ids:l,action:"up_next",value:!0},"Batch toggle up next")}else await k(a,{ids:l,action:"up_next",value:!1},"Batch toggle up next");m()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let a=Array.from(n.selectedIds),i=n.tickets.filter(o=>n.selectedIds.has(o.id));await k(i,{ids:a,action:"delete"},"Batch delete"),n.selectedIds.clear(),m()}),document.getElementById("batch-select-all").addEventListener("change",a=>{if(a.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();v()})}var L=null;function jt(){document.getElementById("detail-close").addEventListener("click",Ee);let e=["detail-title","detail-details"];for(let s of e){let a=document.getElementById(s);a.addEventListener("input",()=>{let i=n.tickets.find(o=>o.id===n.activeTicketId);if(i){let o=s.replace("detail-","");G(i,o,a.value)}L&&clearTimeout(L),L=setTimeout(()=>{if(n.activeTicketId==null)return;let o=s.replace("detail-","");p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[o]:a.value}}).then(()=>{m()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let s of t){let a=document.getElementById(s);a.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let i=n.tickets.find(l=>l.id===n.activeTicketId),o=s.replace("detail-","");i?await T(i,{[o]:a.value},`Change ${o}`):await p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[o]:a.value}}),m()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let s=n.tickets.find(i=>i.id===n.activeTicketId),a=document.getElementById("detail-upnext");s?a.checked&&(s.status==="completed"||s.status==="verified")?await T(s,{status:"not_started",up_next:!0},"Toggle up next"):await T(s,{up_next:!s.up_next},"Toggle up next"):await p(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"}),m(),z(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async s=>{let a=s.target,i=a.files?.[0];!i||n.activeTicketId==null||(await ke(`/tickets/${n.activeTicketId}/attachments`,i),a.value="",z(n.activeTicketId),m())}),document.getElementById("detail-attachments").addEventListener("click",async s=>{let a=s.target,i=a.closest(".attachment-reveal");if(i){let r=i.dataset.attId;r&&p(`/attachments/${r}/reveal`,{method:"POST"});return}let o=a.closest(".attachment-delete");if(o===null)return;let l=o.dataset.attId;l===void 0||l===""||(await p(`/attachments/${l}`,{method:"DELETE"}),n.activeTicketId!=null&&z(n.activeTicketId))})}function Wt(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 Jt(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let s=Wt(e.notes);if(s.length>0){t.push("");for(let a of s)t.push(`- ${a.text}`)}return t.join(`
|
|
2
|
-
`)}function Ve(){console.log("[undo] triggerUndo called, canUndo:",Be()),L&&(clearTimeout(L),L=null),de(),_e().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function je(){console.log("[undo] triggerRedo called, canRedo:",Me()),L&&(clearTimeout(L),L=null),de(),Ce().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function Gt(){window.addEventListener("app:undo",Ve),window.addEventListener("app:redo",je),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?je():Ve())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,s=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",
|
|
1
|
+
"use strict";(()=>{var Ge=Object.defineProperty;var Ye=(e,t,s)=>t in e?Ge(e,t,{enumerable:!0,configurable:!0,writable:!0,value:s}):e[t]=s;var O=(e,t,s)=>Ye(e,typeof t!="symbol"?t+"":t,s);function ve(e){return e.replace(/&/g,"&").replace(/</g,"<").replace(/>/g,">").replace(/"/g,""")}function he(e){return e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(/</g,"<").replace(/>/g,">")}var S=class{constructor(t){O(this,"__html");this.__html=t}toString(){return this.__html}};function _(e){return new S(e)}var Xe=new Set(["area","base","br","col","embed","hr","img","input","link","meta","source","track","wbr"]);function Z(e){return e==null||typeof e=="boolean"?"":e instanceof S?e.__html:typeof e=="string"?ve(e):typeof e=="number"?String(e):Array.isArray(e)?e.map(Z).join(""):""}function Qe(e,t){if(t==null||t===!1)return"";if(t===!0)return` ${e}`;let s=e==="className"?"class":e==="htmlFor"?"for":e,i;return t instanceof S?i=t.__html:typeof t=="number"?i=String(t):typeof t=="string"?i=he(t):i="",` ${s}="${i}"`}function c(e,t){if(typeof e=="function")return e(t);let{children:s,...i}=t,a=Object.entries(i).map(([o,r])=>Qe(o,r)).join("");if(Xe.has(e))return new S(`<${e}${a}>`);let l=s!=null?Z(s):"";return new S(`<${e}${a}>${l}</${e}>`)}function D({children:e}){return new S(e!=null?Z(e):"")}function y(e){let t=document.createElement("template");return t.innerHTML=e.toString(),t.content.firstElementChild}function be(e){document.getElementById("network-error-popup")?.remove();let t=y(c("div",{id:"network-error-popup",className:"error-popup",children:c("div",{className:"error-popup-content",children:[c("strong",{children:"Connection Error"}),c("p",{children:e}),c("button",{children:_("Dismiss")})]})}));t.querySelector("button").addEventListener("click",()=>t.remove()),document.body.appendChild(t)}async function p(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(s){throw be("Unable to reach the server. It may have been stopped."),s}}async function ke(e,t){try{let s=new FormData;return s.append("file",t),(await fetch("/api"+e,{method:"POST",body:s})).json()}catch(s){throw be("Unable to reach the server. It may have been stopped."),s}}var Ze={detail_position:"side",detail_width:360,detail_height:300,trash_cleanup_days:3,verified_cleanup_days:30},n={tickets:[],selectedIds:new Set,lastClickedId:null,activeTicketId:null,view:"all",layout:"list",sortBy:"created",sortDir:"desc",search:"",settings:{...Ze},backupPreview:null},et={issue:"#6b7280",bug:"#ef4444",feature:"#22c55e",requirement_change:"#f97316",task:"#3b82f6",investigation:"#8b5cf6"},tt={issue:"ISS",bug:"BUG",feature:"FEA",requirement_change:"REQ",task:"TSK",investigation:"INV"},nt={highest:"\u2B06\u2B06",high:"\u2B06",default:"\u2014",low:"\u2B07",lowest:"\u2B07\u2B07"},st={highest:"#ef4444",high:"#f97316",default:"#6b7280",low:"#3b82f6",lowest:"#94a3b8"},at={not_started:"\u25CB",started:"\u25D4",completed:"\u2713",verified:"svg",backlog:"\u25A1",archive:"\u25A0"},ee='<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2.5" stroke-linecap="round" stroke-linejoin="round"><path d="M18 6 7 17l-5-5"/><path d="m22 10-9.5 9.5-2-2"/></svg>';function w(e){return et[e]||"#6b7280"}function H(e){return tt[e]||"ISS"}function F(e){return nt[e]||"\u2014"}function P(e){return st[e]||"#6b7280"}function te(e){return at[e]||"\u25CB"}function W(e){n.activeTicketId=e,se(e)}function Ee(){n.selectedIds.clear(),n.activeTicketId=null,A();let e=new CustomEvent("hotsheet:render");document.dispatchEvent(e)}function A(){let e=n.view==="trash",t=!!n.backupPreview?.active,s=document.getElementById("detail-panel"),i=document.getElementById("detail-resize-handle"),a=document.getElementById("detail-header"),l=document.getElementById("detail-body"),o=document.getElementById("detail-placeholder"),r=document.getElementById("detail-placeholder-text");if(e){s.style.display="none",i&&(i.style.display="none"),n.activeTicketId=null;return}if(s.style.display="flex",i&&(i.style.display=""),n.selectedIds.size===1){let u=Array.from(n.selectedIds)[0];s.classList.remove("detail-disabled"),a.style.display="",l.style.display="",o.style.display="none",n.activeTicketId!==u&&(n.activeTicketId=u,t?it(u):se(u))}else n.activeTicketId=null,s.classList.add("detail-disabled"),a.style.display="none",l.style.display="none",o.style.display="",n.selectedIds.size===0?r.textContent="Nothing selected":r.textContent=`${n.selectedIds.size} items selected`}function Te(e){let t=document.getElementById("detail-title"),s=document.getElementById("detail-details"),i=document.getElementById("detail-category"),a=document.getElementById("detail-priority"),l=document.getElementById("detail-status"),o=document.getElementById("detail-upnext"),r=document.querySelector(".upload-btn");t.readOnly=e,s.readOnly=e,i.disabled=e,a.disabled=e,l.disabled=e,o.disabled=e,r&&(r.style.display=e?"none":"")}function it(e){let t=n.backupPreview?.tickets.find(o=>o.id===e);if(!t||n.activeTicketId!==e)return;document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details,Te(!0),document.getElementById("detail-attachments").innerHTML="";let s=document.getElementById("detail-notes-section"),i=document.getElementById("detail-notes"),a=Ie(t.notes);a.length>0?(s.style.display="",i.innerHTML=c(D,{children:a.map(o=>c("div",{className:"note-entry",children:[o.created_at?c("div",{className:"note-timestamp",children:new Date(o.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:o.text})]}))}).toString()):(s.style.display="none",i.innerHTML="");let l=document.getElementById("detail-meta");l.innerHTML=c(D,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function ne(){n.activeTicketId!=null&&se(n.activeTicketId)}async function se(e){let t=await p(`/tickets/${e}`);if(n.activeTicketId!==e)return;Te(!1),document.getElementById("detail-ticket-number").textContent=t.ticket_number,document.getElementById("detail-title").value=t.title,document.getElementById("detail-category").value=t.category,document.getElementById("detail-priority").value=t.priority,document.getElementById("detail-status").value=t.status,document.getElementById("detail-upnext").checked=t.up_next,document.getElementById("detail-details").value=t.details;let s=document.getElementById("detail-attachments");t.attachments.length>0?s.innerHTML=c(D,{children:t.attachments.map(r=>c("div",{className:"attachment-item",children:[c("span",{className:"attachment-name",children:r.original_filename}),c("button",{className:"attachment-reveal","data-att-id":String(r.id),title:"Show in file manager",children:_('<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="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"/></svg>')}),c("button",{className:"attachment-delete","data-att-id":String(r.id),title:"Remove",children:_("×")})]}))}).toString():s.innerHTML="";let i=document.getElementById("detail-notes-section"),a=document.getElementById("detail-notes"),l=Ie(t.notes);l.length>0?(i.style.display="",a.innerHTML=c(D,{children:l.map(r=>c("div",{className:"note-entry",children:[r.created_at?c("div",{className:"note-timestamp",children:new Date(r.created_at).toLocaleString()}):null,c("div",{className:"note-text",children:r.text})]}))}).toString()):(i.style.display="none",a.innerHTML="");let o=document.getElementById("detail-meta");o.innerHTML=c(D,{children:[c("div",{children:["Created: ",new Date(t.created_at).toLocaleString()]}),c("div",{children:["Updated: ",new Date(t.updated_at).toLocaleString()]}),t.completed_at?c("div",{children:["Completed: ",new Date(t.completed_at).toLocaleString()]}):null,t.verified_at?c("div",{children:["Verified: ",new Date(t.verified_at).toLocaleString()]}):null]}).toString()}function Ie(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:""}]:[]}async function J(){try{let e=await p("/stats"),t=document.getElementById("status-bar");t&&(t.textContent=`${e.total} tickets \xB7 ${e.open} open \xB7 ${e.up_next} up next`)}catch{}}function ae(e){let t=document.getElementById("content-area");t.classList.remove("detail-side","detail-bottom"),t.classList.add(e==="bottom"?"detail-bottom":"detail-side")}function ie(){let e=document.getElementById("detail-panel");n.settings.detail_position==="bottom"?(e.style.width="",e.style.height=`${n.settings.detail_height}px`):(e.style.height="",e.style.width=`${n.settings.detail_width}px`)}function we(){let e=document.getElementById("detail-resize-handle"),t=document.getElementById("detail-panel"),s=document.getElementById("content-area"),i=!1;e.addEventListener("mousedown",a=>{a.preventDefault(),i=!0,document.body.style.cursor=n.settings.detail_position==="bottom"?"row-resize":"col-resize",document.body.style.userSelect="none"}),document.addEventListener("mousemove",a=>{if(!i)return;let l=s.getBoundingClientRect();if(n.settings.detail_position==="bottom"){let o=Math.max(150,Math.min(500,l.bottom-a.clientY));n.settings.detail_height=o,t.style.height=`${o}px`}else{let o=Math.max(250,Math.min(600,l.right-a.clientX));n.settings.detail_width=o,t.style.width=`${o}px`}}),document.addEventListener("mouseup",()=>{i&&(i=!1,document.body.style.cursor="",document.body.style.userSelect="",n.settings.detail_position==="bottom"?p("/settings",{method:"PATCH",body:{detail_height:String(n.settings.detail_height)}}):p("/settings",{method:"PATCH",body:{detail_width:String(n.settings.detail_width)}}))})}function $(e,t){let s=t.getBoundingClientRect(),i=e.getBoundingClientRect(),a=window.innerWidth,l=window.innerHeight,o=s.left;o+i.width>a-8&&(o=s.right-i.width),o<8&&(o=8);let r=s.bottom+4;r+i.height>l-8&&(r=s.top-i.height-4),r<8&&(r=8),e.style.left=`${o}px`,e.style.top=`${r}px`}function R(e,t){let s=y(c("div",{className:"dropdown-menu",style:"visibility:hidden;top:0;left:0",children:t.map(r=>c("button",{className:`dropdown-item${r.active?" active":""}`,"data-key":r.key,children:[r.color?c("span",{className:"dropdown-dot",style:`background-color:${r.color}`}):null,c("span",{className:"dropdown-label",children:r.label}),r.shortcut?c("kbd",{className:"dropdown-kbd",children:r.shortcut}):null]}))}));s.querySelectorAll(".dropdown-item").forEach((r,u)=>{r.addEventListener("click",()=>{t[u].action(),s.remove()})});function a(r){let u=t.find(d=>r.key.toLowerCase()===d.key.toLowerCase());u?(r.preventDefault(),r.stopPropagation(),u.action(),l()):r.key==="Escape"&&(r.preventDefault(),l())}function l(){s.remove(),document.removeEventListener("keydown",a,!0),document.removeEventListener("click",o)}function o(){l()}return document.addEventListener("keydown",a,!0),setTimeout(()=>{document.addEventListener("click",o)},0),s}function U(){document.querySelectorAll(".dropdown-menu").forEach(e=>{e.remove()})}var oe=class{constructor(){O(this,"undoStack",[]);O(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 s=this.peekUndo();return!s||s.coalescingKey!==t.coalescingKey||t.timestamp-s.timestamp>=5e3?!1:(s.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}},h=new oe;function B(e){return{id:e.id,title:e.title,details:e.details,category:e.category,priority:e.priority,status:e.status,up_next:e.up_next}}async function T(e,t,s){let i=B(e),a=await p(`/tickets/${e.id}`,{method:"PATCH",body:t}),l=B(a);return h.push({label:s,timestamp:Date.now(),before:[i],after:[l]}),a}function G(e,t,s){let i=`${e.id}:${t}`,a=Date.now(),l={...B(e),[t]:s},o={label:`Edit ${t}`,timestamp:a,before:[B(e)],after:[l],coalescingKey:i};h.coalesce(o)||h.push(o)}async function b(e,t,s){let i=e.map(B);await p("/tickets/batch",{method:"POST",body:t});let a=i.map(l=>{let o={...l};return t.action==="category"?o.category=t.value:t.action==="priority"?o.priority=t.value:t.action==="status"?o.status=t.value:t.action==="up_next"?o.up_next=t.value:t.action==="delete"&&(o.status="deleted"),o});h.push({label:s,timestamp:Date.now(),before:i,after:a})}async function le(e,t,s){let i=e.map(B);for(let l of t)await p("/tickets/batch",{method:"POST",body:l});let a=i.map(l=>{let o={...l};for(let r of t)r.ids.includes(l.id)&&(r.action==="status"?o.status=r.value:r.action==="up_next"?o.up_next=r.value:r.action==="category"?o.category=r.value:r.action==="priority"?o.priority=r.value:r.action==="delete"&&(o.status="deleted"));return o});h.push({label:s,timestamp:Date.now(),before:i,after:a})}async function Le(e){let t=B(e);await p(`/tickets/${e.id}`,{method:"DELETE"});let s={...t,status:"deleted"};h.push({label:"Delete ticket",timestamp:Date.now(),before:[t],after:[s]})}async function xe(e){let t=B(e);await p(`/tickets/${e.id}/restore`,{method:"POST"});let s={...t,status:"not_started"};h.push({label:"Restore ticket",timestamp:Date.now(),before:[t],after:[s]})}async function Se(e){for(let t of e)t.status==="deleted"?await p(`/tickets/${t.id}`,{method:"DELETE"}):await p(`/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}})}var C=!1;async function _e(){if(console.log("[undo] performUndo, inFlight:",C,"canUndo:",h.canUndo()),C){console.log("[undo] skipped \u2014 already in flight");return}let e=h.popUndo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying before-state:",e.label,JSON.stringify(e.before)),C=!0;try{await Se(e.before),console.log("[undo] applySnapshots done, reloading tickets"),await m(),ne()}finally{C=!1}}async function Ce(){if(console.log("[undo] performRedo, inFlight:",C,"canRedo:",h.canRedo()),C){console.log("[undo] skipped \u2014 already in flight");return}let e=h.popRedo();if(!e){console.log("[undo] skipped \u2014 stack empty");return}console.log("[undo] applying after-state:",e.label,JSON.stringify(e.after)),C=!0;try{await Se(e.after),console.log("[undo] applySnapshots done, reloading tickets"),await m(),ne()}finally{C=!1}}function Be(){return h.canUndo()}function Me(){return h.canRedo()}var q=null;function de(){q&&(clearTimeout(q),q=null)}var z=!1,V=null,re="",E=[],Y=[{key:"i",value:"issue",label:"Issue"},{key:"b",value:"bug",label:"Bug"},{key:"f",value:"feature",label:"Feature"},{key:"r",value:"requirement_change",label:"Req Change"},{key:"k",value:"task",label:"Task"},{key:"g",value:"investigation",label:"Investigation"}],ce=[{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 ot(){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 s=t.dataset.id;return s!==void 0&&s!==""?parseInt(s,10):null}function lt(e){e!=null&&(z=!0,e==="draft"?I():document.querySelector(`.ticket-row[data-id="${e}"] .ticket-title-input`)?.focus(),z=!1)}function X(){let e=n.view;return e!=="completed"&&e!=="verified"&&e!=="trash"&&e!=="backlog"&&e!=="archive"}function De(){return n.view==="up-next"||n.view==="open"?[{status:"not_started",label:"Not Started"},{status:"started",label:"Started"}]:n.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 v(){let e=!!n.backupPreview?.active;if(n.layout==="columns"&&X()){if(e){ct();return}ut();return}let t=n.view==="trash",s=e?null:ot(),i=null;if(s!=null&&s!=="draft"){let o=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);o&&(i=o.value)}let a=document.getElementById("ticket-list"),l=a.scrollTop;if(a.innerHTML="",a.classList.remove("ticket-list-columns"),!t&&!e&&a.appendChild(Re()),n.tickets.length===0){let o=t?"Trash is empty":e?"No tickets match this view":"";o&&a.appendChild(y(c("div",{className:"ticket-list-empty",children:o})))}for(let o of n.tickets)e?a.appendChild(rt(o)):t?a.appendChild(yt(o)):a.appendChild(gt(o));if(a.scrollTop=l,e){let o=document.getElementById("batch-toolbar");o&&(o.style.display="none"),j(),A()}else{let o=document.getElementById("batch-toolbar");if(o&&(o.style.display=""),s!=null&&s!=="draft"&&i!=null){let r=document.querySelector(`.ticket-row[data-id="${s}"] .ticket-title-input`);r&&r.value!==i&&(r.value=i)}lt(s),K()}J()}function rt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",i=e.status==="verified",a=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:`ticket-status-btn${i?" verified":""}`,style:"cursor:default",children:i?_(ee):te(e.status)}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)};cursor:default`,title:e.category,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-title-input",style:"cursor:default",children:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,title:e.priority,children:F(e.priority)}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}));return a.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,j(),A()}),a}function Pe(e){let t={scrollLeft:0,columns:{}},s=e.querySelector(".columns-container");return s&&(t.scrollLeft=s.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(i=>{let a=i.dataset.status,l=i.querySelector(".column-body");l&&(t.columns[a]=l.scrollTop)})),t}function Ae(e,t){let s=e.querySelector(".columns-container");s&&(s.scrollLeft=t.scrollLeft,s.querySelectorAll(".column[data-status]").forEach(i=>{let a=i.dataset.status,l=i.querySelector(".column-body");l&&t.columns[a]!=null&&(l.scrollTop=t.columns[a])}))}function ct(){let e=document.getElementById("ticket-list"),t=Pe(e);e.innerHTML="",e.classList.add("ticket-list-columns");let s=De(),i=y(c("div",{className:"columns-container"}));for(let l of s){let o=n.tickets.filter(d=>d.status===l.status),r=y(c("div",{className:"column","data-status":l.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:l.label}),c("span",{className:"column-count",children:String(o.length)})]}),c("div",{className:"column-body"})]})),u=r.querySelector(".column-body");for(let d of o)u.appendChild(dt(d));i.appendChild(r)}e.appendChild(i),Ae(e,t);let a=document.getElementById("batch-toolbar");a&&(a.style.display="none"),J()}function dt(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)};cursor:default`,children:F(e.priority)}),c("span",{className:`ticket-star${e.up_next?" active":""}`,style:"cursor:default",children:e.up_next?"\u2605":"\u2606"})]}),c("div",{className:"column-card-title",children:e.title})]}));return s.addEventListener("click",()=>{n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,$e(),A()}),s}function ut(){let e=document.getElementById("ticket-list"),t=Pe(e);e.innerHTML="",e.classList.add("ticket-list-columns"),e.appendChild(Re());let s=De(),i=y(c("div",{className:"columns-container"}));for(let a of s){let l=n.tickets.filter(u=>u.status===a.status),o=y(c("div",{className:"column","data-status":a.status,children:[c("div",{className:"column-header",children:[c("span",{className:"column-title",children:a.label}),c("span",{className:"column-count",children:String(l.length)})]}),c("div",{className:"column-body"})]})),r=o.querySelector(".column-body");for(let u of l)r.appendChild(pt(u));r.addEventListener("dragover",u=>{u.preventDefault(),u.dataTransfer.dropEffect="move",o.classList.add("column-drop-target")}),r.addEventListener("dragleave",u=>{let d=u.relatedTarget;(!d||!r.contains(d))&&o.classList.remove("column-drop-target")}),r.addEventListener("drop",u=>{u.preventDefault(),o.classList.remove("column-drop-target");let d=E;if(E=[],d.length===0)return;let f=n.tickets.filter(k=>d.includes(k.id));b(f,{ids:d,action:"status",value:a.status},"Change status").then(()=>{m()})}),i.appendChild(o)}e.appendChild(i),Ae(e,t),K(),J()}function pt(e){let t=n.selectedIds.has(e.id),s=y(c("div",{className:`column-card${t?" selected":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("div",{className:"column-card-header",children:[c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,children:F(e.priority)}),c("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"})]}),c("div",{className:"column-card-title",children:e.title})]})),i=s.querySelector(".ticket-priority-indicator");return i.addEventListener("click",a=>{a.stopPropagation(),Oe(i,e)}),s.querySelector(".ticket-star").addEventListener("click",a=>{a.stopPropagation(),Ke(e)}),s.draggable=!0,s.addEventListener("dragstart",a=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?E=Array.from(n.selectedIds):E=[e.id],a.dataTransfer.setData("text/plain",JSON.stringify(E)),a.dataTransfer.effectAllowed="move"}),s.addEventListener("dragend",()=>{E=[]}),s.addEventListener("click",a=>{if(a.metaKey||a.ctrlKey)n.selectedIds.has(e.id)?n.selectedIds.delete(e.id):n.selectedIds.add(e.id),n.lastClickedId=e.id;else if(a.shiftKey&&n.lastClickedId!=null){let l=n.tickets.find(o=>o.id===n.lastClickedId);if(l&&l.status===e.status){let r=n.tickets.filter(f=>f.status===e.status).map(f=>f.id),u=r.indexOf(n.lastClickedId),d=r.indexOf(e.id);if(u!==-1&&d!==-1){let f=Math.min(u,d),k=Math.max(u,d);n.selectedIds.clear();for(let x=f;x<=k;x++)n.selectedIds.add(r[x])}}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id}else n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id;$e(),K()}),s}function $e(){document.querySelectorAll(".column-card[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10);n.selectedIds.has(t)?e.classList.add("selected"):e.classList.remove("selected")})}function Re(){let e=Ue(),t=n.view.startsWith("category:"),s=y(c("div",{className:"ticket-row draft-row",children:[c("span",{className:"ticket-checkbox-spacer"}),c("span",{className:"ticket-status-btn draft-placeholder",children:"\u25CB"}),c("span",{className:"ticket-category-badge draft-badge",style:`background-color:${w(e)}${t?"":";cursor:pointer;opacity:1"}`,children:H(e)}),c("span",{className:"ticket-number draft-number"}),c("input",{type:"text",className:"ticket-title-input draft-input",placeholder:"New ticket...",value:re}),c("span",{className:"ticket-priority-indicator draft-placeholder"}),c("span",{className:"ticket-star draft-placeholder"})]}));if(!t){let a=s.querySelector(".ticket-category-badge");a.addEventListener("click",l=>{l.stopPropagation(),ft(a)})}let i=s.querySelector(".draft-input");return i.addEventListener("input",()=>{re=i.value}),i.addEventListener("keydown",async a=>{if(a.key==="Enter"&&i.value.trim()){a.preventDefault();let l=i.value.trim();re="",i.value="";let o=mt();V&&!n.view.startsWith("category:")&&(o.category=V);let r=await p("/tickets",{method:"POST",body:{title:l,defaults:o}});r&&(n.selectedIds.clear(),n.selectedIds.add(r.id)),await m(),I()}else a.key==="ArrowDown"&&(a.preventDefault(),n.tickets.length>0&&document.querySelector(`.ticket-row[data-id="${n.tickets[0].id}"] .ticket-title-input`)?.focus())}),s}function I(){document.querySelector(".draft-row .draft-input")?.focus()}function mt(){let e=n.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 Ue(){if(V)return V;let e=n.view;return e.startsWith("category:")?e.split(":")[1]:"issue"}function ft(e){U();let s=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",i=Ue(),a=R(e,Y.map(l=>({label:l.label,key:l.key,shortcut:`${s}${l.key.toUpperCase()}`,color:w(l.value),active:i===l.value,action:()=>{V=l.value,v(),I()}})));document.body.appendChild(a),$(a,e),a.style.visibility=""}function gt(e){let t=n.selectedIds.has(e.id),s=e.status==="completed"||e.status==="verified",i=e.status==="verified",a=y(c("div",{className:`ticket-row${t?" selected":""}${s?" completed":""}${e.up_next?" up-next":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("button",{className:`ticket-status-btn${i?" verified":""}`,title:e.status.replace("_"," "),children:i?_(ee):te(e.status)}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,title:e.category,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("input",{type:"text",className:"ticket-title-input",value:e.title}),c("span",{className:"ticket-priority-indicator",style:`color:${P(e.priority)}`,title:e.priority,children:F(e.priority)}),c("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"})]}));a.addEventListener("mousedown",d=>{let f=d.target;f.tagName!=="INPUT"&&f.tagName!=="BUTTON"&&(a.draggable=!0)}),a.addEventListener("mouseup",()=>{a.draggable=!1}),a.addEventListener("dragend",()=>{a.draggable=!1,E=[]}),a.addEventListener("dragstart",d=>{n.selectedIds.has(e.id)&&n.selectedIds.size>1?E=Array.from(n.selectedIds):E=[e.id],d.dataTransfer.setData("text/plain",JSON.stringify(E)),d.dataTransfer.effectAllowed="move"}),a.addEventListener("mousedown",d=>{(d.metaKey||d.ctrlKey||d.shiftKey)&&(d.preventDefault(),qe(d,e)&&d.stopPropagation())});let l=a.querySelector(".ticket-checkbox");l.addEventListener("click",d=>d.stopPropagation()),l.addEventListener("change",()=>{l.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,v()}),a.querySelector(".ticket-status-btn").addEventListener("click",d=>{d.stopPropagation(),kt(e)});let o=a.querySelector(".ticket-category-badge");o.addEventListener("click",d=>{d.stopPropagation(),It(o,e)});let r=a.querySelector(".ticket-title-input");r.addEventListener("focus",()=>{z||n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,j(),K())}),r.addEventListener("input",()=>{G(e,"title",r.value),Tt(e.id,{title:r.value})}),r.addEventListener("keydown",d=>{vt(d,e,r)});let u=a.querySelector(".ticket-priority-indicator");return u.addEventListener("click",d=>{d.stopPropagation(),Oe(u,e)}),a.querySelector(".ticket-star").addEventListener("click",d=>{d.stopPropagation(),Ke(e)}),a}function yt(e){let t=n.selectedIds.has(e.id),s=e.deleted_at?new Date(e.deleted_at):null,i=y(c("div",{className:`ticket-row trash-row${t?" selected":""}`,"data-id":String(e.id),children:[c("input",{type:"checkbox",className:"ticket-checkbox",checked:t}),c("span",{className:"ticket-category-badge",style:`background-color:${w(e.category)}`,children:H(e.category)}),c("span",{className:"ticket-number",children:e.ticket_number}),c("span",{className:"ticket-title-input trash-title",style:"cursor:default",children:e.title}),c("span",{className:"ticket-number",title:s?`Deleted: ${s.toLocaleString()}`:"",children:s?s.toLocaleDateString():""}),c("button",{className:"btn btn-sm",title:"Restore from trash",children:"Restore"})]}));i.addEventListener("mousedown",l=>{(l.metaKey||l.ctrlKey||l.shiftKey)&&(l.preventDefault(),qe(l,e)&&l.stopPropagation())});let a=i.querySelector(".ticket-checkbox");return a.addEventListener("click",l=>l.stopPropagation()),a.addEventListener("change",()=>{a.checked?n.selectedIds.add(e.id):n.selectedIds.delete(e.id),n.lastClickedId=e.id,v()}),i.querySelector(".trash-title").addEventListener("click",()=>{n.selectedIds.size===1&&n.selectedIds.has(e.id)||(n.selectedIds.clear(),n.selectedIds.add(e.id),n.lastClickedId=e.id,j(),K())}),i.querySelector(".btn").addEventListener("click",async l=>{l.stopPropagation(),await xe(e),m()}),i}function qe(e,t){let s=e.metaKey||e.ctrlKey,i=e.shiftKey;if(s)n.selectedIds.has(t.id)?n.selectedIds.delete(t.id):n.selectedIds.add(t.id),n.lastClickedId=t.id,v();else if(i&&n.lastClickedId!=null){let a=n.tickets.map(r=>r.id),l=a.indexOf(n.lastClickedId),o=a.indexOf(t.id);if(l!==-1&&o!==-1){let r=Math.min(l,o),u=Math.max(l,o);n.selectedIds.clear();for(let d=r;d<=u;d++)n.selectedIds.add(a[d])}v()}else return!1;return!0}function vt(e,t,s){if(e.key==="Enter")e.preventDefault(),I();else if(e.key==="Backspace"&&s.value==="")e.preventDefault(),Et(t.id);else if(e.key==="ArrowDown"&&e.shiftKey)e.preventDefault(),He(t.id,1);else if(e.key==="ArrowUp"&&e.shiftKey)e.preventDefault(),He(t.id,-1);else if(e.key==="ArrowDown")e.preventDefault(),ht(t.id);else if(e.key==="ArrowUp")e.preventDefault(),bt(t.id);else if((e.metaKey||e.ctrlKey)&&!e.altKey&&Y.some(i=>i.key===e.key)){e.preventDefault();let i=Y.find(a=>a.key===e.key);Ne(t,"category",i.value)}else if(e.altKey&&!e.metaKey&&!e.ctrlKey&&ce.some(i=>i.key===e.key)){e.preventDefault();let i=ce.find(a=>a.key===e.key);Ne(t,"priority",i.value)}}function ht(e){let t=n.tickets.findIndex(s=>s.id===e);t<n.tickets.length-1&&document.querySelector(`.ticket-row[data-id="${n.tickets[t+1].id}"] .ticket-title-input`)?.focus()}function bt(e){let t=n.tickets.findIndex(s=>s.id===e);t>0?document.querySelector(`.ticket-row[data-id="${n.tickets[t-1].id}"] .ticket-title-input`)?.focus():I()}function He(e,t){let i=n.tickets.findIndex(o=>o.id===e)+t;if(i<0||i>=n.tickets.length)return;let a=n.tickets[i].id;n.selectedIds.add(e),n.selectedIds.has(a)?n.selectedIds.delete(e):n.selectedIds.add(a),z=!0,document.querySelector(`.ticket-row[data-id="${a}"] .ticket-title-input`)?.focus(),z=!1,j(),K()}async function kt(e){let s={not_started:"started",started:"completed",completed:"verified",verified:"not_started",backlog:"not_started",archive:"not_started"}[e.status]||"not_started",i=await T(e,{status:s},"Change status");Object.assign(e,i),v()}async function Ke(e){!e.up_next&&(e.status==="completed"||e.status==="verified")?await T(e,{status:"not_started",up_next:!0},"Toggle up next"):await T(e,{up_next:!e.up_next},"Toggle up next"),m()}async function Ne(e,t,s){let i=await T(e,{[t]:s},`Change ${t}`);Object.assign(e,i),v()}async function Et(e){let t=n.tickets.findIndex(i=>i.id===e),s=n.tickets.find(i=>i.id===e);if(s?await Le(s):await p(`/tickets/${e}`,{method:"DELETE"}),n.tickets=n.tickets.filter(i=>i.id!==e),n.selectedIds.delete(e),v(),t>0&&n.tickets.length>0){let i=Math.min(t-1,n.tickets.length-1);document.querySelector(`.ticket-row[data-id="${n.tickets[i].id}"] .ticket-title-input`)?.focus()}else I()}function Tt(e,t){q&&clearTimeout(q),q=setTimeout(()=>{p(`/tickets/${e}`,{method:"PATCH",body:t})},300)}function It(e,t){U();let i=navigator.platform.includes("Mac")?"\u2318":"Ctrl+",a=R(e,Y.map(l=>({label:l.label,key:l.key,shortcut:`${i}${l.key.toUpperCase()}`,color:w(l.value),active:t.category===l.value,action:async()=>{let o=await T(t,{category:l.value},"Change category");Object.assign(t,o),v()}})));document.body.appendChild(a),$(a,e),a.style.visibility=""}function Oe(e,t){U();let s=R(e,ce.map(i=>({label:i.label,key:i.key,shortcut:`Alt+${i.key}`,color:P(i.value),active:t.priority===i.value,action:async()=>{let a=await T(t,{priority:i.value},"Change priority");Object.assign(t,a),v()}})));document.body.appendChild(s),$(s,e),s.style.visibility=""}function j(){document.querySelectorAll(".ticket-row[data-id]").forEach(e=>{let t=parseInt(e.dataset.id,10),s=e.querySelector(".ticket-checkbox");n.selectedIds.has(t)?(e.classList.add("selected"),s&&(s.checked=!0)):(e.classList.remove("selected"),s&&(s.checked=!1))})}function K(){let e=n.selectedIds.size,t=n.tickets.length,s=e>0,i=n.view==="trash",a=document.getElementById("batch-select-all");a.checked=t>0&&e===t,a.indeterminate=e>0&&e<t,document.getElementById("batch-count").textContent=s?`${e} selected`:"";let l=["batch-category","batch-priority","batch-status","batch-upnext","batch-delete","batch-more"];for(let f of l){let k=document.getElementById(f);k.style.display=i?"none":"",i||(k.disabled=!s)}let o=document.getElementById("batch-restore"),r=document.getElementById("batch-empty-trash");if(i){let f=document.getElementById("batch-toolbar");o||(o=y(c("button",{id:"batch-restore",className:"btn btn-sm",children:"Restore"})),o.addEventListener("click",async()=>{await p("/tickets/batch",{method:"POST",body:{ids:Array.from(n.selectedIds),action:"restore"}}),n.selectedIds.clear(),m()}),f.insertBefore(o,document.getElementById("batch-count"))),o.disabled=!s,o.style.display="",r||(r=y(c("button",{id:"batch-empty-trash",className:"btn btn-sm btn-danger",children:"Empty Trash"})),r.addEventListener("click",async()=>{await p("/trash/empty",{method:"POST"}),n.selectedIds.clear(),m()}),f.insertBefore(r,document.getElementById("batch-count"))),r.disabled=t===0,r.style.display=""}else o&&(o.style.display="none"),r&&(r.style.display="none");let u=document.querySelector(".batch-star-icon"),d=document.getElementById("batch-upnext");if(!i&&u&&s){let f=n.tickets.filter(M=>n.selectedIds.has(M.id)),k=f.every(M=>M.up_next),x=f.every(M=>!M.up_next);k?(u.textContent="\u2605",d.classList.add("active"),d.classList.remove("mixed")):x?(u.textContent="\u2606",d.classList.remove("active","mixed")):(u.innerHTML=c("span",{className:"star-mixed-wrap",children:[c("span",{className:"star-mixed-fill",children:"\u2605"}),"\u2606"]}).toString(),d.classList.remove("active"),d.classList.add("mixed"))}else u&&(u.textContent="\u2606",d.classList.remove("active","mixed"));A()}async function m(){if(n.backupPreview?.active){wt();return}let e=new URLSearchParams;n.view==="trash"?e.set("status","deleted"):n.view==="up-next"?e.set("up_next","true"):n.view==="open"?e.set("status","open"):n.view==="completed"?e.set("status","completed"):n.view==="non-verified"?e.set("status","non_verified"):n.view==="verified"?e.set("status","verified"):n.view==="backlog"?e.set("status","backlog"):n.view==="archive"?e.set("status","archive"):n.view.startsWith("category:")?e.set("category",n.view.split(":")[1]):n.view.startsWith("priority:")?e.set("priority",n.view.split(":")[1]):e.set("status","active"),n.search&&e.set("search",n.search),e.set("sort_by",n.sortBy),e.set("sort_dir",n.sortDir);let t=e.toString();n.tickets=await p(`/tickets${t?"?"+t:""}`),v()}function wt(){let e=[...n.backupPreview?.tickets||[]];if(n.view==="trash")e=e.filter(t=>t.status==="deleted");else if(n.view==="up-next")e=e.filter(t=>t.up_next&&t.status!=="deleted");else if(n.view==="open")e=e.filter(t=>t.status==="not_started"||t.status==="started");else if(n.view==="completed")e=e.filter(t=>t.status==="completed");else if(n.view==="non-verified")e=e.filter(t=>t.status!=="verified"&&t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");else if(n.view==="verified")e=e.filter(t=>t.status==="verified");else if(n.view==="backlog")e=e.filter(t=>t.status==="backlog");else if(n.view==="archive")e=e.filter(t=>t.status==="archive");else if(n.view.startsWith("category:")){let t=n.view.split(":")[1];e=e.filter(s=>s.category===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else if(n.view.startsWith("priority:")){let t=n.view.split(":")[1];e=e.filter(s=>s.priority===t&&s.status!=="deleted"&&s.status!=="backlog"&&s.status!=="archive")}else e=e.filter(t=>t.status!=="deleted"&&t.status!=="backlog"&&t.status!=="archive");if(n.search){let t=n.search.toLowerCase();e=e.filter(s=>s.title.toLowerCase().includes(t)||s.ticket_number.toLowerCase().includes(t)||s.details&&s.details.toLowerCase().includes(t))}n.tickets=e,v()}function Lt(e){let t=Date.now()-new Date(e).getTime(),s=Math.floor(t/6e4);if(s<1)return"just now";if(s<60)return`${s}m ago`;let i=Math.floor(s/60);return i<24?`${i}h ago`:`${Math.floor(i/24)}d ago`}function xt(e){return e<1024?`${e} B`:e<1024*1024?`${(e/1024).toFixed(0)} KB`:`${(e/(1024*1024)).toFixed(1)} MB`}function St(e){return e==="5min"?"Recent (every 5 min)":e==="hourly"?"Hourly":e==="daily"?"Daily":e}async function ue(){var t;let e=document.getElementById("backup-list");if(e)try{let s=await p("/backups");if(s.backups.length===0){e.textContent="No backups yet. First backup will be created shortly.";return}let i={};for(let a of s.backups)(i[t=a.tier]||(i[t]=[])).push(a);e.innerHTML="";for(let a of["5min","hourly","daily"]){let l=i[a];if(!(!l||l.length===0)){e.appendChild(y(c("div",{className:"backup-tier-label",children:St(a)})));for(let o of l){let r=y(c("div",{className:"backup-row","data-tier":o.tier,"data-filename":o.filename,children:[c("span",{className:"backup-row-time",children:Lt(o.createdAt)}),c("span",{className:"backup-row-meta",children:[new Date(o.createdAt).toLocaleString()," \xB7 ",xt(o.sizeBytes)]})]}));r.addEventListener("click",()=>{_t(o.tier,o.filename,o.createdAt)}),e.appendChild(r)}}}}catch{e.textContent="Failed to load backups."}}async function _t(e,t,s){let i=document.getElementById("settings-overlay");i.style.display="none";let a=document.getElementById("backup-preview-banner"),l=document.getElementById("backup-preview-label");l.textContent="Loading backup preview...",a.style.display="flex";try{let o=await p(`/backups/preview/${e}/${t}`);n.backupPreview={active:!0,tickets:o.tickets,timestamp:s,tier:e,filename:t},n.selectedIds.clear(),n.activeTicketId=null,l.textContent=`Previewing backup from ${new Date(s).toLocaleString()} (${o.stats.total} tickets, ${o.stats.open} open) \u2014 read-only`,m()}catch{l.textContent="Failed to load backup preview.",setTimeout(()=>{a.style.display="none"},3e3)}}async function Ct(){let e=document.getElementById("backup-preview-banner");e.style.display="none",n.backupPreview=null,n.selectedIds.clear(),n.activeTicketId=null,await p("/backups/preview/cleanup",{method:"POST"}),m()}async function Bt(){if(!n.backupPreview)return;let e=document.getElementById("backup-restore-btn");e.textContent="Restoring...",e.disabled=!0;try{await p("/backups/restore",{method:"POST",body:{tier:n.backupPreview.tier,filename:n.backupPreview.filename}}),window.location.reload()}catch{e.textContent="Restore failed",e.disabled=!1,setTimeout(()=>{e.textContent="Restore This Backup"},3e3)}}function Fe(){document.getElementById("backup-cancel-btn")?.addEventListener("click",()=>{Ct()}),document.getElementById("backup-restore-btn")?.addEventListener("click",()=>{Bt()});let e=document.getElementById("backup-now-btn");e?.addEventListener("click",async()=>{e.textContent="Backing up...",e.disabled=!0;try{(await p("/backups/now",{method:"POST"})).error?e.textContent="In progress...":(e.textContent="Done!",ue())}catch{e.textContent="Failed"}setTimeout(()=>{e.textContent="Backup Now",e.disabled=!1},1500)})}async function Mt(){await Ht(),Nt(),await m(),Ot(),Ut(),qt(),Ft(),zt(),Vt(),jt(),Gt(),Dt(),Fe(),$t(),Rt(),we(),Yt(),Pt(),document.addEventListener("hotsheet:render",()=>v()),I()}async function Ht(){try{let e=await p("/settings");(e.detail_position==="side"||e.detail_position==="bottom")&&(n.settings.detail_position=e.detail_position),e.detail_width&&(n.settings.detail_width=parseInt(e.detail_width,10)||360),e.detail_height&&(n.settings.detail_height=parseInt(e.detail_height,10)||300),e.trash_cleanup_days&&(n.settings.trash_cleanup_days=parseInt(e.trash_cleanup_days,10)||3),e.verified_cleanup_days&&(n.settings.verified_cleanup_days=parseInt(e.verified_cleanup_days,10)||30),(e.layout==="list"||e.layout==="columns")&&(n.layout=e.layout)}catch{}ae(n.settings.detail_position),ie()}async function Nt(){try{let e=await p("/file-settings");if(e.appName){document.title=e.appName;let t=document.querySelector(".app-title h1");t&&(t.textContent=e.appName)}}catch{}}function Dt(){let e=document.getElementById("settings-overlay"),t=document.getElementById("settings-close");document.getElementById("settings-btn").addEventListener("click",()=>{document.getElementById("settings-trash-days").value=String(n.settings.trash_cleanup_days),document.getElementById("settings-verified-days").value=String(n.settings.verified_cleanup_days),e.style.display="flex",ue(),p("/file-settings").then(g=>{document.getElementById("settings-app-name").value=g.appName||"",document.getElementById("settings-backup-dir").value=g.backupDir||""})}),t.addEventListener("click",()=>{e.style.display="none"}),e.addEventListener("click",g=>{g.target===e&&(e.style.display="none")});let i=document.getElementById("settings-trash-days"),a=null;i.addEventListener("input",()=>{a&&clearTimeout(a),a=setTimeout(()=>{let g=Math.max(1,parseInt(i.value,10)||3);i.value=String(g),n.settings.trash_cleanup_days=g,p("/settings",{method:"PATCH",body:{trash_cleanup_days:String(g)}})},500)});let l=document.getElementById("settings-verified-days"),o=null;l.addEventListener("input",()=>{o&&clearTimeout(o),o=setTimeout(()=>{let g=Math.max(1,parseInt(l.value,10)||30);l.value=String(g),n.settings.verified_cleanup_days=g,p("/settings",{method:"PATCH",body:{verified_cleanup_days:String(g)}})},500)});let r=document.getElementById("settings-app-name"),u=document.getElementById("settings-app-name-hint"),d=null;r.addEventListener("input",()=>{d&&clearTimeout(d),d=setTimeout(()=>{let g=r.value.trim();p("/file-settings",{method:"PATCH",body:{appName:g}}).then(()=>{let N=g||"Hot Sheet";document.title=N;let ye=document.querySelector(".app-title h1");ye&&(ye.textContent=N),u.textContent=g?"Saved. Restart the desktop app to update the title bar.":"Using default name."})},800)});let f=document.getElementById("check-updates-btn"),k=document.getElementById("check-updates-status");f.addEventListener("click",async()=>{let g=ge();if(g){f.disabled=!0,f.textContent="Checking...",k.textContent="";try{let N=await g("check_for_update");N?(k.textContent=`Update available: v${N}`,document.getElementById("settings-overlay").style.display="none",We(N)):k.textContent="Your software is up to date."}catch{k.textContent="Could not check for updates."}f.textContent="Check for Updates",f.disabled=!1}});let x=document.getElementById("settings-backup-dir"),M=document.getElementById("settings-backup-dir-hint"),Q=null;x.addEventListener("input",()=>{Q&&clearTimeout(Q),Q=setTimeout(()=>{let g=x.value.trim();p("/file-settings",{method:"PATCH",body:{backupDir:g}}).then(()=>{M.textContent=g?"Saved. New backups will use this location.":"Using default location inside the data directory."})},800)})}async function Pt(){let e=ge();if(!e)return;let t=document.getElementById("settings-updates-section");t&&(t.style.display="");let s=[0,3e3,1e4];for(let i of s){i>0&&await new Promise(a=>setTimeout(a,i));try{let a=await e("get_pending_update");if(a){We(a);return}}catch{return}}}function ge(){return window.__TAURI__?.core?.invoke??null}function We(e){let t=document.getElementById("update-banner");if(!t)return;let s=document.getElementById("update-banner-label");s&&(s.textContent=`Update available: v${e}`),t.style.display="flex";let i=document.getElementById("update-install-btn");i?.addEventListener("click",async()=>{if(i){i.textContent="Installing...",i.disabled=!0;try{await ge()?.("install_update"),s&&(s.textContent="Update installed! Restart the app to apply."),i.style.display="none"}catch{i.textContent="Install Failed",i.disabled=!1}}}),document.getElementById("update-banner-dismiss")?.addEventListener("click",()=>{t.style.display="none"})}function At(){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 $t(){let e=document.getElementById("copy-prompt-section"),t=document.getElementById("copy-prompt-btn"),s=document.getElementById("copy-prompt-label"),i=document.getElementById("copy-prompt-icon"),a="";p("/worklist-info").then(l=>{a=l.prompt,e.style.display="",l.skillCreated&&At()}),t.addEventListener("click",()=>{a!==""&&navigator.clipboard.writeText(a).then(()=>{s.textContent="Copied!",i.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(()=>{s.textContent="Copy AI prompt",i.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 Rt(){let e=document.getElementById("glassbox-btn"),t=document.getElementById("glassbox-icon");p("/glassbox/status").then(({available:s})=>{s&&(t.src="/static/assets/glassbox-icon.png",e.style.display="")}).catch(()=>{}),e.addEventListener("click",()=>{p("/glassbox/launch",{method:"POST"})})}function fe(){let e=document.getElementById("layout-toggle"),t=X(),s=e.querySelector('[data-layout="columns"]');s.disabled=!t,s.style.opacity=t?"":"0.3";let i=n.layout==="columns"&&!t?"list":n.layout;e.querySelectorAll(".layout-btn").forEach(a=>{a.classList.toggle("active",a.dataset.layout===i)})}function Ut(){document.getElementById("layout-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.layout;s==="columns"&&!X()||(n.layout=s,fe(),v(),p("/settings",{method:"PATCH",body:{layout:s}}))})}),fe()}function ze(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.classList.toggle("active",t.dataset.position===n.settings.detail_position)})}function qt(){document.getElementById("detail-position-toggle").querySelectorAll(".layout-btn").forEach(t=>{t.addEventListener("click",()=>{let s=t.dataset.position;n.settings.detail_position=s,ae(s),ie(),ze(),p("/settings",{method:"PATCH",body:{detail_position:s}})})}),ze()}function Je(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 Kt(e,t){let s=Je(e);if(!s)return;let i=n.tickets.filter(a=>t.includes(a.id));s.action==="delete"?await b(i,{ids:t,action:"delete"},"Delete tickets"):await b(i,{ids:t,action:s.action,value:s.value},`Change ${s.action}`),m()}function Ot(){let e=document.querySelectorAll(".sidebar-item[data-view]");e.forEach(t=>{t.addEventListener("click",()=>{e.forEach(i=>{i.classList.remove("active")}),t.classList.add("active"),n.view=t.dataset.view,n.selectedIds.clear(),fe(),m()});let s=t.dataset.view;Je(s)&&(t.addEventListener("dragover",i=>{i.preventDefault(),i.dataTransfer.dropEffect="move",t.classList.add("drop-target")}),t.addEventListener("dragleave",()=>{t.classList.remove("drop-target")}),t.addEventListener("drop",i=>{i.preventDefault(),t.classList.remove("drop-target");let a=[...E];a.length!==0&&Kt(s,a)}))})}function Ft(){let e=document.getElementById("sort-select");e.addEventListener("change",()=>{let[t,s]=e.value.split(":");n.sortBy=t,n.sortDir=s,m()})}var pe=null;function zt(){let e=document.getElementById("search-input");e.addEventListener("input",()=>{pe&&clearTimeout(pe),pe=setTimeout(()=>{n.search=e.value,m()},200)}),e.addEventListener("keydown",t=>{t.key==="Escape"&&(e.value="",n.search="",m())})}function Vt(){let e=document.getElementById("batch-category");e.addEventListener("change",async()=>{if(!e.value)return;let a=Array.from(n.selectedIds),l=n.tickets.filter(o=>n.selectedIds.has(o.id));await b(l,{ids:a,action:"category",value:e.value},"Batch change category"),e.value="",m()});let t=document.getElementById("batch-priority");t.addEventListener("change",async()=>{if(!t.value)return;let a=Array.from(n.selectedIds),l=n.tickets.filter(o=>n.selectedIds.has(o.id));await b(l,{ids:a,action:"priority",value:t.value},"Batch change priority"),t.value="",m()});let s=document.getElementById("batch-status");s.addEventListener("change",async()=>{if(!s.value)return;let a=Array.from(n.selectedIds),l=n.tickets.filter(o=>n.selectedIds.has(o.id));await b(l,{ids:a,action:"status",value:s.value},"Batch change status"),s.value="",m()}),document.getElementById("batch-upnext").addEventListener("click",async()=>{let a=n.tickets.filter(u=>n.selectedIds.has(u.id)),o=!a.every(u=>u.up_next),r=Array.from(n.selectedIds);if(o){let u=a.filter(d=>d.status==="completed"||d.status==="verified");if(u.length>0){let d=[{ids:u.map(f=>f.id),action:"status",value:"not_started"},{ids:r,action:"up_next",value:!0}];await le(a,d,"Batch toggle up next")}else await b(a,{ids:r,action:"up_next",value:!0},"Batch toggle up next")}else await b(a,{ids:r,action:"up_next",value:!1},"Batch toggle up next");m()}),document.getElementById("batch-delete").addEventListener("click",async()=>{let a=Array.from(n.selectedIds),l=n.tickets.filter(o=>n.selectedIds.has(o.id));await b(l,{ids:a,action:"delete"},"Batch delete"),n.selectedIds.clear(),m()});let i=document.getElementById("batch-more");i.addEventListener("click",a=>{a.stopPropagation(),U();let l=R(i,[{label:"Duplicate",key:"d",action:async()=>{let o=Array.from(n.selectedIds),r=await p("/tickets/duplicate",{method:"POST",body:{ids:o}});n.selectedIds.clear();for(let u of r)n.selectedIds.add(u.id);m()}},{label:"Move to Backlog",key:"b",action:async()=>{let o=Array.from(n.selectedIds),r=n.tickets.filter(u=>n.selectedIds.has(u.id));await b(r,{ids:o,action:"status",value:"backlog"},"Move to backlog"),n.selectedIds.clear(),m()}},{label:"Archive",key:"a",action:async()=>{let o=Array.from(n.selectedIds),r=n.tickets.filter(u=>n.selectedIds.has(u.id));await b(r,{ids:o,action:"status",value:"archive"},"Archive"),n.selectedIds.clear(),m()}}]);document.body.appendChild(l),$(l,i),l.style.visibility=""}),document.getElementById("batch-select-all").addEventListener("change",a=>{if(a.target.checked)for(let o of n.tickets)n.selectedIds.add(o.id);else n.selectedIds.clear();v()})}var L=null;function jt(){document.getElementById("detail-close").addEventListener("click",Ee);let e=["detail-title","detail-details"];for(let s of e){let i=document.getElementById(s);i.addEventListener("input",()=>{let a=n.tickets.find(l=>l.id===n.activeTicketId);if(a){let l=s.replace("detail-","");G(a,l,i.value)}L&&clearTimeout(L),L=setTimeout(()=>{if(n.activeTicketId==null)return;let l=s.replace("detail-","");p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[l]:i.value}}).then(()=>{m()})},300)})}let t=["detail-category","detail-priority","detail-status"];for(let s of t){let i=document.getElementById(s);i.addEventListener("change",async()=>{if(n.activeTicketId==null)return;let a=n.tickets.find(o=>o.id===n.activeTicketId),l=s.replace("detail-","");a?await T(a,{[l]:i.value},`Change ${l}`):await p(`/tickets/${n.activeTicketId}`,{method:"PATCH",body:{[l]:i.value}}),m()})}document.getElementById("detail-upnext").addEventListener("change",async()=>{if(n.activeTicketId==null)return;let s=n.tickets.find(a=>a.id===n.activeTicketId),i=document.getElementById("detail-upnext");s?i.checked&&(s.status==="completed"||s.status==="verified")?await T(s,{status:"not_started",up_next:!0},"Toggle up next"):await T(s,{up_next:!s.up_next},"Toggle up next"):await p(`/tickets/${n.activeTicketId}/up-next`,{method:"POST"}),m(),W(n.activeTicketId)}),document.getElementById("detail-file-input").addEventListener("change",async s=>{let i=s.target,a=i.files?.[0];!a||n.activeTicketId==null||(await ke(`/tickets/${n.activeTicketId}/attachments`,a),i.value="",W(n.activeTicketId),m())}),document.getElementById("detail-attachments").addEventListener("click",async s=>{let i=s.target,a=i.closest(".attachment-reveal");if(a){let r=a.dataset.attId;r&&p(`/attachments/${r}/reveal`,{method:"POST"});return}let l=i.closest(".attachment-delete");if(l===null)return;let o=l.dataset.attId;o===void 0||o===""||(await p(`/attachments/${o}`,{method:"DELETE"}),n.activeTicketId!=null&&W(n.activeTicketId))})}function Wt(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 Jt(e){let t=[];t.push(`${e.ticket_number}: ${e.title}`),e.details.trim()&&(t.push(""),t.push(e.details.trim()));let s=Wt(e.notes);if(s.length>0){t.push("");for(let i of s)t.push(`- ${i.text}`)}return t.join(`
|
|
2
|
+
`)}function Ve(){console.log("[undo] triggerUndo called, canUndo:",Be()),L&&(clearTimeout(L),L=null),de(),_e().then(()=>console.log("[undo] performUndo completed")).catch(e=>console.error("[undo] performUndo error:",e))}function je(){console.log("[undo] triggerRedo called, canRedo:",Me()),L&&(clearTimeout(L),L=null),de(),Ce().then(()=>console.log("[undo] performRedo completed")).catch(e=>console.error("[undo] performRedo error:",e))}function Gt(){window.addEventListener("app:undo",Ve),window.addEventListener("app:redo",je),document.addEventListener("keydown",e=>{(e.metaKey||e.ctrlKey)&&e.key.toLowerCase()==="z"&&(e.preventDefault(),e.stopPropagation(),e.shiftKey?je():Ve())},!0),document.addEventListener("keydown",e=>{let t=e.target.tagName,s=t==="INPUT"||t==="TEXTAREA"||t==="SELECT",i=document.getElementById("settings-overlay");if(e.key==="Escape"&&i.style.display!=="none"){i.style.display="none";return}if(e.key==="Escape"){n.selectedIds.size>0&&(n.selectedIds.clear(),v());return}if((e.metaKey||e.ctrlKey)&&e.key==="a"&&!s){e.preventDefault(),n.selectedIds.clear();for(let a of n.tickets)n.selectedIds.add(a.id);v();return}if((e.metaKey||e.ctrlKey)&&e.key==="d"){if(n.selectedIds.size>0){e.preventDefault();let a=n.tickets.filter(u=>n.selectedIds.has(u.id)),o=!a.every(u=>u.up_next),r=Array.from(n.selectedIds);if(o){let u=a.filter(d=>d.status==="completed"||d.status==="verified");if(u.length>0){le(a,[{ids:u.map(d=>d.id),action:"status",value:"not_started"},{ids:r,action:"up_next",value:!0}],"Toggle up next").then(()=>{m()});return}}b(a,{ids:r,action:"up_next",value:o},"Toggle up next").then(()=>{m()})}return}if((e.metaKey||e.ctrlKey)&&e.key==="c"&&n.selectedIds.size>0&&!(s&&!e.altKey)){let a=!e.altKey&&window.getSelection();if(!(a&&!a.isCollapsed&&a.toString().trim()!=="")){e.preventDefault();let o=n.tickets.filter(r=>n.selectedIds.has(r.id)).map(Jt).join(`
|
|
3
3
|
|
|
4
|
-
`);navigator.clipboard.writeText(
|
|
4
|
+
`);navigator.clipboard.writeText(o);return}}if((e.metaKey||e.ctrlKey)&&e.key==="n"){e.preventDefault(),I();return}if((e.metaKey||e.ctrlKey)&&e.key==="f"){e.preventDefault(),document.getElementById("search-input").focus();return}if(e.key==="n"&&!s){e.preventDefault(),I();return}})}var me=0;function Yt(){async function e(){try{let t=await p(`/poll?version=${me}`);t.version>me&&(me=t.version,n.backupPreview?.active||m())}catch{await new Promise(t=>setTimeout(t,5e3))}setTimeout(e,100)}e()}Mt();})();
|
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}.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-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{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);margin-top:8px}.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-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}.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}.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:contents}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{display:flex;gap:16px;width:100%}.detail-bottom .detail-body .detail-fields-row .detail-field{flex:1;min-width:0}.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-upnext-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:14px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-label input[type=checkbox]{width:auto;accent-color:var(--star)}.detail-attachments{margin-bottom:8px}.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-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}.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:480px;max-width:90vw;max-height:85vh;overflow-y:auto}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.settings-header h2{font-size:16px;font-weight:600}.settings-body{padding:20px}.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}.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)}.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{font-size:12px}.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)}.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-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)}.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}.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-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{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);margin-top:8px}.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}.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}.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:contents}.detail-bottom .detail-body{display:flex;flex-wrap:wrap;gap:0 16px;align-content:flex-start}.detail-bottom .detail-body .detail-fields-row{display:flex;gap:16px;width:100%}.detail-bottom .detail-body .detail-fields-row .detail-field{flex:1;min-width:0}.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-upnext-label{display:flex !important;align-items:center;gap:8px;cursor:pointer;font-size:14px !important;font-weight:400 !important;color:var(--text) !important}.detail-upnext-label input[type=checkbox]{width:auto;accent-color:var(--star)}.detail-attachments{margin-bottom:8px}.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-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}.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:480px;max-width:90vw;max-height:85vh;overflow-y:auto}.settings-header{display:flex;align-items:center;justify-content:space-between;padding:16px 20px;border-bottom:1px solid var(--border)}.settings-header h2{font-size:16px;font-weight:600}.settings-body{padding:20px}.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}.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)}.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{font-size:12px}.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)}.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-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)}.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.2.
|
|
3
|
+
"version": "0.2.12",
|
|
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",
|