@hienlh/ppm 0.8.76 → 0.8.77

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.
Files changed (33) hide show
  1. package/CHANGELOG.md +14 -0
  2. package/dist/web/assets/{browser-tab-D5GfU4Ja.js → browser-tab-DQJLMN11.js} +1 -1
  3. package/dist/web/assets/{chat-tab-BJeNwwUM.js → chat-tab-xp4ZqCGD.js} +4 -4
  4. package/dist/web/assets/{code-editor-CTjgdXh2.js → code-editor-De6Xs-Kq.js} +1 -1
  5. package/dist/web/assets/{database-viewer-QzEuetE6.js → database-viewer-CExMyEmq.js} +1 -1
  6. package/dist/web/assets/{diff-viewer-CvZ06EAH.js → diff-viewer-C7EECdwr.js} +1 -1
  7. package/dist/web/assets/git-graph-DqFYj10H.js +1 -0
  8. package/dist/web/assets/index-CiuAeXR3.js +37 -0
  9. package/dist/web/assets/keybindings-store-DYgvd7L0.js +1 -0
  10. package/dist/web/assets/{markdown-renderer-BVxlq4zO.js → markdown-renderer-CnBEa3kk.js} +1 -1
  11. package/dist/web/assets/{postgres-viewer-DP0FOQOa.js → postgres-viewer-DvMnxJ7g.js} +1 -1
  12. package/dist/web/assets/{settings-tab-CcmhnYpw.js → settings-tab-C0ltpIWq.js} +1 -1
  13. package/dist/web/assets/{sqlite-viewer-4a4hHLZk.js → sqlite-viewer-DR9KKOhW.js} +1 -1
  14. package/dist/web/assets/tab-store-BJw7OCmy.js +1 -0
  15. package/dist/web/assets/{terminal-tab-CKsBIgnq.js → terminal-tab-B__sTLzq.js} +1 -1
  16. package/dist/web/assets/{use-monaco-theme-BwIb9BHq.js → use-monaco-theme-BZiSwNRE.js} +1 -1
  17. package/dist/web/index.html +2 -2
  18. package/dist/web/sw.js +1 -1
  19. package/docs/code-standards.md +126 -0
  20. package/docs/project-changelog.md +36 -1
  21. package/docs/system-architecture.md +35 -3
  22. package/package.json +1 -1
  23. package/src/server/routes/project-scoped.ts +2 -0
  24. package/src/server/routes/workspace.ts +35 -0
  25. package/src/services/db.service.ts +37 -1
  26. package/src/web/app.tsx +37 -35
  27. package/src/web/hooks/use-url-sync.ts +173 -21
  28. package/src/web/stores/panel-store.ts +63 -9
  29. package/src/web/stores/panel-utils.ts +145 -3
  30. package/dist/web/assets/git-graph-BQqdvSjX.js +0 -1
  31. package/dist/web/assets/index-5a-tMkk5.js +0 -37
  32. package/dist/web/assets/keybindings-store-zY8zbJ2c.js +0 -1
  33. package/dist/web/assets/tab-store-BCfMgMKM.js +0 -1
@@ -1,2 +1,2 @@
1
1
  const __vite__mapDeps=(i,m=__vite__mapDeps,d=(m.f||(m.f=["assets/csv-preview-DLqYtXxt.js","assets/chunk-CFjPhJqf.js","assets/lib-BQ34Db2e.js","assets/react-nm2Ru1Pt.js","assets/jsx-runtime-BRW_vwa9.js","assets/arrow-up--LjUXLEt.js","assets/react-dom-Bpkvzu3U.js"])))=>i.map(i=>d[i]);
2
- import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import"./react-dom-Bpkvzu3U.js";import{n,t as r}from"./jsx-runtime-BRW_vwa9.js";import{t as i}from"./chevron-right-DeV0ehiG.js";import{n as a,t as o}from"./markdown-renderer-BVxlq4zO.js";import{o as s,t as c}from"./tab-store-BCfMgMKM.js";import{t as l}from"./table-C7X5UAEI.js";import{i as u,n as d,t as f}from"./use-monaco-theme-BwIb9BHq.js";import{t as p}from"./preload-helper-uTix4PVD.js";import"./dist-lF8CoYII.js";import{t as m}from"./utils-BNytJOb1.js";import{i as h,r as g,t as _}from"./api-client-BfBM3I7n.js";import{$ as v,E as y,P as b,X as x,at as S,c as C,d as w,et as T,f as E,it as D,l as O,m as k,nt as A,p as j,rt as M,tt as N,u as P}from"./index-5a-tMkk5.js";import"./chunk-GEFDOKGD-BbQkJu8C.js";import"./src-BqX54PbV.js";import"./chunk-7R4GIKGN-BbIFzsIv.js";import"./chunk-HHEYEP7N-HRhYy3kG.js";import"./dist-CSJdAyA9.js";import"./chunk-PU5JKC2W-Dw8ClWch.js";import"./chunk-MX3YWQON-BpS_PtKp.js";import"./chunk-YBOYWFTD-CeU4Q-xC.js";import"./chunk-PQ6SQG4A-D6BTbCQw.js";import"./chunk-KYZI473N-BcUZNnwd.js";import"./chunk-O4XLMI2P-JC6EGoUz.js";import"./chunk-GLR3WWYH-CzYx4w-r.js";import"./chunk-XPW4576I-BPQQBakK.js";var F=n(`file-exclamation-point`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),I=e(t(),1),L=r(),R={ts:M,tsx:M,js:M,jsx:M,py:M,rs:M,go:M,html:M,css:M,scss:M,json:D,md:A,txt:A,yaml:N,yml:N};function z(e,t){return t?v:R[e.split(`.`).pop()?.toLowerCase()??``]??T}function B(e,t){let n=[],r=e;for(let e=0;e<t.length;e++){let i=t[e],a=t.slice(0,e+1).join(`/`),o=r.find(e=>e.name===i);if(n.push({name:i,fullPath:a,node:o??null,siblings:r}),o?.children)r=o.children;else{for(let r=e+1;r<t.length;r++)n.push({name:t[r],fullPath:t.slice(0,r+1).join(`/`),node:null,siblings:[]});break}}return n}function V(e){return[...e].sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1)}function H({filePath:e,projectName:t,tabId:n,className:r}){let a=y(e=>e.tree),{updateTab:o,openTab:s}=c(),l=(0,I.useRef)(null),u=(0,I.useMemo)(()=>B(a,e.split(`/`).filter(Boolean)),[a,e]);(0,I.useEffect)(()=>{l.current&&(l.current.scrollLeft=l.current.scrollWidth)},[u]);function d(e,r){let i=m(e);r.metaKey||r.ctrlKey?s({type:`editor`,title:i,metadata:{filePath:e,projectName:t},projectId:t,closable:!0}):o(n,{title:i,metadata:{filePath:e,projectName:t}})}return(0,L.jsx)(`div`,{ref:l,className:r,children:u.map((e,n)=>(0,L.jsxs)(`div`,{className:`flex items-center shrink-0`,children:[n>0&&(0,L.jsx)(i,{className:`size-3 text-muted-foreground shrink-0 mx-0.5`}),e.siblings.length>0?(0,L.jsx)(U,{segment:e,isLast:n===u.length-1,projectName:t,onFileClick:d}):(0,L.jsx)(`span`,{className:`text-xs text-muted-foreground px-1 py-0.5`,children:e.name})]},e.fullPath))})}function U({segment:e,isLast:t,projectName:n,onFileClick:r}){let i=(0,I.useMemo)(()=>V(e.siblings),[e.siblings]);return(0,L.jsxs)(C,{children:[(0,L.jsx)(k,{asChild:!0,children:(0,L.jsx)(`button`,{type:`button`,className:`text-xs px-1 py-0.5 rounded hover:bg-muted transition-colors truncate max-w-[120px] ${t?`text-foreground font-medium`:`text-muted-foreground`}`,children:e.name})}),(0,L.jsx)(O,{align:`start`,className:`max-h-[300px] p-1`,children:i.map(t=>(0,L.jsx)(W,{node:t,projectName:n,activePath:e.fullPath,onFileClick:r},t.path))})]})}function W({node:e,projectName:t,activePath:n,onFileClick:r}){let i=z(e.name,e.type===`directory`),a=e.path===n;return e.type===`directory`&&e.children&&e.children.length>0?(0,L.jsxs)(w,{children:[(0,L.jsxs)(j,{className:`text-xs gap-1.5 ${a?`bg-muted`:``}`,children:[(0,L.jsx)(i,{className:`size-3.5 shrink-0 text-muted-foreground`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.name})]}),(0,L.jsx)(E,{className:`max-h-[300px] overflow-y-auto p-1`,children:V(e.children).map(e=>(0,L.jsx)(W,{node:e,projectName:t,activePath:n,onFileClick:r},e.path))})]}):(0,L.jsxs)(P,{className:`text-xs gap-1.5 cursor-pointer ${a?`bg-muted`:``}`,onSelect:e=>{},onClick:t=>{e.type!==`directory`&&r(e.path,t)},children:[(0,L.jsx)(i,{className:`size-3.5 shrink-0 text-muted-foreground`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.name})]})}function G({active:e,onClick:t,icon:n,label:r}){return(0,L.jsxs)(`button`,{type:`button`,onClick:t,className:`flex items-center gap-1 px-2 py-1 rounded text-xs transition-colors ${e?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:[(0,L.jsx)(n,{className:`size-3`}),(0,L.jsx)(`span`,{className:`hidden sm:inline`,children:r})]})}function K({ext:e,mdMode:t,onMdModeChange:n,csvMode:r,onCsvModeChange:i,wordWrap:o,onToggleWordWrap:s,className:c}){return(0,L.jsxs)(`div`,{className:c,children:[(e===`md`||e===`mdx`)&&n&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{active:t===`edit`,onClick:()=>n(`edit`),icon:a,label:`Edit`}),(0,L.jsx)(G,{active:t===`preview`,onClick:()=>n(`preview`),icon:S,label:`Preview`})]}),e===`csv`&&i&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{active:r===`table`,onClick:()=>i(`table`),icon:l,label:`Table`}),(0,L.jsx)(G,{active:r===`raw`,onClick:()=>i(`raw`),icon:a,label:`Raw`})]}),(0,L.jsx)(G,{active:o,onClick:s,icon:u,label:`Wrap`})]})}var q=(0,I.lazy)(()=>p(()=>import(`./csv-preview-DLqYtXxt.js`).then(e=>({default:e.CsvPreview})),__vite__mapDeps([0,1,2,3,4,5,6]))),J=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`svg`,`ico`]),Y=new Set([`db`,`sqlite`,`sqlite3`]);function X(e){return e.split(`.`).pop()?.toLowerCase()??``}function ee(e){return{js:`javascript`,jsx:`javascript`,ts:`typescript`,tsx:`typescript`,py:`python`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,mdx:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,bash:`shell`}[X(e)]??`plaintext`}function Z({metadata:e,tabId:t}){let n=e?.filePath,r=e?.projectName,[i,a]=(0,I.useState)(null),[o,s]=(0,I.useState)(`utf-8`),[l,u]=(0,I.useState)(!0),[p,g]=(0,I.useState)(null),[v,y]=(0,I.useState)(!1),S=(0,I.useRef)(null),C=(0,I.useRef)(``),w=(0,I.useRef)(null),{tabs:T,updateTab:E}=c(),{wordWrap:D,toggleWordWrap:O}=b(),k=f(),A=T.find(e=>e.id===t),j=n?X(n):``,M=J.has(j),N=j===`pdf`,P=Y.has(j),R=j===`md`||j===`mdx`,z=j===`csv`,[B,V]=(0,I.useState)(`preview`),[U,W]=(0,I.useState)(`table`);(0,I.useEffect)(()=>{P&&t&&E(t,{type:`sqlite`})},[P,t,E]);let G=n?/^(\/|[A-Za-z]:[/\\])/.test(n):!1;(0,I.useEffect)(()=>{if(!n||!G&&!r)return;if(M||N){u(!1);return}u(!0),g(null);let e=G?`/api/fs/read?path=${encodeURIComponent(n)}`:`${h(r)}/files/read?path=${encodeURIComponent(n)}`;return _.get(e).then(e=>{a(e.content),e.encoding&&s(e.encoding),C.current=e.content,u(!1)}).catch(e=>{g(e instanceof Error?e.message:`Failed to load file`),u(!1)}),()=>{S.current&&clearTimeout(S.current)}},[n,r,M,N,G]),(0,I.useEffect)(()=>{if(!A)return;let e=n?m(n):`Untitled`,t=v?`${e} \u25CF`:e;A.title!==t&&E(A.id,{title:t})},[v]);let Z=(0,I.useCallback)(async e=>{if(n&&!(!G&&!r))try{G?await _.put(`/api/fs/write`,{path:n,content:e}):await _.put(`${h(r)}/files/write`,{path:n,content:e}),y(!1)}catch{}},[n,r,G]);function Q(e){let t=e??``;a(t),C.current=t,y(!0),S.current&&clearTimeout(S.current),S.current=setTimeout(()=>Z(C.current),1e3)}let $=e?.lineNumber,ie=(0,I.useCallback)((e,t)=>{w.current=e,$&&$>0&&setTimeout(()=>{e.revealLineInCenter($),e.setPosition({lineNumber:$,column:1}),e.focus()},100),e.addCommand(t.KeyMod.Alt|t.KeyCode.KeyZ,()=>b.getState().toggleWordWrap()),t.languages.typescript.typescriptDefaults.setDiagnosticsOptions({noSemanticValidation:!0,noSyntaxValidation:!0,noSuggestionDiagnostics:!0}),t.languages.typescript.javascriptDefaults.setDiagnosticsOptions({noSemanticValidation:!0,noSyntaxValidation:!0,noSuggestionDiagnostics:!0})},[]);return!n||!G&&!r?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full text-text-secondary text-sm`,children:`No file selected.`}):l?(0,L.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-text-secondary`,children:[(0,L.jsx)(x,{className:`size-5 animate-spin`}),(0,L.jsx)(`span`,{className:`text-sm`,children:`Loading file...`})]}):p?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full text-error text-sm`,children:p}):M?(0,L.jsx)(ne,{filePath:n,projectName:r}):N?(0,L.jsx)(re,{filePath:n,projectName:r}):o===`base64`?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`This file is a binary format and cannot be displayed.`}),(0,L.jsx)(`p`,{className:`text-xs text-text-subtle`,children:n})]}):(0,L.jsxs)(`div`,{className:`flex flex-col h-full w-full overflow-hidden`,children:[n&&r&&t&&(0,L.jsxs)(`div`,{className:`hidden md:flex items-center h-7 border-b border-border bg-background shrink-0`,children:[(0,L.jsx)(H,{filePath:n,projectName:r,tabId:t,className:`flex items-center flex-1 min-w-0 overflow-x-auto scrollbar-none px-2 gap-0.5`}),(0,L.jsx)(K,{ext:j,mdMode:B,onMdModeChange:V,csvMode:U,onCsvModeChange:W,wordWrap:D,onToggleWordWrap:O,className:`shrink-0 flex items-center gap-1 px-2`})]}),z&&U===`table`?(0,L.jsx)(I.Suspense,{fallback:(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})}),children:(0,L.jsx)(q,{content:i??``,onContentChange:Q,wordWrap:D})}):R&&B===`preview`?(0,L.jsx)(te,{content:i??``}):(0,L.jsx)(`div`,{className:`flex-1 overflow-hidden`,children:(0,L.jsx)(d,{height:`100%`,language:ee(n),value:i??``,onChange:Q,onMount:ie,theme:k,options:{fontSize:13,fontFamily:`Menlo, Monaco, Consolas, monospace`,wordWrap:D?`on`:`off`,minimap:{enabled:!1},scrollBeyondLastLine:!1,automaticLayout:!0,lineNumbers:`on`,folding:!0,bracketPairColorization:{enabled:!0}},loading:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})})]})}function te({content:e}){return(0,L.jsx)(o,{content:e,className:`flex-1 overflow-auto p-4`})}function ne({filePath:e,projectName:t}){let[n,r]=(0,I.useState)(null),[i,a]=(0,I.useState)(!1);return(0,I.useEffect)(()=>{let n,i=`${h(t)}/files/raw?path=${encodeURIComponent(e)}`,o=g();return fetch(i,{headers:o?{Authorization:`Bearer ${o}`}:{}}).then(e=>{if(!e.ok)throw Error(`Failed`);return e.blob()}).then(e=>{let t=URL.createObjectURL(e);n=t,r(t)}).catch(()=>a(!0)),()=>{n&&URL.revokeObjectURL(n)}},[e,t]),i?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`Failed to load image.`})]}):n?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,L.jsx)(`img`,{src:n,alt:e,className:`max-w-full max-h-full object-contain`})}):(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})}function re({filePath:e,projectName:t}){let[n,r]=(0,I.useState)(null),[i,a]=(0,I.useState)(!1);(0,I.useEffect)(()=>{let n,i=`${h(t)}/files/raw?path=${encodeURIComponent(e)}`,o=g();return fetch(i,{headers:o?{Authorization:`Bearer ${o}`}:{}}).then(e=>{if(!e.ok)throw Error(`Failed`);return e.blob()}).then(e=>{let t=URL.createObjectURL(new Blob([e],{type:`application/pdf`}));n=t,r(t)}).catch(()=>a(!0)),()=>{n&&URL.revokeObjectURL(n)}},[e,t]);let o=(0,I.useCallback)(()=>{n&&window.open(n,`_blank`)},[n]);return i?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`Failed to load PDF.`})]}):n?(0,L.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-1.5 border-b border-border bg-background shrink-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-text-secondary truncate`,children:e}),(0,L.jsxs)(`button`,{onClick:o,className:`flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary transition-colors`,children:[(0,L.jsx)(s,{className:`size-3`}),` Open in new tab`]})]}),(0,L.jsx)(`iframe`,{src:n,title:e,className:`flex-1 w-full border-none`})]}):(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})}export{Z as CodeEditor};
2
+ import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import"./react-dom-Bpkvzu3U.js";import{n,t as r}from"./jsx-runtime-BRW_vwa9.js";import{t as i}from"./chevron-right-DeV0ehiG.js";import{n as a,t as o}from"./markdown-renderer-CnBEa3kk.js";import{l as s,t as c}from"./tab-store-BJw7OCmy.js";import{t as l}from"./table-C7X5UAEI.js";import{i as u,n as d,t as f}from"./use-monaco-theme-BZiSwNRE.js";import{t as p}from"./preload-helper-uTix4PVD.js";import"./dist-lF8CoYII.js";import{t as m}from"./utils-BNytJOb1.js";import{i as h,r as g,t as _}from"./api-client-BfBM3I7n.js";import{$ as v,E as y,P as b,X as x,at as S,c as C,d as w,et as T,f as E,it as D,l as O,m as k,nt as A,p as j,rt as M,tt as N,u as P}from"./index-CiuAeXR3.js";import"./chunk-GEFDOKGD-BbQkJu8C.js";import"./src-BqX54PbV.js";import"./chunk-7R4GIKGN-BbIFzsIv.js";import"./chunk-HHEYEP7N-HRhYy3kG.js";import"./dist-CSJdAyA9.js";import"./chunk-PU5JKC2W-Dw8ClWch.js";import"./chunk-MX3YWQON-BpS_PtKp.js";import"./chunk-YBOYWFTD-CeU4Q-xC.js";import"./chunk-PQ6SQG4A-D6BTbCQw.js";import"./chunk-KYZI473N-BcUZNnwd.js";import"./chunk-O4XLMI2P-JC6EGoUz.js";import"./chunk-GLR3WWYH-CzYx4w-r.js";import"./chunk-XPW4576I-BPQQBakK.js";var F=n(`file-exclamation-point`,[[`path`,{d:`M6 22a2 2 0 0 1-2-2V4a2 2 0 0 1 2-2h8a2.4 2.4 0 0 1 1.704.706l3.588 3.588A2.4 2.4 0 0 1 20 8v12a2 2 0 0 1-2 2z`,key:`1oefj6`}],[`path`,{d:`M12 9v4`,key:`juzpu7`}],[`path`,{d:`M12 17h.01`,key:`p32p05`}]]),I=e(t(),1),L=r(),R={ts:M,tsx:M,js:M,jsx:M,py:M,rs:M,go:M,html:M,css:M,scss:M,json:D,md:A,txt:A,yaml:N,yml:N};function z(e,t){return t?v:R[e.split(`.`).pop()?.toLowerCase()??``]??T}function B(e,t){let n=[],r=e;for(let e=0;e<t.length;e++){let i=t[e],a=t.slice(0,e+1).join(`/`),o=r.find(e=>e.name===i);if(n.push({name:i,fullPath:a,node:o??null,siblings:r}),o?.children)r=o.children;else{for(let r=e+1;r<t.length;r++)n.push({name:t[r],fullPath:t.slice(0,r+1).join(`/`),node:null,siblings:[]});break}}return n}function V(e){return[...e].sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1)}function H({filePath:e,projectName:t,tabId:n,className:r}){let a=y(e=>e.tree),{updateTab:o,openTab:s}=c(),l=(0,I.useRef)(null),u=(0,I.useMemo)(()=>B(a,e.split(`/`).filter(Boolean)),[a,e]);(0,I.useEffect)(()=>{l.current&&(l.current.scrollLeft=l.current.scrollWidth)},[u]);function d(e,r){let i=m(e);r.metaKey||r.ctrlKey?s({type:`editor`,title:i,metadata:{filePath:e,projectName:t},projectId:t,closable:!0}):o(n,{title:i,metadata:{filePath:e,projectName:t}})}return(0,L.jsx)(`div`,{ref:l,className:r,children:u.map((e,n)=>(0,L.jsxs)(`div`,{className:`flex items-center shrink-0`,children:[n>0&&(0,L.jsx)(i,{className:`size-3 text-muted-foreground shrink-0 mx-0.5`}),e.siblings.length>0?(0,L.jsx)(U,{segment:e,isLast:n===u.length-1,projectName:t,onFileClick:d}):(0,L.jsx)(`span`,{className:`text-xs text-muted-foreground px-1 py-0.5`,children:e.name})]},e.fullPath))})}function U({segment:e,isLast:t,projectName:n,onFileClick:r}){let i=(0,I.useMemo)(()=>V(e.siblings),[e.siblings]);return(0,L.jsxs)(C,{children:[(0,L.jsx)(k,{asChild:!0,children:(0,L.jsx)(`button`,{type:`button`,className:`text-xs px-1 py-0.5 rounded hover:bg-muted transition-colors truncate max-w-[120px] ${t?`text-foreground font-medium`:`text-muted-foreground`}`,children:e.name})}),(0,L.jsx)(O,{align:`start`,className:`max-h-[300px] p-1`,children:i.map(t=>(0,L.jsx)(W,{node:t,projectName:n,activePath:e.fullPath,onFileClick:r},t.path))})]})}function W({node:e,projectName:t,activePath:n,onFileClick:r}){let i=z(e.name,e.type===`directory`),a=e.path===n;return e.type===`directory`&&e.children&&e.children.length>0?(0,L.jsxs)(w,{children:[(0,L.jsxs)(j,{className:`text-xs gap-1.5 ${a?`bg-muted`:``}`,children:[(0,L.jsx)(i,{className:`size-3.5 shrink-0 text-muted-foreground`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.name})]}),(0,L.jsx)(E,{className:`max-h-[300px] overflow-y-auto p-1`,children:V(e.children).map(e=>(0,L.jsx)(W,{node:e,projectName:t,activePath:n,onFileClick:r},e.path))})]}):(0,L.jsxs)(P,{className:`text-xs gap-1.5 cursor-pointer ${a?`bg-muted`:``}`,onSelect:e=>{},onClick:t=>{e.type!==`directory`&&r(e.path,t)},children:[(0,L.jsx)(i,{className:`size-3.5 shrink-0 text-muted-foreground`}),(0,L.jsx)(`span`,{className:`truncate`,children:e.name})]})}function G({active:e,onClick:t,icon:n,label:r}){return(0,L.jsxs)(`button`,{type:`button`,onClick:t,className:`flex items-center gap-1 px-2 py-1 rounded text-xs transition-colors ${e?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:[(0,L.jsx)(n,{className:`size-3`}),(0,L.jsx)(`span`,{className:`hidden sm:inline`,children:r})]})}function K({ext:e,mdMode:t,onMdModeChange:n,csvMode:r,onCsvModeChange:i,wordWrap:o,onToggleWordWrap:s,className:c}){return(0,L.jsxs)(`div`,{className:c,children:[(e===`md`||e===`mdx`)&&n&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{active:t===`edit`,onClick:()=>n(`edit`),icon:a,label:`Edit`}),(0,L.jsx)(G,{active:t===`preview`,onClick:()=>n(`preview`),icon:S,label:`Preview`})]}),e===`csv`&&i&&(0,L.jsxs)(L.Fragment,{children:[(0,L.jsx)(G,{active:r===`table`,onClick:()=>i(`table`),icon:l,label:`Table`}),(0,L.jsx)(G,{active:r===`raw`,onClick:()=>i(`raw`),icon:a,label:`Raw`})]}),(0,L.jsx)(G,{active:o,onClick:s,icon:u,label:`Wrap`})]})}var q=(0,I.lazy)(()=>p(()=>import(`./csv-preview-DLqYtXxt.js`).then(e=>({default:e.CsvPreview})),__vite__mapDeps([0,1,2,3,4,5,6]))),J=new Set([`png`,`jpg`,`jpeg`,`gif`,`webp`,`svg`,`ico`]),Y=new Set([`db`,`sqlite`,`sqlite3`]);function X(e){return e.split(`.`).pop()?.toLowerCase()??``}function ee(e){return{js:`javascript`,jsx:`javascript`,ts:`typescript`,tsx:`typescript`,py:`python`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,mdx:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,bash:`shell`}[X(e)]??`plaintext`}function Z({metadata:e,tabId:t}){let n=e?.filePath,r=e?.projectName,[i,a]=(0,I.useState)(null),[o,s]=(0,I.useState)(`utf-8`),[l,u]=(0,I.useState)(!0),[p,g]=(0,I.useState)(null),[v,y]=(0,I.useState)(!1),S=(0,I.useRef)(null),C=(0,I.useRef)(``),w=(0,I.useRef)(null),{tabs:T,updateTab:E}=c(),{wordWrap:D,toggleWordWrap:O}=b(),k=f(),A=T.find(e=>e.id===t),j=n?X(n):``,M=J.has(j),N=j===`pdf`,P=Y.has(j),R=j===`md`||j===`mdx`,z=j===`csv`,[B,V]=(0,I.useState)(`preview`),[U,W]=(0,I.useState)(`table`);(0,I.useEffect)(()=>{P&&t&&E(t,{type:`sqlite`})},[P,t,E]);let G=n?/^(\/|[A-Za-z]:[/\\])/.test(n):!1;(0,I.useEffect)(()=>{if(!n||!G&&!r)return;if(M||N){u(!1);return}u(!0),g(null);let e=G?`/api/fs/read?path=${encodeURIComponent(n)}`:`${h(r)}/files/read?path=${encodeURIComponent(n)}`;return _.get(e).then(e=>{a(e.content),e.encoding&&s(e.encoding),C.current=e.content,u(!1)}).catch(e=>{g(e instanceof Error?e.message:`Failed to load file`),u(!1)}),()=>{S.current&&clearTimeout(S.current)}},[n,r,M,N,G]),(0,I.useEffect)(()=>{if(!A)return;let e=n?m(n):`Untitled`,t=v?`${e} \u25CF`:e;A.title!==t&&E(A.id,{title:t})},[v]);let Z=(0,I.useCallback)(async e=>{if(n&&!(!G&&!r))try{G?await _.put(`/api/fs/write`,{path:n,content:e}):await _.put(`${h(r)}/files/write`,{path:n,content:e}),y(!1)}catch{}},[n,r,G]);function Q(e){let t=e??``;a(t),C.current=t,y(!0),S.current&&clearTimeout(S.current),S.current=setTimeout(()=>Z(C.current),1e3)}let $=e?.lineNumber,ie=(0,I.useCallback)((e,t)=>{w.current=e,$&&$>0&&setTimeout(()=>{e.revealLineInCenter($),e.setPosition({lineNumber:$,column:1}),e.focus()},100),e.addCommand(t.KeyMod.Alt|t.KeyCode.KeyZ,()=>b.getState().toggleWordWrap()),t.languages.typescript.typescriptDefaults.setDiagnosticsOptions({noSemanticValidation:!0,noSyntaxValidation:!0,noSuggestionDiagnostics:!0}),t.languages.typescript.javascriptDefaults.setDiagnosticsOptions({noSemanticValidation:!0,noSyntaxValidation:!0,noSuggestionDiagnostics:!0})},[]);return!n||!G&&!r?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full text-text-secondary text-sm`,children:`No file selected.`}):l?(0,L.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-text-secondary`,children:[(0,L.jsx)(x,{className:`size-5 animate-spin`}),(0,L.jsx)(`span`,{className:`text-sm`,children:`Loading file...`})]}):p?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full text-error text-sm`,children:p}):M?(0,L.jsx)(ne,{filePath:n,projectName:r}):N?(0,L.jsx)(re,{filePath:n,projectName:r}):o===`base64`?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`This file is a binary format and cannot be displayed.`}),(0,L.jsx)(`p`,{className:`text-xs text-text-subtle`,children:n})]}):(0,L.jsxs)(`div`,{className:`flex flex-col h-full w-full overflow-hidden`,children:[n&&r&&t&&(0,L.jsxs)(`div`,{className:`hidden md:flex items-center h-7 border-b border-border bg-background shrink-0`,children:[(0,L.jsx)(H,{filePath:n,projectName:r,tabId:t,className:`flex items-center flex-1 min-w-0 overflow-x-auto scrollbar-none px-2 gap-0.5`}),(0,L.jsx)(K,{ext:j,mdMode:B,onMdModeChange:V,csvMode:U,onCsvModeChange:W,wordWrap:D,onToggleWordWrap:O,className:`shrink-0 flex items-center gap-1 px-2`})]}),z&&U===`table`?(0,L.jsx)(I.Suspense,{fallback:(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})}),children:(0,L.jsx)(q,{content:i??``,onContentChange:Q,wordWrap:D})}):R&&B===`preview`?(0,L.jsx)(te,{content:i??``}):(0,L.jsx)(`div`,{className:`flex-1 overflow-hidden`,children:(0,L.jsx)(d,{height:`100%`,language:ee(n),value:i??``,onChange:Q,onMount:ie,theme:k,options:{fontSize:13,fontFamily:`Menlo, Monaco, Consolas, monospace`,wordWrap:D?`on`:`off`,minimap:{enabled:!1},scrollBeyondLastLine:!1,automaticLayout:!0,lineNumbers:`on`,folding:!0,bracketPairColorization:{enabled:!0}},loading:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})})]})}function te({content:e}){return(0,L.jsx)(o,{content:e,className:`flex-1 overflow-auto p-4`})}function ne({filePath:e,projectName:t}){let[n,r]=(0,I.useState)(null),[i,a]=(0,I.useState)(!1);return(0,I.useEffect)(()=>{let n,i=`${h(t)}/files/raw?path=${encodeURIComponent(e)}`,o=g();return fetch(i,{headers:o?{Authorization:`Bearer ${o}`}:{}}).then(e=>{if(!e.ok)throw Error(`Failed`);return e.blob()}).then(e=>{let t=URL.createObjectURL(e);n=t,r(t)}).catch(()=>a(!0)),()=>{n&&URL.revokeObjectURL(n)}},[e,t]),i?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`Failed to load image.`})]}):n?(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full p-4 bg-surface overflow-auto`,children:(0,L.jsx)(`img`,{src:n,alt:e,className:`max-w-full max-h-full object-contain`})}):(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})}function re({filePath:e,projectName:t}){let[n,r]=(0,I.useState)(null),[i,a]=(0,I.useState)(!1);(0,I.useEffect)(()=>{let n,i=`${h(t)}/files/raw?path=${encodeURIComponent(e)}`,o=g();return fetch(i,{headers:o?{Authorization:`Bearer ${o}`}:{}}).then(e=>{if(!e.ok)throw Error(`Failed`);return e.blob()}).then(e=>{let t=URL.createObjectURL(new Blob([e],{type:`application/pdf`}));n=t,r(t)}).catch(()=>a(!0)),()=>{n&&URL.revokeObjectURL(n)}},[e,t]);let o=(0,I.useCallback)(()=>{n&&window.open(n,`_blank`)},[n]);return i?(0,L.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-text-secondary`,children:[(0,L.jsx)(F,{className:`size-10 text-text-subtle`}),(0,L.jsx)(`p`,{className:`text-sm`,children:`Failed to load PDF.`})]}):n?(0,L.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,L.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-1.5 border-b border-border bg-background shrink-0`,children:[(0,L.jsx)(`span`,{className:`text-xs text-text-secondary truncate`,children:e}),(0,L.jsxs)(`button`,{onClick:o,className:`flex items-center gap-1 text-xs text-text-secondary hover:text-text-primary transition-colors`,children:[(0,L.jsx)(s,{className:`size-3`}),` Open in new tab`]})]}),(0,L.jsx)(`iframe`,{src:n,title:e,className:`flex-1 w-full border-none`})]}):(0,L.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,L.jsx)(x,{className:`size-5 animate-spin text-text-subtle`})})}export{Z as CodeEditor};
@@ -1 +1 @@
1
- import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{t as n}from"./jsx-runtime-BRW_vwa9.js";import{t as r}from"./chevron-right-DeV0ehiG.js";import{a as i,i as a,n as o,r as s,t as c}from"./dist-DylI9XxN.js";import{t as l}from"./api-client-BfBM3I7n.js";import{V as u,X as d,pt as f,st as p}from"./index-5a-tMkk5.js";import{n as m,r as h,t as g}from"./lib-BQ34Db2e.js";var _=e(t(),1);function v(e,t,n,r){return`ppm-db-${e}-${n}.${t}-p${r}`}function y(e,t,n,r){try{let i=sessionStorage.getItem(v(e,t,n,r));return i?JSON.parse(i):null}catch{return null}}function b(e,t,n,r,i,a){try{sessionStorage.setItem(v(e,t,n,r),JSON.stringify({data:i,cols:a}))}catch{}}function x(e){let t=`/api/db/connections/${e}`,[n,r]=(0,_.useState)(null),[i,a]=(0,_.useState)(`public`),[o,s]=(0,_.useState)(null),[c,u]=(0,_.useState)([]),[d,f]=(0,_.useState)(!0),[p,m]=(0,_.useState)(null),[h,g]=(0,_.useState)(1),[v,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(null),[w,T]=(0,_.useState)(!1),E=(0,_.useCallback)(async(r,a,o)=>{let c=r??n,d=a??i;if(c){f(!0);try{let[n,r]=await Promise.all([l.get(`${t}/data?table=${encodeURIComponent(c)}&schema=${d}&page=${o??h}&limit=100`),l.get(`${t}/schema?table=${encodeURIComponent(c)}&schema=${d}`)]);s(n),u(r),b(e,c,d,o??h,n,r)}catch(e){m(e.message)}finally{f(!1)}}},[t,e,n,i,h]);return{selectedTable:n,selectTable:(0,_.useCallback)((t,n=`public`)=>{r(t),a(n),g(1),x(null);let i=y(e,t,n,1);i?(s(i.data),u(i.cols),f(!1),E(t,n,1)):E(t,n,1)},[e,E]),tableData:o,schema:c,loading:d,error:p,page:h,setPage:(0,_.useCallback)(e=>{g(e),E(void 0,void 0,e)},[E]),queryResult:v,queryError:S,queryLoading:w,executeQuery:(0,_.useCallback)(async e=>{T(!0),C(null);try{let r=await l.post(`${t}/query`,{sql:e});x(r),r.changeType===`modify`&&E(n??void 0,i)}catch(e){C(e.message)}finally{T(!1)}},[t,n,i,E]),updateCell:(0,_.useCallback)(async(e,r,a,o)=>{if(!n)return;let s=n,c=i;try{await l.put(`${t}/cell`,{table:s,schema:c,pkColumn:e,pkValue:r,column:a,value:o}),E(s,c)}catch(e){m(e.message)}},[t,n,i,E]),refreshData:E}}var S=n(),C={postgres:c,sqlite:o};function w({metadata:e}){let t=e?.connectionId,n=e?.connectionName,r=e?.dbType??`postgres`,i=e?.tableName,a=e?.schemaName??`public`,o=x(t),[s,l]=(0,_.useState)(!1),d=(0,_.useRef)(!1);return(0,_.useEffect)(()=>{!i||d.current||(d.current=!0,o.selectTable(i,a))},[i,a]),(0,S.jsx)(`div`,{className:`flex h-full w-full overflow-hidden`,children:(0,S.jsxs)(`div`,{className:`flex-1 flex flex-col overflow-hidden`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5 border-b border-border bg-background shrink-0`,children:[(0,S.jsx)(p,{className:`size-3.5 text-muted-foreground`}),(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground truncate`,children:n??`Database`}),o.selectedTable&&(0,S.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`/ `,o.selectedTable]}),(0,S.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,S.jsx)(`button`,{type:`button`,onClick:()=>o.refreshData(),title:`Reload data`,className:`p-1 rounded text-muted-foreground hover:text-foreground transition-colors`,children:(0,S.jsx)(u,{className:`size-3 ${o.loading?`animate-spin`:``}`})}),(0,S.jsx)(`button`,{type:`button`,onClick:()=>l(e=>!e),className:`px-2 py-1 rounded text-xs transition-colors ${s?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:`SQL`})]})]}),(0,S.jsx)(`div`,{className:`flex-1 overflow-hidden ${s?`max-h-[60%]`:``}`,children:(0,S.jsx)(T,{tableData:o.tableData,schema:o.schema,loading:o.loading,page:o.page,onPageChange:o.setPage,onCellUpdate:o.updateCell})}),s&&(0,S.jsx)(`div`,{className:`border-t border-border h-[40%] shrink-0`,children:(0,S.jsx)(E,{dialect:C[r]??c,onExecute:o.executeQuery,result:o.queryResult,error:o.queryError,loading:o.queryLoading})})]})})}function T({tableData:e,schema:t,loading:n,page:i,onPageChange:a,onCellUpdate:o}){let[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),p=(0,_.useMemo)(()=>t.find(e=>e.pk)?.name??null,[t]),v=(0,_.useCallback)((e,t,n)=>{c({rowIdx:e,col:t}),u(n==null?``:String(n))},[]),y=(0,_.useCallback)(()=>{if(!s||!e||!p)return;let t=e.rows[s.rowIdx];if(!t)return;let n=t[s.col];String(n??``)!==l&&o(p,t[p],s.col,l===``?null:l),c(null)},[s,l,e,p,o]),b=(0,_.useCallback)(()=>c(null),[]),x=(0,_.useMemo)(()=>(e?.columns??[]).map(e=>({id:e,accessorFn:t=>t[e],header:()=>(0,S.jsx)(`span`,{className:t.find(t=>t.name===e)?.pk?`font-bold`:``,children:e}),cell:({row:t,getValue:n})=>{let r=s?.rowIdx===t.index&&s?.col===e,i=n();return r?(0,S.jsx)(`input`,{autoFocus:!0,className:`w-full bg-transparent border border-primary/50 rounded px-1 py-0 text-xs outline-none`,value:l,onChange:e=>u(e.target.value),onBlur:y,onKeyDown:e=>{e.key===`Enter`&&y(),e.key===`Escape`&&b()}}):(0,S.jsx)(`span`,{className:`cursor-pointer truncate block ${i==null?`text-muted-foreground/40 italic`:``}`,onDoubleClick:()=>p&&v(t.index,e,i),title:i==null?`NULL`:String(i),children:i==null?`NULL`:String(i)})}})),[e?.columns,t,s,l,y,b,v,p]),C=m({data:e?.rows??[],columns:x,getCoreRowModel:h()});if(!e)return(0,S.jsx)(`div`,{className:`flex items-center justify-center h-full text-xs text-muted-foreground`,children:n?(0,S.jsx)(d,{className:`size-4 animate-spin`}):`Select a table`});let w=Math.ceil(e.total/e.limit)||1;return(0,S.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,S.jsx)(`div`,{className:`flex-1 overflow-auto`,children:(0,S.jsxs)(`table`,{className:`w-full text-xs border-collapse`,children:[(0,S.jsx)(`thead`,{className:`sticky top-0 z-10 bg-muted`,children:C.getHeaderGroups().map(e=>(0,S.jsx)(`tr`,{children:e.headers.map(e=>(0,S.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium text-muted-foreground border-b border-border whitespace-nowrap`,children:g(e.column.columnDef.header,e.getContext())},e.id))},e.id))}),(0,S.jsxs)(`tbody`,{children:[C.getRowModel().rows.map(e=>(0,S.jsx)(`tr`,{className:`hover:bg-muted/30 border-b border-border/50`,children:e.getVisibleCells().map(e=>(0,S.jsx)(`td`,{className:`px-2 py-1 max-w-[300px]`,children:g(e.column.columnDef.cell,e.getContext())},e.id))},e.id)),e.rows.length===0&&(0,S.jsx)(`tr`,{children:(0,S.jsx)(`td`,{colSpan:e.columns.length,className:`px-2 py-8 text-center text-muted-foreground`,children:`No data`})})]})]})}),(0,S.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-1.5 border-t border-border bg-background shrink-0 text-xs text-muted-foreground`,children:[(0,S.jsxs)(`span`,{children:[e.total.toLocaleString(),` rows`]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`button`,{type:`button`,disabled:i<=1,onClick:()=>a(i-1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,S.jsx)(f,{className:`size-3.5`})}),(0,S.jsxs)(`span`,{children:[i,` / `,w]}),(0,S.jsx)(`button`,{type:`button`,disabled:i>=w,onClick:()=>a(i+1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,S.jsx)(r,{className:`size-3.5`})})]})]})]})}function E({dialect:e,onExecute:t,result:n,error:r,loading:o}){let[c,l]=(0,_.useState)(`SELECT * FROM `),u=(0,_.useCallback)(()=>{let e=c.trim();e&&t(e)},[c,t]);return(0,S.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,S.jsxs)(`div`,{className:`flex items-start gap-1 border-b border-border bg-background`,onKeyDown:(0,_.useCallback)(e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),u())},[u]),children:[(0,S.jsx)(`div`,{className:`flex-1 max-h-[120px] overflow-auto`,children:(0,S.jsx)(a,{value:c,onChange:l,extensions:[s({dialect:e})],basicSetup:{lineNumbers:!1,foldGutter:!1,highlightActiveLine:!1},className:`text-xs [&_.cm-editor]:!outline-none [&_.cm-scroller]:!overflow-auto`})}),(0,S.jsx)(`button`,{type:`button`,onClick:u,disabled:o,title:`Execute (Cmd+Enter)`,className:`shrink-0 m-1 p-1.5 rounded bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors`,children:o?(0,S.jsx)(d,{className:`size-3.5 animate-spin`}):(0,S.jsx)(i,{className:`size-3.5`})})]}),(0,S.jsxs)(`div`,{className:`flex-1 overflow-auto text-xs`,children:[r&&(0,S.jsx)(`div`,{className:`px-3 py-2 text-destructive bg-destructive/5`,children:r}),n?.changeType===`modify`&&(0,S.jsxs)(`div`,{className:`px-3 py-2 text-green-500`,children:[`Query executed. `,n.rowsAffected,` row(s) affected.`]}),n?.changeType===`select`&&n.rows.length>0&&(0,S.jsxs)(`table`,{className:`w-full border-collapse`,children:[(0,S.jsx)(`thead`,{className:`sticky top-0 bg-muted`,children:(0,S.jsx)(`tr`,{children:n.columns.map(e=>(0,S.jsx)(`th`,{className:`px-2 py-1 text-left font-medium text-muted-foreground border-b border-border whitespace-nowrap`,children:e},e))})}),(0,S.jsx)(`tbody`,{children:n.rows.map((e,t)=>(0,S.jsx)(`tr`,{className:`hover:bg-muted/30 border-b border-border/50`,children:n.columns.map(t=>(0,S.jsx)(`td`,{className:`px-2 py-1 max-w-[300px] truncate`,title:e[t]==null?`NULL`:String(e[t]),children:e[t]==null?(0,S.jsx)(`span`,{className:`text-muted-foreground/40 italic`,children:`NULL`}):String(e[t])},t))},t))})]}),n?.changeType===`select`&&n.rows.length===0&&(0,S.jsx)(`div`,{className:`px-3 py-2 text-muted-foreground`,children:`No results`})]})]})}export{w as DatabaseViewer};
1
+ import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{t as n}from"./jsx-runtime-BRW_vwa9.js";import{t as r}from"./chevron-right-DeV0ehiG.js";import{a as i,i as a,n as o,r as s,t as c}from"./dist-DylI9XxN.js";import{t as l}from"./api-client-BfBM3I7n.js";import{V as u,X as d,pt as f,st as p}from"./index-CiuAeXR3.js";import{n as m,r as h,t as g}from"./lib-BQ34Db2e.js";var _=e(t(),1);function v(e,t,n,r){return`ppm-db-${e}-${n}.${t}-p${r}`}function y(e,t,n,r){try{let i=sessionStorage.getItem(v(e,t,n,r));return i?JSON.parse(i):null}catch{return null}}function b(e,t,n,r,i,a){try{sessionStorage.setItem(v(e,t,n,r),JSON.stringify({data:i,cols:a}))}catch{}}function x(e){let t=`/api/db/connections/${e}`,[n,r]=(0,_.useState)(null),[i,a]=(0,_.useState)(`public`),[o,s]=(0,_.useState)(null),[c,u]=(0,_.useState)([]),[d,f]=(0,_.useState)(!0),[p,m]=(0,_.useState)(null),[h,g]=(0,_.useState)(1),[v,x]=(0,_.useState)(null),[S,C]=(0,_.useState)(null),[w,T]=(0,_.useState)(!1),E=(0,_.useCallback)(async(r,a,o)=>{let c=r??n,d=a??i;if(c){f(!0);try{let[n,r]=await Promise.all([l.get(`${t}/data?table=${encodeURIComponent(c)}&schema=${d}&page=${o??h}&limit=100`),l.get(`${t}/schema?table=${encodeURIComponent(c)}&schema=${d}`)]);s(n),u(r),b(e,c,d,o??h,n,r)}catch(e){m(e.message)}finally{f(!1)}}},[t,e,n,i,h]);return{selectedTable:n,selectTable:(0,_.useCallback)((t,n=`public`)=>{r(t),a(n),g(1),x(null);let i=y(e,t,n,1);i?(s(i.data),u(i.cols),f(!1),E(t,n,1)):E(t,n,1)},[e,E]),tableData:o,schema:c,loading:d,error:p,page:h,setPage:(0,_.useCallback)(e=>{g(e),E(void 0,void 0,e)},[E]),queryResult:v,queryError:S,queryLoading:w,executeQuery:(0,_.useCallback)(async e=>{T(!0),C(null);try{let r=await l.post(`${t}/query`,{sql:e});x(r),r.changeType===`modify`&&E(n??void 0,i)}catch(e){C(e.message)}finally{T(!1)}},[t,n,i,E]),updateCell:(0,_.useCallback)(async(e,r,a,o)=>{if(!n)return;let s=n,c=i;try{await l.put(`${t}/cell`,{table:s,schema:c,pkColumn:e,pkValue:r,column:a,value:o}),E(s,c)}catch(e){m(e.message)}},[t,n,i,E]),refreshData:E}}var S=n(),C={postgres:c,sqlite:o};function w({metadata:e}){let t=e?.connectionId,n=e?.connectionName,r=e?.dbType??`postgres`,i=e?.tableName,a=e?.schemaName??`public`,o=x(t),[s,l]=(0,_.useState)(!1),d=(0,_.useRef)(!1);return(0,_.useEffect)(()=>{!i||d.current||(d.current=!0,o.selectTable(i,a))},[i,a]),(0,S.jsx)(`div`,{className:`flex h-full w-full overflow-hidden`,children:(0,S.jsxs)(`div`,{className:`flex-1 flex flex-col overflow-hidden`,children:[(0,S.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5 border-b border-border bg-background shrink-0`,children:[(0,S.jsx)(p,{className:`size-3.5 text-muted-foreground`}),(0,S.jsx)(`span`,{className:`text-xs text-muted-foreground truncate`,children:n??`Database`}),o.selectedTable&&(0,S.jsxs)(`span`,{className:`text-xs text-muted-foreground`,children:[`/ `,o.selectedTable]}),(0,S.jsxs)(`div`,{className:`ml-auto flex items-center gap-1`,children:[(0,S.jsx)(`button`,{type:`button`,onClick:()=>o.refreshData(),title:`Reload data`,className:`p-1 rounded text-muted-foreground hover:text-foreground transition-colors`,children:(0,S.jsx)(u,{className:`size-3 ${o.loading?`animate-spin`:``}`})}),(0,S.jsx)(`button`,{type:`button`,onClick:()=>l(e=>!e),className:`px-2 py-1 rounded text-xs transition-colors ${s?`bg-muted text-foreground`:`text-muted-foreground hover:text-foreground`}`,children:`SQL`})]})]}),(0,S.jsx)(`div`,{className:`flex-1 overflow-hidden ${s?`max-h-[60%]`:``}`,children:(0,S.jsx)(T,{tableData:o.tableData,schema:o.schema,loading:o.loading,page:o.page,onPageChange:o.setPage,onCellUpdate:o.updateCell})}),s&&(0,S.jsx)(`div`,{className:`border-t border-border h-[40%] shrink-0`,children:(0,S.jsx)(E,{dialect:C[r]??c,onExecute:o.executeQuery,result:o.queryResult,error:o.queryError,loading:o.queryLoading})})]})})}function T({tableData:e,schema:t,loading:n,page:i,onPageChange:a,onCellUpdate:o}){let[s,c]=(0,_.useState)(null),[l,u]=(0,_.useState)(``),p=(0,_.useMemo)(()=>t.find(e=>e.pk)?.name??null,[t]),v=(0,_.useCallback)((e,t,n)=>{c({rowIdx:e,col:t}),u(n==null?``:String(n))},[]),y=(0,_.useCallback)(()=>{if(!s||!e||!p)return;let t=e.rows[s.rowIdx];if(!t)return;let n=t[s.col];String(n??``)!==l&&o(p,t[p],s.col,l===``?null:l),c(null)},[s,l,e,p,o]),b=(0,_.useCallback)(()=>c(null),[]),x=(0,_.useMemo)(()=>(e?.columns??[]).map(e=>({id:e,accessorFn:t=>t[e],header:()=>(0,S.jsx)(`span`,{className:t.find(t=>t.name===e)?.pk?`font-bold`:``,children:e}),cell:({row:t,getValue:n})=>{let r=s?.rowIdx===t.index&&s?.col===e,i=n();return r?(0,S.jsx)(`input`,{autoFocus:!0,className:`w-full bg-transparent border border-primary/50 rounded px-1 py-0 text-xs outline-none`,value:l,onChange:e=>u(e.target.value),onBlur:y,onKeyDown:e=>{e.key===`Enter`&&y(),e.key===`Escape`&&b()}}):(0,S.jsx)(`span`,{className:`cursor-pointer truncate block ${i==null?`text-muted-foreground/40 italic`:``}`,onDoubleClick:()=>p&&v(t.index,e,i),title:i==null?`NULL`:String(i),children:i==null?`NULL`:String(i)})}})),[e?.columns,t,s,l,y,b,v,p]),C=m({data:e?.rows??[],columns:x,getCoreRowModel:h()});if(!e)return(0,S.jsx)(`div`,{className:`flex items-center justify-center h-full text-xs text-muted-foreground`,children:n?(0,S.jsx)(d,{className:`size-4 animate-spin`}):`Select a table`});let w=Math.ceil(e.total/e.limit)||1;return(0,S.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,S.jsx)(`div`,{className:`flex-1 overflow-auto`,children:(0,S.jsxs)(`table`,{className:`w-full text-xs border-collapse`,children:[(0,S.jsx)(`thead`,{className:`sticky top-0 z-10 bg-muted`,children:C.getHeaderGroups().map(e=>(0,S.jsx)(`tr`,{children:e.headers.map(e=>(0,S.jsx)(`th`,{className:`px-2 py-1.5 text-left font-medium text-muted-foreground border-b border-border whitespace-nowrap`,children:g(e.column.columnDef.header,e.getContext())},e.id))},e.id))}),(0,S.jsxs)(`tbody`,{children:[C.getRowModel().rows.map(e=>(0,S.jsx)(`tr`,{className:`hover:bg-muted/30 border-b border-border/50`,children:e.getVisibleCells().map(e=>(0,S.jsx)(`td`,{className:`px-2 py-1 max-w-[300px]`,children:g(e.column.columnDef.cell,e.getContext())},e.id))},e.id)),e.rows.length===0&&(0,S.jsx)(`tr`,{children:(0,S.jsx)(`td`,{colSpan:e.columns.length,className:`px-2 py-8 text-center text-muted-foreground`,children:`No data`})})]})]})}),(0,S.jsxs)(`div`,{className:`flex items-center justify-between px-3 py-1.5 border-t border-border bg-background shrink-0 text-xs text-muted-foreground`,children:[(0,S.jsxs)(`span`,{children:[e.total.toLocaleString(),` rows`]}),(0,S.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,S.jsx)(`button`,{type:`button`,disabled:i<=1,onClick:()=>a(i-1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,S.jsx)(f,{className:`size-3.5`})}),(0,S.jsxs)(`span`,{children:[i,` / `,w]}),(0,S.jsx)(`button`,{type:`button`,disabled:i>=w,onClick:()=>a(i+1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,S.jsx)(r,{className:`size-3.5`})})]})]})]})}function E({dialect:e,onExecute:t,result:n,error:r,loading:o}){let[c,l]=(0,_.useState)(`SELECT * FROM `),u=(0,_.useCallback)(()=>{let e=c.trim();e&&t(e)},[c,t]);return(0,S.jsxs)(`div`,{className:`flex flex-col h-full overflow-hidden`,children:[(0,S.jsxs)(`div`,{className:`flex items-start gap-1 border-b border-border bg-background`,onKeyDown:(0,_.useCallback)(e=>{(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&(e.preventDefault(),u())},[u]),children:[(0,S.jsx)(`div`,{className:`flex-1 max-h-[120px] overflow-auto`,children:(0,S.jsx)(a,{value:c,onChange:l,extensions:[s({dialect:e})],basicSetup:{lineNumbers:!1,foldGutter:!1,highlightActiveLine:!1},className:`text-xs [&_.cm-editor]:!outline-none [&_.cm-scroller]:!overflow-auto`})}),(0,S.jsx)(`button`,{type:`button`,onClick:u,disabled:o,title:`Execute (Cmd+Enter)`,className:`shrink-0 m-1 p-1.5 rounded bg-primary text-primary-foreground hover:bg-primary/90 disabled:opacity-50 transition-colors`,children:o?(0,S.jsx)(d,{className:`size-3.5 animate-spin`}):(0,S.jsx)(i,{className:`size-3.5`})})]}),(0,S.jsxs)(`div`,{className:`flex-1 overflow-auto text-xs`,children:[r&&(0,S.jsx)(`div`,{className:`px-3 py-2 text-destructive bg-destructive/5`,children:r}),n?.changeType===`modify`&&(0,S.jsxs)(`div`,{className:`px-3 py-2 text-green-500`,children:[`Query executed. `,n.rowsAffected,` row(s) affected.`]}),n?.changeType===`select`&&n.rows.length>0&&(0,S.jsxs)(`table`,{className:`w-full border-collapse`,children:[(0,S.jsx)(`thead`,{className:`sticky top-0 bg-muted`,children:(0,S.jsx)(`tr`,{children:n.columns.map(e=>(0,S.jsx)(`th`,{className:`px-2 py-1 text-left font-medium text-muted-foreground border-b border-border whitespace-nowrap`,children:e},e))})}),(0,S.jsx)(`tbody`,{children:n.rows.map((e,t)=>(0,S.jsx)(`tr`,{className:`hover:bg-muted/30 border-b border-border/50`,children:n.columns.map(t=>(0,S.jsx)(`td`,{className:`px-2 py-1 max-w-[300px] truncate`,title:e[t]==null?`NULL`:String(e[t]),children:e[t]==null?(0,S.jsx)(`span`,{className:`text-muted-foreground/40 italic`,children:`NULL`}):String(e[t])},t))},t))})]}),n?.changeType===`select`&&n.rows.length===0&&(0,S.jsx)(`div`,{className:`px-3 py-2 text-muted-foreground`,children:`No results`})]})]})}export{w as DatabaseViewer};
@@ -1,4 +1,4 @@
1
- import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{n,t as r}from"./jsx-runtime-BRW_vwa9.js";import{t as i}from"./columns-2-DpsNbZOc.js";import{i as a,r as o,t as s}from"./use-monaco-theme-BwIb9BHq.js";import{i as c,t as l}from"./api-client-BfBM3I7n.js";import{K as u,P as d,X as f,rt as p}from"./index-5a-tMkk5.js";var m=n(`panel-right-open`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}],[`path`,{d:`m10 15-3-3 3-3`,key:`1pgupc`}]]),h=e(t(),1),g=r();function _(e){return{js:`javascript`,jsx:`javascript`,ts:`typescript`,tsx:`typescript`,py:`python`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,mdx:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,bash:`shell`}[e.split(`.`).pop()?.toLowerCase()??``]??`plaintext`}function v({metadata:e}){let t=e?.filePath,n=e?.projectName,r=e?.ref1,v=e?.ref2,b=e?.file1,x=e?.file2,S=e?.original,C=e?.modified,w=S!=null||C!=null,T=!!(b&&x),[E,D]=(0,h.useState)(null),[O,k]=(0,h.useState)(null),[A,j]=(0,h.useState)(!w),[M,N]=(0,h.useState)(null),[P,F]=(0,h.useState)(`both`),{wordWrap:I,toggleWordWrap:L}=d(),R=s(),z=(0,h.useRef)(null),[B,V]=(0,h.useState)();(0,h.useEffect)(()=>{let e=z.current;if(!e)return;let t=new ResizeObserver(([e])=>{e&&V(Math.floor(e.contentRect.height))});return t.observe(e),()=>t.disconnect()},[A,M]),(0,h.useEffect)(()=>{if(w||!n)return;if(j(!0),N(null),b&&x){let e=new URLSearchParams({file1:b,file2:x});l.get(`${c(n)}/files/compare?${e}`).then(e=>{k(e),j(!1)}).catch(e=>{N(e instanceof Error?e.message:`Failed to compare files`),j(!1)});return}let e;if(t){let i=new URLSearchParams({file:t});r&&i.set(`ref`,r),e=`${c(n)}/git/file-diff?${i}`}else if(r||v){let t=new URLSearchParams;r&&t.set(`ref1`,r),v&&t.set(`ref2`,v),e=`${c(n)}/git/diff?${t}`}else e=`${c(n)}/git/diff`;l.get(e).then(e=>{D(e.diff),j(!1)}).catch(e=>{N(e instanceof Error?e.message:`Failed to load diff`),j(!1)})},[t,n,r,v,b,x,w]);let{original:H,modified:U}=(0,h.useMemo)(()=>w?{original:S??``,modified:C??``}:T&&O?O:E?y(E):{original:``,modified:``},[E,w,S,C,T,O]),W=(0,h.useMemo)(()=>{let e=t??x??b;return e?_(e):`plaintext`},[t,b,x]),G=typeof window<`u`&&window.innerWidth<768,K=!G&&P===`both`;return!n&&!w?(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full text-muted-foreground text-sm`,children:`No project selected.`}):A?(0,g.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,g.jsx)(f,{className:`size-5 animate-spin`}),(0,g.jsx)(`span`,{className:`text-sm`,children:`Loading diff...`})]}):M?(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full text-destructive text-sm`,children:M}):!w&&!T&&!H&&!U?(0,g.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,g.jsx)(p,{className:`size-8`}),(0,g.jsx)(`p`,{className:`text-sm`,children:`No content changes`}),t&&(0,g.jsx)(`p`,{className:`text-xs font-mono`,children:t})]}):(0,g.jsxs)(`div`,{className:`flex flex-col h-full`,children:[!G&&(0,g.jsxs)(`div`,{className:`flex items-center justify-end gap-0.5 px-2 py-0.5 border-b border-border shrink-0`,children:[(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(P===`left`?`both`:`left`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`left`?`bg-muted text-foreground`:``}`,title:`Expand original`,children:(0,g.jsx)(u,{className:`size-3.5`})}),(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(`both`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`both`?`bg-muted text-foreground`:``}`,title:`Side by side`,children:(0,g.jsx)(i,{className:`size-3.5`})}),(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(P===`right`?`both`:`right`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`right`?`bg-muted text-foreground`:``}`,title:`Expand modified`,children:(0,g.jsx)(m,{className:`size-3.5`})}),(0,g.jsx)(`div`,{className:`w-px h-3.5 bg-border mx-0.5 shrink-0`}),(0,g.jsx)(`button`,{type:`button`,onClick:L,title:`Toggle word wrap`,className:`p-1 rounded hover:bg-muted transition-colors ${I?`bg-muted text-foreground`:``}`,children:(0,g.jsx)(a,{className:`size-3.5`})})]}),(0,g.jsx)(`div`,{ref:z,className:`flex-1 overflow-hidden`,children:B&&B>0?(0,g.jsx)(o,{height:B,language:W,original:H,modified:U,theme:R,options:{fontSize:G?11:13,fontFamily:`Menlo, Monaco, Consolas, monospace`,wordWrap:G||I?`on`:`off`,renderSideBySide:K,readOnly:!0,automaticLayout:!0,scrollBeyondLastLine:!1},loading:(0,g.jsx)(f,{className:`size-5 animate-spin text-muted-foreground`})}):(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,g.jsx)(f,{className:`size-5 animate-spin text-muted-foreground`})})})]})}function y(e){let t=e.split(`
1
+ import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import{n,t as r}from"./jsx-runtime-BRW_vwa9.js";import{t as i}from"./columns-2-DpsNbZOc.js";import{i as a,r as o,t as s}from"./use-monaco-theme-BZiSwNRE.js";import{i as c,t as l}from"./api-client-BfBM3I7n.js";import{K as u,P as d,X as f,rt as p}from"./index-CiuAeXR3.js";var m=n(`panel-right-open`,[[`rect`,{width:`18`,height:`18`,x:`3`,y:`3`,rx:`2`,key:`afitv7`}],[`path`,{d:`M15 3v18`,key:`14nvp0`}],[`path`,{d:`m10 15-3-3 3-3`,key:`1pgupc`}]]),h=e(t(),1),g=r();function _(e){return{js:`javascript`,jsx:`javascript`,ts:`typescript`,tsx:`typescript`,py:`python`,html:`html`,css:`css`,scss:`scss`,json:`json`,md:`markdown`,mdx:`markdown`,yaml:`yaml`,yml:`yaml`,sh:`shell`,bash:`shell`}[e.split(`.`).pop()?.toLowerCase()??``]??`plaintext`}function v({metadata:e}){let t=e?.filePath,n=e?.projectName,r=e?.ref1,v=e?.ref2,b=e?.file1,x=e?.file2,S=e?.original,C=e?.modified,w=S!=null||C!=null,T=!!(b&&x),[E,D]=(0,h.useState)(null),[O,k]=(0,h.useState)(null),[A,j]=(0,h.useState)(!w),[M,N]=(0,h.useState)(null),[P,F]=(0,h.useState)(`both`),{wordWrap:I,toggleWordWrap:L}=d(),R=s(),z=(0,h.useRef)(null),[B,V]=(0,h.useState)();(0,h.useEffect)(()=>{let e=z.current;if(!e)return;let t=new ResizeObserver(([e])=>{e&&V(Math.floor(e.contentRect.height))});return t.observe(e),()=>t.disconnect()},[A,M]),(0,h.useEffect)(()=>{if(w||!n)return;if(j(!0),N(null),b&&x){let e=new URLSearchParams({file1:b,file2:x});l.get(`${c(n)}/files/compare?${e}`).then(e=>{k(e),j(!1)}).catch(e=>{N(e instanceof Error?e.message:`Failed to compare files`),j(!1)});return}let e;if(t){let i=new URLSearchParams({file:t});r&&i.set(`ref`,r),e=`${c(n)}/git/file-diff?${i}`}else if(r||v){let t=new URLSearchParams;r&&t.set(`ref1`,r),v&&t.set(`ref2`,v),e=`${c(n)}/git/diff?${t}`}else e=`${c(n)}/git/diff`;l.get(e).then(e=>{D(e.diff),j(!1)}).catch(e=>{N(e instanceof Error?e.message:`Failed to load diff`),j(!1)})},[t,n,r,v,b,x,w]);let{original:H,modified:U}=(0,h.useMemo)(()=>w?{original:S??``,modified:C??``}:T&&O?O:E?y(E):{original:``,modified:``},[E,w,S,C,T,O]),W=(0,h.useMemo)(()=>{let e=t??x??b;return e?_(e):`plaintext`},[t,b,x]),G=typeof window<`u`&&window.innerWidth<768,K=!G&&P===`both`;return!n&&!w?(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full text-muted-foreground text-sm`,children:`No project selected.`}):A?(0,g.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,g.jsx)(f,{className:`size-5 animate-spin`}),(0,g.jsx)(`span`,{className:`text-sm`,children:`Loading diff...`})]}):M?(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full text-destructive text-sm`,children:M}):!w&&!T&&!H&&!U?(0,g.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,g.jsx)(p,{className:`size-8`}),(0,g.jsx)(`p`,{className:`text-sm`,children:`No content changes`}),t&&(0,g.jsx)(`p`,{className:`text-xs font-mono`,children:t})]}):(0,g.jsxs)(`div`,{className:`flex flex-col h-full`,children:[!G&&(0,g.jsxs)(`div`,{className:`flex items-center justify-end gap-0.5 px-2 py-0.5 border-b border-border shrink-0`,children:[(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(P===`left`?`both`:`left`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`left`?`bg-muted text-foreground`:``}`,title:`Expand original`,children:(0,g.jsx)(u,{className:`size-3.5`})}),(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(`both`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`both`?`bg-muted text-foreground`:``}`,title:`Side by side`,children:(0,g.jsx)(i,{className:`size-3.5`})}),(0,g.jsx)(`button`,{type:`button`,onClick:()=>F(P===`right`?`both`:`right`),className:`p-1 rounded hover:bg-muted transition-colors ${P===`right`?`bg-muted text-foreground`:``}`,title:`Expand modified`,children:(0,g.jsx)(m,{className:`size-3.5`})}),(0,g.jsx)(`div`,{className:`w-px h-3.5 bg-border mx-0.5 shrink-0`}),(0,g.jsx)(`button`,{type:`button`,onClick:L,title:`Toggle word wrap`,className:`p-1 rounded hover:bg-muted transition-colors ${I?`bg-muted text-foreground`:``}`,children:(0,g.jsx)(a,{className:`size-3.5`})})]}),(0,g.jsx)(`div`,{ref:z,className:`flex-1 overflow-hidden`,children:B&&B>0?(0,g.jsx)(o,{height:B,language:W,original:H,modified:U,theme:R,options:{fontSize:G?11:13,fontFamily:`Menlo, Monaco, Consolas, monospace`,wordWrap:G||I?`on`:`off`,renderSideBySide:K,readOnly:!0,automaticLayout:!0,scrollBeyondLastLine:!1},loading:(0,g.jsx)(f,{className:`size-5 animate-spin text-muted-foreground`})}):(0,g.jsx)(`div`,{className:`flex items-center justify-center h-full`,children:(0,g.jsx)(f,{className:`size-5 animate-spin text-muted-foreground`})})})]})}function y(e){let t=e.split(`
2
2
  `),n=[],r=[],i=!1;for(let e of t)if(!(e.startsWith(`diff --git`)||e.startsWith(`diff --no-index`)||e.startsWith(`index `)||e.startsWith(`new file`)||e.startsWith(`deleted file`)||e.startsWith(`old mode`)||e.startsWith(`new mode`)||e.startsWith(`---`)||e.startsWith(`+++`)||e.startsWith(`Binary files`)||e.startsWith(`\\ No newline`))){if(e.startsWith(`@@`)){i=!0;continue}if(i)if(e.startsWith(`-`))n.push(e.slice(1));else if(e.startsWith(`+`))r.push(e.slice(1));else{let t=e.startsWith(` `)?e.slice(1):e;n.push(t),r.push(t)}}return{original:n.join(`
3
3
  `),modified:r.join(`
4
4
  `)}}export{v as DiffViewer};
@@ -0,0 +1 @@
1
+ import{o as e}from"./chunk-CFjPhJqf.js";import{t}from"./react-nm2Ru1Pt.js";import"./react-dom-Bpkvzu3U.js";import{n,t as r}from"./jsx-runtime-BRW_vwa9.js";import{a as i,i as a,n as o,r as s,t as c}from"./input-BglMT33g.js";import{l,t as u}from"./tab-store-BJw7OCmy.js";import{t as d}from"./tag-CCtdV063.js";import"./dist-lF8CoYII.js";import{t as f}from"./utils-BNytJOb1.js";import{i as p,t as m}from"./api-client-BfBM3I7n.js";import{B as h,C as g,F as _,L as v,Q as y,S as b,T as x,V as S,X as C,_t as w,b as T,ct as E,g as D,h as O,ot as k,v as A,w as j,x as M,y as N,z as P}from"./index-CiuAeXR3.js";var F=n(`cherry`,[[`path`,{d:`M2 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z`,key:`cvxqlc`}],[`path`,{d:`M12 17a5 5 0 0 0 10 0c0-2.76-2.5-5-5-3-2.5-2-5 .24-5 3Z`,key:`1ostrc`}],[`path`,{d:`M7 14c3.22-2.91 4.29-8.75 5-12 1.66 2.38 4.94 9 5 12`,key:`hqx58h`}],[`path`,{d:`M22 9c-4.29 0-7.14-2.33-10-7 5.71 0 10 4.67 10 7Z`,key:`eykp1o`}]]),ee=n(`git-merge`,[[`circle`,{cx:`18`,cy:`18`,r:`3`,key:`1xkwt0`}],[`circle`,{cx:`6`,cy:`6`,r:`3`,key:`1lh9wr`}],[`path`,{d:`M6 21V9a9 9 0 0 0 9 9`,key:`7kw0sc`}]]),I=e(t(),1),L=[`#0085d9`,`#d73a49`,`#6f42c1`,`#2cbe4e`,`#e36209`,`#005cc5`,`#b31d28`,`#5a32a3`,`#22863a`,`#cb2431`];function te(e){let t=new Map;if(!e)return t;let n=new Set;for(let t of e.branches)if(!t.remote)for(let e of t.remotes)n.add(`remotes/${e}/${t.name}`);for(let r of e.branches)if(r.remote){if(n.has(r.name))continue;let e=t.get(r.commitHash)??[],i=r.name.replace(/^remotes\//,``);e.push({name:i,type:`branch`,remotes:[],current:!1}),t.set(r.commitHash,e)}else{let e=t.get(r.commitHash)??[];e.push({name:r.name,type:`branch`,remotes:r.remotes,current:r.current}),t.set(r.commitHash,e)}for(let n of e.commits)for(let e of n.refs)if(e.startsWith(`tag: `)){let r=e.replace(`tag: `,``),i=t.get(n.hash)??[];i.push({name:r,type:`tag`,remotes:[],current:!1}),t.set(n.hash,i)}return t}function ne(e){let t=new Map;if(!e)return{laneMap:t,maxLane:0,unloadedParentLanes:new Map};let n=0,r=0,i=new Map,a=new Set(e.commits.map(e=>e.hash)),o=[],s=()=>o.length>0?(o.sort((e,t)=>e-t),o.shift()):n++;for(let n of e.commits){let e=i.get(n.hash);e===void 0&&(e=s()),t.set(n.hash,e),e>r&&(r=e),i.delete(n.hash);let a=!1;for(let t=0;t<n.parents.length;t++){let o=n.parents[t];if(!i.has(o))if(t===0)i.set(o,e),a=!0;else{let e=s();i.set(o,e),e>r&&(r=e)}}a||o.push(e)}let c=new Map;for(let[e,t]of i)a.has(e)||c.set(e,t);return{laneMap:t,maxLane:r,unloadedParentLanes:c}}function re(e,t,n,r){if(!e)return[];let i=[],a=new Set(e.commits.map(e=>e.hash));for(let o=0;o<e.commits.length;o++){let s=e.commits[o],c=t.get(s.hash)??0,l=L[c%L.length];for(let u of s.parents){let d=e.commits.findIndex(e=>e.hash===u);if(d>=0){let e=t.get(u)??0,n=L[e%L.length],r=c*16+16/2,a=o*24+24/2,f=e*16+16/2,p=d*24+24/2,m,h=s.parents.indexOf(u)>0;if(r===f)m=`M ${r} ${a} L ${f} ${p}`;else if(h){let e=a+24;m=`M ${r} ${a} C ${r} ${e} ${f} ${a} ${f} ${e} L ${f} ${p}`}else{let e=p-24;m=`M ${r} ${a} L ${r} ${e} C ${r} ${p} ${f} ${e} ${f} ${p}`}let g=s.parents.indexOf(u)===0?l:n;i.push({d:m,color:g})}else if(!a.has(u)){let e=n.get(u)??c,t=L[e%L.length],a=c*16+16/2,s=o*24+24/2,d=e*16+16/2;if(a===d)i.push({d:`M ${a} ${s} L ${a} ${r}`,color:l});else{let e=s+24,n=`M ${a} ${s} C ${a} ${e} ${d} ${s} ${d} ${e} L ${d} ${r}`;i.push({d:n,color:t})}}}}return i}function R(e){let t=new Date(e),n=new Date().getTime()-t.getTime(),r=Math.floor(n/6e4);if(r<1)return`just now`;if(r<60)return`${r}m ago`;let i=Math.floor(r/60);if(i<24)return`${i}h ago`;let a=Math.floor(i/24);if(a<30)return`${a}d ago`;let o=Math.floor(a/30);return o<12?`${o}mo ago`:`${Math.floor(o/12)}y ago`}var z=200;function B(e){let[t,n]=(0,I.useState)(null),[r,i]=(0,I.useState)(!0),[a,o]=(0,I.useState)(!1),[s,c]=(0,I.useState)(!0),[l,d]=(0,I.useState)(null),[f,h]=(0,I.useState)(!1),[g,_]=(0,I.useState)(null),[v,y]=(0,I.useState)([]),[b,x]=(0,I.useState)(!1),[S,C]=(0,I.useState)(`__all__`),[w,T]=(0,I.useState)(``),[E,D]=(0,I.useState)(!1),{openTab:O}=u(),k=(0,I.useRef)(0),A=(0,I.useCallback)(async()=>{if(e)try{i(!0);let t=Math.max(z,k.current),r=await m.get(`${p(e)}/git/graph?max=${t}`);n(r),k.current=r.commits.length,c(r.commits.length>=t),d(null)}catch(e){d(e instanceof Error?e.message:`Failed to fetch graph`)}finally{i(!1)}},[e]),j=(0,I.useCallback)(async()=>{if(!(!e||a||!s))try{o(!0);let t=k.current,r=await m.get(`${p(e)}/git/graph?max=${z}&skip=${t}`);if(r.commits.length===0){c(!1);return}n(e=>{if(!e)return r;let t=new Set(e.commits.map(e=>e.hash)),n=r.commits.filter(e=>!t.has(e.hash)),i=new Set(e.branches.map(e=>e.name)),a=r.branches.filter(e=>!i.has(e.name));return{commits:[...e.commits,...n],branches:[...e.branches,...a],head:e.head}}),k.current=t+r.commits.length,c(r.commits.length>=z)}catch(e){d(e instanceof Error?e.message:`Failed to load more`)}finally{o(!1)}},[e,a,s]);(0,I.useEffect)(()=>{A();let e=setInterval(A,1e4);return()=>clearInterval(e)},[A]);let M=async(t,n)=>{if(e){h(!0);try{await m.post(`${p(e)}${t}`,n),await A()}catch(e){d(e instanceof Error?e.message:`Action failed`)}finally{h(!1)}}},N=()=>M(`/git/fetch`,{}),P=e=>M(`/git/checkout`,{ref:e}),F=e=>M(`/git/cherry-pick`,{hash:e}),ee=e=>M(`/git/revert`,{hash:e}),L=e=>M(`/git/merge`,{source:e}),R=e=>M(`/git/branch/delete`,{name:e}),B=e=>M(`/git/push`,{branch:e}),V=(e,t)=>M(`/git/tag`,{name:e,hash:t}),H=e=>navigator.clipboard.writeText(e),U=async(e,n)=>{if(t?.branches.some(t=>t.name===e||t.name.endsWith(`/${e}`))){if(!window.confirm(`Branch "${e}" already exists.\nDelete and recreate from this commit?`))return;await M(`/git/branch/delete`,{name:e})}await M(`/git/branch/create`,{name:e,from:n})},W=async t=>{if(e)try{let n=await m.get(`${p(e)}/git/pr-url?branch=${encodeURIComponent(t)}`);n.url&&window.open(n.url,`_blank`)}catch{}},G=async t=>{if(g?.hash===t.hash){_(null);return}_(t),x(!0);try{let n=t.parents[0]??``,r=n?`ref1=${encodeURIComponent(n)}&`:``,i=await m.get(`${p(e)}/git/diff-stat?${r}ref2=${encodeURIComponent(t.hash)}`);y(Array.isArray(i)?i:[])}catch{y([])}finally{x(!1)}},K=t=>O({type:`git-diff`,title:`Diff ${t.abbreviatedHash}`,closable:!0,metadata:{projectName:e,ref1:t.parents[0]??void 0,ref2:t.hash},projectId:e??null}),q=(0,I.useMemo)(()=>te(t),[t]),J=t?.branches.find(e=>e.current),Y=t?.head??``,X=(0,I.useMemo)(()=>{if(!t)return[];let e=t.commits;if(S!==`__all__`){let n=t.branches.find(e=>e.name===S);if(n){let r=new Set,i=[n.commitHash];for(;i.length>0;){let e=i.pop();if(r.has(e))continue;r.add(e);let n=t.commits.find(t=>t.hash===e);n&&i.push(...n.parents)}e=e.filter(e=>r.has(e.hash))}}if(w.trim()){let t=w.toLowerCase();e=e.filter(e=>e.subject.toLowerCase().includes(t)||e.authorName.toLowerCase().includes(t)||e.abbreviatedHash.includes(t)||e.hash.includes(t))}return e},[t,S,w]),Z=(0,I.useMemo)(()=>t?{...t,commits:X}:null,[t,X]),Q=(0,I.useMemo)(()=>ne(Z),[Z]),$=X.length*24+48;return{data:t,loading:r,loadingMore:a,hasMore:s,error:l,acting:f,selectedCommit:g,setSelectedCommit:_,commitFiles:v,loadingDetail:b,branchFilter:S,setBranchFilter:C,searchQuery:w,setSearchQuery:T,showSearch:E,setShowSearch:D,fetchGraph:A,fetchFromRemotes:N,loadMore:j,handleCheckout:P,handleCherryPick:F,handleRevert:ee,handleMerge:L,handleDeleteBranch:R,handlePushBranch:B,handleCreateBranch:U,handleCreateTag:V,handleCreatePr:W,copyHash:H,selectCommit:G,openDiffForCommit:K,commitLabels:q,currentBranch:J,headHash:Y,filteredCommits:X,filteredLanes:Q,svgHeight:$,svgPaths:(0,I.useMemo)(()=>re(Z,Q.laneMap,Q.unloadedParentLanes,$),[Z,Q.laneMap,Q.unloadedParentLanes,$])}}function V(e){let[t,n]=(0,I.useState)(e),r=(0,I.useRef)(e);r.current=t;let i=(0,I.useRef)(!1);return{widths:t,startResize:(e,t)=>{i.current=!0;let a=r.current[e]??80,o=r=>{if(!i.current)return;let o=`touches`in r?r.touches[0].clientX:r.clientX,s=Math.max(40,a+o-t);n(t=>({...t,[e]:s}))},s=()=>{i.current=!1,window.removeEventListener(`mousemove`,o),window.removeEventListener(`mouseup`,s),window.removeEventListener(`touchmove`,o),window.removeEventListener(`touchend`,s)};window.addEventListener(`mousemove`,o),window.addEventListener(`mouseup`,s),window.addEventListener(`touchmove`,o,{passive:!1}),window.addEventListener(`touchend`,s)}}}var H=r();function U({branches:e,branchFilter:t,onBranchFilterChange:n,searchQuery:r,onSearchQueryChange:i,showSearch:s,onToggleSearch:l,onFetch:u,onRefresh:d,onOpenSettings:f,loading:p,acting:m,projectName:g}){let v=e.filter(e=>!e.remote),[y,b]=(0,I.useState)(!1),[x,C]=(0,I.useState)(``),w=(0,I.useRef)(null);(0,I.useEffect)(()=>{if(!y)return;let e=e=>{w.current&&!w.current.contains(e.target)&&(b(!1),C(``))};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[y]);let T=x?v.filter(e=>e.name.toLowerCase().includes(x.toLowerCase())):v,E=t===`__all__`?`Show All`:v.find(e=>e.name===t)?.name??`Show All`;return(0,H.jsx)(`div`,{className:`border-b bg-background`,children:(0,H.jsxs)(`div`,{className:`flex items-center gap-1.5 px-2 py-1.5`,children:[(0,H.jsxs)(`div`,{className:`flex items-center gap-1 text-xs text-muted-foreground shrink-0`,children:[(0,H.jsx)(`span`,{className:`font-semibold`,children:`Repo:`}),(0,H.jsx)(`span`,{className:`font-medium text-foreground truncate max-w-[120px]`,children:g??`—`})]}),(0,H.jsx)(`div`,{className:`w-px h-4 bg-border mx-1`}),(0,H.jsxs)(`div`,{className:`relative shrink-0`,ref:w,children:[(0,H.jsxs)(`button`,{type:`button`,className:`flex items-center gap-1 h-6 px-2 text-xs border rounded-md bg-transparent hover:bg-muted/50`,onClick:()=>{b(e=>!e),C(``)},children:[(0,H.jsx)(`span`,{className:`font-semibold text-muted-foreground`,children:`Branches:`}),(0,H.jsx)(`span`,{className:`max-w-[100px] truncate`,children:E}),(0,H.jsx)(a,{className:`size-3 opacity-50`})]}),y&&(0,H.jsxs)(`div`,{className:`absolute top-full left-0 mt-1 z-50 w-[220px] rounded-md border bg-popover shadow-md`,children:[(0,H.jsx)(`div`,{className:`p-1.5`,children:(0,H.jsx)(c,{className:`h-6 text-xs px-2`,placeholder:`Filter branches...`,value:x,onChange:e=>C(e.target.value),autoFocus:!0})}),(0,H.jsxs)(`div`,{className:`max-h-[200px] overflow-y-auto p-1`,children:[(0,H.jsx)(W,{label:`Show All`,selected:t===`__all__`,onClick:()=>{n(`__all__`),b(!1)}}),T.map(e=>(0,H.jsx)(W,{label:e.name,current:e.current,selected:t===e.name,onClick:()=>{n(e.name),b(!1)}},e.name)),T.length===0&&x&&(0,H.jsx)(`div`,{className:`px-2 py-1.5 text-xs text-muted-foreground`,children:`No branches found`})]})]})]}),(0,H.jsx)(`div`,{className:`flex-1`}),s&&(0,H.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,H.jsx)(c,{className:`h-6 text-xs w-[160px] px-2`,placeholder:`Search commits...`,value:r,onChange:e=>i(e.target.value),autoFocus:!0}),(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:l,children:(0,H.jsx)(_,{className:`size-3`})})]}),!s&&(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:l,title:`Find`,children:(0,H.jsx)(h,{className:`size-3.5`})}),(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:f,title:`Settings`,children:(0,H.jsx)(P,{className:`size-3.5`})}),(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:u,disabled:m,title:`Fetch`,children:(0,H.jsx)(k,{className:`size-3.5`})}),(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:d,disabled:m,title:`Refresh`,children:(0,H.jsx)(S,{className:`size-3.5 ${p?`animate-spin`:``}`})})]})})}function W({label:e,selected:t,current:n,onClick:r}){return(0,H.jsxs)(`button`,{type:`button`,className:`flex items-center gap-2 w-full px-2 py-1 text-xs rounded-sm hover:bg-accent hover:text-accent-foreground text-left`,onClick:r,children:[(0,H.jsx)(i,{className:`size-3 shrink-0 ${t?`opacity-100`:`opacity-0`}`}),(0,H.jsx)(`span`,{className:`truncate flex-1`,children:e}),n&&(0,H.jsx)(`span`,{className:`text-[10px] text-muted-foreground italic`,children:`current`})]})}function G({commits:e,laneMap:t,svgPaths:n,width:r,height:i,headHash:a}){return(0,H.jsxs)(`svg`,{width:r,height:i,children:[n.map((e,t)=>(0,H.jsx)(`path`,{d:e.d,stroke:e.color,strokeWidth:2,fill:`none`},t)),e.map((e,n)=>{let r=t.get(e.hash)??0,i=r*16+16/2,o=n*24+24/2,s=L[r%L.length],c=e.hash===a;return(0,H.jsx)(`circle`,{cx:i,cy:o,r:c?5:4,fill:s,stroke:c?`#000`:`none`,strokeWidth:c?2:0},e.hash)})]})}function K({name:e,type:t,remotes:n,isCurrent:r,color:i,currentBranch:a,onCheckout:o,onMerge:s,onPush:c,onCreatePr:u,onDelete:f}){return t===`tag`?(0,H.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 px-1.5 py-0.5 rounded text-[10px] font-medium shrink-0 bg-amber-500/20 text-amber-500 border border-amber-500/30`,children:[(0,H.jsx)(d,{className:`size-2.5`}),e]}):(0,H.jsxs)(M,{children:[(0,H.jsx)(x,{asChild:!0,children:(0,H.jsxs)(`span`,{className:`inline-flex items-center rounded text-[10px] font-medium shrink-0 cursor-context-menu overflow-hidden`,style:{border:r?`1.5px solid ${i}`:`1px solid ${i}50`},children:[(0,H.jsxs)(`span`,{className:`inline-flex items-center gap-0.5 px-1.5 py-0.5`,style:{backgroundColor:r?i:`${i}30`,color:r?`#fff`:i},children:[(0,H.jsx)(y,{className:`size-2.5`}),e]}),n.map(e=>(0,H.jsx)(`span`,{className:`px-1.5 py-0.5 italic opacity-70`,style:{borderLeft:`1px solid ${i}40`,color:i,backgroundColor:`${i}15`},children:e},e))]})}),(0,H.jsxs)(b,{children:[(0,H.jsx)(g,{onClick:()=>o(e),children:`Checkout`}),(0,H.jsxs)(g,{onClick:()=>s(e),disabled:e===a?.name,children:[(0,H.jsx)(ee,{className:`size-3`}),`Merge into current`]}),(0,H.jsx)(j,{}),(0,H.jsxs)(g,{onClick:()=>c(e),children:[(0,H.jsx)(w,{className:`size-3`}),`Push`]}),(0,H.jsxs)(g,{onClick:()=>u(e),children:[(0,H.jsx)(l,{className:`size-3`}),`Create PR`]}),(0,H.jsx)(j,{}),(0,H.jsxs)(g,{variant:`destructive`,onClick:()=>f(e),disabled:e===a?.name,children:[(0,H.jsx)(v,{className:`size-3`}),`Delete`]})]})]})}function q({commit:e,lane:t,isSelected:n,isHead:r,labels:i,currentBranch:a,onSelect:o,onCheckout:c,onCherryPick:l,onRevert:u,onMerge:f,onDeleteBranch:p,onPushBranch:m,onCreatePr:h,onOpenCreateBranch:_,onOpenCreateTag:v,onOpenDiff:S,onCopyHash:C}){let w=L[t%L.length],T=i.filter(e=>e.type===`branch`),D=i.filter(e=>e.type===`tag`);return(0,H.jsxs)(M,{children:[(0,H.jsx)(x,{asChild:!0,children:(0,H.jsxs)(`tr`,{className:`hover:bg-muted/50 cursor-pointer border-b border-border/20 ${n?`bg-primary/10`:``} ${r?`font-medium`:``}`,style:{height:`24px`},onClick:o,children:[(0,H.jsx)(`td`,{className:`px-2 truncate max-w-0`,children:(0,H.jsxs)(`div`,{className:`flex items-center gap-1.5 min-w-0`,children:[T.map(e=>(0,H.jsx)(K,{name:e.name,type:`branch`,remotes:e.remotes,isCurrent:e.current,color:w,currentBranch:a,onCheckout:c,onMerge:f,onPush:m,onCreatePr:h,onDelete:p},`branch-${e.name}`)),D.map(e=>(0,H.jsx)(K,{name:e.name,type:`tag`,remotes:[],isCurrent:!1,color:w,currentBranch:a,onCheckout:c,onMerge:f,onPush:m,onCreatePr:h,onDelete:p},`tag-${e.name}`)),(0,H.jsx)(`span`,{className:`truncate text-xs`,children:e.subject})]})}),(0,H.jsx)(`td`,{className:`px-2 text-xs text-muted-foreground whitespace-nowrap shrink-0`,children:R(e.authorDate)}),(0,H.jsx)(`td`,{className:`px-2 text-xs text-muted-foreground truncate max-w-[120px]`,children:e.authorName}),(0,H.jsx)(`td`,{className:`px-2 text-xs text-muted-foreground font-mono whitespace-nowrap`,children:e.abbreviatedHash})]})}),(0,H.jsxs)(b,{children:[(0,H.jsx)(g,{onClick:()=>c(e.hash),children:`Checkout`}),(0,H.jsxs)(g,{onClick:()=>_(e.hash),children:[(0,H.jsx)(y,{className:`size-3`}),`Create Branch...`]}),(0,H.jsx)(j,{}),(0,H.jsxs)(g,{onClick:()=>l(e.hash),children:[(0,H.jsx)(F,{className:`size-3`}),`Cherry Pick`]}),(0,H.jsxs)(g,{onClick:()=>u(e.hash),children:[(0,H.jsx)(s,{className:`size-3`}),`Revert`]}),(0,H.jsxs)(g,{onClick:()=>v(e.hash),children:[(0,H.jsx)(d,{className:`size-3`}),`Create Tag...`]}),(0,H.jsx)(j,{}),(0,H.jsx)(g,{onClick:S,children:`View Diff`}),(0,H.jsxs)(g,{onClick:C,children:[(0,H.jsx)(E,{className:`size-3`}),`Copy Hash`]})]})]})}function J({commit:e,files:t,loadingDetail:n,projectName:r,onClose:i,copyHash:a}){let{openTab:s}=u();return(0,H.jsxs)(`div`,{className:`border-t bg-muted/30 max-h-[40%] overflow-auto`,children:[(0,H.jsxs)(`div`,{className:`px-3 py-2 border-b flex items-center justify-between`,children:[(0,H.jsxs)(`span`,{className:`text-sm font-medium truncate`,children:[e.abbreviatedHash,` — `,e.subject]}),(0,H.jsx)(o,{variant:`ghost`,size:`icon-xs`,onClick:i,children:`✕`})]}),(0,H.jsxs)(`div`,{className:`px-3 py-2 text-xs space-y-1`,children:[(0,H.jsxs)(`div`,{className:`flex gap-4`,children:[(0,H.jsx)(`span`,{className:`text-muted-foreground w-12 shrink-0`,children:`Author`}),(0,H.jsxs)(`span`,{children:[e.authorName,` <`,e.authorEmail,`>`]})]}),(0,H.jsxs)(`div`,{className:`flex gap-4`,children:[(0,H.jsx)(`span`,{className:`text-muted-foreground w-12 shrink-0`,children:`Date`}),(0,H.jsx)(`span`,{children:new Date(e.authorDate).toLocaleString()})]}),(0,H.jsxs)(`div`,{className:`flex gap-4`,children:[(0,H.jsx)(`span`,{className:`text-muted-foreground w-12 shrink-0`,children:`Hash`}),(0,H.jsx)(`span`,{className:`font-mono cursor-pointer hover:text-primary`,onClick:()=>a(e.hash),children:e.hash})]}),e.parents.length>0&&(0,H.jsxs)(`div`,{className:`flex gap-4`,children:[(0,H.jsx)(`span`,{className:`text-muted-foreground w-12 shrink-0`,children:`Parents`}),(0,H.jsx)(`span`,{className:`font-mono`,children:e.parents.map(e=>e.slice(0,7)).join(`, `)})]}),e.body&&(0,H.jsx)(`div`,{className:`mt-2 p-2 bg-background rounded text-xs whitespace-pre-wrap`,children:e.body})]}),(0,H.jsxs)(`div`,{className:`px-3 py-1 border-t`,children:[(0,H.jsx)(`div`,{className:`text-xs text-muted-foreground py-1`,children:n?`Loading files...`:`${t.length} file${t.length===1?``:`s`} changed`}),t.map(t=>(0,H.jsxs)(`div`,{className:`flex items-center gap-2 py-0.5 text-xs hover:bg-muted/50 rounded px-1 cursor-pointer`,onClick:()=>s({type:`git-diff`,title:`Diff ${f(t.path)}`,closable:!0,metadata:{projectName:r,ref1:e.parents[0]??void 0,ref2:e.hash,filePath:t.path},projectId:r}),children:[(0,H.jsx)(`span`,{className:`flex-1 truncate font-mono`,children:t.path}),t.additions>0&&(0,H.jsxs)(`span`,{className:`text-green-500`,children:[`+`,t.additions]}),t.deletions>0&&(0,H.jsxs)(`span`,{className:`text-red-500`,children:[`-`,t.deletions]})]},t.path))]})]})}function Y({type:e,hash:t,onClose:n,onCreateBranch:r,onCreateTag:i}){let[a,s]=(0,I.useState)(``),l=()=>{a.trim()&&(e===`branch`?r(a.trim(),t):i(a.trim(),t),n())};return(0,H.jsx)(O,{open:e!==null,onOpenChange:e=>{e||n()},children:(0,H.jsxs)(D,{children:[(0,H.jsx)(N,{children:(0,H.jsx)(T,{children:e===`branch`?`Create Branch`:`Create Tag`})}),(0,H.jsx)(c,{placeholder:e===`branch`?`Branch name`:`Tag name`,value:a,onChange:e=>s(e.target.value),onKeyDown:e=>{e.key===`Enter`&&l()},autoFocus:!0}),(0,H.jsxs)(A,{children:[(0,H.jsx)(o,{variant:`outline`,onClick:n,children:`Cancel`}),(0,H.jsx)(o,{disabled:!a.trim(),onClick:l,children:`Create`})]})]})})}function X({open:e,onClose:t,projectName:n,branches:r}){let i=r.filter(e=>!e.remote),a=r.filter(e=>e.remote),o=new Map;for(let e of a){let t=e.name.replace(/^remotes\//,``),n=t.indexOf(`/`);if(n<0)continue;let r=t.slice(0,n),i=t.slice(n+1),a=o.get(r)??[];a.push(i),o.set(r,a)}return(0,H.jsx)(O,{open:e,onOpenChange:e=>{e||t()},children:(0,H.jsxs)(D,{className:`max-w-md`,children:[(0,H.jsx)(N,{children:(0,H.jsx)(T,{children:`Repository Settings`})}),(0,H.jsxs)(`div`,{className:`space-y-4 text-sm`,children:[(0,H.jsxs)(Z,{title:`General`,children:[(0,H.jsx)(Q,{label:`Name`,value:n}),(0,H.jsx)(Q,{label:`Branches`,value:`${i.length} local, ${a.length} remote`})]}),(0,H.jsx)(Z,{title:`Local Branches`,children:i.map(e=>(0,H.jsxs)(`div`,{className:`flex items-center gap-2 py-0.5`,children:[(0,H.jsx)(`span`,{className:`text-xs ${e.current?`font-semibold text-primary`:`text-foreground`}`,children:e.name}),e.current&&(0,H.jsx)(`span`,{className:`text-[10px] text-muted-foreground italic`,children:`HEAD`}),e.remotes.length>0&&(0,H.jsxs)(`span`,{className:`text-[10px] text-muted-foreground`,children:[`(`,e.remotes.join(`, `),`)`]})]},e.name))}),(0,H.jsxs)(Z,{title:`Remotes`,children:[[...o.entries()].map(([e,t])=>(0,H.jsxs)(`div`,{className:`py-0.5`,children:[(0,H.jsx)(`span`,{className:`text-xs font-medium`,children:e}),(0,H.jsxs)(`span`,{className:`text-[10px] text-muted-foreground ml-2`,children:[t.length,` branch`,t.length===1?``:`es`]})]},e)),o.size===0&&(0,H.jsx)(`span`,{className:`text-xs text-muted-foreground`,children:`No remotes configured`})]})]})]})})}function Z({title:e,children:t}){return(0,H.jsxs)(`div`,{children:[(0,H.jsx)(`h4`,{className:`text-xs font-semibold text-muted-foreground uppercase tracking-wider mb-1.5`,children:e}),(0,H.jsx)(`div`,{className:`pl-1`,children:t})]})}function Q({label:e,value:t}){return(0,H.jsxs)(`div`,{className:`flex items-center gap-3 py-0.5`,children:[(0,H.jsx)(`span`,{className:`text-xs text-muted-foreground w-16 shrink-0`,children:e}),(0,H.jsx)(`span`,{className:`text-xs`,children:t})]})}function $({metadata:e}){let t=e?.projectName,n=B(t),[r,i]=(0,I.useState)({type:null}),[a,o]=(0,I.useState)(!1),s=(typeof window<`u`&&window.innerWidth<768?6:10)*16+16,[c,l]=(0,I.useState)(s),u=(0,I.useRef)(s);u.current=c;let d=(0,I.useRef)(!1),f=e=>{d.current=!0;let t=u.current,n=n=>{if(!d.current)return;let r=`touches`in n?n.touches[0].clientX:n.clientX;l(Math.max(40,t+r-e))},r=()=>{d.current=!1,window.removeEventListener(`mousemove`,n),window.removeEventListener(`mouseup`,r),window.removeEventListener(`touchmove`,n),window.removeEventListener(`touchend`,r)};window.addEventListener(`mousemove`,n),window.addEventListener(`mouseup`,r),window.addEventListener(`touchmove`,n,{passive:!1}),window.addEventListener(`touchend`,r)},{widths:p,startResize:m}=V({date:80,author:120,commit:70}),h=(0,I.useRef)(n.loadMore);h.current=n.loadMore;let g=(0,I.useCallback)(e=>{let t=e.currentTarget;t.scrollHeight-t.scrollTop-t.clientHeight<200&&h.current()},[]);return t?n.loading&&!n.data?(0,H.jsx)(oe,{}):n.error&&!n.data?(0,H.jsx)(se,{error:n.error,onRetry:n.fetchGraph}):(0,H.jsxs)(`div`,{className:`flex flex-col h-full`,children:[(0,H.jsx)(U,{branches:n.data?.branches??[],branchFilter:n.branchFilter,onBranchFilterChange:n.setBranchFilter,searchQuery:n.searchQuery,onSearchQueryChange:n.setSearchQuery,showSearch:n.showSearch,onToggleSearch:()=>n.setShowSearch(!n.showSearch),onFetch:n.fetchFromRemotes,onRefresh:n.fetchGraph,onOpenSettings:()=>o(!0),loading:n.loading,acting:n.acting,projectName:t}),n.error&&(0,H.jsx)(`div`,{className:`px-3 py-1.5 text-xs text-destructive bg-destructive/10`,children:n.error}),(0,H.jsx)(`div`,{className:`flex-1 overflow-auto`,onScroll:g,children:(0,H.jsxs)(`div`,{className:`flex min-w-max md:min-w-0`,children:[(0,H.jsxs)(`div`,{className:`sticky left-0 z-10 shrink-0 bg-background relative overflow-hidden`,style:{width:`${c}px`},children:[(0,H.jsx)(`div`,{className:`text-[11px] font-semibold text-muted-foreground px-2 border-b bg-background sticky top-0 z-20`,style:{height:`24px`,lineHeight:`24px`},children:`Graph`}),(0,H.jsx)(G,{commits:n.filteredCommits,laneMap:n.filteredLanes.laneMap,svgPaths:n.svgPaths,width:(n.filteredLanes.maxLane+2)*16,height:n.svgHeight,headHash:n.headHash}),(0,H.jsx)(`div`,{className:`absolute top-0 right-0 w-1.5 h-full cursor-col-resize hover:bg-primary/30`,onMouseDown:e=>{e.preventDefault(),f(e.clientX)},onTouchStart:e=>f(e.touches[0].clientX)})]}),(0,H.jsxs)(`div`,{className:`flex-1 min-w-[400px]`,children:[(0,H.jsxs)(`table`,{className:`w-full border-collapse text-xs`,style:{tableLayout:`fixed`},children:[(0,H.jsxs)(`colgroup`,{children:[(0,H.jsx)(`col`,{}),(0,H.jsx)(`col`,{style:{width:`${p.date}px`}}),(0,H.jsx)(`col`,{style:{width:`${p.author}px`}}),(0,H.jsx)(`col`,{style:{width:`${p.commit}px`}})]}),(0,H.jsx)(`thead`,{className:`sticky top-0 z-10 bg-background`,children:(0,H.jsxs)(`tr`,{className:`border-b text-[11px] font-semibold text-muted-foreground`,style:{height:`24px`},children:[(0,H.jsx)(`th`,{className:`text-left px-2 font-semibold`,children:`Description`}),(0,H.jsx)(ie,{label:`Date`,colKey:`date`,onStartResize:m}),(0,H.jsx)(ie,{label:`Author`,colKey:`author`,onStartResize:m}),(0,H.jsx)(`th`,{className:`text-left px-2 font-semibold`,children:`Commit`})]})}),(0,H.jsx)(`tbody`,{children:n.filteredCommits.map(e=>(0,H.jsx)(q,{commit:e,lane:n.filteredLanes.laneMap.get(e.hash)??0,isSelected:n.selectedCommit?.hash===e.hash,isHead:e.hash===n.headHash,labels:n.commitLabels.get(e.hash)??[],currentBranch:n.currentBranch,onSelect:()=>n.selectCommit(e),onCheckout:n.handleCheckout,onCherryPick:n.handleCherryPick,onRevert:n.handleRevert,onMerge:n.handleMerge,onDeleteBranch:n.handleDeleteBranch,onPushBranch:n.handlePushBranch,onCreatePr:n.handleCreatePr,onOpenCreateBranch:e=>i({type:`branch`,hash:e}),onOpenCreateTag:e=>i({type:`tag`,hash:e}),onOpenDiff:()=>n.openDiffForCommit(e),onCopyHash:()=>n.copyHash(e.hash)},e.hash))})]}),n.loadingMore&&(0,H.jsxs)(`div`,{className:`flex items-center justify-center gap-2 py-3 text-xs text-muted-foreground`,children:[(0,H.jsx)(C,{className:`size-3.5 animate-spin`}),` Loading more commits...`]}),!n.hasMore&&n.data&&n.data.commits.length>0&&(0,H.jsxs)(`div`,{className:`text-center py-2 text-xs text-muted-foreground`,children:[n.data.commits.length,` commits loaded`]})]})]})}),n.selectedCommit&&t&&(0,H.jsx)(J,{commit:n.selectedCommit,files:n.commitFiles,loadingDetail:n.loadingDetail,projectName:t,onClose:()=>n.setSelectedCommit(null),copyHash:n.copyHash}),(0,H.jsx)(Y,{type:r.type,hash:r.hash,onClose:()=>i({type:null}),onCreateBranch:n.handleCreateBranch,onCreateTag:n.handleCreateTag}),(0,H.jsx)(X,{open:a,onClose:()=>o(!1),projectName:t,branches:n.data?.branches??[]})]}):(0,H.jsx)(ae,{msg:`No project selected.`})}function ie({label:e,colKey:t,onStartResize:n}){return(0,H.jsxs)(`th`,{className:`text-left px-2 font-semibold relative`,children:[e,(0,H.jsx)(`div`,{className:`absolute top-0 right-0 w-1.5 h-full cursor-col-resize hover:bg-primary/30`,onMouseDown:e=>{e.preventDefault(),n(t,e.clientX)},onTouchStart:e=>n(t,e.touches[0].clientX)})]})}function ae({msg:e}){return(0,H.jsx)(`div`,{className:`flex items-center justify-center h-full text-muted-foreground text-sm`,children:e})}function oe(){return(0,H.jsxs)(`div`,{className:`flex items-center justify-center h-full gap-2 text-muted-foreground`,children:[(0,H.jsx)(C,{className:`size-5 animate-spin`}),(0,H.jsx)(`span`,{className:`text-sm`,children:`Loading git graph...`})]})}function se({error:e,onRetry:t}){return(0,H.jsxs)(`div`,{className:`flex flex-col items-center justify-center h-full gap-2 text-destructive text-sm`,children:[(0,H.jsx)(`p`,{children:e}),(0,H.jsx)(o,{variant:`outline`,size:`sm`,onClick:t,children:`Retry`})]})}export{$ as GitGraph};