@runfusion/fusion 0.27.1 → 0.28.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/bin.js +3418 -864
- package/dist/client/assets/AgentDetailView-DSpIqBOs.css +1 -0
- package/dist/client/assets/{AgentDetailView-shgiiUb4.js → AgentDetailView-V32TpEe1.js} +3 -3
- package/dist/client/assets/{AgentsView-CpwqOVDz.js → AgentsView-CxITZE-U.js} +3 -3
- package/dist/client/assets/ChatView-7WPHyB_7.js +1 -0
- package/dist/client/assets/DevServerView-Diw4hjw0.js +1 -0
- package/dist/client/assets/{DirectoryPicker-C0kmRv0u.js → DirectoryPicker-CWSApoLU.js} +1 -1
- package/dist/client/assets/{DocumentsView-B94U9ijs.js → DocumentsView-1kr0dhsV.js} +1 -1
- package/dist/client/assets/{EvalsView-O_4YWy--.js → EvalsView-cDfXYiK6.js} +1 -1
- package/dist/client/assets/{ExperimentalAgentOnboardingModal-CkEiF85-.js → ExperimentalAgentOnboardingModal-lNSf6UtY.js} +1 -1
- package/dist/client/assets/{InsightsView-D-Qe0tRr.js → InsightsView-D2AjxOnu.js} +1 -1
- package/dist/client/assets/{MemoryView-CoRUmRvb.js → MemoryView-Dq4yjIPI.js} +1 -1
- package/dist/client/assets/{NodesView-DQzXjcLc.js → NodesView-Cpmkze7n.js} +4 -4
- package/dist/client/assets/{PiExtensionsManager-Dn1LmFbq.js → PiExtensionsManager-oi9FHT0y.js} +2 -2
- package/dist/client/assets/PluginManager-C4UoLv4U.css +1 -0
- package/dist/client/assets/PluginManager-o12KG4e8.js +1 -0
- package/dist/client/assets/ResearchView-C7uXon3o.css +1 -0
- package/dist/client/assets/ResearchView-C9bjVB7-.js +1 -0
- package/dist/client/assets/{SettingsModal-Bg1-3JO_.js → SettingsModal-CT01a5Rh.js} +1 -1
- package/dist/client/assets/SettingsModal-Cu93Jjho.js +31 -0
- package/dist/client/assets/{SetupWizardModal-DuzYPbuJ.js → SetupWizardModal-Agi3XNtZ.js} +1 -1
- package/dist/client/assets/{SkillsView-BIFoVNUf.js → SkillsView-DmZfbGLs.js} +1 -1
- package/dist/client/assets/{StashRecoveryView-C52KsV7f.js → StashRecoveryView-BwKJQaUW.js} +1 -1
- package/dist/client/assets/{TodoView-sS_mT0Y7.js → TodoView-uJRg4Cnl.js} +2 -2
- package/dist/client/assets/dashboard-view-C7Snlgow.js +21 -0
- package/dist/client/assets/dashboard-view-DqWnXEbq.css +1 -0
- package/dist/client/assets/{folder-open-B9cwJ-OX.js → folder-open-DU-Ec_iC.js} +1 -1
- package/dist/client/assets/index-CD0_dkME.css +1 -0
- package/dist/client/assets/index-DiewofJh.js +692 -0
- package/dist/client/assets/{star-BDn04UYV.js → star-Qi0GspVN.js} +1 -1
- package/dist/client/assets/{upload-zdPPycKQ.js → upload-Dx_l9Vbu.js} +1 -1
- package/dist/client/assets/{users-CPYZjK2g.js → users-3Qw_TMah.js} +1 -1
- package/dist/client/index.html +2 -2
- package/dist/client/version.json +1 -1
- package/dist/droid-cli/package.json +1 -1
- package/dist/extension.js +2628 -573
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/package.json +1 -1
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/registration.test.ts +2 -4
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/runtime-availability.test.ts +5 -2
- package/dist/plugins/fusion-plugin-cli-printing-press/src/__tests__/workflow-integration.test.ts +7 -4
- package/dist/plugins/fusion-plugin-cursor-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/dist/plugins/fusion-plugin-droid-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-hermes-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-openclaw-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-paperclip-runtime/package.json +1 -1
- package/dist/plugins/fusion-plugin-reports/package.json +1 -1
- package/dist/plugins/fusion-plugin-roadmap/package.json +1 -1
- package/dist/plugins/fusion-plugin-whatsapp-chat/package.json +1 -1
- package/package.json +1 -1
- package/skill/fusion/references/engine-tools.md +1 -0
- package/skill/fusion/references/extension-tools.md +3 -1
- package/dist/client/assets/AgentDetailView-B7QRcHJH.css +0 -1
- package/dist/client/assets/ChatView-DyRBOIKL.js +0 -1
- package/dist/client/assets/DevServerView-Cdelj9-m.js +0 -1
- package/dist/client/assets/PluginManager-DtRQXia5.css +0 -1
- package/dist/client/assets/PluginManager-Y0fs-6No.js +0 -1
- package/dist/client/assets/ResearchView-BEI4ZSGs.css +0 -1
- package/dist/client/assets/ResearchView-CjOxKhdS.js +0 -1
- package/dist/client/assets/SettingsModal-DL7tjJQa.js +0 -31
- package/dist/client/assets/dashboard-view-BoTzlP8b.css +0 -1
- package/dist/client/assets/dashboard-view-MB-86hAu.js +0 -21
- package/dist/client/assets/index-BOjPRqEk.js +0 -692
- package/dist/client/assets/index-BmSEq8Rb.css +0 -1
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as o,j as e}from"./vendor-react-K0fH_qHe.js";import{cl as w,b1 as L,cm as O,cn as _,co as $,X as W,b as Y,C as k,L as G}from"./index-BOjPRqEk.js";import{D as q}from"./DirectoryPicker-C0kmRv0u.js";import{s as f}from"./projectDetection-G3XuxD2X.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-B9cwJ-OX.js";function V({onProjectRegistered:m,onClose:p}){const C="https://github.com/runfusion/fusion/discussions",[z,y]=o.useState(!0),[s,n]=o.useState(()=>({step:w()?"manual":"auth",manualMode:"existing",manualPath:"",manualCloneUrl:"",manualName:"",manualIsolationMode:"in-process",manualNodeId:"",isRegistering:!1,error:null})),[j,M]=o.useState(!1),[i,c]=o.useState(""),[u,x]=o.useState(()=>w()),{nodes:g,loading:I}=L(),S=g.find(a=>a.type==="local")?.id,N=o.useCallback(()=>{y(!1),p?.()},[p]),P=o.useCallback(a=>{n(t=>{const d={manualPath:a};return a&&(!t.manualName||t.manualName===f(t.manualPath))&&(d.manualName=f(a)),{...t,...d}})},[]),R=o.useCallback(async()=>{const a=s.manualPath.trim(),t=s.manualName.trim(),d=s.manualCloneUrl.trim();if(!(!a||!t)&&!(s.manualMode==="clone"&&!d)){n(r=>({...r,isRegistering:!0,error:null}));try{const r={name:t,path:a,isolationMode:s.manualIsolationMode,nodeId:s.manualNodeId||void 0,cloneUrl:s.manualMode==="clone"?d:void 0},h=await O(r);m(h),n(B=>({...B,step:"complete",isRegistering:!1}))}catch(r){n(h=>({...h,isRegistering:!1,error:r instanceof Error?r.message:"Failed to register project"}))}}},[s.manualPath,s.manualName,s.manualCloneUrl,s.manualMode,s.manualIsolationMode,s.manualNodeId,m]),b=o.useCallback(()=>{const a=i.trim();a&&(_(a),x(a),c(""),n(t=>t.step==="auth"?{...t,step:"manual"}:t))},[i]),A=o.useCallback(()=>{$(),x(void 0),c("")},[]),F=o.useCallback(()=>{n(a=>({...a,step:"manual"}))},[]);if(!z)return null;const v=s.manualMode==="existing",l=s.manualMode==="clone",T=s.manualPath.trim().length>0,U=s.manualName.trim().length>0,D=s.manualCloneUrl.trim().length>0,E=s.isRegistering||!T||!U||l&&!D;return e.jsx("div",{className:"modal-overlay open setup-wizard-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wizard-title",children:e.jsxs("div",{className:"modal setup-wizard-modal",children:[e.jsxs("div",{className:"setup-wizard-header",children:[e.jsxs("div",{className:"setup-wizard-heading",children:[e.jsxs("div",{className:"setup-wizard-brand","aria-label":"Fusion",children:[e.jsxs("svg",{className:"setup-wizard-brand-logo",width:28,height:28,viewBox:"0 0 128 128",fill:"none","aria-label":"Fusion logo",role:"img",children:[e.jsx("circle",{cx:"64",cy:"64",r:"52",stroke:"currentColor",strokeWidth:"8"}),e.jsx("path",{d:"M26 101C44 82 62 64 82 45C90 37 98 30 104 24C96 35 89 47 81 60C70 79 57 95 43 108C38 112 32 108 26 101Z",fill:"currentColor"})]}),e.jsx("span",{className:"setup-wizard-brand-name",children:"Fusion"})]}),e.jsxs("h2",{id:"wizard-title",className:"setup-wizard-title",children:[s.step==="auth"&&"Set Auth Token",s.step==="manual"&&"Welcome to Fusion",s.step==="complete"&&"Setup Complete!"]})]}),s.step!=="complete"&&e.jsx("button",{className:"modal-close",onClick:N,"aria-label":"Close wizard",children:e.jsx(W,{size:20})})]}),e.jsxs("div",{className:"setup-wizard-content",children:[s.step==="auth"&&e.jsxs("div",{className:"setup-wizard-auth-step",children:[e.jsx("p",{className:"setup-wizard-auth-step-description",children:"This dashboard requires an auth token to communicate with the Fusion daemon. Paste the token below to continue."}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"setup-auth-token",children:"Auth Token"}),e.jsx("input",{id:"setup-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:"Paste the daemon auth token",autoComplete:"off",spellCheck:!1,autoFocus:!0}),e.jsxs("p",{className:"form-hint",children:["The token was set via the ",e.jsx("code",{children:"FUSION_DAEMON_TOKEN"})," environment variable when starting the dashboard."]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="manual"&&e.jsxs("div",{className:"setup-wizard-manual",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-name",children:"Project Name"}),e.jsx("input",{id:"project-name",type:"text",value:s.manualName,onChange:a=>n(t=>({...t,manualName:a.target.value})),placeholder:"my-project"}),e.jsx("p",{className:"form-hint",children:l?"By default this follows the destination folder name unless you edit it.":"By default this follows the selected directory name unless you edit it."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-path",children:l?"Destination Directory":"Project Directory"}),e.jsx(q,{value:s.manualPath,onChange:P,nodeId:s.manualNodeId||void 0,localNodeId:S,placeholder:l?"/path/for/new-clone":"/path/to/your/project"}),e.jsx("p",{className:"form-hint",children:l?"Select or type an absolute destination path. Fusion will clone into this directory.":"Select or type the absolute path to your project"})]}),e.jsxs("div",{className:"setup-wizard-advanced",children:[e.jsxs("button",{type:"button",className:"setup-wizard-advanced-toggle","aria-expanded":j,onClick:()=>M(a=>!a),children:[e.jsx(Y,{size:16,className:"setup-wizard-advanced-chevron"}),e.jsx("span",{children:"Advanced settings"})]}),j&&e.jsxs("div",{className:"setup-wizard-advanced-panel",children:[e.jsxs("fieldset",{className:"setup-wizard-mode-switch","aria-label":"Project setup mode",children:[e.jsx("legend",{children:"Setup Mode"}),e.jsxs("label",{className:`setup-wizard-mode-option${v?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"existing",checked:v,onChange:()=>n(a=>({...a,manualMode:"existing",error:null}))}),e.jsx("span",{children:"Use Existing Directory"})]}),e.jsxs("label",{className:`setup-wizard-mode-option${l?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"clone",checked:l,onChange:()=>n(a=>({...a,manualMode:"clone",error:null}))}),e.jsx("span",{children:"Clone Git Repository"})]})]}),l&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-clone-url",children:"Repository URL"}),e.jsx("input",{id:"project-clone-url",type:"text",value:s.manualCloneUrl,onChange:a=>n(t=>({...t,manualCloneUrl:a.target.value})),placeholder:"https://github.com/owner/repo.git"}),e.jsx("p",{className:"form-hint",children:"Fusion will run git clone into the destination directory, then register that cloned folder."})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"project-node-selector",children:[e.jsx("span",{className:"project-node-selector__label",children:"Runtime Node"}),e.jsxs("select",{value:s.manualNodeId,onChange:a=>n(t=>({...t,manualNodeId:a.target.value})),disabled:I||s.isRegistering,children:[e.jsx("option",{value:"",children:"Local node"}),g.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.type,")"]},a.id))]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Isolation Mode"}),e.jsxs("div",{className:"setup-wizard-isolation-options",children:[e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="in-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"in-process",checked:s.manualIsolationMode==="in-process",onChange:()=>n(a=>({...a,manualIsolationMode:"in-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"In-Process"}),e.jsx("span",{children:"Lower overhead, shared memory. Best for most projects."}),e.jsx("span",{className:"wizard-option-recommended",children:"Recommended"})]})]}),e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="child-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"child-process",checked:s.manualIsolationMode==="child-process",onChange:()=>n(a=>({...a,manualIsolationMode:"child-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"Child-Process"}),e.jsx("span",{children:"Isolated execution with crash containment."})]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"advanced-auth-token",children:"Browser Auth Token"}),e.jsxs("div",{className:"setup-wizard-auth-token",children:[e.jsx("input",{id:"advanced-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:u?"Enter a new token to replace the stored one":"Paste the auth token for this browser",autoComplete:"off",spellCheck:!1}),e.jsxs("div",{className:"setup-wizard-auth-token-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:b,disabled:i.trim().length===0,children:u?"Update token":"Set token"}),u&&e.jsx("button",{type:"button",className:"btn",onClick:A,children:"Reset token"})]})]}),e.jsx("p",{className:"form-hint",children:u?"A token is already stored in this browser. You can update or reset it below.":"No token is stored. Use the auth prompt at the top of the wizard, or set one here."})]})]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="complete"&&e.jsxs("div",{className:"setup-wizard-complete",children:[e.jsxs("div",{className:"setup-wizard-success-streak","aria-hidden":"true",children:[e.jsx("div",{className:"setup-wizard-success-streak-core"}),e.jsx("div",{className:"setup-wizard-success-streak-glow"})]}),e.jsx(k,{size:64,className:"success-icon"}),e.jsx("h3",{children:"All Set!"}),e.jsx("p",{children:"Your project has been registered successfully."}),e.jsx("p",{children:"You can add more projects anytime from the project overview."})]})]}),e.jsxs("div",{className:"setup-wizard-footer",children:[e.jsx("a",{className:"btn setup-wizard-help-link",href:C,target:"_blank",rel:"noreferrer",children:"Need help?"}),s.step==="auth"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn",onClick:F,children:"Skip"}),e.jsx("button",{className:"btn btn-primary",onClick:b,disabled:i.trim().length===0,children:e.jsx("span",{children:"Set Token & Continue"})})]}),s.step==="manual"&&e.jsx("button",{className:"btn btn-primary",onClick:R,disabled:E,children:s.isRegistering?e.jsxs(e.Fragment,{children:[e.jsx(G,{size:16,className:"animate-spin"}),e.jsx("span",{children:"Registering..."})]}):e.jsx("span",{children:"Register Project"})}),s.step==="complete"&&e.jsxs("button",{className:"btn btn-primary",onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Get Started"})]})]})]})})}export{V as SetupWizardModal};
|
|
1
|
+
import{r as o,j as e}from"./vendor-react-K0fH_qHe.js";import{co as w,b2 as L,cp as O,cq as _,cr as $,X as W,b as Y,C as k,L as q}from"./index-DiewofJh.js";import{D as G}from"./DirectoryPicker-CWSApoLU.js";import{s as f}from"./projectDetection-G3XuxD2X.js";import"./vendor-xterm-DzcZoU0P.js";import"./folder-open-DU-Ec_iC.js";function V({onProjectRegistered:m,onClose:p}){const C="https://github.com/runfusion/fusion/discussions",[z,y]=o.useState(!0),[s,n]=o.useState(()=>({step:w()?"manual":"auth",manualMode:"existing",manualPath:"",manualCloneUrl:"",manualName:"",manualIsolationMode:"in-process",manualNodeId:"",isRegistering:!1,error:null})),[j,M]=o.useState(!1),[i,c]=o.useState(""),[u,x]=o.useState(()=>w()),{nodes:g,loading:I}=L(),S=g.find(a=>a.type==="local")?.id,N=o.useCallback(()=>{y(!1),p?.()},[p]),P=o.useCallback(a=>{n(t=>{const d={manualPath:a};return a&&(!t.manualName||t.manualName===f(t.manualPath))&&(d.manualName=f(a)),{...t,...d}})},[]),R=o.useCallback(async()=>{const a=s.manualPath.trim(),t=s.manualName.trim(),d=s.manualCloneUrl.trim();if(!(!a||!t)&&!(s.manualMode==="clone"&&!d)){n(r=>({...r,isRegistering:!0,error:null}));try{const r={name:t,path:a,isolationMode:s.manualIsolationMode,nodeId:s.manualNodeId||void 0,cloneUrl:s.manualMode==="clone"?d:void 0},h=await O(r);m(h),n(B=>({...B,step:"complete",isRegistering:!1}))}catch(r){n(h=>({...h,isRegistering:!1,error:r instanceof Error?r.message:"Failed to register project"}))}}},[s.manualPath,s.manualName,s.manualCloneUrl,s.manualMode,s.manualIsolationMode,s.manualNodeId,m]),b=o.useCallback(()=>{const a=i.trim();a&&(_(a),x(a),c(""),n(t=>t.step==="auth"?{...t,step:"manual"}:t))},[i]),A=o.useCallback(()=>{$(),x(void 0),c("")},[]),F=o.useCallback(()=>{n(a=>({...a,step:"manual"}))},[]);if(!z)return null;const v=s.manualMode==="existing",l=s.manualMode==="clone",T=s.manualPath.trim().length>0,U=s.manualName.trim().length>0,D=s.manualCloneUrl.trim().length>0,E=s.isRegistering||!T||!U||l&&!D;return e.jsx("div",{className:"modal-overlay open setup-wizard-overlay",role:"dialog","aria-modal":"true","aria-labelledby":"wizard-title",children:e.jsxs("div",{className:"modal setup-wizard-modal",children:[e.jsxs("div",{className:"setup-wizard-header",children:[e.jsxs("div",{className:"setup-wizard-heading",children:[e.jsxs("div",{className:"setup-wizard-brand","aria-label":"Fusion",children:[e.jsxs("svg",{className:"setup-wizard-brand-logo",width:28,height:28,viewBox:"0 0 128 128",fill:"none","aria-label":"Fusion logo",role:"img",children:[e.jsx("circle",{cx:"64",cy:"64",r:"52",stroke:"currentColor",strokeWidth:"8"}),e.jsx("path",{d:"M26 101C44 82 62 64 82 45C90 37 98 30 104 24C96 35 89 47 81 60C70 79 57 95 43 108C38 112 32 108 26 101Z",fill:"currentColor"})]}),e.jsx("span",{className:"setup-wizard-brand-name",children:"Fusion"})]}),e.jsxs("h2",{id:"wizard-title",className:"setup-wizard-title",children:[s.step==="auth"&&"Set Auth Token",s.step==="manual"&&"Welcome to Fusion",s.step==="complete"&&"Setup Complete!"]})]}),s.step!=="complete"&&e.jsx("button",{className:"modal-close",onClick:N,"aria-label":"Close wizard",children:e.jsx(W,{size:20})})]}),e.jsxs("div",{className:"setup-wizard-content",children:[s.step==="auth"&&e.jsxs("div",{className:"setup-wizard-auth-step",children:[e.jsx("p",{className:"setup-wizard-auth-step-description",children:"This dashboard requires an auth token to communicate with the Fusion daemon. Paste the token below to continue."}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"setup-auth-token",children:"Auth Token"}),e.jsx("input",{id:"setup-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:"Paste the daemon auth token",autoComplete:"off",spellCheck:!1,autoFocus:!0}),e.jsxs("p",{className:"form-hint",children:["The token was set via the ",e.jsx("code",{children:"FUSION_DAEMON_TOKEN"})," environment variable when starting the dashboard."]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="manual"&&e.jsxs("div",{className:"setup-wizard-manual",children:[e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-name",children:"Project Name"}),e.jsx("input",{id:"project-name",type:"text",value:s.manualName,onChange:a=>n(t=>({...t,manualName:a.target.value})),placeholder:"my-project"}),e.jsx("p",{className:"form-hint",children:l?"By default this follows the destination folder name unless you edit it.":"By default this follows the selected directory name unless you edit it."})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-path",children:l?"Destination Directory":"Project Directory"}),e.jsx(G,{value:s.manualPath,onChange:P,nodeId:s.manualNodeId||void 0,localNodeId:S,placeholder:l?"/path/for/new-clone":"/path/to/your/project"}),e.jsx("p",{className:"form-hint",children:l?"Select or type an absolute destination path. Fusion will clone into this directory.":"Select or type the absolute path to your project"})]}),e.jsxs("div",{className:"setup-wizard-advanced",children:[e.jsxs("button",{type:"button",className:"setup-wizard-advanced-toggle","aria-expanded":j,onClick:()=>M(a=>!a),children:[e.jsx(Y,{size:16,className:"setup-wizard-advanced-chevron"}),e.jsx("span",{children:"Advanced settings"})]}),j&&e.jsxs("div",{className:"setup-wizard-advanced-panel",children:[e.jsxs("fieldset",{className:"setup-wizard-mode-switch","aria-label":"Project setup mode",children:[e.jsx("legend",{children:"Setup Mode"}),e.jsxs("label",{className:`setup-wizard-mode-option${v?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"existing",checked:v,onChange:()=>n(a=>({...a,manualMode:"existing",error:null}))}),e.jsx("span",{children:"Use Existing Directory"})]}),e.jsxs("label",{className:`setup-wizard-mode-option${l?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"setup-mode",value:"clone",checked:l,onChange:()=>n(a=>({...a,manualMode:"clone",error:null}))}),e.jsx("span",{children:"Clone Git Repository"})]})]}),l&&e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"project-clone-url",children:"Repository URL"}),e.jsx("input",{id:"project-clone-url",type:"text",value:s.manualCloneUrl,onChange:a=>n(t=>({...t,manualCloneUrl:a.target.value})),placeholder:"https://github.com/owner/repo.git"}),e.jsx("p",{className:"form-hint",children:"Fusion will run git clone into the destination directory, then register that cloned folder."})]}),e.jsx("div",{className:"form-group",children:e.jsxs("div",{className:"project-node-selector",children:[e.jsx("span",{className:"project-node-selector__label",children:"Runtime Node"}),e.jsxs("select",{value:s.manualNodeId,onChange:a=>n(t=>({...t,manualNodeId:a.target.value})),disabled:I||s.isRegistering,children:[e.jsx("option",{value:"",children:"Local node"}),g.map(a=>e.jsxs("option",{value:a.id,children:[a.name," (",a.type,")"]},a.id))]})]})}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{children:"Isolation Mode"}),e.jsxs("div",{className:"setup-wizard-isolation-options",children:[e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="in-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"in-process",checked:s.manualIsolationMode==="in-process",onChange:()=>n(a=>({...a,manualIsolationMode:"in-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"In-Process"}),e.jsx("span",{children:"Lower overhead, shared memory. Best for most projects."}),e.jsx("span",{className:"wizard-option-recommended",children:"Recommended"})]})]}),e.jsxs("label",{className:`setup-wizard-isolation-option${s.manualIsolationMode==="child-process"?" selected":""}`,children:[e.jsx("input",{type:"radio",name:"isolation-mode",value:"child-process",checked:s.manualIsolationMode==="child-process",onChange:()=>n(a=>({...a,manualIsolationMode:"child-process"}))}),e.jsxs("div",{className:"setup-wizard-isolation-option-content",children:[e.jsx("strong",{children:"Child-Process"}),e.jsx("span",{children:"Isolated execution with crash containment."})]})]})]})]}),e.jsxs("div",{className:"form-group",children:[e.jsx("label",{htmlFor:"advanced-auth-token",children:"Browser Auth Token"}),e.jsxs("div",{className:"setup-wizard-auth-token",children:[e.jsx("input",{id:"advanced-auth-token",type:"password",value:i,onChange:a=>c(a.target.value),placeholder:u?"Enter a new token to replace the stored one":"Paste the auth token for this browser",autoComplete:"off",spellCheck:!1}),e.jsxs("div",{className:"setup-wizard-auth-token-actions",children:[e.jsx("button",{type:"button",className:"btn",onClick:b,disabled:i.trim().length===0,children:u?"Update token":"Set token"}),u&&e.jsx("button",{type:"button",className:"btn",onClick:A,children:"Reset token"})]})]}),e.jsx("p",{className:"form-hint",children:u?"A token is already stored in this browser. You can update or reset it below.":"No token is stored. Use the auth prompt at the top of the wizard, or set one here."})]})]})]}),s.error&&e.jsx("div",{className:"wizard-error",role:"alert",children:s.error})]}),s.step==="complete"&&e.jsxs("div",{className:"setup-wizard-complete",children:[e.jsxs("div",{className:"setup-wizard-success-streak","aria-hidden":"true",children:[e.jsx("div",{className:"setup-wizard-success-streak-core"}),e.jsx("div",{className:"setup-wizard-success-streak-glow"})]}),e.jsx(k,{size:64,className:"success-icon"}),e.jsx("h3",{children:"All Set!"}),e.jsx("p",{children:"Your project has been registered successfully."}),e.jsx("p",{children:"You can add more projects anytime from the project overview."})]})]}),e.jsxs("div",{className:"setup-wizard-footer",children:[e.jsx("a",{className:"btn setup-wizard-help-link",href:C,target:"_blank",rel:"noreferrer",children:"Need help?"}),s.step==="auth"&&e.jsxs(e.Fragment,{children:[e.jsx("button",{className:"btn",onClick:F,children:"Skip"}),e.jsx("button",{className:"btn btn-primary",onClick:b,disabled:i.trim().length===0,children:e.jsx("span",{children:"Set Token & Continue"})})]}),s.step==="manual"&&e.jsx("button",{className:"btn btn-primary",onClick:R,disabled:E,children:s.isRegistering?e.jsxs(e.Fragment,{children:[e.jsx(q,{size:16,className:"animate-spin"}),e.jsx("span",{children:"Registering..."})]}):e.jsx("span",{children:"Register Project"})}),s.step==="complete"&&e.jsxs("button",{className:"btn btn-primary",onClick:N,children:[e.jsx(k,{size:16}),e.jsx("span",{children:"Get Started"})]})]})]})})}export{V as SetupWizardModal};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";import{
|
|
1
|
+
import{r as i,j as e}from"./vendor-react-K0fH_qHe.js";import{bq as X,bC as _,bD as B,bE as G,bA as H,X as P,R as J,a as O,b as Y,L as Z,aq as I}from"./index-DiewofJh.js";import"./vendor-xterm-DzcZoU0P.js";function ie({projectId:c,addToast:o,onClose:Q}){const[d,v]=i.useState([]),[f,y]=i.useState(!0),[A,E]=i.useState(!1),[L,p]=i.useState(null),[D,q]=i.useState([]),[h,K]=i.useState(""),[m,g]=i.useState(null),[k,x]=i.useState(null),[V,R]=i.useState(!1),[z,b]=i.useState(null),r=i.useRef(null),[N,W]=i.useState(""),F=h.trim()?d.filter(s=>s.name.toLowerCase().includes(h.toLowerCase())||s.relativePath.toLowerCase().includes(h.toLowerCase())):d,C=i.useCallback(async()=>{y(!0);try{const s=await X(c);v(s)}catch(s){const a=s instanceof Error?s.message:"Failed to load discovered skills";o(a,"error")}finally{y(!1)}},[c,o]),u=i.useCallback(async s=>{const a=l=>{if(!l||typeof l!="object")return!1;const t=l;if(typeof t.status=="number"&&t.status>=500)return!0;if(t.details&&typeof t.details=="object"){const w=t.details;if(typeof w.code=="string"&&w.code.startsWith("upstream_"))return!0}const n=l;return typeof n.error=="string"&&typeof n.code=="string"};E(!0),p(null);try{const l=await _(s,20,c);q(l.entries)}catch(l){if(a(l))p("Catalog is temporarily unavailable. Please try again later.");else{const t=l instanceof Error?l.message:"Failed to load catalog";p(t)}}finally{E(!1)}},[c]);i.useEffect(()=>{C(),u("")},[C,u]);const M=i.useCallback(s=>{K(s),r.current&&clearTimeout(r.current),r.current=setTimeout(()=>{W(s),r.current=null},300)},[]);i.useEffect(()=>()=>{r.current&&(clearTimeout(r.current),r.current=null)},[]),i.useEffect(()=>{u(N)},[N,u]);const T=i.useCallback(async(s,a)=>{const l=!a;v(t=>t.map(n=>n.id===s?{...n,toggling:!0}:n));try{await B(s,l,c),v(t=>t.map(n=>n.id===s?{...n,enabled:l,toggling:!1}:n)),o(`Skill ${l?"enabled":"disabled"}`,"success")}catch(t){v(w=>w.map(S=>S.id===s?{...S,toggling:!1}:S));const n=t instanceof Error?t.message:"Failed to toggle skill";o(`Failed to toggle skill: ${n}`,"error")}},[c,o]),j=i.useCallback(async s=>{R(!0),b(null),x(null);try{const a=await G(s,c);x(a)}catch(a){const l=a instanceof Error?a.message:"Failed to load skill content";b(l)}finally{R(!1)}},[c]),$=i.useCallback((s,a)=>{if(!(a&&a.target.closest(".skills-view-item-toggle"))){if(m===s){g(null),x(null),b(null);return}g(s),j(s)}},[m,j]),U=i.useCallback(s=>{m!==s&&g(s),j(s)},[j,m]);return e.jsxs("div",{className:"skills-view","data-testid":"skills-view",children:[e.jsxs("div",{className:"skills-view-header",children:[e.jsxs("div",{className:"skills-view-title",children:[e.jsxs("h2",{children:[e.jsx(H,{size:20}),"Skills"]}),e.jsxs("span",{className:"skills-view-count","aria-label":`${d.length} discovered skills`,children:[d.length," discovered"]})]}),e.jsxs("div",{className:"skills-view-actions",children:[e.jsx("button",{className:"btn-icon skills-view-close touch-target",onClick:Q,"aria-label":"Close skills view",children:e.jsx(P,{size:16})}),e.jsxs("button",{className:"btn btn-sm touch-target",onClick:()=>void C(),disabled:f,children:[e.jsx(J,{size:14,className:f?"spin":""}),"Refresh"]})]})]}),e.jsxs("div",{className:"skills-view-content",children:[e.jsx("div",{className:"skills-view-search",children:e.jsx("input",{type:"text",className:"form-input",placeholder:"Search skills...",value:h,onChange:s=>M(s.target.value),"aria-label":"Search skills"})}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"discovered-skills-title",children:[e.jsx("h3",{id:"discovered-skills-title",className:"skills-view-section-title",children:"Discovered Skills"}),f?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading discovered skills..."]}):d.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No skills discovered in this project."})}):F.length===0?e.jsx("div",{className:"skills-view-empty",children:e.jsx("p",{children:"No discovered skills match your search."})}):e.jsx("div",{className:"skills-view-list",children:F.map(s=>{const a=m===s.id;return e.jsxs("div",{children:[e.jsxs("div",{className:`skills-view-item${a?" skills-view-item--selected":""}`,onClick:l=>$(s.id,l),role:"button",tabIndex:0,onKeyDown:l=>{(l.key==="Enter"||l.key===" ")&&(l.preventDefault(),$(s.id))},"aria-expanded":a,"aria-label":`View details for ${s.name}`,children:[e.jsxs("div",{className:"skills-view-item-info",children:[e.jsxs("span",{className:"skills-view-item-name",children:[a?e.jsx(O,{size:14}):e.jsx(Y,{size:14}),s.name]}),e.jsx("span",{className:"skills-view-item-path",children:s.relativePath}),e.jsx("span",{className:"skills-view-item-source",children:s.metadata.source})]}),e.jsxs("label",{className:"skills-view-item-toggle",onClick:l=>l.stopPropagation(),children:[e.jsx("input",{type:"checkbox",checked:s.enabled,disabled:s.toggling,onChange:()=>void T(s.id,s.enabled),"aria-label":`${s.enabled?"Disable":"Enable"} ${s.name}`}),e.jsx("span",{className:"skills-view-toggle-slider"})]})]}),a&&e.jsxs("div",{className:"skills-view-detail","data-testid":"skill-detail",children:[e.jsxs("div",{className:"skills-view-detail-header",children:[e.jsx("span",{className:"skills-view-detail-title",children:s.name}),e.jsxs("button",{className:"btn btn-sm skills-view-detail-close",onClick:()=>{g(null),x(null),b(null)},"aria-label":"Close skill detail",children:[e.jsx(P,{size:14}),"Close"]})]}),V?e.jsxs("div",{className:"skills-view-detail-loading",children:[e.jsx(Z,{size:16,className:"spin"}),"Loading skill content..."]}):z?e.jsxs("div",{className:"skills-view-detail-error",children:[e.jsx(I,{size:14}),e.jsx("span",{children:z}),e.jsx("button",{className:"btn btn-sm",onClick:()=>U(s.id),children:"Retry"})]}):k?e.jsxs(e.Fragment,{children:[e.jsx("pre",{className:"skills-view-detail-content",children:k.skillMd||"(No SKILL.md found)"}),k.files.length>0&&e.jsxs("div",{className:"skills-view-detail-files",children:[e.jsx("span",{className:"skills-view-detail-files-label",children:"Files:"}),k.files.map(l=>e.jsxs("span",{className:"badge badge--sm",children:[l.name,l.type==="directory"&&"/"]},l.relativePath))]})]}):null]})]},s.id)})})]}),e.jsxs("section",{className:"skills-view-section","aria-labelledby":"catalog-title",children:[e.jsx("h3",{id:"catalog-title",className:"skills-view-section-title",children:"Skills Catalog"}),L?e.jsxs("div",{className:"skills-view-error",children:[e.jsx("p",{children:L}),e.jsx("button",{className:"btn btn-sm",onClick:()=>void u(N),children:"Try Again"})]}):A?e.jsxs("div",{className:"skills-view-loading",children:[e.jsx("span",{className:"spinner"}),"Loading catalog..."]}):D.length===0?e.jsx("div",{className:"skills-view-empty",children:h?e.jsx("p",{children:"No skills match your search."}):e.jsx("p",{children:"No skills available in the catalog."})}):e.jsx("div",{className:"skills-view-grid",children:D.map(s=>e.jsxs("div",{className:"skills-view-card",children:[e.jsx("h4",{className:"skills-view-card-title",children:s.name}),s.description&&e.jsx("p",{className:"skills-view-card-description",children:s.description}),s.tags&&s.tags.length>0&&e.jsx("div",{className:"skills-view-card-tags",children:s.tags.map(a=>e.jsx("span",{className:"badge badge--sm",children:a},a))}),s.installs!==void 0&&e.jsxs("span",{className:"skills-view-card-installs",children:[s.installs.toLocaleString()," installs"]})]},s.id))})]})]})]})}export{ie as SkillsView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as t,j as s}from"./vendor-react-K0fH_qHe.js";import{v as y,
|
|
1
|
+
import{r as t,j as s}from"./vendor-react-K0fH_qHe.js";import{v as y,cl as i}from"./index-DiewofJh.js";import"./vendor-xterm-DzcZoU0P.js";function w(){const{confirm:h}=y(),[c,u]=t.useState([]),[d,f]=t.useState(null),[p,x]=t.useState({}),[n,l]=t.useState(null),o=t.useCallback(async()=>{try{f(null);const a=await i("/stash-recovery/orphans");u(a.records??[])}catch(a){f(a instanceof Error?a.message:"Failed to load orphans")}},[]);t.useEffect(()=>{o()},[o]);const j=t.useMemo(()=>{const a=new Map;for(const e of c){const r=e.sourceTaskId??"Unknown source",m=a.get(r)??[];m.push(e),a.set(r,m)}return Array.from(a.entries())},[c]),v=t.useCallback(async a=>{const e=await i(`/stash-recovery/orphans/${a}/apply`,{method:"POST"});x(r=>({...r,[a]:e.ok?"Applied":e.stderr??e.reason??"Apply failed"}))},[]),b=t.useCallback(async a=>{await h({title:"Drop orphaned stash?",message:"This removes the stash entry permanently.",confirmLabel:"Drop",danger:!0})&&(await i(`/stash-recovery/orphans/${a}/drop`,{method:"POST",body:JSON.stringify({confirm:!0})}),await o())},[h,o]),N=t.useCallback(async a=>{l({sha:a,diff:"",truncated:!1,loading:!0,error:null});try{const e=await i(`/stash-recovery/orphans/${a}/diff`);l({sha:a,diff:e.diff??"",truncated:!!e.truncated,loading:!1,error:null})}catch(e){l({sha:a,diff:"",truncated:!1,loading:!1,error:e instanceof Error?e.message:"Failed to load diff"})}},[]);return c.length===0&&!d?s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsx("p",{children:"No orphaned merger autostashes found."}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}):s.jsxs("div",{className:"card stash-recovery-view",children:[s.jsxs("div",{className:"stash-recovery-header",children:[s.jsx("h2",{children:"Stash Recovery"}),s.jsxs("span",{children:[c.length," orphans"]}),s.jsx("button",{className:"btn btn-sm",onClick:()=>void o(),children:"Refresh"})]}),d&&s.jsx("div",{className:"form-error",children:d}),j.map(([a,e])=>s.jsxs("section",{children:[s.jsx("h3",{children:a}),e.map(r=>s.jsxs("div",{className:"stash-row",children:[s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"SHA"}),s.jsx("span",{children:r.sha.slice(0,7)})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Classification"}),s.jsx("span",{children:r.classification})]}),s.jsxs("div",{className:"stash-field",children:[s.jsx("span",{className:"stash-field-label",children:"Changed paths"}),s.jsxs("span",{children:[r.changedPaths.length," files"]})]}),s.jsxs("div",{className:"stash-row-actions",children:[s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void N(r.sha),children:"Inspect diff"}),s.jsx("button",{className:"btn btn-sm stash-action-btn",onClick:()=>void v(r.sha),children:"Apply"})]}),s.jsx("div",{className:"stash-row-actions-danger",children:s.jsx("button",{className:"btn btn-sm btn-danger stash-action-btn",onClick:()=>void b(r.sha),children:"Drop"})}),p[r.sha]&&s.jsx("div",{className:"stash-status",children:p[r.sha]})]},r.sha))]},a)),n&&s.jsx("div",{className:"modal-overlay open",onClick:()=>l(null),children:s.jsxs("div",{className:"modal stash-recovery-diff-modal",role:"dialog","aria-modal":"true","aria-label":`Diff for ${n.sha}`,onClick:a=>a.stopPropagation(),children:[s.jsxs("div",{className:"modal-header",children:[s.jsxs("h3",{children:["Diff for ",n.sha.slice(0,7)]}),s.jsx("button",{className:"modal-close",onClick:()=>l(null),"aria-label":"Close diff dialog",children:"×"})]}),n.loading&&s.jsx("p",{children:"Loading diff…"}),n.error&&s.jsx("div",{className:"form-error",children:n.error}),!n.loading&&!n.error&&s.jsxs(s.Fragment,{children:[s.jsx("pre",{className:"stash-recovery-diff-pre",children:n.diff||"No diff output available."}),n.truncated&&s.jsx("p",{className:"stash-status",children:"Diff output truncated."})]}),s.jsx("div",{className:"modal-actions",children:s.jsx("button",{className:"btn",onClick:()=>l(null),children:"Close"})})]})})]})}export{w as StashRecoveryView};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{r as d,j as e}from"./vendor-react-K0fH_qHe.js";import{c as wt,
|
|
1
|
+
import{r as d,j as e}from"./vendor-react-K0fH_qHe.js";import{c as wt,cb as Ct,cc as St,cd as At,ce as $t,cf as Et,cg as Dt,ch as Ft,ci as Tt,v as Mt,i as Ot,z as H,cj as lt,L as Rt,I as Pt,br as J,X as Q,ck as ut,aX as mt,W as bt,ad as Ut,a as _t,as as Kt,B as pt}from"./index-DiewofJh.js";import"./vendor-xterm-DzcZoU0P.js";/**
|
|
2
2
|
* @license lucide-react v1.7.0 - ISC
|
|
3
3
|
*
|
|
4
4
|
* This source code is licensed under the ISC license.
|
|
5
5
|
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
-
*/const Bt=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]],Wt=wt("circle-plus",Bt);function zt(L){const{items:l,...x}=L;return x}function ht(L){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`${L}-${crypto.randomUUID()}`:`${L}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Vt(L={}){const{projectId:l,addToast:x}=L,[k,N]=d.useState([]),[g,I]=d.useState([]),[W,F]=d.useState(!0),[S,j]=d.useState(null),[$,E]=d.useState(null),[y,f]=d.useState([]),C=d.useRef($);C.current=$,d.useEffect(()=>{let s=!1;async function c(){F(!0),j(null);try{const r=await Tt(l);if(s)return;f(r),N(r.map(zt));const m=C.current&&r.some(i=>i.id===C.current)?C.current:r[0]?.id??null;E(m),I(m?r.find(i=>i.id===m)?.items??[]:[])}catch(r){if(s)return;f([]),N([]),I([]),E(null),j(r instanceof Error?r.message:"Failed to load todo lists")}finally{s||F(!1)}}return c(),()=>{s=!0}},[l]),d.useEffect(()=>{if(!$){I([]);return}const s=y.find(c=>c.id===$);I(s?.items??[])},[y,$]);const z=d.useCallback(async s=>{const c=k,r=y,m=new Date().toISOString(),i={id:ht("temp-list"),projectId:l??"",title:s,createdAt:m,updatedAt:m};j(null),N(n=>[...n,i]),f(n=>[...n,{...i,items:[]}]);try{const n=await Ct(s,l);N(a=>a.map(o=>o.id===i.id?n:o)),f(a=>a.map(o=>o.id===i.id?{...n,items:[]}:o)),C.current||E(n.id)}catch(n){N(c),f(r),j(n instanceof Error?n.message:"Failed to create list"),x?.("Failed to create todo list","error")}},[x,y,k,l]),V=d.useCallback(async(s,c)=>{const r=k,m=y;j(null),N(i=>i.map(n=>n.id===s?{...n,title:c}:n)),f(i=>i.map(n=>n.id===s?{...n,title:c}:n));try{const i=await St(s,c,l);N(n=>n.map(a=>a.id===s?i:a)),f(n=>n.map(a=>a.id===s?{...i,items:a.items}:a))}catch(i){N(r),f(m),j(i instanceof Error?i.message:"Failed to rename list"),x?.("Failed to rename todo list","error")}},[x,y,k,l]),X=d.useCallback(async s=>{const c=k,r=y,m=C.current,i=m===s?k.find(n=>n.id!==s)?.id??null:m;j(null),N(n=>n.filter(a=>a.id!==s)),f(n=>n.filter(a=>a.id!==s)),m===s&&E(i);try{await At(s,l)}catch(n){N(c),f(r),E(m),j(n instanceof Error?n.message:"Failed to delete list"),x?.("Failed to delete todo list","error")}},[x,y,k,l]),T=d.useCallback(async s=>{const c=C.current;if(!c)return;const r=g,m=y,i=new Date().toISOString(),n=g.reduce((o,u)=>Math.max(o,u.sortOrder),-1),a={id:ht("temp-item"),listId:c,text:s,completed:!1,completedAt:null,createdAt:i,updatedAt:i,sortOrder:n+1};j(null),I(o=>[...o,a]),f(o=>o.map(u=>u.id===c?{...u,items:[...u.items,a]}:u));try{const o=await $t(c,s,l);I(u=>u.map(h=>h.id===a.id?o:h)),f(u=>u.map(h=>h.id===c?{...h,items:h.items.map(D=>D.id===a.id?o:D)}:h))}catch(o){I(r),f(m),j(o instanceof Error?o.message:"Failed to create item"),x?.("Failed to create todo item","error")}},[x,g,y,l]),w=d.useCallback(async(s,c)=>{const r=g.find(o=>o.id===s);if(!r)return;const m=g,i=y,n=c.completed??r.completed,a={...r,...c,completed:n,completedAt:n?r.completedAt??new Date().toISOString():null,updatedAt:new Date().toISOString()};j(null),I(o=>o.map(u=>u.id===s?a:u)),f(o=>o.map(u=>u.id===a.listId?{...u,items:u.items.map(h=>h.id===s?a:h)}:u));try{const o=await Et(s,c,l);I(u=>u.map(h=>h.id===s?o:h)),f(u=>u.map(h=>h.id===o.listId?{...h,items:h.items.map(D=>D.id===s?o:D)}:h))}catch(o){I(m),f(i),j(o instanceof Error?o.message:"Failed to update item"),x?.("Failed to update todo item","error")}},[x,g,y,l]),_=d.useCallback(async s=>{const c=g.find(r=>r.id===s);c&&await w(s,{completed:!c.completed})},[g,w]),A=d.useCallback(async s=>{const c=g,r=y;j(null),I(m=>m.filter(i=>i.id!==s)),f(m=>m.map(i=>({...i,items:i.items.filter(n=>n.id!==s)})));try{await Dt(s,l)}catch(m){I(c),f(r),j(m instanceof Error?m.message:"Failed to delete item"),x?.("Failed to delete todo item","error")}},[x,g,y,l]),M=d.useCallback(async s=>{const c=C.current;if(!c)return;const r=g,m=y,i=new Map(g.map(a=>[a.id,a])),n=s.map((a,o)=>{const u=i.get(a);return u?{...u,sortOrder:o}:null}).filter(a=>a!==null);j(null),I(n),f(a=>a.map(o=>o.id===c?{...o,items:n}:o));try{await Ft(c,s,l)}catch(a){I(r),f(m),j(a instanceof Error?a.message:"Failed to reorder items"),x?.("Failed to reorder todo items","error")}},[x,g,y,l]);return{lists:k,items:g,loading:W,error:S,selectedListId:$,setSelectedListId:E,createList:z,renameList:V,deleteList:X,createItem:T,updateItem:w,toggleItem:_,deleteItem:A,reorderItems:M}}function Xt(L){return[...L].sort((l,x)=>l.sortOrder-x.sortOrder)}function Jt({projectId:L,addToast:l,onPlanningMode:x,onTaskCreated:k,mobileKeyboardActive:N=!1}){const{lists:g,items:I,loading:W,error:F,selectedListId:S,setSelectedListId:j,createList:$,renameList:E,deleteList:y,createItem:f,updateItem:C,toggleItem:z,deleteItem:V,reorderItems:X}=Vt({projectId:L,addToast:(t,p)=>{if(p==="success"||p==="error"||p==="info"||p===void 0){l(t,p);return}l(t,"info")}}),[T,w]=d.useState(null),[_,A]=d.useState(""),[M,s]=d.useState(null),[c,r]=d.useState(""),[m,i]=d.useState(""),[n,a]=d.useState(!1),[o,u]=d.useState(""),[h,D]=d.useState([]),[ft,Y]=d.useState(!1),[q,O]=d.useState(!1),[Z,R]=d.useState(null),G=d.useRef(null),{confirm:xt}=Mt(),tt=d.useMemo(()=>g.find(t=>t.id===S)??null,[g,S]),K=d.useMemo(()=>Xt(I.filter(t=>t.listId===S)),[I,S]);function et(){w(null),A(""),i(""),a(!1)}function B(){s(null),r(""),u("")}function gt(t){et(),B(),j(t)}const vt=d.useCallback(async()=>{Y(!0);try{const t=await Ot(void 0,L);D(t),O(!0)}catch(t){l(`Failed to load agents: ${H(t)}`,"error"),O(!1),R(null)}finally{Y(!1)}},[L,l]);d.useEffect(()=>{w(null),A(""),i(""),a(!1),s(null),r(""),u(""),O(!1),R(null)},[S]),d.useEffect(()=>{if(!q)return;const t=p=>{G.current&&!G.current.contains(p.target)&&(O(!1),R(null))};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[q]);function jt(t){B(),w(t.id),A(t.title),a(!1)}async function st(){if(!T)return;const t=_.trim();if(!t){w(null),A("");return}await E(T,t),w(null),A("")}function nt(){w(null),A("")}function at(t){et(),s(t.id),r(t.text)}async function it(){if(!M)return;const t=c.trim();if(!t){s(null),r("");return}await C(M,{text:t}),s(null),r("")}function ot(){s(null),r("")}async function dt(){const t=m.trim();t&&(await $(t),i(""),a(!1))}async function rt(){if(!S)return;const t=o.trim();t&&(await f(t),u(""))}async function yt(t){await xt({title:"Delete List",message:"Delete this list and all its items?",danger:!0})&&await y(t)}async function It(t){await V(t)}async function ct(t,p){const v=K.map(U=>U.id),b=v.findIndex(U=>U===t);if(b<0)return;const P=p==="up"?b-1:b+1;P<0||P>=v.length||([v[b],v[P]]=[v[P],v[b]],await X(v))}const Lt=d.useCallback(async t=>{try{const p={description:t.text,column:"triage",source:{sourceType:"dashboard_ui"}},v=await lt(p,L);k?.(v),l(`Created ${v.id} from todo`,"success")}catch(p){l(`Failed to create task: ${H(p)}`,"error")}},[L,l,k]),kt=d.useCallback(async(t,p)=>{try{const v={description:t.text,column:"triage",assignedAgentId:p,source:{sourceType:"dashboard_ui"}},b=await lt(v,L);k?.(b);const U=h.find(Nt=>Nt.id===p)?.name??p;l(`Created ${b.id} and assigned to ${U}`,"success"),O(!1),R(null)}catch(v){l(`Failed to create and assign task: ${H(v)}`,"error")}},[L,l,h,k]);return W?e.jsx("div",{className:"todo-view",children:e.jsxs("div",{className:"todo-loading",children:[e.jsx(Rt,{className:"todo-loading-icon","aria-hidden":"true"}),e.jsx("p",{children:"Loading todos..."})]})}):e.jsx("div",{className:`todo-view${N?" todo-view--mobile-keyboard-active":""}`,"data-testid":"todo-view-root",children:e.jsxs("div",{className:"todo-view-layout",children:[e.jsxs("aside",{className:"todo-view-sidebar","aria-label":"Todo lists sidebar",children:[e.jsxs("div",{className:"todo-sidebar-header",children:[e.jsx("h3",{className:"todo-sidebar-title",children:"Lists"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-add-list-btn",onClick:()=>{B(),a(!0),w(null)},"aria-label":"Add list","data-testid":"add-list-button",children:e.jsx(Pt,{})})]}),n&&e.jsxs("div",{className:"todo-list-item",children:[e.jsx("input",{className:"input todo-inline-edit-input",placeholder:"New list title",value:m,onChange:t=>i(t.target.value),onKeyDown:t=>{t.key==="Enter"&&dt(),t.key==="Escape"&&(i(""),a(!1))},autoFocus:!0,"data-testid":"new-list-input"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{dt()},"aria-label":"Save list",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{i(""),a(!1)},"aria-label":"Cancel list",children:e.jsx(Q,{})})]}),g.length===0&&!n?e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(ut,{"aria-hidden":"true"}),e.jsx("p",{children:"No todo lists yet. Create one to get started."}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{B(),a(!0)},children:"Create List"})]}):e.jsx("div",{className:"todo-list-items",role:"list","aria-label":"Todo lists",children:g.map(t=>{const p=t.id===S,v=t.id===T;return e.jsx("div",{className:`todo-list-item${p?" todo-list-item--active":""}`,role:"listitem",children:v?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"input todo-inline-edit-input",value:_,onChange:b=>A(b.target.value),onKeyDown:b=>{b.key==="Enter"&&st(),b.key==="Escape"&&nt()},autoFocus:!0,"data-testid":`rename-list-input-${t.id}`}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{st()},"aria-label":"Save list rename",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:nt,"aria-label":"Cancel list rename",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"todo-list-select-btn",onClick:()=>gt(t.id),"aria-label":`Select list ${t.title}`,"aria-current":p?"true":void 0,"data-testid":`todo-list-${t.id}`,children:e.jsx("span",{className:"todo-list-item-name",children:t.title})}),e.jsxs("div",{className:"todo-list-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{jt(t)},"aria-label":`Rename ${t.title}`,"data-testid":`rename-list-button-${t.id}`,children:e.jsx(mt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{yt(t.id)},"aria-label":`Delete ${t.title}`,"data-testid":`delete-list-button-${t.id}`,children:e.jsx(bt,{})})]})]})},t.id)})})]}),e.jsxs("section",{className:"todo-view-main","aria-label":"Todo items",children:[F&&e.jsxs("div",{className:"todo-error-banner",role:"alert",children:[e.jsx("span",{className:"todo-error-message",children:F}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>window.location.reload(),children:"Retry"})]}),tt?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"todo-items-header",children:e.jsx("h3",{children:tt.title})}),e.jsxs("div",{className:"todo-add-item-row",children:[e.jsx("input",{className:"input",placeholder:"Add a todo item",value:o,onChange:t=>u(t.target.value),onKeyDown:t=>{t.key==="Enter"&&rt(),t.key==="Escape"&&u("")},"data-testid":"new-item-input"}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>{rt()},children:"Add"})]}),K.length===0?e.jsx("div",{className:"todo-empty-state",children:e.jsx("p",{children:"No items in this list. Add one above."})}):e.jsx("div",{className:"todo-items-list",children:K.map((t,p)=>{const v=t.id===M;return e.jsxs("div",{className:"todo-item","data-testid":`todo-item-${t.id}`,children:[e.jsxs("div",{className:"todo-item-main-row",children:[e.jsx("input",{type:"checkbox",checked:t.completed,onChange:()=>{z(t.id)},className:"todo-item-checkbox","aria-label":`Toggle ${t.text}`,"data-testid":`toggle-item-${t.id}`}),v?e.jsx("input",{className:"input todo-inline-edit-input",value:c,onChange:b=>r(b.target.value),onKeyDown:b=>{b.key==="Enter"&&it(),b.key==="Escape"&&ot()},autoFocus:!0,"data-testid":`edit-item-input-${t.id}`}):e.jsx("button",{type:"button",className:`todo-item-text${t.completed?" todo-item-text--completed":""}`,onClick:()=>at(t),children:t.text})]}),e.jsx("div",{className:"todo-item-actions","data-testid":`todo-item-actions-${t.id}`,children:v?e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{it()},"aria-label":"Save item edit",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:ot,"aria-label":"Cancel item edit",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"todo-item-reorder-btns",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{ct(t.id,"up")},disabled:p===0,"aria-label":`Move ${t.text} up`,"data-testid":`move-up-${t.id}`,children:e.jsx(Ut,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{ct(t.id,"down")},disabled:p===K.length-1,"aria-label":`Move ${t.text} down`,"data-testid":`move-down-${t.id}`,children:e.jsx(_t,{})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{x?.(t.text)},"aria-label":`Start planning from ${t.text}`,"data-testid":`planning-from-${t.id}`,children:e.jsx(Kt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{Lt(t)},"aria-label":`Create task from ${t.text}`,"data-testid":`create-task-from-${t.id}`,children:e.jsx(Wt,{})}),e.jsxs("div",{className:"todo-agent-picker-trigger",ref:Z===t.id?G:void 0,children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{R(t.id),vt()},"aria-label":`Assign ${t.text} to agent`,"data-testid":`assign-agent-for-${t.id}`,children:e.jsx(pt,{})}),q&&Z===t.id&&e.jsx("div",{className:"todo-agent-picker-dropdown",onMouseDown:b=>{b.preventDefault()},children:ft?e.jsx("div",{className:"todo-agent-picker-loading",children:"Loading agents..."}):h.length>0?h.map(b=>e.jsxs("button",{type:"button",className:"todo-agent-picker-item",onClick:()=>{kt(t,b.id)},children:[e.jsx(pt,{}),e.jsx("span",{children:b.name}),e.jsx("span",{className:"todo-agent-picker-role",children:b.role})]},b.id)):e.jsx("div",{className:"todo-agent-picker-empty",children:"No agents available"})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>at(t),"aria-label":`Edit ${t.text}`,"data-testid":`edit-item-${t.id}`,children:e.jsx(mt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{It(t.id)},"aria-label":`Delete ${t.text}`,"data-testid":`delete-item-${t.id}`,children:e.jsx(bt,{})})]})})]},t.id)})})]}):e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(ut,{"aria-hidden":"true"}),e.jsx("p",{children:"Select a list from the sidebar"})]})]})]})})}export{Jt as TodoView};
|
|
6
|
+
*/const Bt=[["circle",{cx:"12",cy:"12",r:"10",key:"1mglay"}],["path",{d:"M8 12h8",key:"1wcyev"}],["path",{d:"M12 8v8",key:"napkw2"}]],Xt=wt("circle-plus",Bt);function zt(L){const{items:l,...x}=L;return x}function ht(L){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?`${L}-${crypto.randomUUID()}`:`${L}-${Date.now()}-${Math.random().toString(36).slice(2,10)}`}function Vt(L={}){const{projectId:l,addToast:x}=L,[k,N]=d.useState([]),[g,I]=d.useState([]),[X,F]=d.useState(!0),[S,j]=d.useState(null),[$,E]=d.useState(null),[y,f]=d.useState([]),C=d.useRef($);C.current=$,d.useEffect(()=>{let s=!1;async function c(){F(!0),j(null);try{const r=await Tt(l);if(s)return;f(r),N(r.map(zt));const m=C.current&&r.some(i=>i.id===C.current)?C.current:r[0]?.id??null;E(m),I(m?r.find(i=>i.id===m)?.items??[]:[])}catch(r){if(s)return;f([]),N([]),I([]),E(null),j(r instanceof Error?r.message:"Failed to load todo lists")}finally{s||F(!1)}}return c(),()=>{s=!0}},[l]),d.useEffect(()=>{if(!$){I([]);return}const s=y.find(c=>c.id===$);I(s?.items??[])},[y,$]);const z=d.useCallback(async s=>{const c=k,r=y,m=new Date().toISOString(),i={id:ht("temp-list"),projectId:l??"",title:s,createdAt:m,updatedAt:m};j(null),N(n=>[...n,i]),f(n=>[...n,{...i,items:[]}]);try{const n=await Ct(s,l);N(a=>a.map(o=>o.id===i.id?n:o)),f(a=>a.map(o=>o.id===i.id?{...n,items:[]}:o)),C.current||E(n.id)}catch(n){N(c),f(r),j(n instanceof Error?n.message:"Failed to create list"),x?.("Failed to create todo list","error")}},[x,y,k,l]),V=d.useCallback(async(s,c)=>{const r=k,m=y;j(null),N(i=>i.map(n=>n.id===s?{...n,title:c}:n)),f(i=>i.map(n=>n.id===s?{...n,title:c}:n));try{const i=await St(s,c,l);N(n=>n.map(a=>a.id===s?i:a)),f(n=>n.map(a=>a.id===s?{...i,items:a.items}:a))}catch(i){N(r),f(m),j(i instanceof Error?i.message:"Failed to rename list"),x?.("Failed to rename todo list","error")}},[x,y,k,l]),W=d.useCallback(async s=>{const c=k,r=y,m=C.current,i=m===s?k.find(n=>n.id!==s)?.id??null:m;j(null),N(n=>n.filter(a=>a.id!==s)),f(n=>n.filter(a=>a.id!==s)),m===s&&E(i);try{await At(s,l)}catch(n){N(c),f(r),E(m),j(n instanceof Error?n.message:"Failed to delete list"),x?.("Failed to delete todo list","error")}},[x,y,k,l]),T=d.useCallback(async s=>{const c=C.current;if(!c)return;const r=g,m=y,i=new Date().toISOString(),n=g.reduce((o,u)=>Math.max(o,u.sortOrder),-1),a={id:ht("temp-item"),listId:c,text:s,completed:!1,completedAt:null,createdAt:i,updatedAt:i,sortOrder:n+1};j(null),I(o=>[...o,a]),f(o=>o.map(u=>u.id===c?{...u,items:[...u.items,a]}:u));try{const o=await $t(c,s,l);I(u=>u.map(h=>h.id===a.id?o:h)),f(u=>u.map(h=>h.id===c?{...h,items:h.items.map(D=>D.id===a.id?o:D)}:h))}catch(o){I(r),f(m),j(o instanceof Error?o.message:"Failed to create item"),x?.("Failed to create todo item","error")}},[x,g,y,l]),w=d.useCallback(async(s,c)=>{const r=g.find(o=>o.id===s);if(!r)return;const m=g,i=y,n=c.completed??r.completed,a={...r,...c,completed:n,completedAt:n?r.completedAt??new Date().toISOString():null,updatedAt:new Date().toISOString()};j(null),I(o=>o.map(u=>u.id===s?a:u)),f(o=>o.map(u=>u.id===a.listId?{...u,items:u.items.map(h=>h.id===s?a:h)}:u));try{const o=await Et(s,c,l);I(u=>u.map(h=>h.id===s?o:h)),f(u=>u.map(h=>h.id===o.listId?{...h,items:h.items.map(D=>D.id===s?o:D)}:h))}catch(o){I(m),f(i),j(o instanceof Error?o.message:"Failed to update item"),x?.("Failed to update todo item","error")}},[x,g,y,l]),_=d.useCallback(async s=>{const c=g.find(r=>r.id===s);c&&await w(s,{completed:!c.completed})},[g,w]),A=d.useCallback(async s=>{const c=g,r=y;j(null),I(m=>m.filter(i=>i.id!==s)),f(m=>m.map(i=>({...i,items:i.items.filter(n=>n.id!==s)})));try{await Dt(s,l)}catch(m){I(c),f(r),j(m instanceof Error?m.message:"Failed to delete item"),x?.("Failed to delete todo item","error")}},[x,g,y,l]),M=d.useCallback(async s=>{const c=C.current;if(!c)return;const r=g,m=y,i=new Map(g.map(a=>[a.id,a])),n=s.map((a,o)=>{const u=i.get(a);return u?{...u,sortOrder:o}:null}).filter(a=>a!==null);j(null),I(n),f(a=>a.map(o=>o.id===c?{...o,items:n}:o));try{await Ft(c,s,l)}catch(a){I(r),f(m),j(a instanceof Error?a.message:"Failed to reorder items"),x?.("Failed to reorder todo items","error")}},[x,g,y,l]);return{lists:k,items:g,loading:X,error:S,selectedListId:$,setSelectedListId:E,createList:z,renameList:V,deleteList:W,createItem:T,updateItem:w,toggleItem:_,deleteItem:A,reorderItems:M}}function Wt(L){return[...L].sort((l,x)=>l.sortOrder-x.sortOrder)}function Jt({projectId:L,addToast:l,onPlanningMode:x,onTaskCreated:k,mobileKeyboardActive:N=!1}){const{lists:g,items:I,loading:X,error:F,selectedListId:S,setSelectedListId:j,createList:$,renameList:E,deleteList:y,createItem:f,updateItem:C,toggleItem:z,deleteItem:V,reorderItems:W}=Vt({projectId:L,addToast:(t,p)=>{if(p==="success"||p==="error"||p==="info"||p===void 0){l(t,p);return}l(t,"info")}}),[T,w]=d.useState(null),[_,A]=d.useState(""),[M,s]=d.useState(null),[c,r]=d.useState(""),[m,i]=d.useState(""),[n,a]=d.useState(!1),[o,u]=d.useState(""),[h,D]=d.useState([]),[ft,Y]=d.useState(!1),[q,O]=d.useState(!1),[Z,R]=d.useState(null),G=d.useRef(null),{confirm:xt}=Mt(),tt=d.useMemo(()=>g.find(t=>t.id===S)??null,[g,S]),K=d.useMemo(()=>Wt(I.filter(t=>t.listId===S)),[I,S]);function et(){w(null),A(""),i(""),a(!1)}function B(){s(null),r(""),u("")}function gt(t){et(),B(),j(t)}const vt=d.useCallback(async()=>{Y(!0);try{const t=await Ot(void 0,L);D(t),O(!0)}catch(t){l(`Failed to load agents: ${H(t)}`,"error"),O(!1),R(null)}finally{Y(!1)}},[L,l]);d.useEffect(()=>{w(null),A(""),i(""),a(!1),s(null),r(""),u(""),O(!1),R(null)},[S]),d.useEffect(()=>{if(!q)return;const t=p=>{G.current&&!G.current.contains(p.target)&&(O(!1),R(null))};return document.addEventListener("mousedown",t),()=>{document.removeEventListener("mousedown",t)}},[q]);function jt(t){B(),w(t.id),A(t.title),a(!1)}async function st(){if(!T)return;const t=_.trim();if(!t){w(null),A("");return}await E(T,t),w(null),A("")}function nt(){w(null),A("")}function at(t){et(),s(t.id),r(t.text)}async function it(){if(!M)return;const t=c.trim();if(!t){s(null),r("");return}await C(M,{text:t}),s(null),r("")}function ot(){s(null),r("")}async function dt(){const t=m.trim();t&&(await $(t),i(""),a(!1))}async function rt(){if(!S)return;const t=o.trim();t&&(await f(t),u(""))}async function yt(t){await xt({title:"Delete List",message:"Delete this list and all its items?",danger:!0})&&await y(t)}async function It(t){await V(t)}async function ct(t,p){const v=K.map(U=>U.id),b=v.findIndex(U=>U===t);if(b<0)return;const P=p==="up"?b-1:b+1;P<0||P>=v.length||([v[b],v[P]]=[v[P],v[b]],await W(v))}const Lt=d.useCallback(async t=>{try{const p={description:t.text,column:"triage",source:{sourceType:"dashboard_ui"}},v=await lt(p,L);k?.(v),l(`Created ${v.id} from todo`,"success")}catch(p){l(`Failed to create task: ${H(p)}`,"error")}},[L,l,k]),kt=d.useCallback(async(t,p)=>{try{const v={description:t.text,column:"triage",assignedAgentId:p,source:{sourceType:"dashboard_ui"}},b=await lt(v,L);k?.(b);const U=h.find(Nt=>Nt.id===p)?.name??p;l(`Created ${b.id} and assigned to ${U}`,"success"),O(!1),R(null)}catch(v){l(`Failed to create and assign task: ${H(v)}`,"error")}},[L,l,h,k]);return X?e.jsx("div",{className:"todo-view",children:e.jsxs("div",{className:"todo-loading",children:[e.jsx(Rt,{className:"todo-loading-icon","aria-hidden":"true"}),e.jsx("p",{children:"Loading todos..."})]})}):e.jsx("div",{className:`todo-view${N?" todo-view--mobile-keyboard-active":""}`,"data-testid":"todo-view-root",children:e.jsxs("div",{className:"todo-view-layout",children:[e.jsxs("aside",{className:"todo-view-sidebar","aria-label":"Todo lists sidebar",children:[e.jsxs("div",{className:"todo-sidebar-header",children:[e.jsx("h3",{className:"todo-sidebar-title",children:"Lists"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-add-list-btn",onClick:()=>{B(),a(!0),w(null)},"aria-label":"Add list","data-testid":"add-list-button",children:e.jsx(Pt,{})})]}),n&&e.jsxs("div",{className:"todo-list-item",children:[e.jsx("input",{className:"input todo-inline-edit-input",placeholder:"New list title",value:m,onChange:t=>i(t.target.value),onKeyDown:t=>{t.key==="Enter"&&dt(),t.key==="Escape"&&(i(""),a(!1))},autoFocus:!0,"data-testid":"new-list-input"}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{dt()},"aria-label":"Save list",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{i(""),a(!1)},"aria-label":"Cancel list",children:e.jsx(Q,{})})]}),g.length===0&&!n?e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(ut,{"aria-hidden":"true"}),e.jsx("p",{children:"No todo lists yet. Create one to get started."}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>{B(),a(!0)},children:"Create List"})]}):e.jsx("div",{className:"todo-list-items",role:"list","aria-label":"Todo lists",children:g.map(t=>{const p=t.id===S,v=t.id===T;return e.jsx("div",{className:`todo-list-item${p?" todo-list-item--active":""}`,role:"listitem",children:v?e.jsxs(e.Fragment,{children:[e.jsx("input",{className:"input todo-inline-edit-input",value:_,onChange:b=>A(b.target.value),onKeyDown:b=>{b.key==="Enter"&&st(),b.key==="Escape"&&nt()},autoFocus:!0,"data-testid":`rename-list-input-${t.id}`}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{st()},"aria-label":"Save list rename",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:nt,"aria-label":"Cancel list rename",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"todo-list-select-btn",onClick:()=>gt(t.id),"aria-label":`Select list ${t.title}`,"aria-current":p?"true":void 0,"data-testid":`todo-list-${t.id}`,children:e.jsx("span",{className:"todo-list-item-name",children:t.title})}),e.jsxs("div",{className:"todo-list-item-actions",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{jt(t)},"aria-label":`Rename ${t.title}`,"data-testid":`rename-list-button-${t.id}`,children:e.jsx(mt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{yt(t.id)},"aria-label":`Delete ${t.title}`,"data-testid":`delete-list-button-${t.id}`,children:e.jsx(bt,{})})]})]})},t.id)})})]}),e.jsxs("section",{className:"todo-view-main","aria-label":"Todo items",children:[F&&e.jsxs("div",{className:"todo-error-banner",role:"alert",children:[e.jsx("span",{className:"todo-error-message",children:F}),e.jsx("button",{type:"button",className:"btn btn-sm",onClick:()=>window.location.reload(),children:"Retry"})]}),tt?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"todo-items-header",children:e.jsx("h3",{children:tt.title})}),e.jsxs("div",{className:"todo-add-item-row",children:[e.jsx("input",{className:"input",placeholder:"Add a todo item",value:o,onChange:t=>u(t.target.value),onKeyDown:t=>{t.key==="Enter"&&rt(),t.key==="Escape"&&u("")},"data-testid":"new-item-input"}),e.jsx("button",{type:"button",className:"btn btn-primary",onClick:()=>{rt()},children:"Add"})]}),K.length===0?e.jsx("div",{className:"todo-empty-state",children:e.jsx("p",{children:"No items in this list. Add one above."})}):e.jsx("div",{className:"todo-items-list",children:K.map((t,p)=>{const v=t.id===M;return e.jsxs("div",{className:"todo-item","data-testid":`todo-item-${t.id}`,children:[e.jsxs("div",{className:"todo-item-main-row",children:[e.jsx("input",{type:"checkbox",checked:t.completed,onChange:()=>{z(t.id)},className:"todo-item-checkbox","aria-label":`Toggle ${t.text}`,"data-testid":`toggle-item-${t.id}`}),v?e.jsx("input",{className:"input todo-inline-edit-input",value:c,onChange:b=>r(b.target.value),onKeyDown:b=>{b.key==="Enter"&&it(),b.key==="Escape"&&ot()},autoFocus:!0,"data-testid":`edit-item-input-${t.id}`}):e.jsx("button",{type:"button",className:`todo-item-text${t.completed?" todo-item-text--completed":""}`,onClick:()=>at(t),children:t.text})]}),e.jsx("div",{className:"todo-item-actions","data-testid":`todo-item-actions-${t.id}`,children:v?e.jsxs(e.Fragment,{children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{it()},"aria-label":"Save item edit",children:e.jsx(J,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:ot,"aria-label":"Cancel item edit",children:e.jsx(Q,{})})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"todo-item-reorder-btns",children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{ct(t.id,"up")},disabled:p===0,"aria-label":`Move ${t.text} up`,"data-testid":`move-up-${t.id}`,children:e.jsx(Ut,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-item-reorder-btn",onClick:()=>{ct(t.id,"down")},disabled:p===K.length-1,"aria-label":`Move ${t.text} down`,"data-testid":`move-down-${t.id}`,children:e.jsx(_t,{})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{x?.(t.text)},"aria-label":`Start planning from ${t.text}`,"data-testid":`planning-from-${t.id}`,children:e.jsx(Kt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{Lt(t)},"aria-label":`Create task from ${t.text}`,"data-testid":`create-task-from-${t.id}`,children:e.jsx(Xt,{})}),e.jsxs("div",{className:"todo-agent-picker-trigger",ref:Z===t.id?G:void 0,children:[e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>{R(t.id),vt()},"aria-label":`Assign ${t.text} to agent`,"data-testid":`assign-agent-for-${t.id}`,children:e.jsx(pt,{})}),q&&Z===t.id&&e.jsx("div",{className:"todo-agent-picker-dropdown",onMouseDown:b=>{b.preventDefault()},children:ft?e.jsx("div",{className:"todo-agent-picker-loading",children:"Loading agents..."}):h.length>0?h.map(b=>e.jsxs("button",{type:"button",className:"todo-agent-picker-item",onClick:()=>{kt(t,b.id)},children:[e.jsx(pt,{}),e.jsx("span",{children:b.name}),e.jsx("span",{className:"todo-agent-picker-role",children:b.role})]},b.id)):e.jsx("div",{className:"todo-agent-picker-empty",children:"No agents available"})})]}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon todo-icon-btn",onClick:()=>at(t),"aria-label":`Edit ${t.text}`,"data-testid":`edit-item-${t.id}`,children:e.jsx(mt,{})}),e.jsx("button",{type:"button",className:"btn btn-sm btn-icon btn-danger todo-icon-btn",onClick:()=>{It(t.id)},"aria-label":`Delete ${t.text}`,"data-testid":`delete-item-${t.id}`,children:e.jsx(bt,{})})]})})]},t.id)})})]}):e.jsxs("div",{className:"todo-empty-state",children:[e.jsx(ut,{"aria-hidden":"true"}),e.jsx("p",{children:"Select a list from the sidebar"})]})]})]})})}export{Jt as TodoView};
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import{r as n,j as C}from"./vendor-react-K0fH_qHe.js";import{cm as St,cn as Dt,t as It,w as Nt,b8 as Rt}from"./index-DiewofJh.js";import{c as ut}from"./createLucideIcon-BazL2hk5.js";import"./vendor-xterm-DzcZoU0P.js";const ht=4,mt=300,_t=24;function zt({taskId:e,position:r,scale:c,canDrag:s,onPositionChange:l,onDragStateChange:a,onDragEnd:m,onDoubleTap:k}){const[w,D]=n.useState(!1),y=n.useRef(null),I=n.useRef(r),u=n.useRef(!1),o=n.useRef(null),T=n.useRef(!1);I.current=r,T.current=w;const f=n.useCallback(()=>{o.current=null},[]),E=n.useCallback(d=>{y.current=null,D(!1),T.current=!1,d&&(a?.(!1),m?.(),u.current=!0,f())},[m,a,f]),R=n.useCallback(d=>{if(!d.isPrimary)return;if(d.defaultPrevented){f();return}const P=Date.now();o.current&&P-o.current.timeStamp>mt&&f(),s&&d.stopPropagation();const x=d.currentTarget;s&&typeof x.setPointerCapture=="function"&&x.setPointerCapture(d.pointerId),y.current={pointerId:d.pointerId,pointerType:d.pointerType,startPointer:{x:d.clientX,y:d.clientY},startPosition:I.current,defaultPrevented:d.defaultPrevented,movedBeyondThreshold:!1}},[s,f]),j=n.useCallback(d=>{const P=y.current;if(!P||P.pointerId!==d.pointerId)return;s&&d.stopPropagation();const x=d.clientX-P.startPointer.x,_=d.clientY-P.startPointer.y,B=Math.hypot(x,_);if(B>=ht&&(P.movedBeyondThreshold=!0),!s){P.movedBeyondThreshold&&f();return}if(!T.current&&B>=ht&&(D(!0),T.current=!0,a?.(!0),f()),B<ht)return;const Z=c>0?c:1;l(e,{x:P.startPosition.x+x/Z,y:P.startPosition.y+_/Z})},[s,a,l,f,c,e]),Y=n.useCallback((d,P)=>{if(!k||P.defaultPrevented||P.movedBeyondThreshold)return Date.now()-(o.current?.timeStamp??0)>mt&&f(),!1;if(P.pointerType==="mouse")return f(),!1;const x={timeStamp:Date.now(),point:{x:P.startPointer.x,y:P.startPointer.y}},_=o.current;return!_||x.timeStamp-_.timeStamp>mt||Math.hypot(x.point.x-_.point.x,x.point.y-_.point.y)>_t?(o.current=x,!1):(u.current=!0,f(),k(),!0)},[k,f]),G=n.useCallback(d=>{const P=y.current;if(!P||P.pointerId!==d.pointerId)return;s&&d.stopPropagation(),s&&typeof d.currentTarget.hasPointerCapture=="function"&&d.currentTarget.hasPointerCapture(d.pointerId)&&typeof d.currentTarget.releasePointerCapture=="function"&&d.currentTarget.releasePointerCapture(d.pointerId);const x=T.current;!x&&Y(d,P)&&d.preventDefault(),E(x)},[s,E,Y]),L=n.useCallback(d=>{const P=y.current;!P||P.pointerId!==d.pointerId||(s&&d.stopPropagation(),s&&typeof d.currentTarget.hasPointerCapture=="function"&&d.currentTarget.hasPointerCapture(d.pointerId)&&typeof d.currentTarget.releasePointerCapture=="function"&&d.currentTarget.releasePointerCapture(d.pointerId),f(),E(T.current))},[s,E,f]),A=n.useCallback(d=>{u.current&&(u.current=!1,d.preventDefault(),d.stopPropagation())},[]);return n.useMemo(()=>({isDragging:w,onPointerDown:R,onPointerMove:j,onPointerUp:G,onPointerCancel:L,onClickCapture:A}),[w,A,L,R,j,G])}const Et=new Set(["planning","researching","executing","finalizing","merging","merging-fix"]);function Xt(e){return e?e.charAt(0).toUpperCase()+e.slice(1):"Executing"}function jt({style:e,position:r,scale:c,isSelected:s=!1,isHighlighted:l=!1,isDimmed:a=!1,onMouseEnter:m,onMouseLeave:k,onClick:w,onNodePositionChange:D,onNodeDragStateChange:y,onNodeDragEnd:I,...u}){const{task:o,globalPaused:T,taskStuckTimeoutMs:f,lastFetchTimeMs:E,onOpenDetail:R}=u,j=o.status==="failed",Y=o.paused===!0,G=St(o,f,E),L=o.column==="triage"&&o.status==="awaiting-approval",A=!T&&!j&&!Y&&!G&&!L&&(o.column==="in-progress"||Et.has(o.status)),d=typeof o.currentStep=="number"&&o.currentStep>=0&&Array.isArray(o.steps)&&o.currentStep<o.steps.length,P=o.column==="in-review",x=zt({taskId:o.id,position:r,scale:c,canDrag:s,onPositionChange:D,onDragStateChange:y,onDragEnd:I,onDoubleTap:()=>R(o)});return C.jsxs("div",{className:`graph-task-node${s?" graph-node--draggable graph-task-node--selected":""}${x.isDragging?" graph-node--dragging":""}${l?" graph-task-node--highlighted graph-node--highlighted":""}${a?" graph-task-node--dimmed graph-node--dimmed":""}${A?" graph-task-node--active":""}${P?" graph-task-node--in-review":""}`,style:e,draggable:!1,"data-testid":`graph-task-node-${o.id}`,"data-current-step":A&&d?String(o.currentStep):void 0,onMouseEnter:m,onMouseLeave:k,onClick:w,onDoubleClick:_=>{_.defaultPrevented||R(o)},onClickCapture:x.onClickCapture,onPointerDown:x.onPointerDown,onPointerMove:x.onPointerMove,onPointerUp:x.onPointerUp,onPointerCancel:x.onPointerCancel,children:[A?C.jsx("div",{className:"graph-task-active-indicator",children:C.jsx("span",{className:"graph-task-active-indicator-text",children:Xt(o.status)})}):null,C.jsx(Dt,{...u,onOpenDetail:()=>{},disableDrag:!0})]})}/**
|
|
2
|
+
* @license lucide-react v0.542.0 - ISC
|
|
3
|
+
*
|
|
4
|
+
* This source code is licensed under the ISC license.
|
|
5
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
6
|
+
*/const Ot=[["path",{d:"M8 3H5a2 2 0 0 0-2 2v3",key:"1dcmit"}],["path",{d:"M21 8V5a2 2 0 0 0-2-2h-3",key:"1e4gt3"}],["path",{d:"M3 16v3a2 2 0 0 0 2 2h3",key:"wsl5sc"}],["path",{d:"M16 21h3a2 2 0 0 0 2-2v-3",key:"18trek"}]],Yt=ut("maximize",Ot);/**
|
|
7
|
+
* @license lucide-react v0.542.0 - ISC
|
|
8
|
+
*
|
|
9
|
+
* This source code is licensed under the ISC license.
|
|
10
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
11
|
+
*/const At=[["path",{d:"M3 12a9 9 0 1 0 9-9 9.75 9.75 0 0 0-6.74 2.74L3 8",key:"1357e3"}],["path",{d:"M3 3v5h5",key:"1xhq8a"}]],$t=ut("rotate-ccw",At);/**
|
|
12
|
+
* @license lucide-react v0.542.0 - ISC
|
|
13
|
+
*
|
|
14
|
+
* This source code is licensed under the ISC license.
|
|
15
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
16
|
+
*/const Gt=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"11",x2:"11",y1:"8",y2:"14",key:"1vmskp"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],Ht=ut("zoom-in",Gt);/**
|
|
17
|
+
* @license lucide-react v0.542.0 - ISC
|
|
18
|
+
*
|
|
19
|
+
* This source code is licensed under the ISC license.
|
|
20
|
+
* See the LICENSE file in the root directory of this source tree.
|
|
21
|
+
*/const Lt=[["circle",{cx:"11",cy:"11",r:"8",key:"4ej97u"}],["line",{x1:"21",x2:"16.65",y1:"21",y2:"16.65",key:"13gj7c"}],["line",{x1:"8",x2:"14",y1:"11",y2:"11",key:"durymu"}]],vt=ut("zoom-out",Lt);function Wt({zoom:e,onZoomIn:r,onZoomOut:c,onFitToGraph:s,onResetView:l}){return C.jsxs("div",{className:"graph-toolbar","data-testid":"graph-toolbar",children:[C.jsx("button",{className:"btn btn-icon",title:"Zoom in (Ctrl+=)","aria-label":"Zoom in",onClick:r,children:C.jsx(Ht,{size:16})}),C.jsx("button",{className:"btn btn-icon",title:"Zoom out (Ctrl+-)","aria-label":"Zoom out",onClick:c,children:C.jsx(vt,{size:16})}),C.jsxs("div",{className:"graph-toolbar__zoom-label","aria-live":"polite",children:[Math.round(e*100),"%"]}),C.jsx("button",{className:"btn btn-icon",title:"Fit to graph (Ctrl+Shift+F)","aria-label":"Fit to graph",onClick:s,children:C.jsx(Yt,{size:16})}),C.jsx("button",{className:"btn btn-icon",title:"Reset view (Ctrl+0)","aria-label":"Reset view",onClick:l,children:C.jsx($t,{size:16})})]})}const Ut=280,Ft=100;function Bt({edges:e,positions:r,nodeWidth:c=Ut,nodeHeight:s=Ft,highlightedEdgeIds:l}){const a=!!(l&&l.size>0);return C.jsxs("svg",{className:"dependency-graph-edges","aria-hidden":"true",children:[C.jsx("defs",{children:C.jsx("marker",{id:"dependency-graph-arrowhead",markerWidth:"10",markerHeight:"7",refX:"10",refY:"3.5",orient:"auto",markerUnits:"strokeWidth",children:C.jsx("path",{d:"M 0 0 L 10 3.5 L 0 7 z",fill:"var(--border)"})})}),e.map(m=>{const k=r.get(m.source),w=r.get(m.target);if(!k||!w)return null;const D=`${m.source}->${m.target}`,y=a&&(l?.has(D)??!1),I=k.x+c/2,u=k.y+s,o=w.x+c/2,T=w.y,f=u+(T-u)/2;return C.jsx("path",{"data-testid":"dependency-edge","data-edge-id":D,className:`dependency-graph-edge${y?" graph-edge--highlighted":""}${a&&!y?" graph-edge--dimmed":""}`,d:`M ${I} ${u} C ${I} ${f}, ${o} ${f}, ${o} ${T}`,fill:"none",stroke:y?"var(--todo)":"var(--border)",strokeWidth:y?"var(--space-xs)":"var(--btn-border-width)",opacity:a&&!y?.15:1,markerEnd:"url(#dependency-graph-arrowhead)",style:{transition:"opacity var(--transition-fast), stroke var(--transition-fast), stroke-width var(--transition-fast)"}},D)})]})}const Zt=new Set(["triage","todo","in-progress","in-review"]);function Kt(e){return e.filter(r=>Zt.has(r.column))}const Vt={nodeWidth:280,nodeHeight:100,horizontalGap:40,verticalGap:80};function gt(e,r){const c={...Vt,...r},s=e.nodes.map(u=>u.task.id);if(s.length===0)return new Map;const l=new Map,a=new Map;for(const u of s)a.set(u,0),l.set(u,[]);for(const u of e.edges)!a.has(u.source)||!a.has(u.target)||(l.get(u.target)?.push(u.source),a.set(u.source,(a.get(u.source)??0)+1));const m=s.filter(u=>(a.get(u)??0)===0),k=[];for(;m.length>0;){const u=m.shift();k.push(u);for(const o of l.get(u)??[]){const T=(a.get(o)??0)-1;a.set(o,T),T===0&&m.push(o)}}for(const u of s)k.includes(u)||k.push(u);const w=new Map;for(const u of k){const o=e.edges.filter(f=>f.source===u).map(f=>f.target);let T=0;for(const f of o)T=Math.max(T,(w.get(f)??0)+1);w.set(u,T)}const D=new Map;for(const u of s){const o=w.get(u)??0,T=D.get(o)??[];T.push(u),D.set(o,T)}const y=new Map,I=Array.from(D.keys()).sort((u,o)=>u-o);for(const u of I){const o=D.get(u)??[];o.sort();const f=-(o.length*c.nodeWidth+Math.max(0,o.length-1)*c.horizontalGap)/2;o.forEach((E,R)=>{const j=f+R*(c.nodeWidth+c.horizontalGap),Y=u*(c.nodeHeight+c.verticalGap);y.set(E,{x:j,y:Y})})}return y}function qt(e){return n.useMemo(()=>{const r=e.map(l=>({task:l})),c=new Set(e.map(l=>l.id)),s=e.flatMap(l=>(l.dependencies??[]).filter(a=>c.has(a)).map(a=>({source:l.id,target:a})));return{nodes:r,edges:s}},[e])}const at=.1,it=3,Pt=40,Jt=200;function J(e,r,c){return Math.min(c,Math.max(r,e))}function Qt(e){if(!(e instanceof HTMLElement))return!1;const r=e.tagName.toLowerCase();return e.isContentEditable||r==="input"||r==="textarea"||r==="select"}function te(){const[e,r]=n.useState({x:0,y:0}),[c,s]=n.useState(1),[l,a]=n.useState(!1),m=n.useRef(e),k=n.useRef(c),w=n.useRef(null),D=n.useRef(null),y=n.useRef(new Map),I=n.useRef(null),u=n.useRef({minX:0,minY:0,maxX:0,maxY:0});n.useEffect(()=>{m.current=e},[e]),n.useEffect(()=>{k.current=c},[c]),n.useEffect(()=>()=>{w.current!==null&&window.clearTimeout(w.current)},[]);const o=n.useMemo(()=>`translate(${e.x}px, ${e.y}px) scale(${c})`,[e.x,e.y,c]),T=n.useMemo(()=>Math.round(c*100),[c]),f=n.useCallback(i=>{if(!i){w.current!==null&&(window.clearTimeout(w.current),w.current=null),a(!1);return}a(!0),w.current!==null&&window.clearTimeout(w.current),w.current=window.setTimeout(()=>{a(!1),w.current=null},Jt)},[]),E=n.useCallback((i,p,h,b=k.current)=>{const M=u.current;if(M.maxX<=M.minX||M.maxY<=M.minY)return{x:J(i.x,-p,p),y:J(i.y,-h,h)};const N=p-M.maxX*b,z=-M.minX*b,X=h-M.maxY*b,v=-M.minY*b,et=N>z?(N+z)/2:J(i.x,N,z),V=X>v?(X+v)/2:J(i.y,X,v);return{x:et,y:V}},[]),R=n.useCallback((i,p,h,b)=>{const M=k.current,N=m.current,z=J(i,at,it),X=z/M,v=E({x:p.x-(p.x-N.x)*X,y:p.y-(p.y-N.y)*X},h,b,z);s(z),r(v)},[E]),j=n.useCallback((i,p,h,b)=>{f(!1);const M=b??{x:p/2,y:h/2};R(k.current*i,M,p,h)},[f,R]),Y=n.useCallback((i,p)=>{if(i&&p){j(1.2,i,p);return}s(h=>J(h+.1,at,it))},[j]),G=n.useCallback((i,p)=>{if(i&&p){j(1/1.2,i,p);return}s(h=>J(h-.1,at,it))},[j]),L=n.useCallback(()=>{f(!0),r({x:0,y:0}),s(1)},[f]),A=n.useCallback((i,p,h,b)=>{if(f(!0),i.size===0){r({x:0,y:0}),s(1);return}const M=b?.nodeWidth??280,N=b?.nodeHeight??100,z=Array.from(i.values()),X=Math.min(...z.map(U=>U.x)),v=Math.min(...z.map(U=>U.y)),et=Math.max(...z.map(U=>U.x+M)),V=Math.max(...z.map(U=>U.y+N)),nt=Math.max(1,et-X),rt=Math.max(1,V-v),ot=Math.max(1,p-Pt*2),lt=Math.max(1,h-Pt*2),W=J(Math.min(ot/nt,lt/rt),at,it),dt=(p-nt*W)/2-X*W,ft=(h-rt*W)/2-v*W;s(W),r(E({x:dt,y:ft},p,h,W))},[E,f]),d=n.useCallback((i,p)=>{if(y.current.set(i,p),y.current.size===2){const[h,b]=Array.from(y.current.values());I.current={distance:Math.hypot(h.x-b.x,h.y-b.y),zoom:k.current,pan:m.current,midpoint:{x:(h.x+b.x)/2,y:(h.y+b.y)/2}},D.current=null;return}D.current={start:p,panStart:m.current}},[]),P=n.useCallback((i,p,h,b)=>{if(y.current.has(i)&&y.current.set(i,p),y.current.size===2&&I.current){f(!1);const[z,X]=Array.from(y.current.values()),et=Math.hypot(z.x-X.x,z.y-X.y)/Math.max(1,I.current.distance),V={x:(z.x+X.x)/2,y:(z.y+X.y)/2},nt=J(I.current.zoom*et,at,it),rt=nt/I.current.zoom,ot=E({x:V.x-(I.current.midpoint.x-I.current.pan.x)*rt,y:V.y-(I.current.midpoint.y-I.current.pan.y)*rt},h,b);s(nt),r(ot);return}const M=D.current;if(!M)return;f(!1);const N={x:M.panStart.x+(p.x-M.start.x),y:M.panStart.y+(p.y-M.start.y)};r(E(N,h,b))},[E,f]),x=n.useCallback(i=>{if(y.current.delete(i),y.current.size<2&&(I.current=null),y.current.size===1){const[p]=Array.from(y.current.values());D.current={start:p,panStart:m.current};return}y.current.size===0&&(D.current=null)},[]),_=n.useCallback((i,p,h,b)=>{f(!1);const M={x:m.current.x-i,y:m.current.y-p};r(E(M,h,b))},[E,f]),B=n.useCallback((i,p,h,b)=>{const M=i<0?1.1:.9;f(!1),R(k.current*M,p,h,b)},[f,R]),Z=n.useCallback(i=>{u.current=i},[]),K=n.useCallback((i,p,h,b,M)=>{if(Qt(i.target))return;const N=i.metaKey||i.ctrlKey;if(i.key==="Escape"){i.preventDefault(),L();return}if(N){if(i.key==="="||i.key==="+"){i.preventDefault(),j(1.2,p,h);return}if(i.key==="-"){i.preventDefault(),j(1/1.2,p,h);return}if(i.key==="0"){i.preventDefault(),L();return}(i.key==="f"||i.key==="F")&&i.shiftKey&&(i.preventDefault(),A(b,p,h,M))}},[A,L,j]);return{pan:e,zoom:c,zoomPercent:T,transform:o,transitioning:l,zoomIn:Y,zoomOut:G,resetView:L,fitToGraph:A,setAnimate:f,onPointerDown:d,onPointerMove:P,onPointerUp:x,onWheelPan:_,onWheelZoom:B,handleKeyDown:K,setGraphBounds:Z}}function ee(e){const{upstreamMap:r,downstreamMap:c}=n.useMemo(()=>{const l=new Map,a=new Map;for(const m of e)l.set(m.id,new Set(m.dependencies??[])),a.has(m.id)||a.set(m.id,new Set);for(const m of e)for(const k of m.dependencies??[])a.has(k)||a.set(k,new Set),a.get(k)?.add(m.id);return{upstreamMap:l,downstreamMap:a}},[e]);return{getChain:n.useCallback(l=>{if(!r.has(l)&&!c.has(l))return new Set;const a=new Set([l]),m=(k,w)=>{const D=[k],y=new Set([k]);for(;D.length>0;){const I=D.shift();if(!I)continue;const u=w.get(I);if(u)for(const o of u)y.has(o)||(y.add(o),a.add(o),D.push(o))}};return m(l,r),m(l,c),a},[c,r])}}const yt="fusion-plugin-dependency-graph:positions";function ct(e){if(!e||typeof e!="object")return!1;const r=e;return typeof r.x=="number"&&Number.isFinite(r.x)&&typeof r.y=="number"&&Number.isFinite(r.y)}function ne(e){const r=It(yt,e);if(!r)return{};try{const c=JSON.parse(r);if(!c||typeof c!="object")return{};const s={};for(const[l,a]of Object.entries(c))ct(a)&&(s[l]=a);return s}catch{return{}}}function re(e,r,c){const s={};for(const[l,a]of Object.entries(e))r.has(l)&&ct(a)&&(s[l]=a);Nt(yt,JSON.stringify(s),c)}function oe(e){Rt(yt,e)}function se(e,r,c){const s={};for(const[l,a]of Object.entries(e))c.has(l)&&ct(a)&&(s[l]=a);for(const[l,a]of Object.entries(r))c.has(l)&&ct(a)&&(s[l]=a);return s}function ae(e,r){const c={};for(const[s,l]of Object.entries(e))r.has(s)&&(c[s]=l);return c}function ie({projectId:e,visibleTaskIds:r}){const[c,s]=n.useState(null);n.useEffect(()=>{s(ne(e))},[e]);const l=n.useCallback(m=>{re(m,r,e),s(ae(m,r))},[e,r]),a=n.useCallback(()=>{oe(e),s(null)},[e]);return{savedPositions:c,persistPositions:l,clearSavedPositions:a}}const tt=280,Q=100,Mt=4;function ce({tasks:e,projectId:r,onOpenTaskDetail:c,onOpenDetail:s,addToast:l,globalPaused:a,onUpdateTask:m,onArchiveTask:k,onUnarchiveTask:w,onDeleteTask:D,onRetryTask:y,onOpenDetailWithTab:I,taskStuckTimeoutMs:u,onOpenMission:o,onMoveTask:T,lastFetchTimeMs:f,workflowStepNameLookup:E}){const R=n.useRef(null),j=n.useRef(!1),Y=n.useRef(null),G=n.useRef(!1),[L,A]=n.useState(null),[d,P]=n.useState(null),x=n.useMemo(()=>Kt(e),[e]),_=qt(x),{getChain:B}=ee(x),Z=L??d,K=n.useMemo(()=>Z?B(Z):new Set,[Z,B]),i=n.useMemo(()=>gt(_,{nodeWidth:tt,nodeHeight:Q,horizontalGap:40,verticalGap:80}),[_]),p=n.useMemo(()=>new Set(x.map(t=>t.id)),[x]),{savedPositions:h,persistPositions:b,clearSavedPositions:M}=ie({projectId:r,visibleTaskIds:p}),[N,z]=n.useState(i),[X,v]=n.useState(!1);n.useEffect(()=>{const t={};for(const[S,O]of i.entries())t[S]=O;const g=h?se(t,h,p):t;z(new Map(Object.entries(g)))},[i,h,p]);const{transform:et,zoom:V,transitioning:nt,zoomIn:rt,zoomOut:ot,resetView:lt,fitToGraph:W,onPointerDown:dt,onPointerMove:ft,onPointerUp:U,onWheelPan:bt,onWheelZoom:wt,handleKeyDown:Ct,setGraphBounds:xt}=te();n.useEffect(()=>{if(j.current||x.length===0)return;if(!!(h&&Object.keys(h).length>0)){j.current=!0;return}const g=R.current;g&&(W(N,g.clientWidth,g.clientHeight,{nodeWidth:tt,nodeHeight:Q}),j.current=!0)},[x.length,W,N,h]);const H=n.useMemo(()=>{const t=Array.from(N.values());if(t.length===0)return{minX:0,minY:0,maxX:0,maxY:0,width:0,height:0};const g=Math.min(...t.map($=>$.x)),S=Math.min(...t.map($=>$.y)),O=Math.max(...t.map($=>$.x+tt)),F=Math.max(...t.map($=>$.y+Q));return{minX:g,minY:S,maxX:O,maxY:F,width:Math.max(0,O-g),height:Math.max(0,F-S)}},[N]),pt=n.useMemo(()=>{if(N.size===0)return N;const t=new Map;for(const[g,S]of N.entries())t.set(g,{x:S.x-H.minX,y:S.y-H.minY});return t},[H.minX,H.minY,N]);n.useEffect(()=>{xt({minX:0,minY:0,maxX:H.width,maxY:H.height})},[H.height,H.width,xt]);const kt=n.useCallback(()=>{M();const t=gt(_,{nodeWidth:tt,nodeHeight:Q,horizontalGap:40,verticalGap:80});z(t)},[M,_]),Tt=n.useCallback(()=>{const t={};for(const[g,S]of N.entries())t[g]=S;b(t)},[b,N]);return C.jsxs("section",{className:"dependency-graph","data-testid":"dependency-graph",children:[C.jsx("div",{ref:R,className:"dependency-graph__viewport",onPointerDown:t=>{X||(Y.current={x:t.clientX,y:t.clientY},G.current=!1,dt(t.pointerId,{x:t.clientX,y:t.clientY}))},onPointerMove:t=>{if(X)return;const g=R.current;if(!g)return;const S=Y.current;if(S){const O=Math.abs(t.clientX-S.x),F=Math.abs(t.clientY-S.y);(O>Mt||F>Mt)&&(G.current=!0)}ft(t.pointerId,{x:t.clientX,y:t.clientY},g.clientWidth,g.clientHeight)},onPointerUp:t=>{X||U(t.pointerId),Y.current=null},onPointerCancel:t=>{X||U(t.pointerId),Y.current=null,G.current=!1},onWheel:t=>{t.preventDefault();const g=R.current;if(g){if(t.ctrlKey||t.metaKey){const S=g.getBoundingClientRect();wt(t.deltaY,{x:t.clientX-S.left,y:t.clientY-S.top},g.clientWidth,g.clientHeight);return}bt(t.deltaX,t.deltaY,g.clientWidth,g.clientHeight)}},onKeyDown:t=>{const g=R.current;g&&Ct(t,g.clientWidth,g.clientHeight,pt,{nodeWidth:tt,nodeHeight:Q})},tabIndex:0,onClick:()=>{G.current||X||P(null)},children:x.length===0?C.jsx("div",{className:"dependency-graph__empty",children:"No active tasks to display in graph view."}):C.jsxs("div",{className:`graph-canvas-transform${nt?" graph-canvas-transform--animate":""}`,style:{transform:et,width:`${H.width}px`,height:`${H.height}px`},children:[C.jsx(Bt,{edges:_.edges,positions:pt,nodeWidth:tt,nodeHeight:Q,highlightedEdgeIds:K.size>0?new Set(_.edges.filter(t=>K.has(t.source)&&K.has(t.target)).map(t=>`${t.source}->${t.target}`)):void 0}),C.jsx("div",{className:"dependency-graph__nodes-layer",children:_.nodes.map(t=>{const g=pt.get(t.task.id);return g?C.jsx(jt,{task:t.task,projectId:r,isSelected:d===t.task.id,style:{minHeight:`${Q}px`,left:`${g.x}px`,top:`${g.y}px`},position:g,scale:V,onNodePositionChange:(S,O)=>{z(F=>{const $={x:O.x+H.minX,y:O.y+H.minY},q=F.get(S);if(q&&q.x===$.x&&q.y===$.y)return F;const st=new Map(F);return st.set(S,$),st})},onNodeDragStateChange:v,onNodeDragEnd:Tt,isHighlighted:K.size>0&&K.has(t.task.id),isDimmed:K.size>0&&!K.has(t.task.id),onOpenDetail:s??(S=>c?.(S.id)),addToast:l??(()=>{}),globalPaused:a,onUpdateTask:m,onArchiveTask:k,onUnarchiveTask:w,onDeleteTask:D,onRetryTask:y,onOpenDetailWithTab:I,taskStuckTimeoutMs:u,onOpenMission:o,onMoveTask:T,lastFetchTimeMs:f,workflowStepNameLookup:E,onMouseEnter:()=>A(t.task.id),onMouseLeave:()=>A(null),onClick:S=>{S.stopPropagation(),G.current=!1,P(O=>O===t.task.id?null:t.task.id)}},t.task.id):null})})]})}),C.jsx(Wt,{zoom:V,onZoomIn:()=>{const t=R.current;t&&rt(t.clientWidth,t.clientHeight)},onZoomOut:()=>{const t=R.current;t&&ot(t.clientWidth,t.clientHeight)},onFitToGraph:()=>{kt();const t=R.current;if(!t)return;const g=gt(_,{nodeWidth:tt,nodeHeight:Q,horizontalGap:40,verticalGap:80}),S=new Map,O=Array.from(g.values()),F=O.length>0?Math.min(...O.map(q=>q.x)):0,$=O.length>0?Math.min(...O.map(q=>q.y)):0;for(const[q,st]of g.entries())S.set(q,{x:st.x-F,y:st.y-$});W(S,t.clientWidth,t.clientHeight,{nodeWidth:tt,nodeHeight:Q})},onResetView:()=>{kt(),lt()}})]})}function ue(e){return new Map((e??[]).map(r=>[r.id,r.name]))}function he({context:e}){return n.createElement(ce,{tasks:e?.tasks??[],projectId:e?.projectId,workflowStepNameLookup:ue(e?.workflowSteps),onOpenDetail:e?.openTaskDetail})}export{ce as DependencyGraph,he as DependencyGraphDashboardView,he as default};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
.graph-task-node{position:absolute;z-index:1;width:min(100%,var(--graph-task-node-width, calc(var(--space-2xl) * 9)));max-width:var(--graph-task-node-max-width, calc(var(--space-2xl) * 9.5));transition:box-shadow var(--transition-fast),z-index var(--transition-fast),opacity var(--transition-fast),border-color var(--transition-fast);border:var(--btn-border-width) solid transparent;border-radius:var(--radius-sm);touch-action:manipulation}.graph-task-node:hover{box-shadow:var(--shadow-md);z-index:2}.graph-task-node--selected{box-shadow:var(--focus-ring-strong),var(--shadow-md);z-index:2}.graph-task-node--highlighted{box-shadow:0 0 0 var(--btn-border-width) var(--todo),var(--shadow-md);z-index:2}.graph-task-node--dimmed{opacity:.4}.graph-task-node--active{border-color:color-mix(in srgb,var(--in-progress) 50%,transparent);box-shadow:0 0 0 var(--btn-border-width) color-mix(in srgb,var(--in-progress) 45%,transparent),0 0 var(--space-md) color-mix(in srgb,var(--in-progress) 50%,transparent),0 0 var(--space-xl) color-mix(in srgb,var(--in-progress) 20%,transparent);transform:scale(1.01)}.graph-task-node--in-review{border-inline-start:calc(var(--btn-border-width) * 3) solid var(--in-review);border-start-start-radius:var(--radius-md);border-end-start-radius:var(--radius-md)}.graph-task-active-indicator{display:flex;align-items:center;min-height:calc(var(--space-xs) * 5);width:100%;padding-inline:var(--space-sm);background:color-mix(in srgb,var(--in-progress) 85%,transparent);border-radius:var(--radius-sm) var(--radius-sm) 0 0;animation:graph-task-active-pulse calc(var(--transition-normal) * 8) ease-in-out infinite}.graph-task-active-indicator-text{font-family:var(--font-mono);font-size:calc(var(--space-xs) * 2.5);font-weight:600;line-height:1;letter-spacing:.04em;text-transform:uppercase;color:var(--card)}.graph-task-node .card{width:100%;height:100%}.graph-task-node[data-current-step="0"] .card-steps-list .card-step-item:nth-child(1),.graph-task-node[data-current-step="1"] .card-steps-list .card-step-item:nth-child(2),.graph-task-node[data-current-step="2"] .card-steps-list .card-step-item:nth-child(3),.graph-task-node[data-current-step="3"] .card-steps-list .card-step-item:nth-child(4),.graph-task-node[data-current-step="4"] .card-steps-list .card-step-item:nth-child(5),.graph-task-node[data-current-step="5"] .card-steps-list .card-step-item:nth-child(6),.graph-task-node[data-current-step="6"] .card-steps-list .card-step-item:nth-child(7),.graph-task-node[data-current-step="7"] .card-steps-list .card-step-item:nth-child(8),.graph-task-node[data-current-step="8"] .card-steps-list .card-step-item:nth-child(9),.graph-task-node[data-current-step="9"] .card-steps-list .card-step-item:nth-child(10),.graph-task-node[data-current-step="10"] .card-steps-list .card-step-item:nth-child(11),.graph-task-node[data-current-step="11"] .card-steps-list .card-step-item:nth-child(12),.graph-task-node[data-current-step="12"] .card-steps-list .card-step-item:nth-child(13),.graph-task-node[data-current-step="13"] .card-steps-list .card-step-item:nth-child(14),.graph-task-node[data-current-step="14"] .card-steps-list .card-step-item:nth-child(15),.graph-task-node[data-current-step="15"] .card-steps-list .card-step-item:nth-child(16),.graph-task-node[data-current-step="16"] .card-steps-list .card-step-item:nth-child(17),.graph-task-node[data-current-step="17"] .card-steps-list .card-step-item:nth-child(18),.graph-task-node[data-current-step="18"] .card-steps-list .card-step-item:nth-child(19),.graph-task-node[data-current-step="19"] .card-steps-list .card-step-item:nth-child(20){background:color-mix(in srgb,var(--in-progress) 15%,transparent);border-left:calc(var(--btn-border-width) * 2) solid var(--in-progress);padding-left:var(--space-xs);font-weight:500}.graph-task-node[data-current-step="0"] .card-steps-list .card-step-item:nth-child(1) .card-step-dot,.graph-task-node[data-current-step="1"] .card-steps-list .card-step-item:nth-child(2) .card-step-dot,.graph-task-node[data-current-step="2"] .card-steps-list .card-step-item:nth-child(3) .card-step-dot,.graph-task-node[data-current-step="3"] .card-steps-list .card-step-item:nth-child(4) .card-step-dot,.graph-task-node[data-current-step="4"] .card-steps-list .card-step-item:nth-child(5) .card-step-dot,.graph-task-node[data-current-step="5"] .card-steps-list .card-step-item:nth-child(6) .card-step-dot,.graph-task-node[data-current-step="6"] .card-steps-list .card-step-item:nth-child(7) .card-step-dot,.graph-task-node[data-current-step="7"] .card-steps-list .card-step-item:nth-child(8) .card-step-dot,.graph-task-node[data-current-step="8"] .card-steps-list .card-step-item:nth-child(9) .card-step-dot,.graph-task-node[data-current-step="9"] .card-steps-list .card-step-item:nth-child(10) .card-step-dot,.graph-task-node[data-current-step="10"] .card-steps-list .card-step-item:nth-child(11) .card-step-dot,.graph-task-node[data-current-step="11"] .card-steps-list .card-step-item:nth-child(12) .card-step-dot,.graph-task-node[data-current-step="12"] .card-steps-list .card-step-item:nth-child(13) .card-step-dot,.graph-task-node[data-current-step="13"] .card-steps-list .card-step-item:nth-child(14) .card-step-dot,.graph-task-node[data-current-step="14"] .card-steps-list .card-step-item:nth-child(15) .card-step-dot,.graph-task-node[data-current-step="15"] .card-steps-list .card-step-item:nth-child(16) .card-step-dot,.graph-task-node[data-current-step="16"] .card-steps-list .card-step-item:nth-child(17) .card-step-dot,.graph-task-node[data-current-step="17"] .card-steps-list .card-step-item:nth-child(18) .card-step-dot,.graph-task-node[data-current-step="18"] .card-steps-list .card-step-item:nth-child(19) .card-step-dot,.graph-task-node[data-current-step="19"] .card-steps-list .card-step-item:nth-child(20) .card-step-dot{width:var(--space-sm);height:var(--space-sm);animation:graph-task-step-pulse calc(var(--transition-normal) * 10) ease-in-out infinite}@keyframes graph-task-active-pulse{0%,to{background:color-mix(in srgb,var(--in-progress) 85%,transparent)}50%{background:color-mix(in srgb,var(--in-progress) 65%,transparent)}}@keyframes graph-task-step-pulse{0%,to{transform:scale(1);opacity:1}50%{transform:scale(1.2);opacity:.75}}@media(max-width:768px){.graph-task-node{width:min(100%,var(--graph-task-node-mobile-width, calc(var(--space-2xl) * 8)))}.graph-task-node--active{transform:scale(1.005)}.graph-task-active-indicator{min-height:var(--space-xl);padding-inline:var(--space-md)}.graph-task-active-indicator-text{font-size:calc(var(--space-xs) * 2.75)}}.graph-node--highlighted{opacity:1;box-shadow:var(--shadow-glow)}.graph-node--dimmed{opacity:.25;transition:opacity var(--transition-fast)}.graph-edge--highlighted{opacity:1;stroke:var(--todo);stroke-width:var(--space-xs)}.graph-edge--dimmed{opacity:.15;transition:opacity var(--transition-fast)}@media(max-width:768px){.graph-node--dimmed,.graph-edge--dimmed{transition:opacity var(--transition-fast)}}.graph-node--draggable{cursor:grab;touch-action:none}.graph-node--dragging{z-index:3;cursor:grabbing;box-shadow:var(--shadow-lg);transform:scale(1.02);transition:transform var(--transition-fast),box-shadow var(--transition-fast),z-index var(--transition-fast)}.graph-toolbar{position:absolute;right:var(--space-md);bottom:var(--space-md);display:flex;flex-direction:column;gap:var(--space-xs);padding:var(--space-sm);background:var(--surface);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);box-shadow:var(--shadow-md);z-index:10}.graph-toolbar__zoom-label{min-width:3.5ch;color:var(--text-muted);font-family:var(--font-mono);font-size:.75rem;text-align:center}@media(max-width:768px){.graph-toolbar{right:var(--space-sm);bottom:var(--space-sm);padding:var(--space-md)}.graph-toolbar .btn-icon{min-width:calc(var(--space-xs) * 11);min-height:calc(var(--space-xs) * 11)}}.dependency-graph{position:relative;height:100%;padding:var(--space-md)}.dependency-graph__viewport{position:relative;overflow:hidden;height:100%;min-height:calc(var(--space-2xl) * 10);border:var(--btn-border-width) solid var(--border);border-radius:var(--radius-md);background:var(--surface);touch-action:none}.dependency-graph__viewport:focus-visible{box-shadow:var(--focus-ring-strong)}.graph-canvas-transform{position:relative;transform-origin:top left}.graph-canvas-transform--animate{transition:transform var(--transition-normal)}.dependency-graph__nodes-layer{position:relative;z-index:1}.dependency-graph__nodes-layer .graph-task-node{max-width:min(100%,calc(var(--space-2xl) * 9))}.dependency-graph-edges{position:absolute;inset:0;width:100%;height:100%;pointer-events:none;overflow:visible}.dependency-graph__empty{color:var(--text-muted);display:flex;align-items:center;justify-content:center;height:100%}@media(max-width:768px){.dependency-graph{padding:var(--space-sm)}}
|