@hienlh/ppm 0.13.44 → 0.13.45

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 (121) hide show
  1. package/CHANGELOG.md +5 -0
  2. package/assets/skills/ppm/SKILL.md +1 -1
  3. package/assets/skills/ppm/references/http-api.md +1 -1
  4. package/dist/web/assets/ai-settings-section-Btix996C.js +2 -1
  5. package/dist/web/assets/ai-settings-section-Btix996C.js.map +1 -0
  6. package/dist/web/assets/api-client-DIhJ5qVW.js +2 -1
  7. package/dist/web/assets/api-client-DIhJ5qVW.js.map +1 -0
  8. package/dist/web/assets/api-settings-DnHv6JgF.js +2 -1
  9. package/dist/web/assets/api-settings-DnHv6JgF.js.map +1 -0
  10. package/dist/web/assets/arrow-up-Rcw6_KKu.js +2 -1
  11. package/dist/web/assets/arrow-up-Rcw6_KKu.js.map +1 -0
  12. package/dist/web/assets/audio-preview-B6a1Djtr.js +2 -1
  13. package/dist/web/assets/audio-preview-B6a1Djtr.js.map +1 -0
  14. package/dist/web/assets/chat-tab-Z5VNzYCz.js +2 -1
  15. package/dist/web/assets/chat-tab-Z5VNzYCz.js.map +1 -0
  16. package/dist/web/assets/chevron-right-DnHIvvcy.js +2 -1
  17. package/dist/web/assets/chevron-right-DnHIvvcy.js.map +1 -0
  18. package/dist/web/assets/code-DGBecc50.js +2 -1
  19. package/dist/web/assets/code-DGBecc50.js.map +1 -0
  20. package/dist/web/assets/code-editor-Clvs0e0Q.js +2 -1
  21. package/dist/web/assets/code-editor-Clvs0e0Q.js.map +1 -0
  22. package/dist/web/assets/conflict-editor-B6nO1gln.js +2 -1
  23. package/dist/web/assets/conflict-editor-B6nO1gln.js.map +1 -0
  24. package/dist/web/assets/createLucideIcon-BjHrJDVb.js +2 -1
  25. package/dist/web/assets/createLucideIcon-BjHrJDVb.js.map +1 -0
  26. package/dist/web/assets/csv-parser-Dly5nqE1.js +2 -1
  27. package/dist/web/assets/csv-parser-Dly5nqE1.js.map +1 -0
  28. package/dist/web/assets/csv-preview-CsqFmPzb.js +2 -1
  29. package/dist/web/assets/csv-preview-CsqFmPzb.js.map +1 -0
  30. package/dist/web/assets/data-grid-overlay-editor-aTzJjALy.js +2 -1
  31. package/dist/web/assets/data-grid-overlay-editor-aTzJjALy.js.map +1 -0
  32. package/dist/web/assets/data-grid-types-BISkUXAY.js +2 -1
  33. package/dist/web/assets/data-grid-types-BISkUXAY.js.map +1 -0
  34. package/dist/web/assets/database-DOWH9-Vv.js +2 -1
  35. package/dist/web/assets/database-DOWH9-Vv.js.map +1 -0
  36. package/dist/web/assets/database-viewer-Boup8MJ_.js +2 -1
  37. package/dist/web/assets/database-viewer-Boup8MJ_.js.map +1 -0
  38. package/dist/web/assets/diff-viewer-Je2KYGME.js +2 -1
  39. package/dist/web/assets/diff-viewer-Je2KYGME.js.map +1 -0
  40. package/dist/web/assets/dist-B1I_4Jtc.js +2 -1
  41. package/dist/web/assets/dist-B1I_4Jtc.js.map +1 -0
  42. package/dist/web/assets/dist-CcDNqGjt.js +2 -1
  43. package/dist/web/assets/dist-CcDNqGjt.js.map +1 -0
  44. package/dist/web/assets/dist-wf2npcsG.js +2 -1
  45. package/dist/web/assets/dist-wf2npcsG.js.map +1 -0
  46. package/dist/web/assets/esm-UZtw2QcY.js +2 -1
  47. package/dist/web/assets/esm-UZtw2QcY.js.map +1 -0
  48. package/dist/web/assets/extension-webview-T9TN70nb.js +2 -1
  49. package/dist/web/assets/extension-webview-T9TN70nb.js.map +1 -0
  50. package/dist/web/assets/file-exclamation-point-BwzaQ50n.js +2 -1
  51. package/dist/web/assets/file-exclamation-point-BwzaQ50n.js.map +1 -0
  52. package/dist/web/assets/file-store-DOxcU_7s.js +2 -1
  53. package/dist/web/assets/file-store-DOxcU_7s.js.map +1 -0
  54. package/dist/web/assets/glide-data-grid-CqT8WzTs.js +2 -1
  55. package/dist/web/assets/glide-data-grid-CqT8WzTs.js.map +1 -0
  56. package/dist/web/assets/image-preview-DeNUcGI9.js +2 -1
  57. package/dist/web/assets/image-preview-DeNUcGI9.js.map +1 -0
  58. package/dist/web/assets/index-DJtqbPFT.js +2 -1
  59. package/dist/web/assets/index-DJtqbPFT.js.map +1 -0
  60. package/dist/web/assets/input-_LFQwhzd.js +2 -1
  61. package/dist/web/assets/input-_LFQwhzd.js.map +1 -0
  62. package/dist/web/assets/katex-Bqvo_ZG0.js +2 -1
  63. package/dist/web/assets/katex-Bqvo_ZG0.js.map +1 -0
  64. package/dist/web/assets/lib-Bu71-TFS.js +2 -1
  65. package/dist/web/assets/lib-Bu71-TFS.js.map +1 -0
  66. package/dist/web/assets/markdown-renderer-CXPtICSx.js +2 -1
  67. package/dist/web/assets/markdown-renderer-CXPtICSx.js.map +1 -0
  68. package/dist/web/assets/number-overlay-editor-CewUR5pB.js +2 -1
  69. package/dist/web/assets/number-overlay-editor-CewUR5pB.js.map +1 -0
  70. package/dist/web/assets/pdf-preview-DI2JU2Lm.js +2 -1
  71. package/dist/web/assets/pdf-preview-DI2JU2Lm.js.map +1 -0
  72. package/dist/web/assets/port-forwarding-tab-Cuv_37LW.js +2 -1
  73. package/dist/web/assets/port-forwarding-tab-Cuv_37LW.js.map +1 -0
  74. package/dist/web/assets/postgres-viewer-D76ygOZo.js +2 -1
  75. package/dist/web/assets/postgres-viewer-D76ygOZo.js.map +1 -0
  76. package/dist/web/assets/react-DMIOAtcX.js +2 -1
  77. package/dist/web/assets/react-DMIOAtcX.js.map +1 -0
  78. package/dist/web/assets/refresh-cw-BjrAbUJe.js +2 -1
  79. package/dist/web/assets/refresh-cw-BjrAbUJe.js.map +1 -0
  80. package/dist/web/assets/scroll-area-BDi_FNzr.js +2 -1
  81. package/dist/web/assets/scroll-area-BDi_FNzr.js.map +1 -0
  82. package/dist/web/assets/search-tM8K5zWU.js +2 -1
  83. package/dist/web/assets/search-tM8K5zWU.js.map +1 -0
  84. package/dist/web/assets/settings-store-CVrIYYCB.js +2 -1
  85. package/dist/web/assets/settings-store-CVrIYYCB.js.map +1 -0
  86. package/dist/web/assets/sparkles-CulWHe4c.js +2 -1
  87. package/dist/web/assets/sparkles-CulWHe4c.js.map +1 -0
  88. package/dist/web/assets/sql-query-editor-lSlKMPlG.js +2 -1
  89. package/dist/web/assets/sql-query-editor-lSlKMPlG.js.map +1 -0
  90. package/dist/web/assets/sqlite-viewer-DwTatNwI.js +2 -1
  91. package/dist/web/assets/sqlite-viewer-DwTatNwI.js.map +1 -0
  92. package/dist/web/assets/tab-store-S9w6U5gm.js +2 -1
  93. package/dist/web/assets/tab-store-S9w6U5gm.js.map +1 -0
  94. package/dist/web/assets/table-BzjWcs87.js +2 -1
  95. package/dist/web/assets/table-BzjWcs87.js.map +1 -0
  96. package/dist/web/assets/terminal-tab-XKe1TZiV.js +2 -1
  97. package/dist/web/assets/terminal-tab-XKe1TZiV.js.map +1 -0
  98. package/dist/web/assets/text-wrap-DJz9Bgpa.js +2 -1
  99. package/dist/web/assets/text-wrap-DJz9Bgpa.js.map +1 -0
  100. package/dist/web/assets/use-blob-url-QX-XajU8.js +2 -1
  101. package/dist/web/assets/use-blob-url-QX-XajU8.js.map +1 -0
  102. package/dist/web/assets/use-monaco-theme-BePWbY58.js +2 -1
  103. package/dist/web/assets/use-monaco-theme-BePWbY58.js.map +1 -0
  104. package/dist/web/assets/utils-CQux7CsO.js +2 -1
  105. package/dist/web/assets/utils-CQux7CsO.js.map +1 -0
  106. package/dist/web/assets/vendor-markdown-0Mxgxy0L.js +2 -1
  107. package/dist/web/assets/vendor-markdown-0Mxgxy0L.js.map +1 -0
  108. package/dist/web/assets/vendor-mermaid-Cl50p6TB.js +2 -1
  109. package/dist/web/assets/vendor-mermaid-Cl50p6TB.js.map +1 -0
  110. package/dist/web/assets/vendor-ui-UXCWAcmi.js +2 -1
  111. package/dist/web/assets/vendor-ui-UXCWAcmi.js.map +1 -0
  112. package/dist/web/assets/vendor-xterm-K3_Xwigj.js +2 -1
  113. package/dist/web/assets/vendor-xterm-K3_Xwigj.js.map +1 -0
  114. package/dist/web/assets/video-preview-wHVbAYar.js +2 -1
  115. package/dist/web/assets/video-preview-wHVbAYar.js.map +1 -0
  116. package/dist/web/assets/x-BPReZWnP.js +2 -1
  117. package/dist/web/assets/x-BPReZWnP.js.map +1 -0
  118. package/dist/web/sw.js +2 -1
  119. package/dist/web/sw.js.map +1 -0
  120. package/package.json +1 -1
  121. package/vite.config.ts +1 -0
@@ -1,3 +1,4 @@
1
1
  import{o as e}from"./rolldown-runtime-FhOqtrmT.js";import{b as t,x as n}from"./vendor-markdown-0Mxgxy0L.js";import{r}from"./api-client-DIhJ5qVW.js";import{G as i,w as a}from"./index-DJtqbPFT.js";var o=e(n(),1),s=t(),c=`<script>
2
2
  function acquireVsCodeApi(){return{postMessage:function(m){window.parent.postMessage(m,"*")},getState:function(){try{return JSON.parse(sessionStorage.getItem("vscode-state")||"null")}catch{return null}},setState:function(s){sessionStorage.setItem("vscode-state",JSON.stringify(s));return s}}}
3
- <\/script>`;function l(e){if(!e)return e;let t=e.indexOf(`<head>`);return t===-1?c+e:e.slice(0,t+6)+c+e.slice(t+6)}function u({metadata:e}){let t=e?.panelId,n=e?.viewType,c=e?.projectName||void 0,[u,d]=(0,o.useState)(!1),f=a(e=>e.contributions!==null),p=a(e=>{if(t&&e.webviewPanels[t])return e.webviewPanels[t];if(n){let t=n.includes(`.`)?n:`${n}.view`;return Object.values(e.webviewPanels).find(e=>e.viewType===n||e.viewType===t)}}),m=p?.id??t,h=(0,o.useRef)(null),g=p?.html??``,_=l(g),v=(0,o.useRef)(null);(0,o.useEffect)(()=>{if(p||!n||!f||c&&c===v.current)return;c&&(v.current=c);let e=n.includes(`.`)?n:`${n}.view`,t=!1;async function i(){let n=[];if(c)try{let e=r(),t=(await(await fetch(`/api/projects`,e?{headers:{Authorization:`Bearer ${e}`}}:{})).json()).data?.find(e=>e.name===c);t&&(n=[t.path])}catch{}t||window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:n}}))}return i(),()=>{t=!0}},[p,n,c,f]);let y=e?.extensionId,b=a(e=>{if(y&&e.activationErrors[y])return e.activationErrors[y];if(n){for(let[t,r]of Object.entries(e.activationErrors))if(t===`ext-${n}`)return r}}),x=(0,o.useCallback)(()=>{if(d(!1),!n)return;let e=n.includes(`.`)?n:`${n}.view`;(async()=>{try{let t=r(),n=(await(await fetch(`/api/projects`,t?{headers:{Authorization:`Bearer ${t}`}}:{})).json()).data?.find(e=>e.name===c),i=n?[n.path]:[];window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:i}}))}catch{}})()},[n,c]),S=(0,o.useRef)(null),C=(0,o.useRef)(n);return(0,o.useEffect)(()=>{S.current=m??null},[m]),(0,o.useEffect)(()=>{C.current=n},[n]),(0,o.useEffect)(()=>()=>{let e=S.current;if(e){let t=C.current;a.getState().removeWebviewPanel(e),window.dispatchEvent(new CustomEvent(`ext:webview:close`,{detail:{panelId:e,viewType:t}}))}},[]),(0,o.useEffect)(()=>{if(p){d(!1);return}if(!f||!n)return;let e=0,t=setInterval(()=>{if(e++,e>3){clearInterval(t),d(!0);return}x()},2e3);return()=>clearInterval(t)},[p,f,n,x]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{h.current&&e.source===h.current.contentWindow&&window.dispatchEvent(new CustomEvent(`ext:webview:send`,{detail:{panelId:m,message:e.data}}))};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)},[m]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{let{panelId:t,message:n}=e.detail;t===m&&h.current?.contentWindow?.postMessage(n,`*`)};return window.addEventListener(`ext:webview:message`,e),()=>window.removeEventListener(`ext:webview:message`,e)},[m]),!p||!g?(0,s.jsx)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-sm text-text-subtle`,children:u?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`span`,{className:`text-destructive font-medium`,children:`Extension failed to load`}),b&&(0,s.jsx)(`span`,{className:`text-xs text-muted-foreground max-w-md text-center`,children:b}),(0,s.jsx)(`button`,{onClick:x,className:`text-xs text-primary hover:underline`,children:`Retry`})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i,{className:`size-5 animate-spin`}),(0,s.jsx)(`span`,{children:`Loading extension...`})]})}):(0,s.jsx)(`div`,{className:`h-full w-full relative`,children:(0,s.jsx)(`iframe`,{ref:h,srcDoc:_,sandbox:`allow-scripts`,className:`w-full h-full border-0 bg-white dark:bg-zinc-900`,title:p.title},m)})}export{u as ExtensionWebview};
3
+ <\/script>`;function l(e){if(!e)return e;let t=e.indexOf(`<head>`);return t===-1?c+e:e.slice(0,t+6)+c+e.slice(t+6)}function u({metadata:e}){let t=e?.panelId,n=e?.viewType,c=e?.projectName||void 0,[u,d]=(0,o.useState)(!1),f=a(e=>e.contributions!==null),p=a(e=>{if(t&&e.webviewPanels[t])return e.webviewPanels[t];if(n){let t=n.includes(`.`)?n:`${n}.view`;return Object.values(e.webviewPanels).find(e=>e.viewType===n||e.viewType===t)}}),m=p?.id??t,h=(0,o.useRef)(null),g=p?.html??``,_=l(g),v=(0,o.useRef)(null);(0,o.useEffect)(()=>{if(p||!n||!f||c&&c===v.current)return;c&&(v.current=c);let e=n.includes(`.`)?n:`${n}.view`,t=!1;async function i(){let n=[];if(c)try{let e=r(),t=(await(await fetch(`/api/projects`,e?{headers:{Authorization:`Bearer ${e}`}}:{})).json()).data?.find(e=>e.name===c);t&&(n=[t.path])}catch{}t||window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:n}}))}return i(),()=>{t=!0}},[p,n,c,f]);let y=e?.extensionId,b=a(e=>{if(y&&e.activationErrors[y])return e.activationErrors[y];if(n){for(let[t,r]of Object.entries(e.activationErrors))if(t===`ext-${n}`)return r}}),x=(0,o.useCallback)(()=>{if(d(!1),!n)return;let e=n.includes(`.`)?n:`${n}.view`;(async()=>{try{let t=r(),n=(await(await fetch(`/api/projects`,t?{headers:{Authorization:`Bearer ${t}`}}:{})).json()).data?.find(e=>e.name===c),i=n?[n.path]:[];window.dispatchEvent(new CustomEvent(`ext:command:execute`,{detail:{command:e,args:i}}))}catch{}})()},[n,c]),S=(0,o.useRef)(null),C=(0,o.useRef)(n);return(0,o.useEffect)(()=>{S.current=m??null},[m]),(0,o.useEffect)(()=>{C.current=n},[n]),(0,o.useEffect)(()=>()=>{let e=S.current;if(e){let t=C.current;a.getState().removeWebviewPanel(e),window.dispatchEvent(new CustomEvent(`ext:webview:close`,{detail:{panelId:e,viewType:t}}))}},[]),(0,o.useEffect)(()=>{if(p){d(!1);return}if(!f||!n)return;let e=0,t=setInterval(()=>{if(e++,e>3){clearInterval(t),d(!0);return}x()},2e3);return()=>clearInterval(t)},[p,f,n,x]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{h.current&&e.source===h.current.contentWindow&&window.dispatchEvent(new CustomEvent(`ext:webview:send`,{detail:{panelId:m,message:e.data}}))};return window.addEventListener(`message`,e),()=>window.removeEventListener(`message`,e)},[m]),(0,o.useEffect)(()=>{if(!m)return;let e=e=>{let{panelId:t,message:n}=e.detail;t===m&&h.current?.contentWindow?.postMessage(n,`*`)};return window.addEventListener(`ext:webview:message`,e),()=>window.removeEventListener(`ext:webview:message`,e)},[m]),!p||!g?(0,s.jsx)(`div`,{className:`flex flex-col items-center justify-center h-full gap-3 text-sm text-text-subtle`,children:u?(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(`span`,{className:`text-destructive font-medium`,children:`Extension failed to load`}),b&&(0,s.jsx)(`span`,{className:`text-xs text-muted-foreground max-w-md text-center`,children:b}),(0,s.jsx)(`button`,{onClick:x,className:`text-xs text-primary hover:underline`,children:`Retry`})]}):(0,s.jsxs)(s.Fragment,{children:[(0,s.jsx)(i,{className:`size-5 animate-spin`}),(0,s.jsx)(`span`,{children:`Loading extension...`})]})}):(0,s.jsx)(`div`,{className:`h-full w-full relative`,children:(0,s.jsx)(`iframe`,{ref:h,srcDoc:_,sandbox:`allow-scripts`,className:`w-full h-full border-0 bg-white dark:bg-zinc-900`,title:p.title},m)})}export{u as ExtensionWebview};
4
+ //# sourceMappingURL=extension-webview-T9TN70nb.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"extension-webview-T9TN70nb.js","names":[],"sources":["../../../src/web/components/extensions/extension-webview.tsx"],"sourcesContent":["import { useRef, useEffect, useState, useCallback } from \"react\";\nimport { useExtensionStore } from \"@/stores/extension-store\";\nimport { getAuthToken } from \"@/lib/api-client\";\nimport { Loader2 } from \"lucide-react\";\n\n/** Inject acquireVsCodeApi() shim so extension webviews can postMessage to parent */\nconst VSCODE_API_SHIM = `<script>\nfunction acquireVsCodeApi(){return{postMessage:function(m){window.parent.postMessage(m,\"*\")},getState:function(){try{return JSON.parse(sessionStorage.getItem(\"vscode-state\")||\"null\")}catch{return null}},setState:function(s){sessionStorage.setItem(\"vscode-state\",JSON.stringify(s));return s}}}\n</script>`;\n\nfunction injectVscodeApiShim(html: string): string {\n if (!html) return html;\n // Insert shim right after <head> tag (or at start if no <head>)\n const headIdx = html.indexOf(\"<head>\");\n if (headIdx !== -1) {\n return html.slice(0, headIdx + 6) + VSCODE_API_SHIM + html.slice(headIdx + 6);\n }\n return VSCODE_API_SHIM + html;\n}\n\ninterface ExtensionWebviewProps {\n metadata?: Record<string, unknown>;\n}\n\n/**\n * iframe-based webview container for extension-contributed webview panels.\n * Matches panel by panelId (direct) or viewType (reload recovery).\n */\nexport function ExtensionWebview({ metadata }: ExtensionWebviewProps) {\n const panelId = metadata?.panelId as string | undefined;\n const viewType = metadata?.viewType as string | undefined;\n // Use the tab's own project name (frozen at creation time) — NOT the global\n // currentProject. Old project's ExtensionWebview must not react to project\n // switches, which would dispatch commands for the wrong project.\n const projectName = (metadata?.projectName as string | undefined) || undefined;\n const [timedOut, setTimedOut] = useState(false);\n // Track whether extensions are activated (contributions received from WS)\n const extensionsReady = useExtensionStore((s) => s.contributions !== null);\n\n // Match panel: prefer panelId (exact), fallback to viewType match (reload recovery)\n const panel = useExtensionStore((s) => {\n if (panelId && s.webviewPanels[panelId]) return s.webviewPanels[panelId];\n if (viewType) {\n // Find panel whose viewType matches (with or without .view suffix)\n const fullViewType = viewType.includes(\".\") ? viewType : `${viewType}.view`;\n return Object.values(s.webviewPanels).find(\n (p) => p.viewType === viewType || p.viewType === fullViewType,\n );\n }\n return undefined;\n });\n\n const resolvedPanelId = panel?.id ?? panelId;\n const iframeRef = useRef<HTMLIFrameElement>(null);\n\n // Inject acquireVsCodeApi shim + write HTML into iframe via srcdoc\n const rawHtml = panel?.html ?? \"\";\n const html = injectVscodeApiShim(rawHtml);\n\n // Track which project was last dispatched to prevent duplicate dispatches\n const prevProjectRef = useRef<string | null>(null);\n\n // On reload: resolve project path and dispatch command once.\n // Wait for extensions to be activated (contributions received) before dispatching.\n useEffect(() => {\n if (panel || !viewType || !extensionsReady) return;\n // Already dispatched for this project — panel is just temporarily missing\n if (projectName && projectName === prevProjectRef.current) return;\n if (projectName) prevProjectRef.current = projectName;\n const command = viewType.includes(\".\") ? viewType : `${viewType}.view`;\n let cancelled = false;\n\n async function dispatch() {\n let args: unknown[] = [];\n if (projectName) {\n try {\n const token = getAuthToken();\n const res = await fetch(\"/api/projects\", token ? { headers: { Authorization: `Bearer ${token}` } } : {});\n const json = await res.json() as { ok: boolean; data?: { name: string; path: string }[] };\n const match = json.data?.find((p) => p.name === projectName);\n if (match) args = [match.path];\n } catch {}\n }\n if (cancelled) return;\n window.dispatchEvent(new CustomEvent(\"ext:command:execute\", {\n detail: { command, args },\n }));\n }\n\n dispatch();\n return () => { cancelled = true; };\n }, [panel, viewType, projectName, extensionsReady]);\n\n // Check activation errors for this extension\n const extensionId = metadata?.extensionId as string | undefined;\n const activationError = useExtensionStore((s) => {\n // Direct match by extensionId (most reliable)\n if (extensionId && s.activationErrors[extensionId]) return s.activationErrors[extensionId];\n // Fallback: check by viewType prefix (e.g. \"ext-git-graph\" for viewType \"git-graph\")\n if (!viewType) return undefined;\n for (const [extId, error] of Object.entries(s.activationErrors)) {\n if (extId === `ext-${viewType}`) return error;\n }\n return undefined;\n });\n\n // Retry handler — re-dispatches the command\n const handleRetry = useCallback(() => {\n setTimedOut(false);\n if (!viewType) return;\n const command = viewType.includes(\".\") ? viewType : `${viewType}.view`;\n (async () => {\n try {\n const token = getAuthToken();\n const res = await fetch(\"/api/projects\", token ? { headers: { Authorization: `Bearer ${token}` } } : {});\n const json = await res.json() as { ok: boolean; data?: { name: string; path: string }[] };\n const match = json.data?.find((p) => p.name === projectName);\n const args = match ? [match.path] : [];\n window.dispatchEvent(new CustomEvent(\"ext:command:execute\", {\n detail: { command, args },\n }));\n } catch {}\n })();\n }, [viewType, projectName]);\n\n // On unmount: notify server to dispose the panel so extension clears activePanel state\n const panelIdForCleanup = useRef<string | null>(null);\n const viewTypeForCleanup = useRef<string | undefined>(viewType);\n useEffect(() => {\n panelIdForCleanup.current = resolvedPanelId ?? null;\n }, [resolvedPanelId]);\n useEffect(() => {\n viewTypeForCleanup.current = viewType;\n }, [viewType]);\n useEffect(() => {\n return () => {\n const id = panelIdForCleanup.current;\n if (id) {\n const vt = viewTypeForCleanup.current;\n useExtensionStore.getState().removeWebviewPanel(id);\n window.dispatchEvent(new CustomEvent(\"ext:webview:close\", { detail: { panelId: id, viewType: vt } }));\n }\n };\n }, []);\n\n // Auto-retry: if panel doesn't appear after extensions are ready,\n // re-dispatch the command every 2s (up to 3 times) before showing error.\n // This handles transient WS instability during initial page load where the\n // first command dispatch may be lost due to connection cycling.\n useEffect(() => {\n if (panel) { setTimedOut(false); return; }\n if (!extensionsReady || !viewType) return;\n let retries = 0;\n const id = setInterval(() => {\n retries++;\n if (retries > 3) {\n clearInterval(id);\n setTimedOut(true);\n return;\n }\n handleRetry();\n }, 2_000);\n return () => clearInterval(id);\n }, [panel, extensionsReady, viewType, handleRetry]);\n\n // Listen for postMessage from iframe → forward to extension via WS bridge\n useEffect(() => {\n if (!resolvedPanelId) return;\n const handler = (event: MessageEvent) => {\n if (iframeRef.current && event.source === iframeRef.current.contentWindow) {\n window.dispatchEvent(new CustomEvent(\"ext:webview:send\", {\n detail: { panelId: resolvedPanelId, message: event.data },\n }));\n }\n };\n window.addEventListener(\"message\", handler);\n return () => window.removeEventListener(\"message\", handler);\n }, [resolvedPanelId]);\n\n // Listen for server→webview messages (dispatched by useExtensionWs)\n useEffect(() => {\n if (!resolvedPanelId) return;\n const handler = (e: Event) => {\n const { panelId: targetId, message } = (e as CustomEvent).detail;\n if (targetId === resolvedPanelId) {\n iframeRef.current?.contentWindow?.postMessage(message, \"*\");\n }\n };\n window.addEventListener(\"ext:webview:message\", handler);\n return () => window.removeEventListener(\"ext:webview:message\", handler);\n }, [resolvedPanelId]);\n\n // Loading state — waiting for extension to create the panel AND deliver HTML.\n // We must wait for HTML before mounting the iframe because browsers don't\n // re-execute scripts when React updates the srcDoc attribute from \"\" to content.\n if (!panel || !rawHtml) {\n return (\n <div className=\"flex flex-col items-center justify-center h-full gap-3 text-sm text-text-subtle\">\n {timedOut ? (\n <>\n <span className=\"text-destructive font-medium\">Extension failed to load</span>\n {activationError && (\n <span className=\"text-xs text-muted-foreground max-w-md text-center\">{activationError}</span>\n )}\n <button\n onClick={handleRetry}\n className=\"text-xs text-primary hover:underline\"\n >\n Retry\n </button>\n </>\n ) : (\n <>\n <Loader2 className=\"size-5 animate-spin\" />\n <span>Loading extension...</span>\n </>\n )}\n </div>\n );\n }\n\n return (\n <div className=\"h-full w-full relative\">\n <iframe\n ref={iframeRef}\n key={resolvedPanelId}\n srcDoc={html}\n sandbox=\"allow-scripts\"\n className=\"w-full h-full border-0 bg-white dark:bg-zinc-900\"\n title={panel.title}\n />\n </div>\n );\n}\n"],"mappings":"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"}
@@ -1 +1,2 @@
1
- import{t as e}from"./createLucideIcon-BjHrJDVb.js";var t=e(`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`}]]);export{t};
1
+ import{t as e}from"./createLucideIcon-BjHrJDVb.js";var t=e(`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`}]]);export{t};
2
+ //# sourceMappingURL=file-exclamation-point-BwzaQ50n.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-exclamation-point-BwzaQ50n.js","names":[],"sources":["../../../node_modules/.bun/lucide-react@0.577.0+b1ab299f0a400331/node_modules/lucide-react/dist/esm/icons/file-exclamation-point.js"],"sourcesContent":["/**\n * @license lucide-react v0.577.0 - ISC\n *\n * This source code is licensed under the ISC license.\n * See the LICENSE file in the root directory of this source tree.\n */\n\nimport createLucideIcon from '../createLucideIcon.js';\n\nconst __iconNode = [\n [\n \"path\",\n {\n 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\",\n key: \"1oefj6\"\n }\n ],\n [\"path\", { d: \"M12 9v4\", key: \"juzpu7\" }],\n [\"path\", { d: \"M12 17h.01\", key: \"p32p05\" }]\n];\nconst FileExclamationPoint = createLucideIcon(\"file-exclamation-point\", __iconNode);\n\nexport { __iconNode, FileExclamationPoint as default };\n//# sourceMappingURL=file-exclamation-point.js.map\n"],"x_google_ignoreList":[0],"mappings":"mDAoBA,IAAM,EAAuB,EAAiB,yBAX3B,CACjB,CACE,OACA,CACE,EAAG,iHACH,IAAK,SACN,CACF,CACD,CAAC,OAAQ,CAAE,EAAG,UAAW,IAAK,SAAU,CAAC,CACzC,CAAC,OAAQ,CAAE,EAAG,aAAc,IAAK,SAAU,CAAC,CAC7C,CACkF"}
@@ -1 +1,2 @@
1
- import{t as e}from"./react-DMIOAtcX.js";import{i as t,t as n}from"./api-client-DIhJ5qVW.js";var r=`ppm-custom-order`;function i(){try{let e=localStorage.getItem(r);return e?JSON.parse(e):null}catch{return null}}function a(e){try{localStorage.setItem(r,JSON.stringify(e))}catch{}}function o(e,t){if(!t)return[...e];let n=new Map(t.map((e,t)=>[e,t]));return[...e].sort((e,t)=>(n.get(e.name)??1/0)-(n.get(t.name)??1/0))}var s=e((e,t)=>({projects:[],activeProject:null,customOrder:i(),loading:!1,error:null,fetchProjects:async()=>{e({loading:!0,error:null});try{e({projects:await n.get(`/api/projects`),loading:!1})}catch(t){e({error:t instanceof Error?t.message:`Failed to fetch projects`,loading:!1})}},setActiveProject:t=>{e({activeProject:t})},addProject:async(r,i)=>{let a=await n.post(`/api/projects`,{path:r,name:i});await t().fetchProjects();let o=t().projects.find(e=>e.name===(i??a.name)||e.path===r);return o&&e({activeProject:o}),a},setProjectColor:async(e,r)=>{await n.patch(`/api/projects/${encodeURIComponent(e)}/color`,{color:r}),await t().fetchProjects()},moveProject:async(r,i)=>{let{projects:s,customOrder:c}=t(),l=o(s,c),u=l.findIndex(e=>e.name===r);if(u===-1)return;let d=i===`up`?u-1:u+1;if(d<0||d>=l.length)return;let f=l.map(e=>e.name);[f[u],f[d]]=[f[d],f[u]],a(f),await n.patch(`/api/projects/reorder`,{order:f}),e({customOrder:f})},reorderProjects:async t=>{a(t),e({customOrder:t}),await n.patch(`/api/projects/reorder`,{order:t}).catch(()=>{})},renameProject:async(e,r)=>{await n.patch(`/api/projects/${encodeURIComponent(e)}`,{name:r}),await t().fetchProjects()},deleteProject:async t=>{await n.del(`/api/projects/${encodeURIComponent(t)}`),e(e=>{let n=e.projects.filter(e=>e.name!==t),r=e.customOrder?e.customOrder.filter(e=>e!==t):null;return r&&a(r),{projects:n,customOrder:r,activeProject:e.activeProject?.name===t?n[0]??null:e.activeProject}})}}));function c(e,t){return e.map(e=>({name:e.name,path:t?`${t}/${e.name}`:e.name,type:e.type,ignored:e.isIgnored}))}function l(e,t,n){return t?e.map(e=>u(e,t,n)):n.map(t=>{let n=e.find(e=>e.path===t.path);return n?{...t,children:n.children}:t})}function u(e,t,n){if(e.path===t){let t=n.map(t=>{let n=e.children?.find(e=>e.path===t.path);return n?{...t,children:n.children}:t});return{...e,children:t}}return e.children&&t.startsWith(e.path+`/`)?{...e,children:e.children.map(e=>u(e,t,n))}:e}var d=e((e,r)=>({tree:[],fileIndex:[],loading:!1,error:null,expandedPaths:new Set,loadedPaths:new Set,inflight:new Map,indexStatus:`idle`,selectedFiles:[],inlineAction:null,clipboard:null,focusedPath:null,setInlineAction:t=>e({inlineAction:t}),clearInlineAction:()=>e({inlineAction:null}),setClipboard:t=>e({clipboard:t}),setFocusedPath:t=>e({focusedPath:t}),loadRoot:async i=>{e({loading:!0,error:null});try{let a=c(await n.get(`${t(i)}/files/list?path=`),``),o=new Set(r().loadedPaths);o.add(``),e({tree:a,loading:!1,loadedPaths:o})}catch(t){e({error:t instanceof Error?t.message:`Failed to load files`,loading:!1})}},loadChildren:async(i,a)=>{let o=r();if(o.loadedPaths.has(a))return;let s=o.inflight.get(a);s&&s.abort();let u=new AbortController,d=new Map(o.inflight);d.set(a,u),e({inflight:d});try{let o=encodeURIComponent(a),s=await n.get(`${t(i)}/files/list?path=${o}`,{signal:u.signal});if(u.signal.aborted)return;let d=c(s,a),f=r(),p=l(f.tree,a,d),m=new Set(f.loadedPaths);m.add(a);let h=new Map(f.inflight);h.delete(a),e({tree:p,loadedPaths:m,inflight:h})}catch(t){if(t instanceof Error&&t.name===`AbortError`)return;let n=new Map(r().inflight);n.delete(a),e({inflight:n})}},loadIndex:async r=>{e({indexStatus:`loading`});try{e({fileIndex:await n.get(`${t(r)}/files/index`),indexStatus:`ready`})}catch{e({indexStatus:`error`})}},invalidateIndex:()=>{e({indexStatus:`idle`,fileIndex:[]})},invalidateFolder:async(t,n)=>{let i=r();if(!i.loadedPaths.has(n))return;let a=new Set(i.loadedPaths);a.delete(n),e({loadedPaths:a}),(!n||i.expandedPaths.has(n))&&await r().loadChildren(t,n)},toggleExpand:(t,n)=>{let i=r(),a=new Set(i.expandedPaths);a.has(n)?(a.delete(n),e({expandedPaths:a})):(a.add(n),e({expandedPaths:a}),i.loadedPaths.has(n)||r().loadChildren(t,n))},setExpanded:(t,n)=>{let i=new Set(r().expandedPaths);n?i.add(t):i.delete(t),e({expandedPaths:i})},collapseAll:()=>{e({expandedPaths:new Set})},toggleFileSelect:t=>{let n=r().selectedFiles;n.indexOf(t)>=0?e({selectedFiles:n.filter(e=>e!==t)}):e({selectedFiles:[...n,t]})},setSelectedFiles:t=>e({selectedFiles:t}),clearSelection:()=>e({selectedFiles:[]}),reset:()=>{for(let e of r().inflight.values())e.abort();e({tree:[],fileIndex:[],loading:!1,error:null,expandedPaths:new Set,loadedPaths:new Set,inflight:new Map,indexStatus:`idle`,selectedFiles:[],inlineAction:null,clipboard:null,focusedPath:null})},fetchTree:async e=>{await r().loadRoot(e),r().loadIndex(e)}}));function f(){let{tree:e,expandedPaths:t}=d.getState(),n=[];function r(e){let i=[...e].sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1);for(let e of i){let i=e;if(e.type===`directory`&&t.has(e.path)&&e.children)for(;i.children&&i.children.length===1&&i.children[0].type===`directory`&&t.has(i.children[0].path);)i=i.children[0];n.push(i.path),i.type===`directory`&&t.has(i.path)&&i.children&&r(i.children)}}return r(e),n}export{s as i,d as n,o as r,f as t};
1
+ import{t as e}from"./react-DMIOAtcX.js";import{i as t,t as n}from"./api-client-DIhJ5qVW.js";var r=`ppm-custom-order`;function i(){try{let e=localStorage.getItem(r);return e?JSON.parse(e):null}catch{return null}}function a(e){try{localStorage.setItem(r,JSON.stringify(e))}catch{}}function o(e,t){if(!t)return[...e];let n=new Map(t.map((e,t)=>[e,t]));return[...e].sort((e,t)=>(n.get(e.name)??1/0)-(n.get(t.name)??1/0))}var s=e((e,t)=>({projects:[],activeProject:null,customOrder:i(),loading:!1,error:null,fetchProjects:async()=>{e({loading:!0,error:null});try{e({projects:await n.get(`/api/projects`),loading:!1})}catch(t){e({error:t instanceof Error?t.message:`Failed to fetch projects`,loading:!1})}},setActiveProject:t=>{e({activeProject:t})},addProject:async(r,i)=>{let a=await n.post(`/api/projects`,{path:r,name:i});await t().fetchProjects();let o=t().projects.find(e=>e.name===(i??a.name)||e.path===r);return o&&e({activeProject:o}),a},setProjectColor:async(e,r)=>{await n.patch(`/api/projects/${encodeURIComponent(e)}/color`,{color:r}),await t().fetchProjects()},moveProject:async(r,i)=>{let{projects:s,customOrder:c}=t(),l=o(s,c),u=l.findIndex(e=>e.name===r);if(u===-1)return;let d=i===`up`?u-1:u+1;if(d<0||d>=l.length)return;let f=l.map(e=>e.name);[f[u],f[d]]=[f[d],f[u]],a(f),await n.patch(`/api/projects/reorder`,{order:f}),e({customOrder:f})},reorderProjects:async t=>{a(t),e({customOrder:t}),await n.patch(`/api/projects/reorder`,{order:t}).catch(()=>{})},renameProject:async(e,r)=>{await n.patch(`/api/projects/${encodeURIComponent(e)}`,{name:r}),await t().fetchProjects()},deleteProject:async t=>{await n.del(`/api/projects/${encodeURIComponent(t)}`),e(e=>{let n=e.projects.filter(e=>e.name!==t),r=e.customOrder?e.customOrder.filter(e=>e!==t):null;return r&&a(r),{projects:n,customOrder:r,activeProject:e.activeProject?.name===t?n[0]??null:e.activeProject}})}}));function c(e,t){return e.map(e=>({name:e.name,path:t?`${t}/${e.name}`:e.name,type:e.type,ignored:e.isIgnored}))}function l(e,t,n){return t?e.map(e=>u(e,t,n)):n.map(t=>{let n=e.find(e=>e.path===t.path);return n?{...t,children:n.children}:t})}function u(e,t,n){if(e.path===t){let t=n.map(t=>{let n=e.children?.find(e=>e.path===t.path);return n?{...t,children:n.children}:t});return{...e,children:t}}return e.children&&t.startsWith(e.path+`/`)?{...e,children:e.children.map(e=>u(e,t,n))}:e}var d=e((e,r)=>({tree:[],fileIndex:[],loading:!1,error:null,expandedPaths:new Set,loadedPaths:new Set,inflight:new Map,indexStatus:`idle`,selectedFiles:[],inlineAction:null,clipboard:null,focusedPath:null,setInlineAction:t=>e({inlineAction:t}),clearInlineAction:()=>e({inlineAction:null}),setClipboard:t=>e({clipboard:t}),setFocusedPath:t=>e({focusedPath:t}),loadRoot:async i=>{e({loading:!0,error:null});try{let a=c(await n.get(`${t(i)}/files/list?path=`),``),o=new Set(r().loadedPaths);o.add(``),e({tree:a,loading:!1,loadedPaths:o})}catch(t){e({error:t instanceof Error?t.message:`Failed to load files`,loading:!1})}},loadChildren:async(i,a)=>{let o=r();if(o.loadedPaths.has(a))return;let s=o.inflight.get(a);s&&s.abort();let u=new AbortController,d=new Map(o.inflight);d.set(a,u),e({inflight:d});try{let o=encodeURIComponent(a),s=await n.get(`${t(i)}/files/list?path=${o}`,{signal:u.signal});if(u.signal.aborted)return;let d=c(s,a),f=r(),p=l(f.tree,a,d),m=new Set(f.loadedPaths);m.add(a);let h=new Map(f.inflight);h.delete(a),e({tree:p,loadedPaths:m,inflight:h})}catch(t){if(t instanceof Error&&t.name===`AbortError`)return;let n=new Map(r().inflight);n.delete(a),e({inflight:n})}},loadIndex:async r=>{e({indexStatus:`loading`});try{e({fileIndex:await n.get(`${t(r)}/files/index`),indexStatus:`ready`})}catch{e({indexStatus:`error`})}},invalidateIndex:()=>{e({indexStatus:`idle`,fileIndex:[]})},invalidateFolder:async(t,n)=>{let i=r();if(!i.loadedPaths.has(n))return;let a=new Set(i.loadedPaths);a.delete(n),e({loadedPaths:a}),(!n||i.expandedPaths.has(n))&&await r().loadChildren(t,n)},toggleExpand:(t,n)=>{let i=r(),a=new Set(i.expandedPaths);a.has(n)?(a.delete(n),e({expandedPaths:a})):(a.add(n),e({expandedPaths:a}),i.loadedPaths.has(n)||r().loadChildren(t,n))},setExpanded:(t,n)=>{let i=new Set(r().expandedPaths);n?i.add(t):i.delete(t),e({expandedPaths:i})},collapseAll:()=>{e({expandedPaths:new Set})},toggleFileSelect:t=>{let n=r().selectedFiles;n.indexOf(t)>=0?e({selectedFiles:n.filter(e=>e!==t)}):e({selectedFiles:[...n,t]})},setSelectedFiles:t=>e({selectedFiles:t}),clearSelection:()=>e({selectedFiles:[]}),reset:()=>{for(let e of r().inflight.values())e.abort();e({tree:[],fileIndex:[],loading:!1,error:null,expandedPaths:new Set,loadedPaths:new Set,inflight:new Map,indexStatus:`idle`,selectedFiles:[],inlineAction:null,clipboard:null,focusedPath:null})},fetchTree:async e=>{await r().loadRoot(e),r().loadIndex(e)}}));function f(){let{tree:e,expandedPaths:t}=d.getState(),n=[];function r(e){let i=[...e].sort((e,t)=>e.type===t.type?e.name.localeCompare(t.name):e.type===`directory`?-1:1);for(let e of i){let i=e;if(e.type===`directory`&&t.has(e.path)&&e.children)for(;i.children&&i.children.length===1&&i.children[0].type===`directory`&&t.has(i.children[0].path);)i=i.children[0];n.push(i.path),i.type===`directory`&&t.has(i.path)&&i.children&&r(i.children)}}return r(e),n}export{s as i,d as n,o as r,f as t};
2
+ //# sourceMappingURL=file-store-DOxcU_7s.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"file-store-DOxcU_7s.js","names":[],"sources":["../../../src/web/stores/project-store.ts","../../../src/web/stores/file-tree-merge-helpers.ts","../../../src/web/stores/file-store.ts"],"sourcesContent":["import { create } from \"zustand\";\nimport { api } from \"@/lib/api-client\";\n\nexport interface Project {\n name: string;\n path: string;\n color?: string;\n}\n\nexport interface ProjectInfo extends Project {\n branch?: string;\n status?: \"clean\" | \"dirty\";\n}\n\n// ---------------------------------------------------------------------------\n// Recently-used tracking via localStorage\n// ---------------------------------------------------------------------------\nconst RECENT_KEY = \"ppm-recent-projects\";\nconst CUSTOM_ORDER_KEY = \"ppm-custom-order\";\n\nfunction loadRecentOrder(): string[] {\n try {\n const raw = localStorage.getItem(RECENT_KEY);\n return raw ? (JSON.parse(raw) as string[]) : [];\n } catch {\n return [];\n }\n}\n\nfunction saveRecentOrder(order: string[]) {\n try {\n localStorage.setItem(RECENT_KEY, JSON.stringify(order));\n } catch { /* ignore */ }\n}\n\n/** Move project name to front of recent list */\nfunction touchRecent(name: string) {\n const order = loadRecentOrder().filter((n) => n !== name);\n order.unshift(name);\n saveRecentOrder(order);\n}\n\n/** Sort projects by recent usage (most recent first) */\nexport function sortByRecent(projects: ProjectInfo[]): ProjectInfo[] {\n const order = loadRecentOrder();\n const orderMap = new Map(order.map((name, i) => [name, i]));\n return [...projects].sort((a, b) => {\n const ai = orderMap.get(a.name) ?? Infinity;\n const bi = orderMap.get(b.name) ?? Infinity;\n return ai - bi;\n });\n}\n\nfunction loadCustomOrder(): string[] | null {\n try {\n const raw = localStorage.getItem(CUSTOM_ORDER_KEY);\n return raw ? (JSON.parse(raw) as string[]) : null;\n } catch {\n return null;\n }\n}\n\nfunction saveCustomOrder(order: string[]) {\n try {\n localStorage.setItem(CUSTOM_ORDER_KEY, JSON.stringify(order));\n } catch { /* ignore */ }\n}\n\n/** Resolve display order: custom order if set, else preserve server order */\nexport function resolveOrder(projects: ProjectInfo[], customOrder: string[] | null): ProjectInfo[] {\n if (!customOrder) return [...projects];\n const orderMap = new Map(customOrder.map((name, i) => [name, i]));\n return [...projects].sort((a, b) => {\n const ai = orderMap.get(a.name) ?? Infinity;\n const bi = orderMap.get(b.name) ?? Infinity;\n return ai - bi;\n });\n}\n\n// ---------------------------------------------------------------------------\n// Store\n// ---------------------------------------------------------------------------\ninterface ProjectStore {\n projects: ProjectInfo[];\n activeProject: ProjectInfo | null;\n customOrder: string[] | null;\n loading: boolean;\n error: string | null;\n fetchProjects: () => Promise<void>;\n setActiveProject: (project: ProjectInfo) => void;\n addProject: (path: string, name?: string) => Promise<ProjectInfo>;\n setProjectColor: (name: string, color: string | null) => Promise<void>;\n moveProject: (name: string, direction: \"up\" | \"down\") => Promise<void>;\n reorderProjects: (newOrder: string[]) => Promise<void>;\n renameProject: (name: string, newName: string) => Promise<void>;\n deleteProject: (name: string) => Promise<void>;\n}\n\nexport const useProjectStore = create<ProjectStore>((set, get) => ({\n projects: [],\n activeProject: null,\n customOrder: loadCustomOrder(),\n loading: false,\n error: null,\n\n fetchProjects: async () => {\n set({ loading: true, error: null });\n try {\n const projects = await api.get<ProjectInfo[]>(\"/api/projects\");\n set({ projects, loading: false });\n } catch (err) {\n set({\n error: err instanceof Error ? err.message : \"Failed to fetch projects\",\n loading: false,\n });\n }\n },\n\n setActiveProject: (project) => {\n set({ activeProject: project });\n },\n\n addProject: async (path, name) => {\n const project = await api.post<ProjectInfo>(\"/api/projects\", { path, name });\n await get().fetchProjects();\n // Auto-select the newly added project\n const added = get().projects.find((p) => p.name === (name ?? project.name) || p.path === path);\n if (added) set({ activeProject: added });\n return project;\n },\n\n setProjectColor: async (name, color) => {\n await api.patch(`/api/projects/${encodeURIComponent(name)}/color`, { color });\n await get().fetchProjects();\n },\n\n moveProject: async (name, direction) => {\n const { projects, customOrder } = get();\n const ordered = resolveOrder(projects, customOrder);\n const idx = ordered.findIndex((p) => p.name === name);\n if (idx === -1) return;\n const newIdx = direction === \"up\" ? idx - 1 : idx + 1;\n if (newIdx < 0 || newIdx >= ordered.length) return;\n const newOrder = ordered.map((p) => p.name);\n [newOrder[idx], newOrder[newIdx]] = [newOrder[newIdx]!, newOrder[idx]!];\n saveCustomOrder(newOrder);\n await api.patch(\"/api/projects/reorder\", { order: newOrder });\n set({ customOrder: newOrder });\n },\n\n reorderProjects: async (newOrder) => {\n saveCustomOrder(newOrder);\n set({ customOrder: newOrder });\n await api.patch(\"/api/projects/reorder\", { order: newOrder }).catch(() => {});\n },\n\n renameProject: async (name, newName) => {\n await api.patch(`/api/projects/${encodeURIComponent(name)}`, { name: newName });\n // Refetch to get updated list\n await get().fetchProjects();\n },\n\n deleteProject: async (name) => {\n await api.del(`/api/projects/${encodeURIComponent(name)}`);\n set((s) => {\n const projects = s.projects.filter((p) => p.name !== name);\n const customOrder = s.customOrder ? s.customOrder.filter((n) => n !== name) : null;\n if (customOrder) saveCustomOrder(customOrder);\n return {\n projects,\n customOrder,\n activeProject: s.activeProject?.name === name\n ? (projects[0] ?? null)\n : s.activeProject,\n };\n });\n },\n}));\n","/**\n * Pure helper functions for immutable lazy-tree merging.\n * Kept separate to stay under the 200-line file size guideline.\n */\nimport type { FileDirEntry } from \"../../types/project\";\nimport type { FileNode } from \"./file-store\";\n\n/** Convert /files/list entries into sparse FileNode children (no grandchildren). */\nexport function entriesToNodes(entries: FileDirEntry[], parentPath: string): FileNode[] {\n return entries.map((e) => ({\n name: e.name,\n path: parentPath ? `${parentPath}/${e.name}` : e.name,\n type: e.type,\n ignored: e.isIgnored,\n // children intentionally undefined — loaded lazily on expand\n }));\n}\n\n/** Immutable deep-merge of newly loaded children into the sparse tree. */\nexport function mergeChildren(tree: FileNode[], folderPath: string, children: FileNode[]): FileNode[] {\n if (!folderPath) {\n // Root level: replace root entries, preserve already-loaded sub-children\n return children.map((newNode) => {\n const existing = tree.find((n) => n.path === newNode.path);\n return existing ? { ...newNode, children: existing.children } : newNode;\n });\n }\n return tree.map((node) => mergeNode(node, folderPath, children));\n}\n\nfunction mergeNode(node: FileNode, targetPath: string, children: FileNode[]): FileNode {\n if (node.path === targetPath) {\n // Merge: preserve already-loaded sub-children keyed by path\n const mergedChildren = children.map((newChild) => {\n const existing = node.children?.find((c) => c.path === newChild.path);\n return existing ? { ...newChild, children: existing.children } : newChild;\n });\n return { ...node, children: mergedChildren };\n }\n if (node.children && targetPath.startsWith(node.path + \"/\")) {\n return { ...node, children: node.children.map((child) => mergeNode(child, targetPath, children)) };\n }\n return node;\n}\n","import { create } from \"zustand\";\nimport { api, projectUrl } from \"@/lib/api-client\";\nimport type { FileEntry, FileDirEntry } from \"../../types/project\";\nimport { entriesToNodes, mergeChildren } from \"./file-tree-merge-helpers\";\n\nexport type { FileEntry };\n\nexport interface FileNode {\n name: string;\n path: string;\n type: \"file\" | \"directory\";\n children?: FileNode[];\n size?: number;\n modified?: string;\n /** True if path is matched by a .gitignore rule */\n ignored?: boolean;\n}\n\n/** State for inline create/rename in the file tree */\nexport interface InlineAction {\n type: \"new-file\" | \"new-folder\" | \"rename\";\n /** Parent directory path (for new-file/new-folder) or parent of the renamed file */\n parentPath: string;\n /** Existing node being renamed (only for type=rename) */\n existingNode?: FileNode;\n}\n\n/** Clipboard state for cut/copy/paste */\nexport interface ClipboardState {\n paths: string[];\n operation: \"cut\" | \"copy\";\n}\n\ninterface FileStore {\n tree: FileNode[];\n fileIndex: FileEntry[];\n loading: boolean;\n error: string | null;\n expandedPaths: Set<string>;\n loadedPaths: Set<string>;\n /** In-flight AbortControllers keyed by folder path */\n inflight: Map<string, AbortController>;\n indexStatus: \"idle\" | \"loading\" | \"ready\" | \"error\";\n selectedFiles: string[];\n inlineAction: InlineAction | null;\n clipboard: ClipboardState | null;\n focusedPath: string | null;\n\n setInlineAction(action: InlineAction | null): void;\n clearInlineAction(): void;\n setClipboard(clipboard: ClipboardState | null): void;\n setFocusedPath(path: string | null): void;\n loadRoot(projectName: string): Promise<void>;\n loadChildren(projectName: string, folderPath: string): Promise<void>;\n loadIndex(projectName: string): Promise<void>;\n invalidateIndex(): void;\n invalidateFolder(projectName: string, folderPath: string): Promise<void>;\n toggleExpand(projectName: string, path: string): void;\n setExpanded(path: string, expanded: boolean): void;\n collapseAll(): void;\n toggleFileSelect(path: string): void;\n setSelectedFiles(paths: string[]): void;\n clearSelection(): void;\n reset(): void;\n /** @deprecated Use loadRoot instead */\n fetchTree(projectName: string): Promise<void>;\n}\n\nexport const useFileStore = create<FileStore>((set, get) => ({\n tree: [],\n fileIndex: [],\n loading: false,\n error: null,\n expandedPaths: new Set<string>(),\n loadedPaths: new Set<string>(),\n inflight: new Map<string, AbortController>(),\n indexStatus: \"idle\",\n selectedFiles: [],\n inlineAction: null,\n clipboard: null,\n focusedPath: null,\n\n setInlineAction: (action) => set({ inlineAction: action }),\n clearInlineAction: () => set({ inlineAction: null }),\n setClipboard: (clipboard) => set({ clipboard }),\n setFocusedPath: (path) => set({ focusedPath: path }),\n\n loadRoot: async (projectName: string) => {\n set({ loading: true, error: null });\n try {\n const data = await api.get<FileDirEntry[]>(\n `${projectUrl(projectName)}/files/list?path=`,\n );\n const rootNodes = entriesToNodes(data, \"\");\n const loadedPaths = new Set(get().loadedPaths);\n loadedPaths.add(\"\"); // root is loaded\n set({ tree: rootNodes, loading: false, loadedPaths });\n } catch (err) {\n set({\n error: err instanceof Error ? err.message : \"Failed to load files\",\n loading: false,\n });\n }\n },\n\n loadChildren: async (projectName: string, folderPath: string) => {\n const state = get();\n\n // Idempotent guard — skip if already loaded\n if (state.loadedPaths.has(folderPath)) return;\n\n // Abort any existing in-flight request for this path\n const existing = state.inflight.get(folderPath);\n if (existing) existing.abort();\n\n const controller = new AbortController();\n const inflight = new Map(state.inflight);\n inflight.set(folderPath, controller);\n set({ inflight });\n\n try {\n const encodedPath = encodeURIComponent(folderPath);\n const data = await api.get<FileDirEntry[]>(\n `${projectUrl(projectName)}/files/list?path=${encodedPath}`,\n { signal: controller.signal },\n );\n\n // Check if aborted between request start and completion (defense in depth)\n if (controller.signal.aborted) return;\n\n const children = entriesToNodes(data, folderPath);\n const currentState = get();\n const newTree = mergeChildren(currentState.tree, folderPath, children);\n const newLoadedPaths = new Set(currentState.loadedPaths);\n newLoadedPaths.add(folderPath);\n const newInflight = new Map(currentState.inflight);\n newInflight.delete(folderPath);\n set({ tree: newTree, loadedPaths: newLoadedPaths, inflight: newInflight });\n } catch (err) {\n if (err instanceof Error && err.name === \"AbortError\") return;\n // Remove from inflight on error\n const newInflight = new Map(get().inflight);\n newInflight.delete(folderPath);\n set({ inflight: newInflight });\n }\n },\n\n loadIndex: async (projectName: string) => {\n set({ indexStatus: \"loading\" });\n try {\n const data = await api.get<FileEntry[]>(\n `${projectUrl(projectName)}/files/index`,\n );\n set({ fileIndex: data, indexStatus: \"ready\" });\n } catch {\n set({ indexStatus: \"error\" });\n }\n },\n\n invalidateIndex: () => {\n set({ indexStatus: \"idle\", fileIndex: [] });\n },\n\n invalidateFolder: async (projectName: string, folderPath: string) => {\n const state = get();\n\n // Only reload if this folder was previously loaded\n if (!state.loadedPaths.has(folderPath)) return;\n\n // Remove from loadedPaths to allow re-fetch\n const newLoadedPaths = new Set(state.loadedPaths);\n newLoadedPaths.delete(folderPath);\n set({ loadedPaths: newLoadedPaths });\n\n // Re-fetch if folder is currently expanded (or root)\n if (!folderPath || state.expandedPaths.has(folderPath)) {\n await get().loadChildren(projectName, folderPath);\n }\n },\n\n toggleExpand: (projectName: string, path: string) => {\n const state = get();\n const expanded = new Set(state.expandedPaths);\n if (expanded.has(path)) {\n expanded.delete(path);\n set({ expandedPaths: expanded });\n } else {\n expanded.add(path);\n set({ expandedPaths: expanded });\n // Lazy load children if not yet loaded\n if (!state.loadedPaths.has(path)) {\n get().loadChildren(projectName, path);\n }\n }\n },\n\n setExpanded: (path: string, expanded: boolean) => {\n const paths = new Set(get().expandedPaths);\n if (expanded) paths.add(path);\n else paths.delete(path);\n set({ expandedPaths: paths });\n },\n\n collapseAll: () => {\n set({ expandedPaths: new Set<string>() });\n },\n\n toggleFileSelect: (path: string) => {\n const current = get().selectedFiles;\n const idx = current.indexOf(path);\n if (idx >= 0) {\n set({ selectedFiles: current.filter((p) => p !== path) });\n } else {\n set({ selectedFiles: [...current, path] });\n }\n },\n\n setSelectedFiles: (paths) => set({ selectedFiles: paths }),\n\n clearSelection: () => set({ selectedFiles: [] }),\n\n reset: () => {\n // Abort all in-flight requests\n for (const ctrl of get().inflight.values()) ctrl.abort();\n set({\n tree: [],\n fileIndex: [],\n loading: false,\n error: null,\n expandedPaths: new Set(),\n loadedPaths: new Set(),\n inflight: new Map(),\n indexStatus: \"idle\",\n selectedFiles: [],\n inlineAction: null,\n clipboard: null,\n focusedPath: null,\n });\n },\n\n /** @deprecated Alias for loadRoot — kept for callers in tab-bar and mobile-nav */\n fetchTree: async (projectName: string) => {\n await get().loadRoot(projectName);\n get().loadIndex(projectName);\n },\n}));\n\n/** Compute flat visible path list from current tree state (for range selection) */\nexport function getVisiblePaths(): string[] {\n const { tree, expandedPaths } = useFileStore.getState();\n const result: string[] = [];\n function walk(nodes: FileNode[]) {\n const sorted = [...nodes].sort((a, b) => {\n if (a.type !== b.type) return a.type === \"directory\" ? -1 : 1;\n return a.name.localeCompare(b.name);\n });\n for (const n of sorted) {\n // Skip compacted intermediate dirs (matches compact folder rendering)\n let effective = n;\n if (n.type === \"directory\" && expandedPaths.has(n.path) && n.children) {\n while (\n effective.children &&\n effective.children.length === 1 &&\n effective.children[0]!.type === \"directory\" &&\n expandedPaths.has(effective.children[0]!.path)\n ) {\n effective = effective.children[0]!;\n }\n }\n result.push(effective.path);\n if (effective.type === \"directory\" && expandedPaths.has(effective.path) && effective.children) {\n walk(effective.children);\n }\n }\n }\n walk(tree);\n return result;\n}\n"],"mappings":"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"}
@@ -133,4 +133,5 @@ import{o as e,t}from"./rolldown-runtime-FhOqtrmT.js";import{b as n,x as r}from".
133
133
  `,t.allowWrapping===!0?void 0:1),i=0;for(let t of r)i=Math.max(i,e.measureText(t).width);return i+2*n.cellHorizontalPadding},onDelete:e=>({...e,data:``}),provideEditor:e=>({disablePadding:e.allowWrapping===!0,editor:t=>{let{isHighlighted:n,onChange:r,value:i,validatedSelection:a}=t;return K.createElement(qt,{style:e.allowWrapping===!0?{padding:`3px 8.5px`}:void 0,highlight:n,autoFocus:i.readonly!==!0,disabled:i.readonly===!0,altNewline:!0,value:i.data,validatedSelection:a,onChange:e=>r({...i,data:e.target.value})})}}),onPaste:(e,t,n)=>e===t.data?void 0:{...t,data:e,displayData:n.formattedString??t.displayData}},Fs=G(`div`)({name:`UriOverlayEditorStyle`,class:`gdg-u1rrojo`,propsAsIs:!1}),Is=e=>{let{uri:t,onChange:n,forceEditMode:r,readonly:i,validatedSelection:a,preview:o}=e,[s,c]=K.useState(!i&&(t===``||r)),l=K.useCallback(()=>{c(!0)},[]);return s?K.createElement(qt,{validatedSelection:a,highlight:!0,autoFocus:!0,value:t,onChange:n}):K.createElement(Fs,null,K.createElement(`a`,{className:`gdg-link-area`,href:t,target:`_blank`,rel:`noopener noreferrer`},o),!i&&K.createElement(`div`,{className:`gdg-edit-icon`,onClick:l},K.createElement(Ot,null)),K.createElement(`textarea`,{className:`gdg-input`,autoFocus:!0}))};function Ls(e,t,n,r){let i=n.cellHorizontalPadding,a=t.height/2-e.actualBoundingBoxAscent/2,o=e.width,s=e.actualBoundingBoxAscent;return r===`right`?i=t.width-o-n.cellHorizontalPadding:r===`center`&&(i=t.width/2-o/2),{x:i,y:a,width:o,height:s}}var Rs=[Cs,Ds,es,is,ls,ms,vs,Ss,As,js,Ns,Ps,{getAccessibilityString:e=>e.data?.toString()??``,kind:z.Uri,needsHover:e=>e.hoverEffect===!0,needsHoverPosition:!0,useLabel:!0,drawPrep:kn,draw:e=>{let{cell:t,theme:n,overrideCursor:r,hoverX:i,hoverY:a,rect:o,ctx:s}=e,c=t.displayData??t.data,l=t.hoverEffect===!0;if(r!==void 0&&l&&i!==void 0&&a!==void 0){let{x:l,y:u,width:d,height:f}=Ls(Sn(c,s,n.baseFontFull),o,n,t.contentAlign);if(i>=l-4&&i<=l-4+d+8&&a>=u-4&&a<=u-4+f+8){let i=wn(s,n.baseFontFull);r(`pointer`);let a=u-i;s.beginPath(),s.moveTo(o.x+l,Math.floor(o.y+a+f+5)+.5),s.lineTo(o.x+l+d,Math.floor(o.y+a+f+5)+.5),s.strokeStyle=n.linkColor,s.stroke(),s.save(),s.fillStyle=e.cellFillColor,Pn({...e,rect:{...o,x:o.x-1}},c,t.contentAlign),Pn({...e,rect:{...o,x:o.x-2}},c,t.contentAlign),Pn({...e,rect:{...o,x:o.x+1}},c,t.contentAlign),Pn({...e,rect:{...o,x:o.x+2}},c,t.contentAlign),s.restore()}}s.fillStyle=l?n.linkColor:n.textDark,Pn(e,c,t.contentAlign)},onClick:e=>{let{cell:t,bounds:n,posX:r,posY:i,theme:a}=e,o=t.displayData??t.data;if(t.hoverEffect!==!0||t.onClickUri===void 0)return;let s=Cn(o,a.baseFontFull);if(s===void 0)return;let c=Ls(s,n,a,t.contentAlign);Br({x:c.x-4,y:c.y-4,width:c.width+8,height:c.height+8},r,i)&&t.onClickUri(e)},measure:(e,t,n)=>e.measureText(t.displayData??t.data).width+n.cellHorizontalPadding*2,onDelete:e=>({...e,data:``}),provideEditor:e=>t=>{let{onChange:n,value:r,forceEditMode:i,validatedSelection:a}=t;return K.createElement(Is,{forceEditMode:r.readonly!==!0&&(i||e.hoverEffect===!0&&e.onClickUri!==void 0),uri:r.data,preview:r.displayData??r.data,validatedSelection:a,readonly:r.readonly===!0,onChange:e=>n({...r,data:e.target.value})})},onPaste:(e,t,n)=>e===t.data?void 0:{...t,data:e,displayData:n.formattedString??t.displayData}}],zs=e(t(((e,t)=>{var n=vt(),r=I(),i=`Expected a function`;function a(e,t,a){var o=!0,s=!0;if(typeof e!=`function`)throw TypeError(i);return r(a)&&(o=`leading`in a?!!a.leading:o,s=`trailing`in a?!!a.trailing:s),n(e,t,{leading:o,maxWait:t,trailing:s})}t.exports=a}))(),1),Bs=[],Vs=class extends Un{imageLoaded=()=>void 0;loadedLocations=[];cache={};setCallback(e){this.imageLoaded=e}sendLoaded=(0,zs.default)(()=>{this.imageLoaded(new Gn(this.loadedLocations)),this.loadedLocations=[]},20);clearOutOfWindow=()=>{let e=Object.keys(this.cache);for(let t of e){let e=this.cache[t],n=!1;for(let t=0;t<e.cells.length;t++){let r=e.cells[t];if(this.isInWindow(r)){n=!0;break}}n?e.cells=e.cells.filter(this.isInWindow):(e.cancel(),delete this.cache[t])}};loadImage(e,t,n,r){let i=!1,a=Bs.pop()??new Image,o=!1,s={img:void 0,cells:[X(t,n)],url:e,cancel:()=>{o||(o=!0,Bs.length<12?Bs.unshift(a):i||(a.src=``))}},c=new Promise(e=>a.addEventListener(`load`,()=>e(null)));requestAnimationFrame(async()=>{try{a.src=e,await c,await a.decode();let t=this.cache[r];if(t!==void 0&&!o){t.img=a;for(let e of t.cells)this.loadedLocations.push(Hn(e));i=!0,this.sendLoaded()}}catch{s.cancel()}}),this.cache[r]=s}loadOrGetImage(e,t,n){let r=e,i=this.cache[r];if(i!==void 0){let e=X(t,n);return i.cells.includes(e)||i.cells.push(e),i.img}else this.loadImage(e,t,n,r)}},Hs=K.forwardRef((e,t)=>{let n=K.useMemo(()=>({...Ar,...e.headerIcons}),[e.headerIcons]),r=K.useMemo(()=>e.imageWindowLoader??new Vs,[e.imageWindowLoader]);return K.createElement(Qo,{...e,renderers:Rs,headerIcons:n,ref:t,imageWindowLoader:r})});function Us(e){return getComputedStyle(document.documentElement).getPropertyValue(e).trim()}function Ws(e,t){if(e.startsWith(`#`)){let n=e.slice(1);return`rgba(${parseInt(n.slice(0,2),16)}, ${parseInt(n.slice(2,4),16)}, ${parseInt(n.slice(4,6),16)}, ${t})`}return e}function Gs(){let e=Us(`--color-background`),t=Us(`--color-foreground`),n=Us(`--color-muted`),r=Us(`--color-muted-foreground`),i=Us(`--color-primary`),a=Us(`--color-primary-foreground`),o=Us(`--color-border`),s=Us(`--color-accent`),c=Us(`--color-text-secondary`),l=Us(`--color-text-subtle`),u=Us(`--font-sans`)||`Geist, system-ui, sans-serif`;return{bgCell:e,bgCellMedium:n,bgHeader:n,bgHeaderHasFocus:s,bgHeaderHovered:s,bgBubble:s,bgBubbleSelected:i,textDark:t,textMedium:c,textLight:l,textHeader:r,textGroupHeader:r,textHeaderSelected:t,textBubble:t,accentColor:i,accentFg:a,accentLight:Ws(i,.12),borderColor:o,horizontalBorderColor:o,fontFamily:u,baseFontStyle:`13px`,headerFontStyle:`600 12px`,editorFontSize:`13px`,lineHeight:1.5,cellHorizontalPadding:8,cellVerticalPadding:4,headerIconSize:16}}function Ks(){let[e,t]=(0,K.useState)(0);return(0,K.useEffect)(()=>{let e=new MutationObserver(()=>t(e=>e+1));return e.observe(document.documentElement,{attributes:!0,attributeFilter:[`class`]}),()=>e.disconnect()},[]),(0,K.useMemo)(()=>Gs(),[e])}function qs(e,t,n){let r=e.length*9+40,i=0,a=Math.min(t.length,20);for(let n=0;n<a;n++){let r=t[n]?.[e];if(r==null)continue;let a=typeof r==`object`?12:String(r).length;i=Math.max(i,a*8)}let o=/^(int|serial|bigint|smallint|float|double|decimal|numeric|real|money|bool)/.test(n.toLowerCase())?80:100;return Math.max(o,Math.min(Math.max(r,i)+16,400))}function Js(e,t,n,r,i,a,o){return(0,K.useMemo)(()=>{let s=t.filter(e=>n.has(e)),c=t.filter(e=>!n.has(e)),l=[...s,...c],u=new Map(e.map(e=>[e.name,e]));return{columns:l.map(e=>{let t=u.get(e),n=t?.pk??!1,s;return a===e?s=o===`ASC`?`sortAsc`:`sortDesc`:n?s=`headerRowID`:t?.fk&&(s=`headerFk`),{title:e,id:e,width:r.get(e)??qs(e,i,t?.type??`text`),hasMenu:!0,icon:s}}),freezeColumns:s.length,columnOrder:l}},[e,t,n,r,i,a,o])}function Ys(e){if(e==null)return!1;if(typeof e==`object`)return!0;let t=String(e);if(t.length>=200)return!0;let n=t.trimStart();return!!((n[0]===`{`||n[0]===`[`)&&(n.endsWith(`}`)||n.endsWith(`]`))||n.startsWith(`<?xml`)||n.startsWith(`<`)&&n.endsWith(`>`))}function Xs(e){return e==null?`NULL`:typeof e==`object`?JSON.stringify(e):String(e)}function Zs(e){let t=e.trimStart();if(t[0]===`{`||t[0]===`[`)try{return JSON.parse(t),`json`}catch{}return t.startsWith(`<?xml`)||t.startsWith(`<`)&&/<\/\w+>/.test(t)?`xml`:t.startsWith(`---`)||/^\w+:\s/m.test(t)?`yaml`:`plaintext`}function Qs(e){let t=e.toLowerCase();return/^(int|serial|bigint|smallint|float|double|decimal|numeric|real|money)/.test(t)?z.Number:/^bool/.test(t)?z.Boolean:z.Text}function $s(e){let t=e.type.toLowerCase();return!!(/^(serial|bigserial|smallserial)/.test(t)||/^(int|bigint|smallint|integer)/.test(t)&&e.defaultValue&&/nextval|identity|auto_increment/i.test(e.defaultValue)||t===`integer`&&e.pk&&!e.defaultValue)}function ec(e,t=200){return e.length>t?e.slice(0,t)+`…`:e}var tc={bgCell:`rgba(251, 191, 36, 0.15)`};function nc(e,t,n,r,i,a){let o=(0,K.useRef)(e);o.current=e;let s=(0,K.useRef)(t);s.current=t;let c=(0,K.useRef)(new Map);return c.current=new Map(n.map(e=>[e.name,e])),{getCellContent:(0,K.useCallback)(([e,t])=>{let n=s.current[e],i=o.current[t];if(!n||!i)return{kind:z.Text,data:``,displayData:``,allowOverlay:!1};let l=c.current.get(n),u=l?Qs(l.type):z.Text,d=l?.pk??!1,f=r?i[r]:void 0,p=typeof f==`string`&&f.startsWith(`__new_`),m=`${f}:${n}`,h=a.current.get(m),g=h===void 0?i[n]:h.newVal,_=h!==void 0;if(d&&p){if(l&&$s(l))return{kind:z.Text,data:``,displayData:`AUTO`,allowOverlay:!1,readonly:!0,themeOverride:{textDark:`#6b7280`}};let e=h===void 0?``:String(h.newVal??``);return{kind:z.Text,data:e,displayData:e||`Enter ID…`,allowOverlay:!0,readonly:!1,themeOverride:e?_?tc:void 0:{textDark:`#9ca3af`}}}if(g==null){let e=p?``:`NULL`;if(p&&!_&&l){let t=l.type.toLowerCase();l.defaultValue?e=l.defaultValue:/^(timestamp|datetime|date)/.test(t)?e=`NOW()`:/^(uuid)/.test(t)&&(e=`gen_random_uuid()`)}return{kind:z.Text,data:``,displayData:e,allowOverlay:!d,readonly:d,themeOverride:_?tc:p||e!==`NULL`?{textDark:`#9ca3af`}:{textDark:`#6b7280`}}}if(u===z.Number&&typeof g==`number`)return{kind:z.Number,data:g,displayData:String(g),allowOverlay:!d,readonly:d,themeOverride:_?tc:void 0};if(u===z.Boolean&&typeof g==`boolean`)return{kind:z.Boolean,data:g,readonly:d,allowOverlay:!1};let v=Xs(g);return{kind:z.Text,data:v,displayData:ec(v),allowOverlay:!d,readonly:d,themeOverride:_?tc:void 0}},[]),onCellEdited:(0,K.useCallback)(([e,t],n)=>{if(!r)return;let a=s.current[e],c=o.current[t];if(!a||!c)return;let l=c[r],u;if(n.kind===z.Text)u=n.data===``?null:n.data;else if(n.kind===z.Number)u=n.data;else if(n.kind===z.Boolean)u=n.data;else return;i(l,a,u)},[r,i])}}var rc={columns:U.empty(),rows:U.empty()};function ic(){let[e,t]=(0,K.useState)(rc);return{gridSelection:e,onGridSelectionChange:(0,K.useCallback)(e=>{t(e)},[]),selectedRowIndices:(0,K.useMemo)(()=>{let t=[];if(e.rows)for(let n of e.rows)if(Array.isArray(n))for(let e=n[0];e<n[1];e++)t.push(e);else t.push(n);return t},[e.rows]),clearSelection:(0,K.useCallback)(()=>{t(rc)},[])}}function ac(e,t,n){let[r,i]=(0,K.useState)(new Map),a=(0,K.useRef)(r);a.current=r;let o=(0,K.useRef)(!1);return{pendingEdits:r,pendingRef:a,addEdit:(0,K.useCallback)((e,t,n)=>{let r=`${e}:${t}`;i(i=>new Map(i).set(r,{pkVal:e,col:t,newVal:n}))},[]),commitAll:(0,K.useCallback)(async()=>{if(!e)return;let r=new Map;for(let n of a.current.values()){let i=String(n.pkVal);i.startsWith(`__new_`)?(r.has(i)||r.set(i,{}),r.get(i)[n.col]=n.newVal):t(e,n.pkVal,n.col,n.newVal)}if(n)for(let e of r.values())await n(e);o.current=!0},[e,t,n]),discardAll:(0,K.useCallback)(()=>{i(new Map),o.current=!1},[]),hasPending:r.size>0,pendingCount:r.size,committedRef:o}}function oc(e,t){let[n,r]=(0,K.useState)(new Set);return{effectiveRows:(0,K.useMemo)(()=>{if(n.size===0||!t)return e;let r=[],i=[];for(let a of e)n.has(String(a[t]??``))?i.push(a):r.push(a);return[...r,...i]},[e,n,t]),pinnedCount:n.size,pinnedPks:n,setPinnedPks:r}}function sc(e){let{displayRows:t,columnOrder:n,schema:r,pkCol:i,connectionId:a,connectionName:o,selectedTable:s,selectedSchema:c,addEdit:l,gridSelection:u,containerRef:d}=e,{openTab:f}=w(k(e=>({openTab:e.openTab}))),[p,m]=(0,K.useState)(null),h=(0,K.useRef)(t);h.current=t;let g=(0,K.useRef)(n);g.current=n;let _=(0,K.useCallback)(e=>{let n=t[e];if(!n)return;let r=i?String(n[i]??``):``,o=s??``,c=JSON.stringify(n,null,2);m({title:r?`Row #${r}${o?` — ${o}`:``}`:`Row — ${o}`,content:c,language:`json`,viewerKey:`${a}:${o}:row:${r}`})},[t,i,s,a]),v=(0,K.useCallback)((e,r)=>{let o=t[e];if(!o)return;let c=n[r];if(!c)return;let l=Xs(o[c]),u=i?String(o[i]??e):String(e),d=s??``;m({title:`${c} #${u}${d?` — ${d}`:``}`,content:l,language:Zs(l),viewerKey:`${a}:${d}:${c}:${u}`})},[t,n,i,s,a]),y=(0,K.useCallback)(()=>{p&&f({type:`editor`,title:p.title,projectId:null,closable:!0,metadata:{inlineContent:p.content,inlineLanguage:p.language,viewerKey:p.viewerKey}})},[f,p]),b=(0,K.useCallback)((e,t)=>{if(!i)return!1;let[n,a]=e;for(let e=0;e<t.length;e++){let o=h.current[a+e];if(!o)continue;let s=o[i];for(let i=0;i<t[e].length;i++){let a=g.current[n+i];if(!a||r.find(e=>e.name===a)?.pk)continue;let o=t[e][i];l(s,a,o===``?null:o)}}return!1},[i,r,l]),x=(0,K.useRef)(r);x.current=r;let S=(0,K.useRef)(u);S.current=u;let C=(0,K.useRef)(l);C.current=l;let T=(0,K.useRef)(i);return T.current=i,(0,K.useEffect)(()=>{if(!d)return;let e=e=>{let t=d.current;if(!t||!t.contains(document.activeElement))return;let n=document.activeElement?.tagName;if(n===`INPUT`||n===`TEXTAREA`)return;let r=T.current;if(!r)return;let i=S.current?.current;if(!i)return;let a=e.clipboardData?.getData(`text/plain`);if(!a)return;let o=a.split(/\r?\n/).filter(e=>e.length>0).map(e=>e.split(` `));if(o.length===0)return;let[s,c]=i.cell;for(let e=0;e<o.length;e++){let t=h.current[c+e];if(!t)continue;let n=t[r];for(let t=0;t<o[e].length;t++){let r=g.current[s+t];if(!r||x.current.find(e=>e.name===r)?.pk)continue;let i=o[e][t];C.current(n,r,i===``?null:i)}}e.preventDefault()};return document.addEventListener(`paste`,e),()=>document.removeEventListener(`paste`,e)},[d]),{previewData:p,setPreviewData:m,openRowPreview:_,openCellPreview:v,openPreviewInTab:y,handlePaste:b,getContextFk:(0,K.useCallback)(e=>e?r.find(t=>t.name===e)?.fk??null:null,[r]),isCellViewable:(0,K.useCallback)((e,t)=>e&&t?Ys(e[t]):!1,[]),openFkTable:(0,K.useCallback)((e,t)=>{t==null||!a||f({type:`database`,title:`${o??`DB`} · ${e.table}`,projectId:null,closable:!0,metadata:{connectionId:a,connectionName:o,tableName:e.table,schemaName:c??`public`,initialSql:`SELECT * FROM "${e.table}" WHERE "${e.column}" = '${String(t).replace(/'/g,`''`)}'`}})},[a,o,c,f])}}function cc({colName:e,bounds:t,isPinned:n,filterValue:r,sortState:i,onFilter:a,onSort:o,onClearSort:l,onTogglePin:u,onClose:d}){let[m,h]=(0,K.useState)(r),g=(0,K.useRef)(null),_=(0,K.useRef)(void 0);(0,K.useEffect)(()=>{let e=e=>{g.current&&!g.current.contains(e.target)&&d()};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[d]),(0,K.useEffect)(()=>{let e=e=>{e.key===`Escape`&&d()};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[d]);let v=e=>{h(e),clearTimeout(_.current),_.current=setTimeout(()=>a(e),300)},b=Math.min(t.x,window.innerWidth-220-8),x=t.y+t.height+2,S=document.getElementById(`portal`);return S?(0,qe.createPortal)((0,q.jsxs)(`div`,{ref:g,style:{position:`fixed`,left:b,top:x,zIndex:1e4},className:`w-[220px] bg-popover border border-border rounded-md shadow-lg text-xs overflow-hidden`,children:[(0,q.jsx)(`div`,{className:`px-3 py-1.5 border-b border-border text-muted-foreground font-medium truncate`,children:e}),(0,q.jsx)(`div`,{className:`px-2 py-1.5 border-b border-border`,children:(0,q.jsxs)(`div`,{className:`flex items-center gap-1`,children:[(0,q.jsx)(Me,{className:`size-3 text-muted-foreground shrink-0`}),(0,q.jsx)(`input`,{autoFocus:!0,type:`text`,value:m,onChange:e=>v(e.target.value),placeholder:`Filter (ILIKE)…`,className:`flex-1 bg-transparent outline-none text-foreground placeholder:text-muted-foreground text-xs`}),m&&(0,q.jsx)(`button`,{type:`button`,onClick:()=>v(``),className:`text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(y,{className:`size-3`})})]})}),(0,q.jsxs)(`div`,{className:`py-1`,children:[(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{o(),d()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[i===`asc`?(0,q.jsx)(s,{className:`size-3`}):(0,q.jsx)(c,{className:`size-3`}),i===`asc`?`Sort Descending`:`Sort Ascending`]}),i&&l&&(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{l(),d()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[(0,q.jsx)(y,{className:`size-3`}),`Clear Sort`]}),(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{u(),d()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[n?(0,q.jsx)(p,{className:`size-3`}):(0,q.jsx)(f,{className:`size-3`}),n?`Unpin Column`:`Pin Column`]})]})]}),S):null}function lc({position:e,isPinned:t,onViewRow:n,onViewCell:r,onPinRow:i,onDeleteRow:a,onOpenFkTable:o,fkLabel:s,onClose:c}){let[l,u]=(0,K.useState)(!1),d=(0,K.useRef)(null);(0,K.useEffect)(()=>{let e=e=>{d.current&&!d.current.contains(e.target)&&c()};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[c]),(0,K.useEffect)(()=>{let e=e=>{e.key===`Escape`&&c()};return document.addEventListener(`keydown`,e),()=>document.removeEventListener(`keydown`,e)},[c]);let m=Math.min(e.x,window.innerWidth-180-8),h=Math.min(e.y,window.innerHeight-130-8),v=document.getElementById(`portal`);return v?(0,qe.createPortal)((0,q.jsxs)(`div`,{ref:d,style:{position:`fixed`,left:m,top:h,zIndex:1e4},className:`w-[180px] bg-popover border border-border rounded-md shadow-lg text-xs overflow-hidden py-1`,children:[(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{n(),c()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[(0,q.jsx)(g,{className:`size-3`}),` View as JSON`]}),r&&(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{r(),c()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[(0,q.jsx)(g,{className:`size-3`}),` View Cell`]}),o&&(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{o(),c()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-blue-400`,children:[(0,q.jsx)(T,{className:`size-3`}),` `,s??`Open Referenced Table`]}),(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{i(),c()},className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-foreground`,children:[t?(0,q.jsx)(p,{className:`size-3`}):(0,q.jsx)(f,{className:`size-3`}),t?`Unpin Row`:`Pin Row`]}),(0,q.jsx)(`div`,{className:`border-t border-border my-0.5`}),l?(0,q.jsxs)(`div`,{className:`px-3 py-1.5 flex items-center gap-2`,children:[(0,q.jsx)(`button`,{type:`button`,onClick:()=>{a(),c()},className:`text-destructive font-medium hover:underline`,children:`Delete?`}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>u(!1),className:`text-muted-foreground hover:underline`,children:`Cancel`})]}):(0,q.jsxs)(`button`,{type:`button`,onClick:()=>u(!0),className:`w-full text-left px-3 py-1.5 hover:bg-muted flex items-center gap-2 text-destructive`,children:[(0,q.jsx)(_,{className:`size-3`}),` Delete Row`]})]}),v):null}function uc({columns:e,onSelect:t,onClose:n,anchorRect:r}){let[i,a]=(0,K.useState)(``),[o,s]=(0,K.useState)(0),c=(0,K.useRef)(null),l=(0,K.useRef)(null),u=i?e.filter(e=>e.toLowerCase().includes(i.toLowerCase())):e;(0,K.useEffect)(()=>{s(0)},[i]),(0,K.useEffect)(()=>{let e=l.current;e&&e.children[o]?.scrollIntoView({block:`nearest`})},[o]),(0,K.useEffect)(()=>{let e=e=>{c.current&&!c.current.contains(e.target)&&n()};return document.addEventListener(`mousedown`,e),()=>document.removeEventListener(`mousedown`,e)},[n]);let d=(0,K.useCallback)(e=>{if(e.key===`Escape`){n();return}if(e.key===`ArrowDown`){e.preventDefault(),s(e=>Math.min(e+1,u.length-1));return}if(e.key===`ArrowUp`){e.preventDefault(),s(e=>Math.max(e-1,0));return}if(e.key===`Enter`){e.preventDefault();let r=u[o];r&&(t(r),n())}},[u,o,t,n]),f=document.getElementById(`portal`);return f?(0,qe.createPortal)((0,q.jsxs)(`div`,{ref:c,style:{position:`fixed`,left:Math.min(r.x,window.innerWidth-216),top:Math.min(r.y,window.innerHeight-308),zIndex:1e4},className:`w-[200px] max-h-[300px] bg-popover border border-border rounded-md shadow-lg text-xs overflow-hidden flex flex-col`,children:[(0,q.jsx)(`div`,{className:`px-2 py-1.5 border-b border-border`,children:(0,q.jsx)(`input`,{autoFocus:!0,value:i,onChange:e=>a(e.target.value),onKeyDown:d,placeholder:`Search columns…`,className:`w-full bg-transparent outline-none text-foreground placeholder:text-muted-foreground text-xs`})}),(0,q.jsxs)(`div`,{ref:l,className:`overflow-y-auto py-1`,children:[u.map((e,r)=>(0,q.jsx)(`button`,{type:`button`,onClick:()=>{t(e),n()},onMouseEnter:()=>s(r),className:`w-full text-left px-3 py-1 truncate text-foreground ${r===o?`bg-muted`:`hover:bg-muted`}`,children:e},e)),u.length===0&&(0,q.jsx)(`div`,{className:`px-3 py-2 text-muted-foreground`,children:`No columns found`})]})]}),f):null}function dc({hasSelection:e,selectedCount:t,onBulkDelete:n,onInsertRow:r,columns:i,selectedRows:a,connectionName:o,searchTerm:s,onSearchChange:c,onColumnJump:l,colSearchOpen:u,onColSearchChange:f}){let[p,h]=(0,K.useState)(!1),[g,b]=(0,K.useState)(!1),x=u??g,S=f??b,C=(0,K.useRef)(null),w=C.current?(()=>{let e=C.current.getBoundingClientRect();return{x:e.left,y:e.bottom+4}})():{x:0,y:0};return(0,q.jsxs)(`div`,{className:`flex items-center gap-2 px-2 py-1 border-b border-border bg-background shrink-0`,children:[e&&(0,q.jsxs)(`div`,{className:`flex items-center gap-1.5 text-xs`,children:[(0,q.jsxs)(`span`,{className:`text-muted-foreground`,children:[t,` selected`]}),n&&(p?(0,q.jsxs)(`span`,{className:`flex items-center gap-1`,children:[(0,q.jsxs)(`button`,{type:`button`,onClick:()=>{n(),h(!1)},className:`text-destructive text-[10px] font-medium hover:underline`,children:[`Delete `,t,`?`]}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>h(!1),className:`text-muted-foreground text-[10px] hover:underline`,children:`Cancel`})]}):(0,q.jsx)(`button`,{type:`button`,onClick:()=>h(!0),className:`p-0.5 text-muted-foreground hover:text-destructive`,children:(0,q.jsx)(_,{className:`size-3`})})),(0,q.jsx)(Ye,{columns:i,rows:a,filename:`${o??`db`}-selected`})]}),(0,q.jsx)(`div`,{className:`flex-1`}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1 text-xs`,children:[(0,q.jsx)(m,{className:`size-3 text-muted-foreground`}),(0,q.jsx)(`input`,{value:s,onChange:e=>c(e.target.value),placeholder:`Search page…`,className:`w-24 bg-transparent outline-none text-foreground placeholder:text-muted-foreground text-xs`}),s&&(0,q.jsx)(`button`,{type:`button`,onClick:()=>c(``),className:`text-muted-foreground hover:text-foreground`,children:(0,q.jsx)(y,{className:`size-3`})})]}),l&&(0,q.jsx)(`button`,{ref:C,type:`button`,onClick:()=>S(!x),className:`p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors`,title:`Jump to column (/)`,children:(0,q.jsx)(d,{className:`size-3.5`})}),r&&(0,q.jsx)(`button`,{type:`button`,onClick:r,className:`p-0.5 rounded text-muted-foreground hover:text-primary transition-colors`,title:`Insert row`,children:(0,q.jsx)(v,{className:`size-3.5`})}),x&&l&&(0,q.jsx)(uc,{columns:i,onSelect:l,onClose:()=>S(!1),anchorRect:w})]})}function fc({pendingCount:e,onSave:t,onDiscard:n}){return e===0?null:(0,q.jsxs)(`div`,{className:`flex items-center gap-2 px-3 py-1.5 border-t border-amber-400/50 bg-amber-50 dark:bg-amber-950/30 shrink-0 text-xs`,children:[(0,q.jsxs)(`span`,{className:`text-amber-700 dark:text-amber-300 font-medium`,children:[e,` pending edit`,e>1?`s`:``]}),(0,q.jsx)(`div`,{className:`flex-1`}),(0,q.jsxs)(`button`,{type:`button`,onClick:n,className:`flex items-center gap-1 px-2 py-0.5 rounded text-muted-foreground hover:text-foreground hover:bg-muted transition-colors`,children:[(0,q.jsx)(D,{className:`size-3`}),` Discard`]}),(0,q.jsxs)(`button`,{type:`button`,onClick:t,className:`flex items-center gap-1 px-2 py-0.5 rounded bg-primary text-primary-foreground hover:bg-primary/90 transition-colors`,children:[(0,q.jsx)(Ne,{className:`size-3`}),` Save`,(0,q.jsx)(`kbd`,{className:`ml-1 text-[9px] opacity-70`,children:`⌘↵`})]})]})}function pc({total:e,page:t,totalPages:n,onPageChange:r}){return(0,q.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,q.jsxs)(`span`,{children:[e.toLocaleString(),` rows`]}),(0,q.jsxs)(`div`,{className:`hidden md:flex items-center gap-2 text-[10px] text-muted-foreground/50`,children:[(0,q.jsxs)(`span`,{children:[(0,q.jsx)(`kbd`,{className:`px-1 py-0.5 rounded bg-muted text-[9px]`,children:`/`}),` columns`]}),(0,q.jsxs)(`span`,{children:[(0,q.jsxs)(`kbd`,{className:`px-1 py-0.5 rounded bg-muted text-[9px]`,children:[`⌘`,`A`]}),` select all`]}),(0,q.jsxs)(`span`,{children:[(0,q.jsxs)(`kbd`,{className:`px-1 py-0.5 rounded bg-muted text-[9px]`,children:[`⌘`,`C`]}),` copy`]})]}),(0,q.jsxs)(`div`,{className:`flex items-center gap-2`,children:[(0,q.jsx)(`button`,{type:`button`,disabled:t<=1,onClick:()=>r(t-1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,q.jsx)(l,{className:`size-3.5`})}),(0,q.jsxs)(`span`,{children:[t,` / `,n]}),(0,q.jsx)(`button`,{type:`button`,disabled:t>=n,onClick:()=>r(t+1),className:`p-0.5 rounded hover:bg-muted disabled:opacity-30`,children:(0,q.jsx)(u,{className:`size-3.5`})})]})]})}function mc({data:e,onClose:t,onOpenInTab:n}){let r=je(),[i,a]=(0,K.useState)(!0),[o,s]=(0,K.useState)(e.content),[c,l]=(0,K.useState)(!1),u=e.language===`json`||e.language===`xml`,d=(0,K.useRef)(e.title);d.current!==e.title&&(d.current=e.title,s(e.content),l(!1));let f=(0,K.useCallback)(()=>{if(c)s(e.content),l(!1);else if(e.language===`json`)try{s(JSON.stringify(JSON.parse(e.content.trim()),null,2)),l(!0)}catch{}else if(e.language===`xml`){let t=0;s(e.content.trim().replace(/>\s*</g,`>
134
134
  <`).split(`
135
135
  `).map(e=>{let n=e.trim();n.startsWith(`</`)&&(t=Math.max(0,t-1));let r=` `.repeat(t)+n;return n.startsWith(`<`)&&!n.startsWith(`</`)&&!n.endsWith(`/>`)&&!n.startsWith(`<?`)&&t++,r}).join(`
136
- `)),l(!0)}},[c,e.content,e.language]),[p,m]=(0,K.useState)(200),h=(0,K.useCallback)(e=>{e.preventDefault();let t=e.clientY,n=p,r=e=>m(Math.max(80,n+(t-e.clientY))),i=()=>{document.removeEventListener(`mousemove`,r),document.removeEventListener(`mouseup`,i)};document.addEventListener(`mousemove`,r),document.addEventListener(`mouseup`,i)},[p]);return(0,q.jsxs)(`div`,{className:`shrink-0 border-t border-border flex flex-col`,style:{height:p},children:[(0,q.jsx)(`div`,{onMouseDown:h,className:`shrink-0 h-1.5 cursor-row-resize bg-border/50 hover:bg-primary/30 flex items-center justify-center transition-colors`,children:(0,q.jsx)(O,{className:`size-3 text-muted-foreground/50`})}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1 px-2 py-1 bg-muted/50 border-b border-border shrink-0`,children:[(0,q.jsx)(g,{className:`size-3 text-muted-foreground`}),(0,q.jsx)(`span`,{className:`text-xs font-medium text-foreground truncate flex-1`,children:e.title}),u&&(0,q.jsx)(`button`,{type:`button`,onClick:f,title:c?`Raw`:`Beautify`,className:`p-0.5 rounded transition-colors ${c?`text-primary`:`text-muted-foreground hover:text-foreground`}`,children:(0,q.jsx)(b,{className:`size-3`})}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>a(!i),title:i?`No wrap`:`Word wrap`,className:`p-0.5 rounded transition-colors ${i?`text-primary`:`text-muted-foreground hover:text-foreground`}`,children:(0,q.jsx)(x,{className:`size-3`})}),(0,q.jsxs)(`button`,{type:`button`,onClick:n,title:`Open in new tab`,className:`flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted transition-colors`,children:[(0,q.jsx)(T,{className:`size-3`}),(0,q.jsx)(`span`,{className:`hidden sm:inline`,children:`Open in Tab`})]}),(0,q.jsx)(`button`,{type:`button`,onClick:t,title:`Close preview (Esc)`,className:`p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors`,children:(0,q.jsx)(y,{className:`size-3`})})]}),(0,q.jsx)(`div`,{className:`flex-1 min-h-0`,children:(0,q.jsx)(Ae,{height:`100%`,language:e.language===`plaintext`?void 0:e.language,value:o,theme:r,options:{readOnly:!0,minimap:{enabled:!1},scrollBeyondLastLine:!1,wordWrap:i?`on`:`off`,lineNumbers:`on`,fontSize:12,folding:!0,bracketPairColorization:{enabled:!0},domReadOnly:!0,contextmenu:!1,overviewRulerLanes:0},loading:(0,q.jsx)(E,{className:`size-4 animate-spin text-muted-foreground`})})})]})}var hc={sortAsc:e=>`<svg viewBox="0 0 16 16" fill="${e.fgColor}"><path d="M8 4l4 6H4z"/></svg>`,sortDesc:e=>`<svg viewBox="0 0 16 16" fill="${e.fgColor}"><path d="M8 12l4-6H4z"/></svg>`,headerFk:()=>`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="#3b82f6" stroke-width="1.5" stroke-linecap="round"><path d="M6 4.5H4.5a2.5 2.5 0 000 5H6M10 4.5h1.5a2.5 2.5 0 010 5H10M5 7h6"/></svg>`};function gc(e){let{columns:t,rows:n,total:r,limit:i,schema:a,loading:o,page:s,onPageChange:c,onCellUpdate:l,onRowDelete:u,onBulkDelete:d,onInsertRow:f,orderBy:p,orderDir:m,onToggleSort:h,onClearSort:g,columnFilters:_={},onColumnFilter:v,connectionId:y,selectedTable:b,selectedSchema:x,connectionName:S}=e,C=Ks(),w=(0,K.useRef)(null),T=(0,K.useRef)(null),D=(0,K.useMemo)(()=>{let e=new Set(a.map(e=>e.name));return t.filter(t=>e.has(t))},[t,a]),[O,k]=(0,K.useState)(new Set),[A,ee]=(0,K.useState)(new Map),[te,ne]=(0,K.useState)(null),[j,re]=(0,K.useState)(null),[ie,ae]=(0,K.useState)(``),[M,oe]=(0,K.useState)([]),N=(0,K.useMemo)(()=>a.find(e=>e.pk)?.name??a.find(e=>e.name.toLowerCase()===`id`)?.name??null,[a]),{effectiveRows:P,pinnedCount:se,pinnedPks:ce,setPinnedPks:le}=oc(n,N),F=(0,K.useMemo)(()=>{if(se===0)return[...P,...M];let e=P.slice(0,P.length-se),t=P.slice(P.length-se);return[...e,...M,...t]},[P,M,se]),I=(0,K.useMemo)(()=>{if(!ie.trim())return F;let e=ie.toLowerCase();return F.filter(t=>D.some(n=>String(t[n]??``).toLowerCase().includes(e)))},[F,D,ie]),ue=(0,K.useMemo)(()=>se===0||!N?0:ie.trim()?I.filter(e=>ce.has(String(e[N]??``))).length:se,[se,N,ie,I,ce]),{pendingRef:de,addEdit:fe,commitAll:pe,discardAll:me,hasPending:he,pendingCount:ge,committedRef:_e}=ac(N,l,f),{columns:ve,freezeColumns:L,columnOrder:ye}=Js(a,D,O,A,I,p,m),{getCellContent:be,onCellEdited:xe}=nc(I,ye,a,N,fe,de),{gridSelection:R,onGridSelectionChange:Se,selectedRowIndices:Ce,clearSelection:z}=ic(),{previewData:B,setPreviewData:we,openRowPreview:V,openCellPreview:H,openPreviewInTab:U,handlePaste:Te,getContextFk:Ee,isCellViewable:W,openFkTable:De}=sc({displayRows:I,columnOrder:ye,schema:a,pkCol:N,connectionId:y,connectionName:S,selectedTable:b,selectedSchema:x,addEdit:fe,gridSelection:R,containerRef:T});(0,K.useEffect)(()=>{_e.current&&(_e.current=!1,me(),oe([]))},[n]);let Oe=(0,K.useCallback)((e,t)=>{ee(n=>new Map(n).set(e.id??e.title,t))},[]),ke=(0,K.useCallback)((e,t)=>{let n=ye[e];n&&ne({colName:n,bounds:t})},[ye]),G=(0,K.useCallback)(([e,t],n)=>{n.preventDefault(),re({position:{x:n.bounds.x+n.localEventX,y:n.bounds.y+n.localEventY},rowIdx:t,colIdx:e})},[]),Ae=(0,K.useCallback)(e=>{k(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),je=(0,K.useCallback)(e=>{if(!N)return;let t=I[e];if(!t)return;let n=String(t[N]??``);le(e=>{let t=new Set(e);return t.has(n)?t.delete(n):t.add(n),t})},[N,I,le]),Me=(0,K.useCallback)(e=>{if(ce.size===0||!N)return;let t=I[e];if(t&&ce.has(String(t[N]??``)))return{bgCell:C.bgCellMedium??C.bgHeader}},[ce,N,I,C]),Ne=(0,K.useCallback)(()=>{!N||!d||(d(N,Ce.map(e=>I[e]?.[N]).filter(e=>e!=null)),z())},[N,d,Ce,I,z]),[Pe,Fe]=(0,K.useState)(!1),Ie=(0,K.useCallback)(e=>{if(e.key===`Escape`){we(null),Fe(!1);return}(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&he&&(e.preventDefault(),pe());let t=e.target?.tagName;e.key===`/`&&t!==`INPUT`&&t!==`TEXTAREA`&&(e.preventDefault(),Fe(!0))},[he,pe]),Le=(0,K.useCallback)(()=>{!N||!f||oe(e=>[...e,{[N]:`__new_${Date.now()}`}])},[N,f]),Re=(0,K.useCallback)(e=>{let t=ye.indexOf(e);t>=0&&w.current?.scrollTo&&w.current.scrollTo(t,0)},[ye]),ze=j?I[j.rowIdx]:null,Be=ze&&N?String(ze[N]??``):``,Ve=j?ye[j.colIdx]:null,He=W(ze??null,Ve??null),Ue=Ee(Ve??null),We=ze&&Ve?ze[Ve]:null;return D.length?(0,q.jsxs)(`div`,{ref:T,className:`flex flex-col h-full overflow-hidden relative`,tabIndex:0,onKeyDown:Ie,children:[(0,q.jsx)(dc,{hasSelection:Ce.length>0,selectedCount:Ce.length,onBulkDelete:d&&N?Ne:void 0,onInsertRow:f&&N?Le:void 0,columns:D,selectedRows:Ce.map(e=>I[e]).filter(Boolean),connectionName:S,searchTerm:ie,onSearchChange:ae,onColumnJump:Re,colSearchOpen:Pe,onColSearchChange:Fe}),o&&(0,q.jsx)(`div`,{className:`absolute inset-0 z-30 flex items-center justify-center bg-background/60`,children:(0,q.jsx)(E,{className:`size-5 animate-spin text-primary`})}),(0,q.jsx)(`div`,{className:`flex-1 min-h-0`,children:(0,q.jsx)(Hs,{ref:w,columns:ve,rows:I.length,getCellContent:be,getCellsForSelection:!0,onCellEdited:xe,onPaste:Te,theme:C,freezeColumns:L,freezeTrailingRows:ue,rowMarkers:N?`checkbox-visible`:`number`,gridSelection:R,onGridSelectionChange:Se,onColumnResize:Oe,onHeaderMenuClick:ke,onCellContextMenu:G,getRowThemeOverride:Me,trailingRowOptions:f&&N?{sticky:!0,tint:!0}:void 0,onRowAppended:f?Le:void 0,headerIcons:hc,smoothScrollX:!0,smoothScrollY:!0,width:`100%`,height:`100%`})}),he&&(0,q.jsx)(fc,{pendingCount:ge,onSave:pe,onDiscard:()=>{me(),oe([])}}),B&&(0,q.jsx)(mc,{data:B,onClose:()=>we(null),onOpenInTab:U}),(0,q.jsx)(pc,{total:r,page:s,totalPages:Math.ceil(r/i)||1,onPageChange:c}),te&&(0,q.jsx)(cc,{colName:te.colName,bounds:te.bounds,isPinned:O.has(te.colName),filterValue:_[te.colName]??``,sortState:p===te.colName?m===`ASC`?`asc`:`desc`:null,onFilter:e=>{if(!v)return;let t={..._};e?t[te.colName]=e:delete t[te.colName],v(t)},onSort:()=>{h&&h(te.colName)},onClearSort:g,onTogglePin:()=>Ae(te.colName),onClose:()=>ne(null)}),j&&ze&&(0,q.jsx)(lc,{position:j.position,isPinned:ce.has(Be),onViewRow:()=>V(j.rowIdx),onViewCell:He?()=>H(j.rowIdx,j.colIdx):void 0,onPinRow:()=>je(j.rowIdx),onDeleteRow:()=>{N&&u&&ze&&u(N,ze[N])},onOpenFkTable:Ue&&We!=null&&y?()=>De(Ue,We):void 0,fkLabel:Ue?`Open ${Ue.table}.${Ue.column}`:void 0,onClose:()=>re(null)})]}):(0,q.jsx)(`div`,{className:`flex items-center justify-center h-full text-xs text-muted-foreground`,children:o?(0,q.jsx)(E,{className:`size-4 animate-spin`}):`Select a table`})}export{Ge as i,Ye as n,Ke as r,gc as t};
136
+ `)),l(!0)}},[c,e.content,e.language]),[p,m]=(0,K.useState)(200),h=(0,K.useCallback)(e=>{e.preventDefault();let t=e.clientY,n=p,r=e=>m(Math.max(80,n+(t-e.clientY))),i=()=>{document.removeEventListener(`mousemove`,r),document.removeEventListener(`mouseup`,i)};document.addEventListener(`mousemove`,r),document.addEventListener(`mouseup`,i)},[p]);return(0,q.jsxs)(`div`,{className:`shrink-0 border-t border-border flex flex-col`,style:{height:p},children:[(0,q.jsx)(`div`,{onMouseDown:h,className:`shrink-0 h-1.5 cursor-row-resize bg-border/50 hover:bg-primary/30 flex items-center justify-center transition-colors`,children:(0,q.jsx)(O,{className:`size-3 text-muted-foreground/50`})}),(0,q.jsxs)(`div`,{className:`flex items-center gap-1 px-2 py-1 bg-muted/50 border-b border-border shrink-0`,children:[(0,q.jsx)(g,{className:`size-3 text-muted-foreground`}),(0,q.jsx)(`span`,{className:`text-xs font-medium text-foreground truncate flex-1`,children:e.title}),u&&(0,q.jsx)(`button`,{type:`button`,onClick:f,title:c?`Raw`:`Beautify`,className:`p-0.5 rounded transition-colors ${c?`text-primary`:`text-muted-foreground hover:text-foreground`}`,children:(0,q.jsx)(b,{className:`size-3`})}),(0,q.jsx)(`button`,{type:`button`,onClick:()=>a(!i),title:i?`No wrap`:`Word wrap`,className:`p-0.5 rounded transition-colors ${i?`text-primary`:`text-muted-foreground hover:text-foreground`}`,children:(0,q.jsx)(x,{className:`size-3`})}),(0,q.jsxs)(`button`,{type:`button`,onClick:n,title:`Open in new tab`,className:`flex items-center gap-1 px-1.5 py-0.5 rounded text-[10px] text-muted-foreground hover:text-foreground hover:bg-muted transition-colors`,children:[(0,q.jsx)(T,{className:`size-3`}),(0,q.jsx)(`span`,{className:`hidden sm:inline`,children:`Open in Tab`})]}),(0,q.jsx)(`button`,{type:`button`,onClick:t,title:`Close preview (Esc)`,className:`p-0.5 rounded text-muted-foreground hover:text-foreground transition-colors`,children:(0,q.jsx)(y,{className:`size-3`})})]}),(0,q.jsx)(`div`,{className:`flex-1 min-h-0`,children:(0,q.jsx)(Ae,{height:`100%`,language:e.language===`plaintext`?void 0:e.language,value:o,theme:r,options:{readOnly:!0,minimap:{enabled:!1},scrollBeyondLastLine:!1,wordWrap:i?`on`:`off`,lineNumbers:`on`,fontSize:12,folding:!0,bracketPairColorization:{enabled:!0},domReadOnly:!0,contextmenu:!1,overviewRulerLanes:0},loading:(0,q.jsx)(E,{className:`size-4 animate-spin text-muted-foreground`})})})]})}var hc={sortAsc:e=>`<svg viewBox="0 0 16 16" fill="${e.fgColor}"><path d="M8 4l4 6H4z"/></svg>`,sortDesc:e=>`<svg viewBox="0 0 16 16" fill="${e.fgColor}"><path d="M8 12l4-6H4z"/></svg>`,headerFk:()=>`<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" fill="none" stroke="#3b82f6" stroke-width="1.5" stroke-linecap="round"><path d="M6 4.5H4.5a2.5 2.5 0 000 5H6M10 4.5h1.5a2.5 2.5 0 010 5H10M5 7h6"/></svg>`};function gc(e){let{columns:t,rows:n,total:r,limit:i,schema:a,loading:o,page:s,onPageChange:c,onCellUpdate:l,onRowDelete:u,onBulkDelete:d,onInsertRow:f,orderBy:p,orderDir:m,onToggleSort:h,onClearSort:g,columnFilters:_={},onColumnFilter:v,connectionId:y,selectedTable:b,selectedSchema:x,connectionName:S}=e,C=Ks(),w=(0,K.useRef)(null),T=(0,K.useRef)(null),D=(0,K.useMemo)(()=>{let e=new Set(a.map(e=>e.name));return t.filter(t=>e.has(t))},[t,a]),[O,k]=(0,K.useState)(new Set),[A,ee]=(0,K.useState)(new Map),[te,ne]=(0,K.useState)(null),[j,re]=(0,K.useState)(null),[ie,ae]=(0,K.useState)(``),[M,oe]=(0,K.useState)([]),N=(0,K.useMemo)(()=>a.find(e=>e.pk)?.name??a.find(e=>e.name.toLowerCase()===`id`)?.name??null,[a]),{effectiveRows:P,pinnedCount:se,pinnedPks:ce,setPinnedPks:le}=oc(n,N),F=(0,K.useMemo)(()=>{if(se===0)return[...P,...M];let e=P.slice(0,P.length-se),t=P.slice(P.length-se);return[...e,...M,...t]},[P,M,se]),I=(0,K.useMemo)(()=>{if(!ie.trim())return F;let e=ie.toLowerCase();return F.filter(t=>D.some(n=>String(t[n]??``).toLowerCase().includes(e)))},[F,D,ie]),ue=(0,K.useMemo)(()=>se===0||!N?0:ie.trim()?I.filter(e=>ce.has(String(e[N]??``))).length:se,[se,N,ie,I,ce]),{pendingRef:de,addEdit:fe,commitAll:pe,discardAll:me,hasPending:he,pendingCount:ge,committedRef:_e}=ac(N,l,f),{columns:ve,freezeColumns:L,columnOrder:ye}=Js(a,D,O,A,I,p,m),{getCellContent:be,onCellEdited:xe}=nc(I,ye,a,N,fe,de),{gridSelection:R,onGridSelectionChange:Se,selectedRowIndices:Ce,clearSelection:z}=ic(),{previewData:B,setPreviewData:we,openRowPreview:V,openCellPreview:H,openPreviewInTab:U,handlePaste:Te,getContextFk:Ee,isCellViewable:W,openFkTable:De}=sc({displayRows:I,columnOrder:ye,schema:a,pkCol:N,connectionId:y,connectionName:S,selectedTable:b,selectedSchema:x,addEdit:fe,gridSelection:R,containerRef:T});(0,K.useEffect)(()=>{_e.current&&(_e.current=!1,me(),oe([]))},[n]);let Oe=(0,K.useCallback)((e,t)=>{ee(n=>new Map(n).set(e.id??e.title,t))},[]),ke=(0,K.useCallback)((e,t)=>{let n=ye[e];n&&ne({colName:n,bounds:t})},[ye]),G=(0,K.useCallback)(([e,t],n)=>{n.preventDefault(),re({position:{x:n.bounds.x+n.localEventX,y:n.bounds.y+n.localEventY},rowIdx:t,colIdx:e})},[]),Ae=(0,K.useCallback)(e=>{k(t=>{let n=new Set(t);return n.has(e)?n.delete(e):n.add(e),n})},[]),je=(0,K.useCallback)(e=>{if(!N)return;let t=I[e];if(!t)return;let n=String(t[N]??``);le(e=>{let t=new Set(e);return t.has(n)?t.delete(n):t.add(n),t})},[N,I,le]),Me=(0,K.useCallback)(e=>{if(ce.size===0||!N)return;let t=I[e];if(t&&ce.has(String(t[N]??``)))return{bgCell:C.bgCellMedium??C.bgHeader}},[ce,N,I,C]),Ne=(0,K.useCallback)(()=>{!N||!d||(d(N,Ce.map(e=>I[e]?.[N]).filter(e=>e!=null)),z())},[N,d,Ce,I,z]),[Pe,Fe]=(0,K.useState)(!1),Ie=(0,K.useCallback)(e=>{if(e.key===`Escape`){we(null),Fe(!1);return}(e.metaKey||e.ctrlKey)&&e.key===`Enter`&&he&&(e.preventDefault(),pe());let t=e.target?.tagName;e.key===`/`&&t!==`INPUT`&&t!==`TEXTAREA`&&(e.preventDefault(),Fe(!0))},[he,pe]),Le=(0,K.useCallback)(()=>{!N||!f||oe(e=>[...e,{[N]:`__new_${Date.now()}`}])},[N,f]),Re=(0,K.useCallback)(e=>{let t=ye.indexOf(e);t>=0&&w.current?.scrollTo&&w.current.scrollTo(t,0)},[ye]),ze=j?I[j.rowIdx]:null,Be=ze&&N?String(ze[N]??``):``,Ve=j?ye[j.colIdx]:null,He=W(ze??null,Ve??null),Ue=Ee(Ve??null),We=ze&&Ve?ze[Ve]:null;return D.length?(0,q.jsxs)(`div`,{ref:T,className:`flex flex-col h-full overflow-hidden relative`,tabIndex:0,onKeyDown:Ie,children:[(0,q.jsx)(dc,{hasSelection:Ce.length>0,selectedCount:Ce.length,onBulkDelete:d&&N?Ne:void 0,onInsertRow:f&&N?Le:void 0,columns:D,selectedRows:Ce.map(e=>I[e]).filter(Boolean),connectionName:S,searchTerm:ie,onSearchChange:ae,onColumnJump:Re,colSearchOpen:Pe,onColSearchChange:Fe}),o&&(0,q.jsx)(`div`,{className:`absolute inset-0 z-30 flex items-center justify-center bg-background/60`,children:(0,q.jsx)(E,{className:`size-5 animate-spin text-primary`})}),(0,q.jsx)(`div`,{className:`flex-1 min-h-0`,children:(0,q.jsx)(Hs,{ref:w,columns:ve,rows:I.length,getCellContent:be,getCellsForSelection:!0,onCellEdited:xe,onPaste:Te,theme:C,freezeColumns:L,freezeTrailingRows:ue,rowMarkers:N?`checkbox-visible`:`number`,gridSelection:R,onGridSelectionChange:Se,onColumnResize:Oe,onHeaderMenuClick:ke,onCellContextMenu:G,getRowThemeOverride:Me,trailingRowOptions:f&&N?{sticky:!0,tint:!0}:void 0,onRowAppended:f?Le:void 0,headerIcons:hc,smoothScrollX:!0,smoothScrollY:!0,width:`100%`,height:`100%`})}),he&&(0,q.jsx)(fc,{pendingCount:ge,onSave:pe,onDiscard:()=>{me(),oe([])}}),B&&(0,q.jsx)(mc,{data:B,onClose:()=>we(null),onOpenInTab:U}),(0,q.jsx)(pc,{total:r,page:s,totalPages:Math.ceil(r/i)||1,onPageChange:c}),te&&(0,q.jsx)(cc,{colName:te.colName,bounds:te.bounds,isPinned:O.has(te.colName),filterValue:_[te.colName]??``,sortState:p===te.colName?m===`ASC`?`asc`:`desc`:null,onFilter:e=>{if(!v)return;let t={..._};e?t[te.colName]=e:delete t[te.colName],v(t)},onSort:()=>{h&&h(te.colName)},onClearSort:g,onTogglePin:()=>Ae(te.colName),onClose:()=>ne(null)}),j&&ze&&(0,q.jsx)(lc,{position:j.position,isPinned:ce.has(Be),onViewRow:()=>V(j.rowIdx),onViewCell:He?()=>H(j.rowIdx,j.colIdx):void 0,onPinRow:()=>je(j.rowIdx),onDeleteRow:()=>{N&&u&&ze&&u(N,ze[N])},onOpenFkTable:Ue&&We!=null&&y?()=>De(Ue,We):void 0,fkLabel:Ue?`Open ${Ue.table}.${Ue.column}`:void 0,onClose:()=>re(null)})]}):(0,q.jsx)(`div`,{className:`flex items-center justify-center h-full text-xs text-muted-foreground`,children:o?(0,q.jsx)(E,{className:`size-4 animate-spin`}):`Select a table`})}export{Ge as i,Ye as n,Ke as r,gc as t};
137
+ //# sourceMappingURL=glide-data-grid-CqT8WzTs.js.map