@runfusion/fusion 0.17.0 → 0.17.1
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 +24 -3
- package/dist/client/assets/{AgentDetailView-DGqT1oDt.js → AgentDetailView-BmxnuM0D.js} +3 -3
- package/dist/client/assets/{AgentsView-BmemrfrO.js → AgentsView-1xSqjJxs.js} +45 -45
- package/dist/client/assets/ChatView-CkWkEwXL.js +1 -0
- package/dist/client/assets/{DevServerView-C3Q0XqDA.js → DevServerView-DIrmWI5T.js} +1 -1
- package/dist/client/assets/{DirectoryPicker-BZWVA9ND.js → DirectoryPicker-Sqwdifcb.js} +1 -1
- package/dist/client/assets/{DocumentsView-DO48ivSq.js → DocumentsView-Cx_02o_z.js} +1 -1
- package/dist/client/assets/{InsightsView-CAngTfMf.js → InsightsView-DAJSq4gV.js} +1 -1
- package/dist/client/assets/{MemoryView-B3rNcAOW.js → MemoryView-CCIBAre3.js} +2 -2
- package/dist/client/assets/{NodesView-BnV1LWa8.js → NodesView-D02HxGCl.js} +4 -4
- package/dist/client/assets/{PiExtensionsManager-C3_Lw4sa.js → PiExtensionsManager-DD0fTQNf.js} +3 -3
- package/dist/client/assets/{PluginManager-Vv3nzrJ1.js → PluginManager-Cfl0VBX9.js} +1 -1
- package/dist/client/assets/ResearchView-B9RqOVbr.js +1 -0
- package/dist/client/assets/{RoadmapsView-BiIpE-b8.js → RoadmapsView-DsH7Hicx.js} +2 -2
- package/dist/client/assets/{SettingsModal-CK4w8Ztb.js → SettingsModal-Cn_CIPXu.js} +1 -1
- package/dist/client/assets/SettingsModal-YH_rM1ZT.js +31 -0
- package/dist/client/assets/{SetupWizardModal-Dw6N4UvY.js → SetupWizardModal-k5vqrHZU.js} +1 -1
- package/dist/client/assets/{SkillsView-C1196wgA.js → SkillsView-BIdt5cfB.js} +1 -1
- package/dist/client/assets/{folder-open-WVtgE4k3.js → folder-open-B3TO7t7Z.js} +1 -1
- package/dist/client/assets/{index-Bv0TGzDH.js → index-BlkXZ4C5.js} +155 -155
- package/dist/client/assets/{star-MSImEC8V.js → star-DW-M-BD_.js} +1 -1
- package/dist/client/assets/{upload-Dmvy3xXd.js → upload-BzG6fknr.js} +1 -1
- package/dist/client/assets/{users-CncYvHNf.js → users-DEicv0kj.js} +1 -1
- package/dist/client/index.html +1 -1
- package/dist/client/version.json +1 -1
- package/dist/extension.js +24 -3
- package/dist/pi-claude-cli/package.json +1 -1
- package/dist/plugins/fusion-plugin-dependency-graph/package.json +1 -1
- package/package.json +1 -1
- package/dist/client/assets/ChatView-CZQUBFlV.js +0 -1
- package/dist/client/assets/ResearchView-Dfdsuc21.js +0 -1
- package/dist/client/assets/SettingsModal-BN00HYJ2.js +0 -31
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Dt,
|
|
1
|
+
import{r as a,j as e}from"./vendor-react-K0fH_qHe.js";import{c as Dt,b9 as Mt,ba as Rt,bb as It,bc as $t,bd as zt,be as tt,bf as At,bg as Ot,bh as at,bi as Ht,bj as Bt,bk as Gt,bl as Pt,bm as Tt,bn as Lt,bo as Vt,bp as Ut,z as Kt,w as Wt,O as ze,bq as me,X as re,aN as Fe,_ as Pe,ag as qt,am as ut,aM as st,ad as Yt,br as qe,bs as Jt}from"./index-BlkXZ4C5.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 Xt=[["path",{d:"M12 2v4",key:"3427ic"}],["path",{d:"m16.2 7.8 2.9-2.9",key:"r700ao"}],["path",{d:"M18 12h4",key:"wj9ykh"}],["path",{d:"m16.2 16.2 2.9 2.9",key:"1bxg5t"}],["path",{d:"M12 18v4",key:"jadmvz"}],["path",{d:"m4.9 19.1 2.9-2.9",key:"bwix9q"}],["path",{d:"M2 12h4",key:"j09sii"}],["path",{d:"m4.9 4.9 2.9 2.9",key:"giyufr"}]],Qt=Dt("loader",Xt);function Zt(l){const n=l?.projectId,[v,f]=a.useState([]),[C,w]=a.useState(null),[y,g]=a.useState(null),[k,D]=a.useState([]),[j,S]=a.useState({}),[A,q]=a.useState(!1),[L,$]=a.useState(null),[ne,pe]=a.useState(null),[Te,ge]=a.useState(!1),[he,Z]=a.useState(null),[fe,B]=a.useState([]),[O,G]=a.useState(!1),[be,P]=a.useState({}),[ie,ee]=a.useState({}),J=a.useRef(be),ve=a.useRef(ie),oe=a.useRef(fe);J.current=be,ve.current=ie,oe.current=fe;const xe=a.useRef(n),M=a.useRef(0),le=a.useRef(0),_e=a.useRef(v),x=a.useRef(C),de=a.useRef(k),we=a.useRef(j),R=a.useRef(n),Ae=a.useRef(ne);_e.current=v,x.current=C,de.current=k,we.current=j,R.current=n,Ae.current=ne,a.useEffect(()=>{xe.current!==n&&(xe.current=n,M.current++,w(null),g(null),D([]),S({}),pe(null),Z(null),B([]),G(!1),P({}),ee({}))},[n]);const X=a.useCallback(async()=>{q(!0),$(null);try{const s=await Mt(n);f(s)}catch(s){$(s instanceof Error?s:new Error("Failed to fetch roadmaps"))}finally{q(!1)}},[n]),N=a.useCallback(async s=>{try{const d=await Rt(s,n);g(d),D(d.milestones||[]);const i={};for(const r of d.milestones||[])i[r.id]=r.features||[];S(i)}catch(d){$(d instanceof Error?d:new Error("Failed to fetch roadmap"))}},[n]);a.useEffect(()=>{X()},[X]),a.useEffect(()=>{C?N(C):(g(null),D([]),S({}))},[C,N]);const Oe=a.useCallback(async(s,d)=>{try{const i=await It(s,R.current);f(r=>[...r,i]),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to create roadmap");throw d?.onError?.(r),r}},[]),je=a.useCallback(async(s,d,i)=>{try{const r=await $t(s,d,R.current);f(c=>c.map(o=>o.id===s?r:o)),x.current===s&&g(c=>c?{...c,...r}:null),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update roadmap");throw i?.onError?.(c),c}},[]),He=a.useCallback(async(s,d)=>{try{await zt(s,R.current),f(i=>i.filter(r=>r.id!==s)),x.current===s&&(w(null),g(null),D([]),S({})),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete roadmap");throw d?.onError?.(r),r}},[]),Le=a.useCallback(s=>{w(s)},[]),p=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const r=new Error("No roadmap selected");throw d?.onError?.(r),r}try{const r=await tt(i,s,R.current);D(c=>[...c,r]),S(c=>({...c,[r.id]:[]})),x.current&&N(x.current),d?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create milestone");throw d?.onError?.(c),c}},[N]),I=a.useCallback(async(s,d,i)=>{try{const r=await At(s,d,R.current);D(c=>c.map(o=>o.id===s?r:o)),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update milestone");throw i?.onError?.(c),c}},[N]),te=a.useCallback(async(s,d)=>{try{await Ot(s,R.current),D(i=>i.filter(r=>r.id!==s)),S(i=>{const r={...i};return delete r[s],r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete milestone");throw d?.onError?.(r),r}},[N]),Ve=a.useCallback(async(s,d,i)=>{try{const r=await at(s,d,R.current);S(c=>({...c,[s]:[...c[s]||[],r]})),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create feature");throw i?.onError?.(c),c}},[N]),De=a.useCallback(async(s,d,i)=>{try{const r=await Ht(s,d,R.current);S(c=>{const o={};for(const[h,m]of Object.entries(c))o[h]=m.map(_=>_.id===s?r:_);return o}),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update feature");throw i?.onError?.(c),c}},[N]),Me=a.useCallback(async(s,d)=>{try{await Bt(s,R.current),S(i=>{const r={};for(const[c,o]of Object.entries(i))r[c]=o.filter(h=>h.id!==s);return r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete feature");throw d?.onError?.(r),r}},[N]),E=a.useCallback(async(s,d,i)=>{const r=de.current,c=d.map(o=>r.find(h=>h.id===o)).filter(o=>o!==void 0).map((o,h)=>({...o,orderIndex:h}));D(c);try{await Gt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(o){D(r);const h=o instanceof Error?o:new Error("Failed to reorder milestones");throw i?.onError?.(h),h}},[N]),ce=a.useCallback(async(s,d,i)=>{const r=we.current[s]||[],c=r.map(m=>m.id);if(JSON.stringify(c)===JSON.stringify(d)){i?.onSuccess?.();return}const o=we.current,h=d.map(m=>r.find(_=>_.id===m)).filter(m=>m!==void 0).map((m,_)=>({...m,orderIndex:_}));S(m=>({...m,[s]:h}));try{await Pt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(m){S(o);const _=m instanceof Error?m:new Error("Failed to reorder features");throw i?.onError?.(_),_}},[N]),Q=a.useCallback(async(s,d,i,r)=>{const c=we.current;let o=null;for(const[F,W]of Object.entries(c))if(W.some(Ke=>Ke.id===s)){o=F;break}if(!o){const F=new Error("Feature not found");throw r?.onError?.(F),F}if(o===d){const F=c[o]||[],W=Math.max(0,Math.min(i,F.length-1));if(F.findIndex(We=>We.id===s)===W){r?.onSuccess?.();return}}const h=c[o]||[],m=c[d]||[],_=h.find(F=>F.id===s);if(!_){const F=new Error("Feature not found");throw r?.onError?.(F),F}const H=h.filter(F=>F.id!==s).map((F,W)=>({...F,orderIndex:W})),ye={..._,milestoneId:d,orderIndex:i},se=[...m];se.splice(i,0,ye);const Ue=se.map((F,W)=>({...F,orderIndex:W}));S(o===d?F=>({...F,[o]:Ue}):F=>({...F,[o]:H,[d]:Ue}));try{await Tt(s,d,i,n),x.current&&N(x.current),r?.onSuccess?.()}catch(F){S(c);const W=F instanceof Error?F:new Error("Failed to move feature");throw r?.onError?.(W),W}},[N,n]);function V(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`draft-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}const ae=a.useCallback(async(s,d=5,i)=>{const r=x.current;if(!r){const h=new Error("No roadmap selected");throw i?.onError?.(h),h}const c=M.current,o=R.current;G(!0);try{const h=await Lt(r,s,d,o);if(M.current!==c)return;const m=h.suggestions.map(_=>({id:V(),title:_.title,description:_.description}));B(m),i?.onSuccess?.()}catch(h){if(M.current!==c)return;const m=h instanceof Error?h:new Error("Failed to generate suggestions");throw i?.onError?.(m),m}finally{M.current===c&&G(!1)}},[]),Re=a.useCallback((s,d)=>{const r=oe.current.map(c=>c.id===s?{...c,...d}:c);oe.current=r,B(c=>c.map(o=>o.id===s?{...o,...d}:o))},[]),U=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const m=new Error("No roadmap selected");throw d?.onError?.(m),m}const r=M.current,c=oe.current,o=c.findIndex(m=>m.id===s);if(o===-1){const m=new Error("Suggestion draft not found");throw d?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw d?.onError?.(m),m}B(m=>m.filter(_=>_.id!==s));try{if(await tt(i,{title:h.title,description:h.description},R.current),M.current!==r){B(m=>{const _=[...m];return _.splice(o,0,h),_});return}x.current&&N(x.current),d?.onSuccess?.()}catch(m){B(H=>{const ye=[...H];return ye.splice(o,0,h),ye});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw d?.onError?.(_),_}},[N]),K=a.useCallback(async s=>{const d=x.current;if(!d){const o=new Error("No roadmap selected");throw s?.onError?.(o),o}const i=[...oe.current];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw s?.onError?.(o),o}B([]);const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await tt(d,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw s?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),s?.onSuccess?.())},[N]),qe=a.useCallback(s=>ve.current[s]??!1,[]),Be=a.useCallback(async(s,d,i)=>{const r=M.current,c=R.current;ee(o=>({...o,[s]:!0}));try{const o=await Vt(s,d,c);if(M.current!==r)return;const h=o.suggestions.map(m=>({id:V(),title:m.title,description:m.description}));P(m=>({...m,[s]:h})),i?.onSuccess?.()}catch(o){if(M.current!==r)return;const h=o instanceof Error?o:new Error("Failed to generate feature suggestions");throw i?.onError?.(h),h}finally{M.current===r&&ee(o=>({...o,[s]:!1}))}},[]),Ce=a.useCallback((s,d,i)=>{const c=(J.current[s]||[]).map(o=>o.id===d?{...o,...i}:o);J.current={...J.current,[s]:c},P(o=>({...o,[s]:o[s]?.map(h=>h.id===d?{...h,...i}:h)||[]}))},[]),Ge=a.useCallback(async(s,d,i)=>{const r=M.current,c=J.current[s]||[],o=c.findIndex(m=>m.id===d);if(o===-1){const m=new Error("Suggestion draft not found");throw i?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw i?.onError?.(m),m}P(m=>({...m,[s]:m[s]?.filter(_=>_.id!==d)||[]}));try{if(await at(s,{title:h.title,description:h.description},R.current),M.current!==r){P(m=>{const H=[...m[s]||[]];return H.splice(o,0,h),{...m,[s]:H}});return}x.current&&N(x.current),i?.onSuccess?.()}catch(m){P(H=>{const se=[...H[s]||[]];return se.splice(o,0,h),{...H,[s]:se}});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw i?.onError?.(_),_}},[N]),Je=a.useCallback(async(s,d)=>{const i=[...J.current[s]||[]];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw d?.onError?.(o),o}P(o=>({...o,[s]:[]}));const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await at(s,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw d?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),d?.onSuccess?.())},[N]),Ne=a.useCallback(()=>{B([]),G(!1)},[]),Xe=a.useCallback(s=>{P(d=>{const i={...d};return delete i[s],i}),ee(d=>{const i={...d};return delete i[s],i})},[]),ue=a.useCallback(async(s,d)=>{const i=++le.current,r=n;ge(!0),Z(null);try{const c=await Ut(s,r);if(le.current!==i||n!==r)return;pe(c),d?.onSuccess?.()}catch(c){if(le.current!==i||n!==r)return;const o=c instanceof Error?c:new Error(String(c));Z(o),pe(null),d?.onError?.(o)}finally{le.current===i&&ge(!1)}},[n]),Ie=a.useCallback(()=>{pe(null),Z(null),ge(!1)},[]),Qe=a.useCallback(async()=>{await X(),x.current&&await N(x.current)},[X,N]);return{roadmaps:v,selectedRoadmapId:C,selectedRoadmap:y,milestones:k,featuresByMilestoneId:j,loading:A,error:L,createRoadmap:Oe,updateRoadmap:je,deleteRoadmap:He,selectRoadmap:Le,createMilestone:p,updateMilestone:I,deleteMilestone:te,reorderMilestones:E,createFeature:Ve,updateFeature:De,deleteFeature:Me,reorderFeatures:ce,moveFeature:Q,milestoneSuggestions:fe,isGeneratingSuggestions:O,generateMilestoneSuggestions:ae,updateMilestoneSuggestionDraft:Re,acceptMilestoneSuggestion:U,acceptAllMilestoneSuggestions:K,clearMilestoneSuggestions:Ne,featureSuggestionsByMilestoneId:be,isGeneratingFeatureSuggestions:qe,generateFeatureSuggestions:Be,updateFeatureSuggestionDraft:Ce,acceptFeatureSuggestion:Ge,acceptAllFeatureSuggestions:Je,clearFeatureSuggestions:Xe,handoffPayload:ne,isFetchingHandoff:Te,handoffError:he,fetchHandoff:ue,clearHandoff:Ie,refresh:Qe}}function ea({isOpen:l,onClose:n,roadmapTitle:v,handoffPayload:f,isLoading:C,error:w,onFetchHandoff:y,onCopyToClipboard:g}){return l?e.jsx("div",{className:"modal-overlay open",onClick:n,role:"presentation",children:e.jsxs("div",{className:"modal modal-lg",onClick:k=>k.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"handoff-modal-title",children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("h2",{id:"handoff-modal-title",children:["Export Roadmap: ",v]}),e.jsx("button",{className:"modal-close",onClick:n,"aria-label":"Close modal",children:e.jsx(re,{size:18})})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("p",{className:"text-muted roadmaps-view__handoff-intro",children:"Export roadmap data for use in mission and task planning flows. This is a read-only export — no missions or tasks will be created."}),w&&e.jsxs("div",{className:"form-error roadmaps-view__handoff-error",children:["Error loading handoff data: ",w.message]}),!f&&!C&&e.jsx("div",{className:"roadmaps-view__handoff-empty-state",children:e.jsxs("button",{className:"btn btn-primary",onClick:y,children:[e.jsx(st,{size:16,className:"roadmaps-view__handoff-button-icon"}),"Load Handoff Data"]})}),C&&e.jsxs("div",{className:"roadmaps-view__handoff-loading-state",children:[e.jsx(Qt,{size:24,className:"spin"}),e.jsx("p",{className:"roadmaps-view__handoff-loading-text",children:"Loading handoff data..."})]}),f&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsx("h3",{className:"roadmaps-view__handoff-section-title",children:"Mission Planning Handoff"}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--mission",children:JSON.stringify(f.mission,null,2)})})]}),e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsxs("h3",{className:"roadmaps-view__handoff-section-title",children:["Feature Task Planning Handoffs (",f.features.length,")"]}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--features",children:JSON.stringify(f.features,null,2)})})]})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:f&&e.jsxs("button",{className:"btn btn-sm",onClick:g,children:[e.jsx(Jt,{size:14,className:"roadmaps-view__handoff-copy-icon"}),"Copy to Clipboard"]})}),e.jsx("div",{className:"modal-actions-right",children:e.jsx("button",{className:"btn",onClick:n,children:"Close"})})]})]})}):null}function ta({roadmap:l,isSelected:n,onSelect:v,onEdit:f,onDelete:C,onExport:w}){const y=j=>{j.key==="Enter"&&v()},g=j=>{j.stopPropagation(),f()},k=j=>{j.stopPropagation(),C()},D=j=>{j.stopPropagation(),w()};return e.jsxs("div",{className:`roadmaps-view__sidebar-item${n?" roadmaps-view__sidebar-item--active":""}`,onClick:v,onKeyDown:y,role:"button",tabIndex:0,"aria-selected":n,"data-testid":`roadmap-item-${l.id}`,children:[e.jsxs("div",{className:"roadmaps-view__sidebar-item-content",children:[e.jsx("div",{className:"roadmaps-view__sidebar-item-title",children:l.title}),l.description&&e.jsx("div",{className:"roadmaps-view__sidebar-item-desc",children:l.description})]}),e.jsxs("div",{className:"roadmaps-view__sidebar-item-actions",onClick:g,role:"presentation",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:D,title:"Export roadmap","aria-label":"Export roadmap","data-testid":`roadmap-export-${l.id}`,type:"button",children:e.jsx(st,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:g,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`roadmap-edit-${l.id}`,type:"button",children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:k,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`roadmap-delete-${l.id}`,type:"button",children:e.jsx(Pe,{size:14})})]})]})}function aa({roadmaps:l,selectedRoadmapId:n,onSelect:v,onCreate:f,onEdit:C,onDelete:w,onExport:y,showCreateForm:g,onCancelCreate:k,onSaveCreate:D}){return e.jsxs("div",{className:"roadmaps-view__mobile-list","data-testid":"roadmaps-view__mobile-list",children:[e.jsxs("div",{className:"roadmaps-view__mobile-list-header",children:[e.jsx("h2",{className:"roadmaps-view__mobile-list-title",children:"Roadmaps"}),!g&&e.jsx("button",{className:"roadmaps-view__mobile-add-btn",onClick:f,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-create-roadmap-btn",children:e.jsx(ze,{size:18})})]}),g&&e.jsx("div",{className:"roadmaps-view__mobile-create-form",children:e.jsx(mt,{onSave:D,onCancel:k})}),l.length===0&&!g?e.jsxs("div",{className:"roadmaps-view__mobile-empty",children:[e.jsx("p",{children:"No roadmaps yet."}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:f,children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Create Roadmap"})]})]}):e.jsx("div",{className:"roadmaps-view__mobile-list-items",children:l.map(j=>e.jsxs("div",{className:`roadmaps-view__mobile-item${j.id===n?" roadmaps-view__mobile-item--active":""}`,onClick:()=>v(j.id),role:"button",tabIndex:0,onKeyDown:S=>{S.key==="Enter"&&v(j.id)},"data-testid":`mobile-roadmap-item-${j.id}`,children:[e.jsxs("div",{className:"roadmaps-view__mobile-item-content",children:[e.jsx("span",{className:"roadmaps-view__mobile-item-title",children:j.title}),j.description&&e.jsx("span",{className:"roadmaps-view__mobile-item-desc",children:j.description})]}),e.jsxs("div",{className:"roadmaps-view__mobile-item-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),y(j)},title:"Export roadmap","aria-label":"Export roadmap","data-testid":`mobile-roadmap-export-${j.id}`,children:e.jsx(st,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),C(j)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`mobile-roadmap-edit-${j.id}`,children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:S=>{S.stopPropagation(),w(j.id)},title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`mobile-roadmap-delete-${j.id}`,children:e.jsx(Pe,{size:16})})]})]},j.id))})]})}function sa({roadmapTitle:l,onBack:n,onEdit:v,onDelete:f,onCreate:C}){return e.jsxs("div",{className:"roadmaps-view__mobile-header","data-testid":"roadmaps-view__mobile-header",children:[e.jsx("button",{className:"roadmaps-view__mobile-back-btn",onClick:n,title:"Back to roadmap list","aria-label":"Back to roadmap list","data-testid":"mobile-back-btn",children:e.jsx(qt,{size:20})}),e.jsx("h2",{className:"roadmaps-view__mobile-header-title",children:l}),e.jsxs("div",{className:"roadmaps-view__mobile-header-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:C,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-header-create-btn",children:e.jsx(ze,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:v,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"mobile-header-edit-btn",children:e.jsx(Fe,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:f,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"mobile-header-delete-btn",children:e.jsx(Pe,{size:18})})]})]})}function ra({milestone:l,features:n,onEditMilestone:v,onDeleteMilestone:f,onAddFeature:C,onEditFeature:w,onDeleteFeature:y,milestoneEdit:g,onMilestoneEditChange:k,onMilestoneEditFieldChange:D,onCancelMilestoneEdit:j,onSaveMilestoneEdit:S,featureEdit:A,onFeatureEditChange:q,onStartFeatureEdit:L,onCancelFeatureEdit:$,onSaveFeatureEdit:ne,projectId:pe,addToast:Te,isMilestoneDragging:ge,isMilestoneDropTarget:he,milestoneDropPosition:Z,onMilestoneDragStart:fe,onMilestoneDragEnd:B,onMilestoneDragOver:O,onMilestoneDrop:G,onMilestoneDragLeave:be,isFeatureDragging:P,isFeatureDropTarget:ie,featureDropIndex:ee,onFeatureDragStart:J,onFeatureDragEnd:ve,onFeatureDragOver:oe,onFeatureDrop:xe,onFeatureDragLeave:M,onFeatureDropOnMilestone:le,featureSuggestions:_e,isGeneratingFeatureSuggestions:x,onGenerateFeatureSuggestions:de,onAcceptFeatureSuggestion:we,onAcceptAllFeatureSuggestions:R,onUpdateFeatureSuggestionDraft:Ae,onClearFeatureSuggestions:X}){const N=g?.milestoneId===l.id,Oe=p=>{p.key==="Enter"?(p.preventDefault(),g&&S({title:g.value})):p.key==="Escape"&&j()},je=p=>{p.key==="Escape"&&j()},He=["roadmaps-view__milestone",ge?"roadmaps-view__milestone--dragging":"",he?"roadmaps-view__milestone--drop-target":"",he&&Z==="before"?"roadmaps-view__milestone--drop-before":"",he&&Z==="after"?"roadmaps-view__milestone--drop-after":""].filter(Boolean).join(" "),Le=["roadmaps-view__feature-list",ie?"roadmaps-view__feature-list--drop-target":""].filter(Boolean).join(" ");return e.jsxs("div",{className:He,draggable:!N,onDragStart:p=>{N||(fe(l.id),p.dataTransfer.setData("text/plain",`milestone:${l.id}`),p.dataTransfer.effectAllowed="move")},onDragEnd:B,onDragOver:p=>{p.dataTransfer.types.includes("text/plain")&&p.dataTransfer.types.includes("text/plain")&&(p.preventDefault(),p.dataTransfer.dropEffect="move",O(l.id))},onDrop:p=>{p.preventDefault(),p.dataTransfer.getData("text/plain")?.startsWith("feature:")||G(l.id)},onDragLeave:be,"data-testid":`milestone-card-${l.id}`,children:[e.jsx("div",{className:"roadmaps-view__milestone-header",children:N?e.jsxs("div",{className:"roadmaps-view__inline-edit",children:[e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(Ye,{size:14})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:g.value,onChange:p=>{D("title"),k(p.target.value)},onKeyDown:Oe,placeholder:"Milestone title",autoFocus:!0,"data-testid":`milestone-title-input-${l.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>S({title:g.value}),"aria-label":"Save milestone title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:j,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:g.field==="description"?g.value:l.description||"",onChange:p=>{D("description"),k(p.target.value)},onKeyDown:je,placeholder:"Milestone description (optional)",rows:2,"data-testid":`milestone-desc-input-${l.id}`})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__milestone-title-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(Ye,{size:14})}),e.jsx("h3",{className:"roadmaps-view__milestone-title",children:l.title}),e.jsxs("div",{className:"roadmaps-view__milestone-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:v,title:"Edit milestone","aria-label":"Edit milestone","data-testid":`milestone-edit-${l.id}`,children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:f,title:"Delete milestone","aria-label":"Delete milestone","data-testid":`milestone-delete-${l.id}`,children:e.jsx(Pe,{size:14})})]})]}),l.description&&e.jsx("p",{className:"roadmaps-view__milestone-desc",children:l.description})]})}),e.jsxs("div",{className:"roadmaps-view__milestone-actions-bar",children:[e.jsxs("button",{className:"roadmaps-view__add-feature-btn",onClick:C,title:"Add feature","aria-label":"Add feature","data-testid":`add-feature-${l.id}`,children:[e.jsx(ze,{size:12}),e.jsx("span",{children:"Add Feature"})]}),e.jsxs("button",{className:"roadmaps-view__suggest-btn",onClick:()=>{de?.()},disabled:x??!1,title:"Generate feature suggestions with AI","aria-label":"Generate feature suggestions","data-testid":`generate-features-${l.id}`,children:[e.jsx(ut,{size:12}),e.jsx("span",{children:x?"Generating...":"AI Suggestions"})]})]}),e.jsxs("div",{className:Le,onDragOver:p=>{p.preventDefault(),p.dataTransfer.dropEffect="move",p.dataTransfer.getData("text/plain")?.startsWith("feature:")&&le()},onDrop:p=>{p.preventDefault();const I=p.dataTransfer.getData("text/plain");I?.startsWith("feature:")&&xe(I.split(":")[1],n.length)},onDragLeave:M,children:[n.length===0?e.jsx("p",{className:"roadmaps-view__empty-features",children:"No features yet."}):n.map((p,I)=>{const te=A?.featureId===p.id,Ve=P(p.id),De=E=>{E.key==="Enter"?(E.preventDefault(),A&&ne({title:A.value})):E.key==="Escape"&&$()},Me=["roadmaps-view__feature-item",Ve?"roadmaps-view__feature-item--dragging":"",ie&&ee===I?"roadmaps-view__feature-item--drop-before":"",ie&&ee===I+1?"roadmaps-view__feature-item--drop-after":""].filter(Boolean).join(" ");return e.jsx("div",{className:Me,draggable:!te,onDragStart:E=>{te||(J(p.id,l.id),E.dataTransfer.setData("text/plain",`feature:${p.id}`),E.dataTransfer.effectAllowed="move")},onDragEnd:ve,onDragOver:E=>{if(E.preventDefault(),E.stopPropagation(),E.dataTransfer.dropEffect="move",E.dataTransfer.getData("text/plain")?.startsWith("feature:")){const Q=E.currentTarget.getBoundingClientRect(),V=Q.top+Q.height/2,ae=E.clientY<V?"before":"after";oe(p.id,ae)}},onDrop:E=>{E.preventDefault(),E.stopPropagation();const ce=E.dataTransfer.getData("text/plain");if(ce?.startsWith("feature:")){const Q=ce.split(":")[1],V=E.currentTarget.getBoundingClientRect(),ae=V.top+V.height/2,Re=E.clientY<ae?"before":"after";let U=I;Re==="after"&&(U=I+1),xe(Q,U)}},onDragLeave:M,"data-testid":`feature-item-${p.id}`,children:te?e.jsx("div",{className:"roadmaps-view__inline-edit roadmaps-view__inline-edit--compact",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(Ye,{size:12})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:A.value,onChange:E=>q(E.target.value),onKeyDown:De,placeholder:"Feature title",autoFocus:!0,"data-testid":`feature-title-input-${p.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ne({title:A.value}),"aria-label":"Save feature title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:$,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]})}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(Ye,{size:12})}),e.jsxs("div",{className:"roadmaps-view__feature-content",children:[e.jsx("span",{className:"roadmaps-view__feature-title",children:p.title}),p.description&&e.jsx("p",{className:"roadmaps-view__feature-desc",children:p.description})]}),e.jsxs("div",{className:"roadmaps-view__feature-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>w(p.id),title:"Edit feature","aria-label":"Edit feature","data-testid":`feature-edit-${p.id}`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>y(p.id),title:"Delete feature","aria-label":"Delete feature","data-testid":`feature-delete-${p.id}`,children:e.jsx(Pe,{size:12})})]})]})},p.id)}),_e&&_e.length>0&&e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h4",{className:"roadmap-suggestion-title",children:"AI Feature Suggestions"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-accept-all-btn",onClick:()=>R?.(),title:"Accept all suggestions","aria-label":"Accept all","data-testid":`accept-all-features-${l.id}`,children:"Accept All"}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:()=>X?.(),title:"Clear suggestions","aria-label":"Clear","data-testid":`clear-features-${l.id}`,children:"Clear"})]})]}),e.jsx("div",{className:"roadmap-suggestion-list",children:_e.map(p=>e.jsx(na,{suggestion:p,onUpdateDraft:I=>Ae?.(l.id,p.id,I),onAccept:()=>{we?.(l.id,p.id)},testIdPrefix:`feature-suggestion-${l.id}`},p.id))})]})]})]})}function na({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},q=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:q,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function ct({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},q=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:q,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function mt({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form","data-testid":"create-roadmap-form",children:e.jsxs("form",{onSubmit:y,children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Roadmap title",autoFocus:!0,"data-testid":"create-roadmap-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Roadmap description (optional)",rows:2,"data-testid":"create-roadmap-description"}),e.jsxs("div",{className:"roadmaps-view__create-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__btn roadmaps-view__btn--primary",disabled:!v.trim(),"data-testid":"create-roadmap-submit",children:"Create"}),e.jsx("button",{type:"button",className:"roadmaps-view__btn",onClick:n,"data-testid":"create-roadmap-cancel",children:"Cancel"})]})]})})}function ia({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-milestone-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":"create-milestone-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-milestone-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save milestone",title:"Save","data-testid":"create-milestone-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-milestone-cancel",children:e.jsx(re,{size:14})})]})]})})}function oa({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-feature-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":"create-feature-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-feature-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save feature",title:"Save","data-testid":"create-feature-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-feature-cancel",children:e.jsx(re,{size:14})})]})]})})}function ma({projectId:l,addToast:n}){const{confirm:v}=Kt(),f=Wt()==="mobile",{roadmaps:C,selectedRoadmapId:w,selectedRoadmap:y,milestones:g,featuresByMilestoneId:k,loading:D,error:j,createRoadmap:S,updateRoadmap:A,deleteRoadmap:q,selectRoadmap:L,createMilestone:$,updateMilestone:ne,deleteMilestone:pe,createFeature:Te,updateFeature:ge,deleteFeature:he,reorderMilestones:Z,reorderFeatures:fe,moveFeature:B,milestoneSuggestions:O,isGeneratingSuggestions:G,generateMilestoneSuggestions:be,updateMilestoneSuggestionDraft:P,acceptMilestoneSuggestion:ie,acceptAllMilestoneSuggestions:ee,clearMilestoneSuggestions:J,featureSuggestionsByMilestoneId:ve,isGeneratingFeatureSuggestions:oe,generateFeatureSuggestions:xe,updateFeatureSuggestionDraft:M,acceptFeatureSuggestion:le,acceptAllFeatureSuggestions:_e,clearFeatureSuggestions:x,handoffPayload:de,isFetchingHandoff:we,handoffError:R,fetchHandoff:Ae,clearHandoff:X}=Zt({projectId:l}),[N,Oe]=a.useState(!1),[je,He]=a.useState(null),[Le,p]=a.useState(""),[I,te]=a.useState(""),[Ve,De]=a.useState(!1),Me=a.useRef(null);a.useEffect(()=>{Me.current!==null&&Me.current!==w&&De(!1),Me.current=w},[w]);const[E,ce]=a.useState({roadmapId:null,field:null,value:""}),[Q,V]=a.useState({milestoneId:null,field:null,value:""}),[ae,Re]=a.useState({featureId:null,field:null,value:""}),[U,K]=a.useState({type:null,parentId:void 0,title:"",description:""}),[qe,Be]=a.useState(!1),[Ce,Ge]=a.useState({draggingId:null,dropTargetId:null,dropPosition:null}),Je=a.useCallback(t=>{Ge(u=>({...u,draggingId:t}))},[]),Ne=a.useCallback(()=>{Ge({draggingId:null,dropTargetId:null,dropPosition:null})},[]),Xe=a.useCallback(t=>{Ge(u=>u.draggingId===t?u:{...u,dropTargetId:t,dropPosition:null})},[]),[ue,Ie]=a.useState({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}),Qe=a.useCallback((t,u)=>{Ie(b=>({...b,draggingId:t,draggingMilestoneId:u}))},[]),s=a.useCallback(()=>{Ie({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null})},[]),d=a.useCallback((t,u)=>{Ie(b=>{if(b.draggingId===t)return b;const T=(k[b.draggingMilestoneId||""]||[]).findIndex(Ee=>Ee.id===t);let Y;return u==="before"?Y=T:Y=T+1,{...b,dropTargetMilestoneId:b.draggingMilestoneId,dropTargetIndex:Y,dropPosition:u}})},[k]),i=a.useCallback(()=>{Ie(t=>({...t,dropTargetMilestoneId:t.draggingMilestoneId,dropTargetIndex:(k[t.draggingMilestoneId||""]||[]).length}))},[k]),r=a.useCallback(async(t,u)=>{const{draggingMilestoneId:b,dropTargetMilestoneId:z}=ue;if(!b){s();return}const T=z||b,Y=k[b]||[],Ee=Y.find(ke=>ke.id===t);if(!Ee){s();return}if(b!==T){if(b===T){s();return}try{await B(t,T,u,{onError:ke=>{n(`Failed to move feature: ${ke.message}`,"error")}})}catch{}}else{const ke=[...Y],kt=ke.findIndex($e=>$e.id===t);ke.splice(kt,1),ke.splice(u,0,Ee);const dt=ke.map($e=>$e.id),Ft=Y.map($e=>$e.id);if(dt.join(",")===Ft.join(",")){s();return}try{await fe(b,dt,{onError:$e=>{n(`Failed to reorder features: ${$e.message}`,"error")}})}catch{}}s()},[ue,k,fe,B,n,s]),c=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ie(T=>({...T,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}))},[]),o=a.useCallback(t=>ue.draggingId===t,[ue.draggingId]),h=a.useCallback(async t=>{const{draggingId:u}=Ce;if(!u||u===t){Ne();return}const b=g.map(Ee=>Ee.id),z=b.indexOf(u),T=b.indexOf(t);if(z===-1||T===-1){Ne();return}const Y=[...b];if(Y.splice(z,1),Y.splice(T,0,u),Y.join(",")===b.join(",")){Ne();return}try{await Z(w,Y,{onError:Ee=>{n(`Failed to reorder milestones: ${Ee.message}`,"error")}})}catch{}Ne()},[Ce,g,w,Z,n,Ne]),m=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ge(T=>({...T,dropTargetId:null,dropPosition:null}))},[]),_=a.useCallback(t=>{L(t.id),ce({roadmapId:t.id,field:"title",value:t.title})},[L]),H=a.useCallback(()=>{ce({roadmapId:null,field:null,value:""})},[]),ye=a.useCallback(async t=>{if(E.roadmapId)try{await A(E.roadmapId,t,{onError:u=>n(u.message,"error")}),H()}catch{}},[E.roadmapId,A,H,n]),se=a.useCallback(async t=>{if(await v({title:"Delete Roadmap",message:"Delete this roadmap? This cannot be undone.",danger:!0}))try{await q(t,{onError:b=>n(b.message,"error")}),n("Roadmap deleted","success")}catch{}},[q,n,v]),Ue=a.useCallback((t,u)=>{He(t),p(u),Oe(!0),X()},[X]),F=a.useCallback(()=>{Oe(!1),He(null),p(""),X()},[X]),W=a.useCallback(()=>{je&&Ae(je,{onError:t=>n(`Failed to load handoff: ${t.message}`,"error")})},[je,Ae,n]),Ke=a.useCallback(()=>{if(de){const t=JSON.stringify(de,null,2);navigator.clipboard.writeText(t).then(()=>{n("Handoff data copied to clipboard","success")}).catch(()=>{n("Failed to copy to clipboard","error")})}},[de,n]),We=a.useCallback(async t=>{try{await S(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Roadmap created","success")}catch{}},[S,n]),pt=a.useCallback(t=>{V({milestoneId:t.id,field:"title",value:t.title})},[]),gt=a.useCallback(t=>{V(u=>({...u,value:t}))},[]),ht=a.useCallback(t=>{V(u=>({...u,field:t}))},[]),Ze=a.useCallback(()=>{V({milestoneId:null,field:null,value:""})},[]),ft=a.useCallback(async t=>{if(Q.milestoneId)try{await ne(Q.milestoneId,t,{onError:u=>n(u.message,"error")}),Ze()}catch{}},[Q.milestoneId,ne,Ze,n]),bt=a.useCallback(async t=>{if(await v({title:"Delete Milestone",message:"Delete this milestone and all its features?",danger:!0}))try{await pe(t,{onError:b=>n(b.message,"error")}),n("Milestone deleted","success")}catch{}},[pe,n,v]),vt=a.useCallback(async t=>{try{await $(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Milestone created","success")}catch{}},[$,n]),rt=a.useCallback((t,u,b)=>{Re({featureId:t,field:"title",value:u})},[]),xt=a.useCallback(t=>{Re(u=>({...u,value:t}))},[]),et=a.useCallback(()=>{Re({featureId:null,field:null,value:""})},[]),_t=a.useCallback(async t=>{if(ae.featureId)try{await ge(ae.featureId,t,{onError:u=>n(u.message,"error")}),et()}catch{}},[ae.featureId,ge,et,n]),wt=a.useCallback(async t=>{if(await v({title:"Delete Feature",message:"Delete this feature?",danger:!0}))try{await he(t,{onError:b=>n(b.message,"error")}),n("Feature deleted","success")}catch{}},[he,n,v]),nt=a.useCallback(async()=>{if(I.trim())try{await be(I,5,{onError:t=>n(t.message,"error")})}catch{}},[I,be,n]),it=a.useCallback(async t=>{try{await ie(t,{onError:u=>n(u.message,"error")}),n("Milestone added","success")}catch{}},[ie,n]),ot=a.useCallback(async()=>{try{await ee({onError:t=>n(t.message,"error")}),n(`${O.length} milestones added`,"success"),te("")}catch{}},[ee,O.length,n]),lt=a.useCallback(()=>{J(),te("")},[J]),jt=a.useCallback(async t=>{try{await xe(t,{count:5},{onError:u=>n(u.message,"error")})}catch{}},[xe,n]),Ct=a.useCallback(async(t,u)=>{try{await le(t,u,{onError:b=>n(b.message,"error")}),n("Feature added","success")}catch{}},[le,n]),Nt=a.useCallback((t,u,b)=>{M(t,u,b)},[M]),yt=a.useCallback(async t=>{const u=ve[t]||[];try{await _e(t,{onError:b=>n(b.message,"error")}),n(`${u.length} features added`,"success")}catch{}},[_e,ve,n]),St=a.useCallback(t=>{x(t)},[x]),Et=a.useCallback(async(t,u)=>{try{await Te(t,u,{onError:b=>n(b.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Feature created","success")}catch{}},[Te,n]),Se=w;return D&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--loading",children:e.jsx("div",{className:"roadmaps-view__loading-state",children:"Loading roadmaps..."})}):j&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--error",children:e.jsxs("div",{className:"roadmaps-view__error-state",children:[e.jsx("p",{children:"Failed to load roadmaps"}),e.jsx("p",{className:"roadmaps-view__error-msg",children:j.message})]})}):e.jsxs("div",{className:"roadmaps-view",children:[f&&!Se&&e.jsx(aa,{roadmaps:C,selectedRoadmapId:Se,onSelect:t=>L(t),onCreate:()=>Be(!0),onEdit:_,onDelete:se,onExport:t=>Ue(t.id,t.title),showCreateForm:qe,onCancelCreate:()=>Be(!1),onSaveCreate:async t=>{await We(t),Be(!1)}}),!f&&e.jsxs("aside",{className:"roadmaps-view__sidebar","aria-label":"Roadmaps",children:[e.jsxs("div",{className:"roadmaps-view__sidebar-header",children:[e.jsx("h2",{className:"roadmaps-view__sidebar-title",children:"Roadmaps"}),e.jsx("button",{className:"roadmaps-view__add-btn",onClick:()=>K({type:"roadmap",title:"",description:""}),title:"Create roadmap","aria-label":"Create roadmap","data-testid":"create-roadmap-btn",children:e.jsx(ze,{size:16})})]}),U.type==="roadmap"&&e.jsx(mt,{onSave:We,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),e.jsx("div",{className:"roadmaps-view__sidebar-list",children:C.length===0?e.jsx("p",{className:"roadmaps-view__empty-sidebar",children:"No roadmaps yet. Click + to create one."}):C.map(t=>e.jsx(ta,{roadmap:t,isSelected:t.id===Se,onSelect:()=>L(t.id),onEdit:()=>_(t),onDelete:()=>se(t.id),onExport:()=>Ue(t.id,t.title)},t.id))})]}),e.jsxs("main",{className:"roadmaps-view__main","aria-label":"Roadmap content",children:[f&&Se&&e.jsx(sa,{roadmapTitle:y?.title||"Untitled Roadmap",onBack:()=>L(null),onEdit:()=>{y&&_(y)},onDelete:()=>se(Se),onCreate:()=>Be(!0)}),Se?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"roadmaps-view__roadmap-header",children:E.roadmapId===Se?e.jsx("div",{className:"roadmaps-view__inline-edit",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input roadmaps-view__inline-input--large",value:E.value,onChange:t=>ce(u=>({...u,value:t.target.value})),onKeyDown:t=>{t.key==="Enter"?ye({title:E.value}):t.key==="Escape"&&H()},placeholder:"Roadmap title",autoFocus:!0,"data-testid":"roadmap-title-input"}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ye({title:E.value}),"aria-label":"Save",title:"Save",children:e.jsx(me,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:H,"aria-label":"Cancel",title:"Cancel",children:e.jsx(re,{size:16})})]})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__roadmap-title-row",children:[e.jsx("h1",{className:"roadmaps-view__roadmap-title",children:y?.title||"Untitled Roadmap"}),e.jsxs("div",{className:"roadmaps-view__roadmap-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>{y&&_(y)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"edit-roadmap-btn",children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>se(Se),title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"delete-roadmap-btn",children:e.jsx(Pe,{size:16})})]})]}),y?.description&&e.jsx("p",{className:"roadmaps-view__roadmap-desc",children:y.description})]})}),f?Ve?e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"}),e.jsx("button",{className:"roadmap-suggestion-collapse-btn",onClick:()=>De(!1),"aria-label":"Collapse suggestion panel","data-testid":"collapse-suggestion-panel-btn",children:e.jsx(Yt,{size:16})})]}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input",autoFocus:!0}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}):e.jsx("div",{className:"roadmap-suggestion-section",children:e.jsxs("button",{className:"roadmap-suggestion-expand-btn",onClick:()=>De(!0),disabled:!w,"data-testid":"expand-suggestion-panel-btn",children:[e.jsx(ut,{size:16}),"Generate Milestone Ideas"]})}):e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsx("div",{className:"roadmap-suggestion-header",children:e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"})}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}),e.jsxs("div",{className:"roadmaps-view__milestone-lanes",children:[U.type==="milestone"&&e.jsx(ia,{onSave:vt,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),g.length===0&&U.type!=="milestone"?e.jsxs("div",{className:"roadmaps-view__empty-milestones",children:[e.jsx("p",{children:"This roadmap has no milestones."}),e.jsxs("button",{className:"roadmaps-view__add-milestone-btn",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn-empty",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]})]}):e.jsxs(e.Fragment,{children:[U.type!=="milestone"&&e.jsxs("button",{className:"roadmaps-view__add-milestone-fab",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]}),g.map(t=>e.jsx(ra,{milestone:t,features:k[t.id]||[],onEditMilestone:()=>pt(t),onDeleteMilestone:()=>bt(t.id),onAddFeature:()=>K({type:"feature",parentId:t.id,title:"",description:""}),onEditFeature:u=>{const b=k[t.id]?.find(z=>z.id===u);b&&rt(u,b.title,b.description)},onDeleteFeature:wt,milestoneEdit:Q,onMilestoneEditChange:gt,onMilestoneEditFieldChange:ht,onCancelMilestoneEdit:Ze,onSaveMilestoneEdit:ft,featureEdit:ae,onFeatureEditChange:xt,onStartFeatureEdit:rt,onCancelFeatureEdit:et,onSaveFeatureEdit:_t,projectId:l,addToast:n,isMilestoneDragging:Ce.draggingId===t.id,isMilestoneDropTarget:Ce.dropTargetId===t.id,milestoneDropPosition:Ce.dropTargetId===t.id?Ce.dropPosition:null,onMilestoneDragStart:Je,onMilestoneDragEnd:Ne,onMilestoneDragOver:Xe,onMilestoneDrop:h,onMilestoneDragLeave:m,isFeatureDragging:o,isFeatureDropTarget:ue.dropTargetMilestoneId===t.id,featureDropIndex:ue.dropTargetMilestoneId===t.id?ue.dropTargetIndex:null,onFeatureDragStart:Qe,onFeatureDragEnd:s,onFeatureDragOver:d,onFeatureDrop:r,onFeatureDragLeave:c,onFeatureDropOnMilestone:i,featureSuggestions:ve[t.id],isGeneratingFeatureSuggestions:oe(t.id),onGenerateFeatureSuggestions:()=>jt(t.id),onAcceptFeatureSuggestion:u=>Ct(t.id,u),onAcceptAllFeatureSuggestions:()=>yt(t.id),onUpdateFeatureSuggestionDraft:(u,b,z)=>Nt(u,b,z),onClearFeatureSuggestions:()=>St(t.id)},t.id))]})]})]}):e.jsx("div",{className:"roadmaps-view__empty-main",children:e.jsx("p",{children:"Select a roadmap from the sidebar to view its milestones."})})]}),U.type==="feature"&&U.parentId&&e.jsx("div",{className:"roadmaps-view__feature-create-overlay",children:e.jsx(oa,{onSave:t=>Et(U.parentId,t),onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})})}),e.jsx(ea,{isOpen:N,onClose:F,roadmapId:je||"",roadmapTitle:Le,handoffPayload:de,isLoading:we,error:R,onFetchHandoff:W,onCopyToClipboard:Ke})]})}export{ma as RoadmapsView};
|
|
6
|
+
*/const Xt=[["path",{d:"M12 2v4",key:"3427ic"}],["path",{d:"m16.2 7.8 2.9-2.9",key:"r700ao"}],["path",{d:"M18 12h4",key:"wj9ykh"}],["path",{d:"m16.2 16.2 2.9 2.9",key:"1bxg5t"}],["path",{d:"M12 18v4",key:"jadmvz"}],["path",{d:"m4.9 19.1 2.9-2.9",key:"bwix9q"}],["path",{d:"M2 12h4",key:"j09sii"}],["path",{d:"m4.9 4.9 2.9 2.9",key:"giyufr"}]],Qt=Dt("loader",Xt);function Zt(l){const n=l?.projectId,[v,f]=a.useState([]),[C,w]=a.useState(null),[y,g]=a.useState(null),[k,D]=a.useState([]),[j,S]=a.useState({}),[A,Y]=a.useState(!1),[L,$]=a.useState(null),[ne,pe]=a.useState(null),[Te,ge]=a.useState(!1),[he,Z]=a.useState(null),[fe,B]=a.useState([]),[O,G]=a.useState(!1),[be,P]=a.useState({}),[ie,ee]=a.useState({}),J=a.useRef(be),ve=a.useRef(ie),oe=a.useRef(fe);J.current=be,ve.current=ie,oe.current=fe;const xe=a.useRef(n),M=a.useRef(0),le=a.useRef(0),_e=a.useRef(v),x=a.useRef(C),de=a.useRef(k),we=a.useRef(j),R=a.useRef(n),Ae=a.useRef(ne);_e.current=v,x.current=C,de.current=k,we.current=j,R.current=n,Ae.current=ne,a.useEffect(()=>{xe.current!==n&&(xe.current=n,M.current++,w(null),g(null),D([]),S({}),pe(null),Z(null),B([]),G(!1),P({}),ee({}))},[n]);const X=a.useCallback(async()=>{Y(!0),$(null);try{const s=await Mt(n);f(s)}catch(s){$(s instanceof Error?s:new Error("Failed to fetch roadmaps"))}finally{Y(!1)}},[n]),N=a.useCallback(async s=>{try{const d=await Rt(s,n);g(d),D(d.milestones||[]);const i={};for(const r of d.milestones||[])i[r.id]=r.features||[];S(i)}catch(d){$(d instanceof Error?d:new Error("Failed to fetch roadmap"))}},[n]);a.useEffect(()=>{X()},[X]),a.useEffect(()=>{C?N(C):(g(null),D([]),S({}))},[C,N]);const Oe=a.useCallback(async(s,d)=>{try{const i=await It(s,R.current);f(r=>[...r,i]),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to create roadmap");throw d?.onError?.(r),r}},[]),je=a.useCallback(async(s,d,i)=>{try{const r=await $t(s,d,R.current);f(c=>c.map(o=>o.id===s?r:o)),x.current===s&&g(c=>c?{...c,...r}:null),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update roadmap");throw i?.onError?.(c),c}},[]),He=a.useCallback(async(s,d)=>{try{await zt(s,R.current),f(i=>i.filter(r=>r.id!==s)),x.current===s&&(w(null),g(null),D([]),S({})),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete roadmap");throw d?.onError?.(r),r}},[]),Le=a.useCallback(s=>{w(s)},[]),p=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const r=new Error("No roadmap selected");throw d?.onError?.(r),r}try{const r=await tt(i,s,R.current);D(c=>[...c,r]),S(c=>({...c,[r.id]:[]})),x.current&&N(x.current),d?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create milestone");throw d?.onError?.(c),c}},[N]),I=a.useCallback(async(s,d,i)=>{try{const r=await At(s,d,R.current);D(c=>c.map(o=>o.id===s?r:o)),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update milestone");throw i?.onError?.(c),c}},[N]),te=a.useCallback(async(s,d)=>{try{await Ot(s,R.current),D(i=>i.filter(r=>r.id!==s)),S(i=>{const r={...i};return delete r[s],r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete milestone");throw d?.onError?.(r),r}},[N]),Ve=a.useCallback(async(s,d,i)=>{try{const r=await at(s,d,R.current);S(c=>({...c,[s]:[...c[s]||[],r]})),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to create feature");throw i?.onError?.(c),c}},[N]),De=a.useCallback(async(s,d,i)=>{try{const r=await Ht(s,d,R.current);S(c=>{const o={};for(const[h,m]of Object.entries(c))o[h]=m.map(_=>_.id===s?r:_);return o}),x.current&&N(x.current),i?.onSuccess?.()}catch(r){const c=r instanceof Error?r:new Error("Failed to update feature");throw i?.onError?.(c),c}},[N]),Me=a.useCallback(async(s,d)=>{try{await Bt(s,R.current),S(i=>{const r={};for(const[c,o]of Object.entries(i))r[c]=o.filter(h=>h.id!==s);return r}),x.current&&N(x.current),d?.onSuccess?.()}catch(i){const r=i instanceof Error?i:new Error("Failed to delete feature");throw d?.onError?.(r),r}},[N]),E=a.useCallback(async(s,d,i)=>{const r=de.current,c=d.map(o=>r.find(h=>h.id===o)).filter(o=>o!==void 0).map((o,h)=>({...o,orderIndex:h}));D(c);try{await Gt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(o){D(r);const h=o instanceof Error?o:new Error("Failed to reorder milestones");throw i?.onError?.(h),h}},[N]),ce=a.useCallback(async(s,d,i)=>{const r=we.current[s]||[],c=r.map(m=>m.id);if(JSON.stringify(c)===JSON.stringify(d)){i?.onSuccess?.();return}const o=we.current,h=d.map(m=>r.find(_=>_.id===m)).filter(m=>m!==void 0).map((m,_)=>({...m,orderIndex:_}));S(m=>({...m,[s]:h}));try{await Pt(s,d,R.current),x.current&&N(x.current),i?.onSuccess?.()}catch(m){S(o);const _=m instanceof Error?m:new Error("Failed to reorder features");throw i?.onError?.(_),_}},[N]),Q=a.useCallback(async(s,d,i,r)=>{const c=we.current;let o=null;for(const[F,W]of Object.entries(c))if(W.some(Ke=>Ke.id===s)){o=F;break}if(!o){const F=new Error("Feature not found");throw r?.onError?.(F),F}if(o===d){const F=c[o]||[],W=Math.max(0,Math.min(i,F.length-1));if(F.findIndex(We=>We.id===s)===W){r?.onSuccess?.();return}}const h=c[o]||[],m=c[d]||[],_=h.find(F=>F.id===s);if(!_){const F=new Error("Feature not found");throw r?.onError?.(F),F}const H=h.filter(F=>F.id!==s).map((F,W)=>({...F,orderIndex:W})),ye={..._,milestoneId:d,orderIndex:i},se=[...m];se.splice(i,0,ye);const Ue=se.map((F,W)=>({...F,orderIndex:W}));S(o===d?F=>({...F,[o]:Ue}):F=>({...F,[o]:H,[d]:Ue}));try{await Tt(s,d,i,n),x.current&&N(x.current),r?.onSuccess?.()}catch(F){S(c);const W=F instanceof Error?F:new Error("Failed to move feature");throw r?.onError?.(W),W}},[N,n]);function V(){return typeof crypto<"u"&&typeof crypto.randomUUID=="function"?crypto.randomUUID():`draft-${Date.now()}-${Math.random().toString(36).slice(2,11)}`}const ae=a.useCallback(async(s,d=5,i)=>{const r=x.current;if(!r){const h=new Error("No roadmap selected");throw i?.onError?.(h),h}const c=M.current,o=R.current;G(!0);try{const h=await Lt(r,s,d,o);if(M.current!==c)return;const m=h.suggestions.map(_=>({id:V(),title:_.title,description:_.description}));B(m),i?.onSuccess?.()}catch(h){if(M.current!==c)return;const m=h instanceof Error?h:new Error("Failed to generate suggestions");throw i?.onError?.(m),m}finally{M.current===c&&G(!1)}},[]),Re=a.useCallback((s,d)=>{const r=oe.current.map(c=>c.id===s?{...c,...d}:c);oe.current=r,B(c=>c.map(o=>o.id===s?{...o,...d}:o))},[]),U=a.useCallback(async(s,d)=>{const i=x.current;if(!i){const m=new Error("No roadmap selected");throw d?.onError?.(m),m}const r=M.current,c=oe.current,o=c.findIndex(m=>m.id===s);if(o===-1){const m=new Error("Suggestion draft not found");throw d?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw d?.onError?.(m),m}B(m=>m.filter(_=>_.id!==s));try{if(await tt(i,{title:h.title,description:h.description},R.current),M.current!==r){B(m=>{const _=[...m];return _.splice(o,0,h),_});return}x.current&&N(x.current),d?.onSuccess?.()}catch(m){B(H=>{const ye=[...H];return ye.splice(o,0,h),ye});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw d?.onError?.(_),_}},[N]),K=a.useCallback(async s=>{const d=x.current;if(!d){const o=new Error("No roadmap selected");throw s?.onError?.(o),o}const i=[...oe.current];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw s?.onError?.(o),o}B([]);const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await tt(d,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw s?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),s?.onSuccess?.())},[N]),Ye=a.useCallback(s=>ve.current[s]??!1,[]),Be=a.useCallback(async(s,d,i)=>{const r=M.current,c=R.current;ee(o=>({...o,[s]:!0}));try{const o=await Vt(s,d,c);if(M.current!==r)return;const h=o.suggestions.map(m=>({id:V(),title:m.title,description:m.description}));P(m=>({...m,[s]:h})),i?.onSuccess?.()}catch(o){if(M.current!==r)return;const h=o instanceof Error?o:new Error("Failed to generate feature suggestions");throw i?.onError?.(h),h}finally{M.current===r&&ee(o=>({...o,[s]:!1}))}},[]),Ce=a.useCallback((s,d,i)=>{const c=(J.current[s]||[]).map(o=>o.id===d?{...o,...i}:o);J.current={...J.current,[s]:c},P(o=>({...o,[s]:o[s]?.map(h=>h.id===d?{...h,...i}:h)||[]}))},[]),Ge=a.useCallback(async(s,d,i)=>{const r=M.current,c=J.current[s]||[],o=c.findIndex(m=>m.id===d);if(o===-1){const m=new Error("Suggestion draft not found");throw i?.onError?.(m),m}const h=c[o];if(!h.title.trim()){const m=new Error("Title cannot be empty");throw i?.onError?.(m),m}P(m=>({...m,[s]:m[s]?.filter(_=>_.id!==d)||[]}));try{if(await at(s,{title:h.title,description:h.description},R.current),M.current!==r){P(m=>{const H=[...m[s]||[]];return H.splice(o,0,h),{...m,[s]:H}});return}x.current&&N(x.current),i?.onSuccess?.()}catch(m){P(H=>{const se=[...H[s]||[]];return se.splice(o,0,h),{...H,[s]:se}});const _=m instanceof Error?m:new Error("Failed to accept suggestion");throw i?.onError?.(_),_}},[N]),Je=a.useCallback(async(s,d)=>{const i=[...J.current[s]||[]];if(i.length===0)return;const r=i.findIndex(o=>!o.title.trim());if(r!==-1){const o=new Error(`Title cannot be empty at position ${r+1}`);throw d?.onError?.(o),o}P(o=>({...o,[s]:[]}));const c=M.current;for(let o=0;o<i.length&&M.current===c;o++){const h=i[o];try{await at(s,{title:h.title,description:h.description},R.current)}catch(m){const _=m instanceof Error?m:new Error("Failed to accept all suggestions");throw d?.onError?.(_),_}}M.current===c&&(x.current&&N(x.current),d?.onSuccess?.())},[N]),Ne=a.useCallback(()=>{B([]),G(!1)},[]),Xe=a.useCallback(s=>{P(d=>{const i={...d};return delete i[s],i}),ee(d=>{const i={...d};return delete i[s],i})},[]),ue=a.useCallback(async(s,d)=>{const i=++le.current,r=n;ge(!0),Z(null);try{const c=await Ut(s,r);if(le.current!==i||n!==r)return;pe(c),d?.onSuccess?.()}catch(c){if(le.current!==i||n!==r)return;const o=c instanceof Error?c:new Error(String(c));Z(o),pe(null),d?.onError?.(o)}finally{le.current===i&&ge(!1)}},[n]),Ie=a.useCallback(()=>{pe(null),Z(null),ge(!1)},[]),Qe=a.useCallback(async()=>{await X(),x.current&&await N(x.current)},[X,N]);return{roadmaps:v,selectedRoadmapId:C,selectedRoadmap:y,milestones:k,featuresByMilestoneId:j,loading:A,error:L,createRoadmap:Oe,updateRoadmap:je,deleteRoadmap:He,selectRoadmap:Le,createMilestone:p,updateMilestone:I,deleteMilestone:te,reorderMilestones:E,createFeature:Ve,updateFeature:De,deleteFeature:Me,reorderFeatures:ce,moveFeature:Q,milestoneSuggestions:fe,isGeneratingSuggestions:O,generateMilestoneSuggestions:ae,updateMilestoneSuggestionDraft:Re,acceptMilestoneSuggestion:U,acceptAllMilestoneSuggestions:K,clearMilestoneSuggestions:Ne,featureSuggestionsByMilestoneId:be,isGeneratingFeatureSuggestions:Ye,generateFeatureSuggestions:Be,updateFeatureSuggestionDraft:Ce,acceptFeatureSuggestion:Ge,acceptAllFeatureSuggestions:Je,clearFeatureSuggestions:Xe,handoffPayload:ne,isFetchingHandoff:Te,handoffError:he,fetchHandoff:ue,clearHandoff:Ie,refresh:Qe}}function ea({isOpen:l,onClose:n,roadmapTitle:v,handoffPayload:f,isLoading:C,error:w,onFetchHandoff:y,onCopyToClipboard:g}){return l?e.jsx("div",{className:"modal-overlay open",onClick:n,role:"presentation",children:e.jsxs("div",{className:"modal modal-lg",onClick:k=>k.stopPropagation(),role:"dialog","aria-modal":"true","aria-labelledby":"handoff-modal-title",children:[e.jsxs("div",{className:"modal-header",children:[e.jsxs("h2",{id:"handoff-modal-title",children:["Export Roadmap: ",v]}),e.jsx("button",{className:"modal-close",onClick:n,"aria-label":"Close modal",children:e.jsx(re,{size:18})})]}),e.jsxs("div",{className:"modal-body",children:[e.jsx("p",{className:"text-muted roadmaps-view__handoff-intro",children:"Export roadmap data for use in mission and task planning flows. This is a read-only export — no missions or tasks will be created."}),w&&e.jsxs("div",{className:"form-error roadmaps-view__handoff-error",children:["Error loading handoff data: ",w.message]}),!f&&!C&&e.jsx("div",{className:"roadmaps-view__handoff-empty-state",children:e.jsxs("button",{className:"btn btn-primary",onClick:y,children:[e.jsx(st,{size:16,className:"roadmaps-view__handoff-button-icon"}),"Load Handoff Data"]})}),C&&e.jsxs("div",{className:"roadmaps-view__handoff-loading-state",children:[e.jsx(Qt,{size:24,className:"spin"}),e.jsx("p",{className:"roadmaps-view__handoff-loading-text",children:"Loading handoff data..."})]}),f&&e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsx("h3",{className:"roadmaps-view__handoff-section-title",children:"Mission Planning Handoff"}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--mission",children:JSON.stringify(f.mission,null,2)})})]}),e.jsxs("div",{className:"roadmaps-view__handoff-section",children:[e.jsxs("h3",{className:"roadmaps-view__handoff-section-title",children:["Feature Task Planning Handoffs (",f.features.length,")"]}),e.jsx("div",{className:"card roadmaps-view__handoff-card",children:e.jsx("pre",{className:"roadmaps-view__handoff-pre roadmaps-view__handoff-pre--features",children:JSON.stringify(f.features,null,2)})})]})]})]}),e.jsxs("div",{className:"modal-actions",children:[e.jsx("div",{className:"modal-actions-left",children:f&&e.jsxs("button",{className:"btn btn-sm",onClick:g,children:[e.jsx(Jt,{size:14,className:"roadmaps-view__handoff-copy-icon"}),"Copy to Clipboard"]})}),e.jsx("div",{className:"modal-actions-right",children:e.jsx("button",{className:"btn",onClick:n,children:"Close"})})]})]})}):null}function ta({roadmap:l,isSelected:n,onSelect:v,onEdit:f,onDelete:C,onExport:w}){const y=j=>{j.key==="Enter"&&v()},g=j=>{j.stopPropagation(),f()},k=j=>{j.stopPropagation(),C()},D=j=>{j.stopPropagation(),w()};return e.jsxs("div",{className:`roadmaps-view__sidebar-item${n?" roadmaps-view__sidebar-item--active":""}`,onClick:v,onKeyDown:y,role:"button",tabIndex:0,"aria-selected":n,"data-testid":`roadmap-item-${l.id}`,children:[e.jsxs("div",{className:"roadmaps-view__sidebar-item-content",children:[e.jsx("div",{className:"roadmaps-view__sidebar-item-title",children:l.title}),l.description&&e.jsx("div",{className:"roadmaps-view__sidebar-item-desc",children:l.description})]}),e.jsxs("div",{className:"roadmaps-view__sidebar-item-actions",onClick:g,role:"presentation",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:D,title:"Export roadmap","aria-label":"Export roadmap","data-testid":`roadmap-export-${l.id}`,type:"button",children:e.jsx(st,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:g,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`roadmap-edit-${l.id}`,type:"button",children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:k,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`roadmap-delete-${l.id}`,type:"button",children:e.jsx(Pe,{size:14})})]})]})}function aa({roadmaps:l,selectedRoadmapId:n,onSelect:v,onCreate:f,onEdit:C,onDelete:w,onExport:y,showCreateForm:g,onCancelCreate:k,onSaveCreate:D}){return e.jsxs("div",{className:"roadmaps-view__mobile-list","data-testid":"roadmaps-view__mobile-list",children:[e.jsxs("div",{className:"roadmaps-view__mobile-list-header",children:[e.jsx("h2",{className:"roadmaps-view__mobile-list-title",children:"Roadmaps"}),!g&&e.jsx("button",{className:"roadmaps-view__mobile-add-btn",onClick:f,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-create-roadmap-btn",children:e.jsx(ze,{size:18})})]}),g&&e.jsx("div",{className:"roadmaps-view__mobile-create-form",children:e.jsx(mt,{onSave:D,onCancel:k})}),l.length===0&&!g?e.jsxs("div",{className:"roadmaps-view__mobile-empty",children:[e.jsx("p",{children:"No roadmaps yet."}),e.jsxs("button",{className:"btn btn-primary btn-sm",onClick:f,children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Create Roadmap"})]})]}):e.jsx("div",{className:"roadmaps-view__mobile-list-items",children:l.map(j=>e.jsxs("div",{className:`roadmaps-view__mobile-item${j.id===n?" roadmaps-view__mobile-item--active":""}`,onClick:()=>v(j.id),role:"button",tabIndex:0,onKeyDown:S=>{S.key==="Enter"&&v(j.id)},"data-testid":`mobile-roadmap-item-${j.id}`,children:[e.jsxs("div",{className:"roadmaps-view__mobile-item-content",children:[e.jsx("span",{className:"roadmaps-view__mobile-item-title",children:j.title}),j.description&&e.jsx("span",{className:"roadmaps-view__mobile-item-desc",children:j.description})]}),e.jsxs("div",{className:"roadmaps-view__mobile-item-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),y(j)},title:"Export roadmap","aria-label":"Export roadmap","data-testid":`mobile-roadmap-export-${j.id}`,children:e.jsx(st,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:S=>{S.stopPropagation(),C(j)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":`mobile-roadmap-edit-${j.id}`,children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:S=>{S.stopPropagation(),w(j.id)},title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":`mobile-roadmap-delete-${j.id}`,children:e.jsx(Pe,{size:16})})]})]},j.id))})]})}function sa({roadmapTitle:l,onBack:n,onEdit:v,onDelete:f,onCreate:C}){return e.jsxs("div",{className:"roadmaps-view__mobile-header","data-testid":"roadmaps-view__mobile-header",children:[e.jsx("button",{className:"roadmaps-view__mobile-back-btn",onClick:n,title:"Back to roadmap list","aria-label":"Back to roadmap list","data-testid":"mobile-back-btn",children:e.jsx(Yt,{size:20})}),e.jsx("h2",{className:"roadmaps-view__mobile-header-title",children:l}),e.jsxs("div",{className:"roadmaps-view__mobile-header-actions",children:[e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:C,title:"Create roadmap","aria-label":"Create roadmap","data-testid":"mobile-header-create-btn",children:e.jsx(ze,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn",onClick:v,title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"mobile-header-edit-btn",children:e.jsx(Fe,{size:18})}),e.jsx("button",{className:"roadmaps-view__mobile-action-btn roadmaps-view__mobile-action-btn--danger",onClick:f,title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"mobile-header-delete-btn",children:e.jsx(Pe,{size:18})})]})]})}function ra({milestone:l,features:n,onEditMilestone:v,onDeleteMilestone:f,onAddFeature:C,onEditFeature:w,onDeleteFeature:y,milestoneEdit:g,onMilestoneEditChange:k,onMilestoneEditFieldChange:D,onCancelMilestoneEdit:j,onSaveMilestoneEdit:S,featureEdit:A,onFeatureEditChange:Y,onStartFeatureEdit:L,onCancelFeatureEdit:$,onSaveFeatureEdit:ne,projectId:pe,addToast:Te,isMilestoneDragging:ge,isMilestoneDropTarget:he,milestoneDropPosition:Z,onMilestoneDragStart:fe,onMilestoneDragEnd:B,onMilestoneDragOver:O,onMilestoneDrop:G,onMilestoneDragLeave:be,isFeatureDragging:P,isFeatureDropTarget:ie,featureDropIndex:ee,onFeatureDragStart:J,onFeatureDragEnd:ve,onFeatureDragOver:oe,onFeatureDrop:xe,onFeatureDragLeave:M,onFeatureDropOnMilestone:le,featureSuggestions:_e,isGeneratingFeatureSuggestions:x,onGenerateFeatureSuggestions:de,onAcceptFeatureSuggestion:we,onAcceptAllFeatureSuggestions:R,onUpdateFeatureSuggestionDraft:Ae,onClearFeatureSuggestions:X}){const N=g?.milestoneId===l.id,Oe=p=>{p.key==="Enter"?(p.preventDefault(),g&&S({title:g.value})):p.key==="Escape"&&j()},je=p=>{p.key==="Escape"&&j()},He=["roadmaps-view__milestone",ge?"roadmaps-view__milestone--dragging":"",he?"roadmaps-view__milestone--drop-target":"",he&&Z==="before"?"roadmaps-view__milestone--drop-before":"",he&&Z==="after"?"roadmaps-view__milestone--drop-after":""].filter(Boolean).join(" "),Le=["roadmaps-view__feature-list",ie?"roadmaps-view__feature-list--drop-target":""].filter(Boolean).join(" ");return e.jsxs("div",{className:He,draggable:!N,onDragStart:p=>{N||(fe(l.id),p.dataTransfer.setData("text/plain",`milestone:${l.id}`),p.dataTransfer.effectAllowed="move")},onDragEnd:B,onDragOver:p=>{p.dataTransfer.types.includes("text/plain")&&p.dataTransfer.types.includes("text/plain")&&(p.preventDefault(),p.dataTransfer.dropEffect="move",O(l.id))},onDrop:p=>{p.preventDefault(),p.dataTransfer.getData("text/plain")?.startsWith("feature:")||G(l.id)},onDragLeave:be,"data-testid":`milestone-card-${l.id}`,children:[e.jsx("div",{className:"roadmaps-view__milestone-header",children:N?e.jsxs("div",{className:"roadmaps-view__inline-edit",children:[e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(qe,{size:14})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:g.value,onChange:p=>{D("title"),k(p.target.value)},onKeyDown:Oe,placeholder:"Milestone title",autoFocus:!0,"data-testid":`milestone-title-input-${l.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>S({title:g.value}),"aria-label":"Save milestone title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:j,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:g.field==="description"?g.value:l.description||"",onChange:p=>{D("description"),k(p.target.value)},onKeyDown:je,placeholder:"Milestone description (optional)",rows:2,"data-testid":`milestone-desc-input-${l.id}`})]}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__milestone-title-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`milestone-drag-handle-${l.id}`,children:e.jsx(qe,{size:14})}),e.jsx("h3",{className:"roadmaps-view__milestone-title",children:l.title}),e.jsxs("div",{className:"roadmaps-view__milestone-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:v,title:"Edit milestone","aria-label":"Edit milestone","data-testid":`milestone-edit-${l.id}`,children:e.jsx(Fe,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:f,title:"Delete milestone","aria-label":"Delete milestone","data-testid":`milestone-delete-${l.id}`,children:e.jsx(Pe,{size:14})})]})]}),l.description&&e.jsx("p",{className:"roadmaps-view__milestone-desc",children:l.description})]})}),e.jsxs("div",{className:"roadmaps-view__milestone-actions-bar",children:[e.jsxs("button",{className:"roadmaps-view__add-feature-btn",onClick:C,title:"Add feature","aria-label":"Add feature","data-testid":`add-feature-${l.id}`,children:[e.jsx(ze,{size:12}),e.jsx("span",{children:"Add Feature"})]}),e.jsxs("button",{className:"roadmaps-view__suggest-btn",onClick:()=>{de?.()},disabled:x??!1,title:"Generate feature suggestions with AI","aria-label":"Generate feature suggestions","data-testid":`generate-features-${l.id}`,children:[e.jsx(ut,{size:12}),e.jsx("span",{children:x?"Generating...":"AI Suggestions"})]})]}),e.jsxs("div",{className:Le,onDragOver:p=>{p.preventDefault(),p.dataTransfer.dropEffect="move",p.dataTransfer.getData("text/plain")?.startsWith("feature:")&&le()},onDrop:p=>{p.preventDefault();const I=p.dataTransfer.getData("text/plain");I?.startsWith("feature:")&&xe(I.split(":")[1],n.length)},onDragLeave:M,children:[n.length===0?e.jsx("p",{className:"roadmaps-view__empty-features",children:"No features yet."}):n.map((p,I)=>{const te=A?.featureId===p.id,Ve=P(p.id),De=E=>{E.key==="Enter"?(E.preventDefault(),A&&ne({title:A.value})):E.key==="Escape"&&$()},Me=["roadmaps-view__feature-item",Ve?"roadmaps-view__feature-item--dragging":"",ie&&ee===I?"roadmaps-view__feature-item--drop-before":"",ie&&ee===I+1?"roadmaps-view__feature-item--drop-after":""].filter(Boolean).join(" ");return e.jsx("div",{className:Me,draggable:!te,onDragStart:E=>{te||(J(p.id,l.id),E.dataTransfer.setData("text/plain",`feature:${p.id}`),E.dataTransfer.effectAllowed="move")},onDragEnd:ve,onDragOver:E=>{if(E.preventDefault(),E.stopPropagation(),E.dataTransfer.dropEffect="move",E.dataTransfer.getData("text/plain")?.startsWith("feature:")){const Q=E.currentTarget.getBoundingClientRect(),V=Q.top+Q.height/2,ae=E.clientY<V?"before":"after";oe(p.id,ae)}},onDrop:E=>{E.preventDefault(),E.stopPropagation();const ce=E.dataTransfer.getData("text/plain");if(ce?.startsWith("feature:")){const Q=ce.split(":")[1],V=E.currentTarget.getBoundingClientRect(),ae=V.top+V.height/2,Re=E.clientY<ae?"before":"after";let U=I;Re==="after"&&(U=I+1),xe(Q,U)}},onDragLeave:M,"data-testid":`feature-item-${p.id}`,children:te?e.jsx("div",{className:"roadmaps-view__inline-edit roadmaps-view__inline-edit--compact",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(qe,{size:12})}),e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:A.value,onChange:E=>Y(E.target.value),onKeyDown:De,placeholder:"Feature title",autoFocus:!0,"data-testid":`feature-title-input-${p.id}`}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ne({title:A.value}),"aria-label":"Save feature title",title:"Save",children:e.jsx(me,{size:14})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:$,"aria-label":"Cancel editing",title:"Cancel",children:e.jsx(re,{size:14})})]})}):e.jsxs(e.Fragment,{children:[e.jsx("span",{className:"roadmaps-view__drag-handle roadmaps-view__drag-handle--feature",title:"Drag to reorder","aria-label":"Drag to reorder","data-testid":`feature-drag-handle-${p.id}`,children:e.jsx(qe,{size:12})}),e.jsxs("div",{className:"roadmaps-view__feature-content",children:[e.jsx("span",{className:"roadmaps-view__feature-title",children:p.title}),p.description&&e.jsx("p",{className:"roadmaps-view__feature-desc",children:p.description})]}),e.jsxs("div",{className:"roadmaps-view__feature-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>w(p.id),title:"Edit feature","aria-label":"Edit feature","data-testid":`feature-edit-${p.id}`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>y(p.id),title:"Delete feature","aria-label":"Delete feature","data-testid":`feature-delete-${p.id}`,children:e.jsx(Pe,{size:12})})]})]})},p.id)}),_e&&_e.length>0&&e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h4",{className:"roadmap-suggestion-title",children:"AI Feature Suggestions"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-accept-all-btn",onClick:()=>R?.(),title:"Accept all suggestions","aria-label":"Accept all","data-testid":`accept-all-features-${l.id}`,children:"Accept All"}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:()=>X?.(),title:"Clear suggestions","aria-label":"Clear","data-testid":`clear-features-${l.id}`,children:"Clear"})]})]}),e.jsx("div",{className:"roadmap-suggestion-list",children:_e.map(p=>e.jsx(na,{suggestion:p,onUpdateDraft:I=>Ae?.(l.id,p.id,I),onAccept:()=>{we?.(l.id,p.id)},testIdPrefix:`feature-suggestion-${l.id}`},p.id))})]})]})]})}function na({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},Y=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:Y,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function ct({suggestion:l,onUpdateDraft:n,onAccept:v,testIdPrefix:f}){const[C,w]=a.useState(!1),[y,g]=a.useState(l.title),[k,D]=a.useState(l.description||""),j=()=>{g(l.title),D(l.description||""),w(!0)},S=()=>{n({title:y.trim(),description:k.trim()||void 0}),w(!1)},A=()=>{g(l.title),D(l.description||""),w(!1)},Y=()=>{l.title.trim()&&v()},L=l.title.trim().length>0;return C?e.jsx("div",{className:"roadmap-suggestion-card roadmap-suggestion-card--editing",children:e.jsxs("div",{className:"roadmap-suggestion-edit-form",children:[e.jsx("input",{type:"text",className:"roadmap-suggestion-input",value:y,onChange:$=>g($.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":`${f}-${l.id}-title-input`}),e.jsx("textarea",{className:"roadmap-suggestion-textarea",value:k,onChange:$=>D($.target.value),placeholder:"Description (optional)",rows:2,"data-testid":`${f}-${l.id}-desc-input`}),e.jsxs("div",{className:"roadmap-suggestion-edit-actions",children:[e.jsx("button",{className:"roadmap-suggestion-save-btn",onClick:S,disabled:!y.trim(),title:"Save","data-testid":`${f}-${l.id}-save`,children:e.jsx(me,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-cancel-btn",onClick:A,title:"Cancel","data-testid":`${f}-${l.id}-cancel`,children:e.jsx(re,{size:12})})]})]})}):e.jsxs("div",{className:"roadmap-suggestion-card","data-testid":`${f}-${l.id}`,children:[e.jsxs("div",{className:"roadmap-suggestion-content",children:[e.jsx("span",{className:"roadmap-suggestion-card-title",children:l.title}),l.description&&e.jsx("p",{className:"roadmap-suggestion-card-desc",children:l.description})]}),e.jsxs("div",{className:"roadmap-suggestion-card-actions",children:[e.jsx("button",{className:"roadmap-suggestion-edit-btn",onClick:j,title:"Edit suggestion","aria-label":"Edit","data-testid":`${f}-${l.id}-edit`,children:e.jsx(Fe,{size:12})}),e.jsx("button",{className:"roadmap-suggestion-accept-btn",onClick:Y,disabled:!L,title:"Accept this suggestion","aria-label":"Accept","data-testid":`${f}-${l.id}-accept`,children:e.jsx(me,{size:12})})]})]})}function mt({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form","data-testid":"create-roadmap-form",children:e.jsxs("form",{onSubmit:y,children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Roadmap title",autoFocus:!0,"data-testid":"create-roadmap-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Roadmap description (optional)",rows:2,"data-testid":"create-roadmap-description"}),e.jsxs("div",{className:"roadmaps-view__create-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__btn roadmaps-view__btn--primary",disabled:!v.trim(),"data-testid":"create-roadmap-submit",children:"Create"}),e.jsx("button",{type:"button",className:"roadmaps-view__btn",onClick:n,"data-testid":"create-roadmap-cancel",children:"Cancel"})]})]})})}function ia({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-milestone-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Milestone title",autoFocus:!0,"data-testid":"create-milestone-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-milestone-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save milestone",title:"Save","data-testid":"create-milestone-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-milestone-cancel",children:e.jsx(re,{size:14})})]})]})})}function oa({onSave:l,onCancel:n}){const[v,f]=a.useState(""),[C,w]=a.useState(""),y=g=>{g.preventDefault(),v.trim()&&l({title:v.trim(),description:C.trim()||void 0})};return e.jsx("div",{className:"roadmaps-view__create-form roadmaps-view__create-form--inline","data-testid":"create-feature-form",children:e.jsxs("form",{onSubmit:y,className:"roadmaps-view__inline-form",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input",value:v,onChange:g=>f(g.target.value),placeholder:"Feature title",autoFocus:!0,"data-testid":"create-feature-title"}),e.jsx("textarea",{className:"roadmaps-view__inline-textarea",value:C,onChange:g=>w(g.target.value),placeholder:"Description (optional)",rows:1,"data-testid":"create-feature-description"}),e.jsxs("div",{className:"roadmaps-view__inline-form-actions",children:[e.jsx("button",{type:"submit",className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",disabled:!v.trim(),"aria-label":"Save feature",title:"Save","data-testid":"create-feature-submit",children:e.jsx(me,{size:14})}),e.jsx("button",{type:"button",className:"roadmaps-view__icon-btn",onClick:n,"aria-label":"Cancel",title:"Cancel","data-testid":"create-feature-cancel",children:e.jsx(re,{size:14})})]})]})})}function ma({projectId:l,addToast:n}){const{confirm:v}=Kt(),f=Wt()==="mobile",{roadmaps:C,selectedRoadmapId:w,selectedRoadmap:y,milestones:g,featuresByMilestoneId:k,loading:D,error:j,createRoadmap:S,updateRoadmap:A,deleteRoadmap:Y,selectRoadmap:L,createMilestone:$,updateMilestone:ne,deleteMilestone:pe,createFeature:Te,updateFeature:ge,deleteFeature:he,reorderMilestones:Z,reorderFeatures:fe,moveFeature:B,milestoneSuggestions:O,isGeneratingSuggestions:G,generateMilestoneSuggestions:be,updateMilestoneSuggestionDraft:P,acceptMilestoneSuggestion:ie,acceptAllMilestoneSuggestions:ee,clearMilestoneSuggestions:J,featureSuggestionsByMilestoneId:ve,isGeneratingFeatureSuggestions:oe,generateFeatureSuggestions:xe,updateFeatureSuggestionDraft:M,acceptFeatureSuggestion:le,acceptAllFeatureSuggestions:_e,clearFeatureSuggestions:x,handoffPayload:de,isFetchingHandoff:we,handoffError:R,fetchHandoff:Ae,clearHandoff:X}=Zt({projectId:l}),[N,Oe]=a.useState(!1),[je,He]=a.useState(null),[Le,p]=a.useState(""),[I,te]=a.useState(""),[Ve,De]=a.useState(!1),Me=a.useRef(null);a.useEffect(()=>{Me.current!==null&&Me.current!==w&&De(!1),Me.current=w},[w]);const[E,ce]=a.useState({roadmapId:null,field:null,value:""}),[Q,V]=a.useState({milestoneId:null,field:null,value:""}),[ae,Re]=a.useState({featureId:null,field:null,value:""}),[U,K]=a.useState({type:null,parentId:void 0,title:"",description:""}),[Ye,Be]=a.useState(!1),[Ce,Ge]=a.useState({draggingId:null,dropTargetId:null,dropPosition:null}),Je=a.useCallback(t=>{Ge(u=>({...u,draggingId:t}))},[]),Ne=a.useCallback(()=>{Ge({draggingId:null,dropTargetId:null,dropPosition:null})},[]),Xe=a.useCallback(t=>{Ge(u=>u.draggingId===t?u:{...u,dropTargetId:t,dropPosition:null})},[]),[ue,Ie]=a.useState({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}),Qe=a.useCallback((t,u)=>{Ie(b=>({...b,draggingId:t,draggingMilestoneId:u}))},[]),s=a.useCallback(()=>{Ie({draggingId:null,draggingMilestoneId:null,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null})},[]),d=a.useCallback((t,u)=>{Ie(b=>{if(b.draggingId===t)return b;const T=(k[b.draggingMilestoneId||""]||[]).findIndex(Ee=>Ee.id===t);let q;return u==="before"?q=T:q=T+1,{...b,dropTargetMilestoneId:b.draggingMilestoneId,dropTargetIndex:q,dropPosition:u}})},[k]),i=a.useCallback(()=>{Ie(t=>({...t,dropTargetMilestoneId:t.draggingMilestoneId,dropTargetIndex:(k[t.draggingMilestoneId||""]||[]).length}))},[k]),r=a.useCallback(async(t,u)=>{const{draggingMilestoneId:b,dropTargetMilestoneId:z}=ue;if(!b){s();return}const T=z||b,q=k[b]||[],Ee=q.find(ke=>ke.id===t);if(!Ee){s();return}if(b!==T){if(b===T){s();return}try{await B(t,T,u,{onError:ke=>{n(`Failed to move feature: ${ke.message}`,"error")}})}catch{}}else{const ke=[...q],kt=ke.findIndex($e=>$e.id===t);ke.splice(kt,1),ke.splice(u,0,Ee);const dt=ke.map($e=>$e.id),Ft=q.map($e=>$e.id);if(dt.join(",")===Ft.join(",")){s();return}try{await fe(b,dt,{onError:$e=>{n(`Failed to reorder features: ${$e.message}`,"error")}})}catch{}}s()},[ue,k,fe,B,n,s]),c=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ie(T=>({...T,dropTargetMilestoneId:null,dropTargetIndex:null,dropPosition:null}))},[]),o=a.useCallback(t=>ue.draggingId===t,[ue.draggingId]),h=a.useCallback(async t=>{const{draggingId:u}=Ce;if(!u||u===t){Ne();return}const b=g.map(Ee=>Ee.id),z=b.indexOf(u),T=b.indexOf(t);if(z===-1||T===-1){Ne();return}const q=[...b];if(q.splice(z,1),q.splice(T,0,u),q.join(",")===b.join(",")){Ne();return}try{await Z(w,q,{onError:Ee=>{n(`Failed to reorder milestones: ${Ee.message}`,"error")}})}catch{}Ne()},[Ce,g,w,Z,n,Ne]),m=a.useCallback(t=>{const u=t.currentTarget.getBoundingClientRect(),b=t.clientX,z=t.clientY;(b<u.left||b>u.right||z<u.top||z>u.bottom)&&Ge(T=>({...T,dropTargetId:null,dropPosition:null}))},[]),_=a.useCallback(t=>{L(t.id),ce({roadmapId:t.id,field:"title",value:t.title})},[L]),H=a.useCallback(()=>{ce({roadmapId:null,field:null,value:""})},[]),ye=a.useCallback(async t=>{if(E.roadmapId)try{await A(E.roadmapId,t,{onError:u=>n(u.message,"error")}),H()}catch{}},[E.roadmapId,A,H,n]),se=a.useCallback(async t=>{if(await v({title:"Delete Roadmap",message:"Delete this roadmap? This cannot be undone.",danger:!0}))try{await Y(t,{onError:b=>n(b.message,"error")}),n("Roadmap deleted","success")}catch{}},[Y,n,v]),Ue=a.useCallback((t,u)=>{He(t),p(u),Oe(!0),X()},[X]),F=a.useCallback(()=>{Oe(!1),He(null),p(""),X()},[X]),W=a.useCallback(()=>{je&&Ae(je,{onError:t=>n(`Failed to load handoff: ${t.message}`,"error")})},[je,Ae,n]),Ke=a.useCallback(()=>{if(de){const t=JSON.stringify(de,null,2);navigator.clipboard.writeText(t).then(()=>{n("Handoff data copied to clipboard","success")}).catch(()=>{n("Failed to copy to clipboard","error")})}},[de,n]),We=a.useCallback(async t=>{try{await S(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Roadmap created","success")}catch{}},[S,n]),pt=a.useCallback(t=>{V({milestoneId:t.id,field:"title",value:t.title})},[]),gt=a.useCallback(t=>{V(u=>({...u,value:t}))},[]),ht=a.useCallback(t=>{V(u=>({...u,field:t}))},[]),Ze=a.useCallback(()=>{V({milestoneId:null,field:null,value:""})},[]),ft=a.useCallback(async t=>{if(Q.milestoneId)try{await ne(Q.milestoneId,t,{onError:u=>n(u.message,"error")}),Ze()}catch{}},[Q.milestoneId,ne,Ze,n]),bt=a.useCallback(async t=>{if(await v({title:"Delete Milestone",message:"Delete this milestone and all its features?",danger:!0}))try{await pe(t,{onError:b=>n(b.message,"error")}),n("Milestone deleted","success")}catch{}},[pe,n,v]),vt=a.useCallback(async t=>{try{await $(t,{onError:u=>n(u.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Milestone created","success")}catch{}},[$,n]),rt=a.useCallback((t,u,b)=>{Re({featureId:t,field:"title",value:u})},[]),xt=a.useCallback(t=>{Re(u=>({...u,value:t}))},[]),et=a.useCallback(()=>{Re({featureId:null,field:null,value:""})},[]),_t=a.useCallback(async t=>{if(ae.featureId)try{await ge(ae.featureId,t,{onError:u=>n(u.message,"error")}),et()}catch{}},[ae.featureId,ge,et,n]),wt=a.useCallback(async t=>{if(await v({title:"Delete Feature",message:"Delete this feature?",danger:!0}))try{await he(t,{onError:b=>n(b.message,"error")}),n("Feature deleted","success")}catch{}},[he,n,v]),nt=a.useCallback(async()=>{if(I.trim())try{await be(I,5,{onError:t=>n(t.message,"error")})}catch{}},[I,be,n]),it=a.useCallback(async t=>{try{await ie(t,{onError:u=>n(u.message,"error")}),n("Milestone added","success")}catch{}},[ie,n]),ot=a.useCallback(async()=>{try{await ee({onError:t=>n(t.message,"error")}),n(`${O.length} milestones added`,"success"),te("")}catch{}},[ee,O.length,n]),lt=a.useCallback(()=>{J(),te("")},[J]),jt=a.useCallback(async t=>{try{await xe(t,{count:5},{onError:u=>n(u.message,"error")})}catch{}},[xe,n]),Ct=a.useCallback(async(t,u)=>{try{await le(t,u,{onError:b=>n(b.message,"error")}),n("Feature added","success")}catch{}},[le,n]),Nt=a.useCallback((t,u,b)=>{M(t,u,b)},[M]),yt=a.useCallback(async t=>{const u=ve[t]||[];try{await _e(t,{onError:b=>n(b.message,"error")}),n(`${u.length} features added`,"success")}catch{}},[_e,ve,n]),St=a.useCallback(t=>{x(t)},[x]),Et=a.useCallback(async(t,u)=>{try{await Te(t,u,{onError:b=>n(b.message,"error")}),K({type:null,parentId:void 0,title:"",description:""}),n("Feature created","success")}catch{}},[Te,n]),Se=w;return D&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--loading",children:e.jsx("div",{className:"roadmaps-view__loading-state",children:"Loading roadmaps..."})}):j&&C.length===0?e.jsx("div",{className:"roadmaps-view roadmaps-view--error",children:e.jsxs("div",{className:"roadmaps-view__error-state",children:[e.jsx("p",{children:"Failed to load roadmaps"}),e.jsx("p",{className:"roadmaps-view__error-msg",children:j.message})]})}):e.jsxs("div",{className:"roadmaps-view",children:[f&&!Se&&e.jsx(aa,{roadmaps:C,selectedRoadmapId:Se,onSelect:t=>L(t),onCreate:()=>Be(!0),onEdit:_,onDelete:se,onExport:t=>Ue(t.id,t.title),showCreateForm:Ye,onCancelCreate:()=>Be(!1),onSaveCreate:async t=>{await We(t),Be(!1)}}),!f&&e.jsxs("aside",{className:"roadmaps-view__sidebar","aria-label":"Roadmaps",children:[e.jsxs("div",{className:"roadmaps-view__sidebar-header",children:[e.jsx("h2",{className:"roadmaps-view__sidebar-title",children:"Roadmaps"}),e.jsx("button",{className:"roadmaps-view__add-btn",onClick:()=>K({type:"roadmap",title:"",description:""}),title:"Create roadmap","aria-label":"Create roadmap","data-testid":"create-roadmap-btn",children:e.jsx(ze,{size:16})})]}),U.type==="roadmap"&&e.jsx(mt,{onSave:We,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),e.jsx("div",{className:"roadmaps-view__sidebar-list",children:C.length===0?e.jsx("p",{className:"roadmaps-view__empty-sidebar",children:"No roadmaps yet. Click + to create one."}):C.map(t=>e.jsx(ta,{roadmap:t,isSelected:t.id===Se,onSelect:()=>L(t.id),onEdit:()=>_(t),onDelete:()=>se(t.id),onExport:()=>Ue(t.id,t.title)},t.id))})]}),e.jsxs("main",{className:"roadmaps-view__main","aria-label":"Roadmap content",children:[f&&Se&&e.jsx(sa,{roadmapTitle:y?.title||"Untitled Roadmap",onBack:()=>L(null),onEdit:()=>{y&&_(y)},onDelete:()=>se(Se),onCreate:()=>Be(!0)}),Se?e.jsxs(e.Fragment,{children:[e.jsx("div",{className:"roadmaps-view__roadmap-header",children:E.roadmapId===Se?e.jsx("div",{className:"roadmaps-view__inline-edit",children:e.jsxs("div",{className:"roadmaps-view__inline-edit-row",children:[e.jsx("input",{type:"text",className:"roadmaps-view__inline-input roadmaps-view__inline-input--large",value:E.value,onChange:t=>ce(u=>({...u,value:t.target.value})),onKeyDown:t=>{t.key==="Enter"?ye({title:E.value}):t.key==="Escape"&&H()},placeholder:"Roadmap title",autoFocus:!0,"data-testid":"roadmap-title-input"}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--success",onClick:()=>ye({title:E.value}),"aria-label":"Save",title:"Save",children:e.jsx(me,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:H,"aria-label":"Cancel",title:"Cancel",children:e.jsx(re,{size:16})})]})}):e.jsxs(e.Fragment,{children:[e.jsxs("div",{className:"roadmaps-view__roadmap-title-row",children:[e.jsx("h1",{className:"roadmaps-view__roadmap-title",children:y?.title||"Untitled Roadmap"}),e.jsxs("div",{className:"roadmaps-view__roadmap-actions",children:[e.jsx("button",{className:"roadmaps-view__icon-btn",onClick:()=>{y&&_(y)},title:"Edit roadmap","aria-label":"Edit roadmap","data-testid":"edit-roadmap-btn",children:e.jsx(Fe,{size:16})}),e.jsx("button",{className:"roadmaps-view__icon-btn roadmaps-view__icon-btn--danger",onClick:()=>se(Se),title:"Delete roadmap","aria-label":"Delete roadmap","data-testid":"delete-roadmap-btn",children:e.jsx(Pe,{size:16})})]})]}),y?.description&&e.jsx("p",{className:"roadmaps-view__roadmap-desc",children:y.description})]})}),f?Ve?e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsxs("div",{className:"roadmap-suggestion-header",children:[e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"}),e.jsx("button",{className:"roadmap-suggestion-collapse-btn",onClick:()=>De(!1),"aria-label":"Collapse suggestion panel","data-testid":"collapse-suggestion-panel-btn",children:e.jsx(qt,{size:16})})]}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input",autoFocus:!0}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}):e.jsx("div",{className:"roadmap-suggestion-section",children:e.jsxs("button",{className:"roadmap-suggestion-expand-btn",onClick:()=>De(!0),disabled:!w,"data-testid":"expand-suggestion-panel-btn",children:[e.jsx(ut,{size:16}),"Generate Milestone Ideas"]})}):e.jsxs("div",{className:"roadmap-suggestion-section",children:[e.jsx("div",{className:"roadmap-suggestion-header",children:e.jsx("h3",{className:"roadmap-suggestion-title",children:"Generate Milestone Ideas"})}),e.jsxs("div",{className:"roadmap-suggestion-form",children:[e.jsx("textarea",{className:"roadmap-suggestion-input",value:I,onChange:t=>te(t.target.value),placeholder:"Describe your roadmap goal (e.g., 'Build a user authentication system with OAuth, profiles, and admin dashboard')",rows:2,disabled:G||!w,"data-testid":"goal-prompt-input"}),e.jsxs("div",{className:"roadmap-suggestion-actions",children:[e.jsx("button",{className:"roadmap-suggestion-generate-btn",onClick:nt,disabled:!I.trim()||G||!w,"data-testid":"generate-suggestions-btn",children:G?"Generating...":"Generate Milestones"}),O.length>0&&e.jsxs(e.Fragment,{children:[e.jsxs("button",{className:"roadmap-suggestion-accept-all-btn",onClick:ot,"data-testid":"accept-all-suggestions-btn",children:["Accept All (",O.length,")"]}),e.jsx("button",{className:"roadmap-suggestion-clear-btn",onClick:lt,title:"Clear suggestions","aria-label":"Clear suggestions","data-testid":"clear-suggestions-btn",children:e.jsx(re,{size:14})})]})]})]}),O.length>0&&e.jsx("div",{className:"roadmap-suggestion-list",children:O.map(t=>e.jsx(ct,{suggestion:t,onUpdateDraft:u=>P(t.id,u),onAccept:()=>it(t.id),testIdPrefix:"suggestion"},t.id))})]}),e.jsxs("div",{className:"roadmaps-view__milestone-lanes",children:[U.type==="milestone"&&e.jsx(ia,{onSave:vt,onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})}),g.length===0&&U.type!=="milestone"?e.jsxs("div",{className:"roadmaps-view__empty-milestones",children:[e.jsx("p",{children:"This roadmap has no milestones."}),e.jsxs("button",{className:"roadmaps-view__add-milestone-btn",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn-empty",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]})]}):e.jsxs(e.Fragment,{children:[U.type!=="milestone"&&e.jsxs("button",{className:"roadmaps-view__add-milestone-fab",onClick:()=>K({type:"milestone",title:"",description:""}),"data-testid":"add-milestone-btn",children:[e.jsx(ze,{size:14}),e.jsx("span",{children:"Add Milestone"})]}),g.map(t=>e.jsx(ra,{milestone:t,features:k[t.id]||[],onEditMilestone:()=>pt(t),onDeleteMilestone:()=>bt(t.id),onAddFeature:()=>K({type:"feature",parentId:t.id,title:"",description:""}),onEditFeature:u=>{const b=k[t.id]?.find(z=>z.id===u);b&&rt(u,b.title,b.description)},onDeleteFeature:wt,milestoneEdit:Q,onMilestoneEditChange:gt,onMilestoneEditFieldChange:ht,onCancelMilestoneEdit:Ze,onSaveMilestoneEdit:ft,featureEdit:ae,onFeatureEditChange:xt,onStartFeatureEdit:rt,onCancelFeatureEdit:et,onSaveFeatureEdit:_t,projectId:l,addToast:n,isMilestoneDragging:Ce.draggingId===t.id,isMilestoneDropTarget:Ce.dropTargetId===t.id,milestoneDropPosition:Ce.dropTargetId===t.id?Ce.dropPosition:null,onMilestoneDragStart:Je,onMilestoneDragEnd:Ne,onMilestoneDragOver:Xe,onMilestoneDrop:h,onMilestoneDragLeave:m,isFeatureDragging:o,isFeatureDropTarget:ue.dropTargetMilestoneId===t.id,featureDropIndex:ue.dropTargetMilestoneId===t.id?ue.dropTargetIndex:null,onFeatureDragStart:Qe,onFeatureDragEnd:s,onFeatureDragOver:d,onFeatureDrop:r,onFeatureDragLeave:c,onFeatureDropOnMilestone:i,featureSuggestions:ve[t.id],isGeneratingFeatureSuggestions:oe(t.id),onGenerateFeatureSuggestions:()=>jt(t.id),onAcceptFeatureSuggestion:u=>Ct(t.id,u),onAcceptAllFeatureSuggestions:()=>yt(t.id),onUpdateFeatureSuggestionDraft:(u,b,z)=>Nt(u,b,z),onClearFeatureSuggestions:()=>St(t.id)},t.id))]})]})]}):e.jsx("div",{className:"roadmaps-view__empty-main",children:e.jsx("p",{children:"Select a roadmap from the sidebar to view its milestones."})})]}),U.type==="feature"&&U.parentId&&e.jsx("div",{className:"roadmaps-view__feature-create-overlay",children:e.jsx(oa,{onSave:t=>Et(U.parentId,t),onCancel:()=>K({type:null,parentId:void 0,title:"",description:""})})}),e.jsx(ea,{isOpen:N,onClose:F,roadmapId:je||"",roadmapTitle:Le,handoffPayload:de,isLoading:we,error:R,onFetchHandoff:W,onCopyToClipboard:Ke})]})}export{ma as RoadmapsView};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{r as e}from"./vendor-react-K0fH_qHe.js";import{
|
|
1
|
+
import{r as e}from"./vendor-react-K0fH_qHe.js";import{de as C}from"./index-BlkXZ4C5.js";function L(k={}){const{projectId:d,pollInterval:b=6e4,autoRefresh:p=!1,enabled:t=!0}=k,[S,o]=e.useState(null),[m,l]=e.useState(t),[E,c]=e.useState(null),[R,v]=e.useState(null),r=e.useRef(null),n=e.useRef(null),a=e.useRef(!0),s=e.useCallback(async()=>{if(!t){l(!1),c(null),o(null);return}r.current&&r.current.abort(),r.current=new AbortController,l(!0),c(null),o(null);try{const u=await C(d);if(!a.current)return;o(u),c(null),v(new Date),l(!1)}catch(u){if(u instanceof Error&&u.name==="AbortError"||!a.current)return;const A=u instanceof Error?u.message:"Failed to fetch memory backend status";c(A),l(!1)}},[t,d]);e.useEffect(()=>(a.current=!0,t?(s(),()=>{a.current=!1}):(r.current&&r.current.abort(),o(null),c(null),l(!1),()=>{a.current=!1})),[t,s]),e.useEffect(()=>{if(!(!t||!p))return n.current=setInterval(()=>{s()},b),()=>{n.current&&(clearInterval(n.current),n.current=null)}},[t,p,b,s]),e.useEffect(()=>()=>{a.current=!1,r.current&&r.current.abort(),n.current&&(clearInterval(n.current),n.current=null)},[]);const h=e.useCallback(()=>s(),[s]),f=m?null:S,B=f?.currentBackend??null,i=f?.capabilities??null,y=f?.availableBackends??[],I=i?.readable??!1,g=i?.writable??!1,w=i?.supportsAtomicWrite??!1;return{status:f,currentBackend:B,capabilities:i,availableBackends:y,isReadable:I,isWritable:g,supportsAtomicWrite:w,loading:m,error:E,lastUpdated:R,refresh:h}}export{L as u};
|