@libxai/board 1.5.29 → 1.5.30
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/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -128,7 +128,7 @@
|
|
|
128
128
|
to { opacity: 1; transform: translateY(0); }
|
|
129
129
|
}
|
|
130
130
|
`})]});return reactDom.createPortal(f,document.body)}function gi({label:e,value:t,labelColor:a,valueColor:r}){return jsxRuntime.jsxs("div",{children:[jsxRuntime.jsxs("span",{style:{color:a},children:[e,": "]}),jsxRuntime.jsx("span",{style:{color:r,fontWeight:500},children:t})]})}function Zn({x1:e,y1:t,x2:a,y2:r,theme:o,onDelete:s,lineStyle:n="curved",isHoverLayer:i=false,onHoverChange:c,hoverOverlayOnly:l=false,colorOverride:m,strokeWidthOverride:d,glowFilter:p}){let[,g]=react.useState(false),[h,b]=react.useState(null),x=r-t,f=x>0,y=Math.abs(x)<5,w=20,v=!y&&a<=e,T,C,D=a-e,k=e+D/2;C=k;let I=8;if(n==="squared")if(y)T=`M ${e} ${t} L ${a} ${r}`;else if(v){let ke=e+15,Ie=a-w,He=f?t+20:t-20;C=Ie;let et=f?1:-1;T=`M ${e} ${t} L ${ke-I} ${t} Q ${ke} ${t} ${ke} ${t+et*I} L ${ke} ${He-et*I} Q ${ke} ${He} ${ke-I} ${He} L ${Ie+I} ${He} Q ${Ie} ${He} ${Ie} ${He+et*I} L ${Ie} ${r-et*I} Q ${Ie} ${r} ${Ie+I} ${r} L ${a} ${r}`;}else {C=a-w;let Se=f?1:-1;T=`M ${e} ${t} L ${C-I} ${t} Q ${C} ${t} ${C} ${t+Se*I} L ${C} ${r-Se*I} Q ${C} ${r} ${C+I} ${r} L ${a} ${r}`;}else T=`M ${e} ${t} C ${k} ${t}, ${k} ${r}, ${a} ${r}`;let $=6,P=5,te=`M ${a} ${r} L ${a-$} ${r-P/2} L ${a-$} ${r+P/2} Z`,O=!o.bgPrimary||o.bgPrimary.startsWith("#0")||o.bgPrimary.startsWith("#1"),H=m||(O?"rgba(255,255,255,0.25)":"rgba(0,0,0,0.20)"),F=d||1,J=o.dependencyHover||(O?"rgba(255,255,255,0.5)":"rgba(0,0,0,0.45)"),ee="#f87171",Re="rgba(248, 113, 113, 0.15)",B=C,Y=(t+r)/2;if(h)if(n==="squared")if(y)B=Math.max(e+10,Math.min(a-10,h.x)),Y=t;else if(v){let Se=e+15,ke=a-w,Ie=f?t+20:t-20,He=[[e,t,Se,t],[Se,t,Se,Ie],[Se,Ie,ke,Ie],[ke,Ie,ke,r],[ke,r,a,r]],et=1/0,ae={x:B,y:Y};for(let Xe of He){let pe=ye(h.x,h.y,Xe[0],Xe[1],Xe[2],Xe[3]),at=Math.hypot(h.x-pe.x,h.y-pe.y);at<et&&(et=at,ae=pe);}B=ae.x,Y=ae.y;}else {let Se=[[e,t,C,t],[C,t,C,r],[C,r,a,r]],ke=1/0,Ie={x:B,y:Y};for(let He of Se){let et=ye(h.x,h.y,He[0],He[1],He[2],He[3]),ae=Math.hypot(h.x-et.x,h.y-et.y);ae<ke&&(ke=ae,Ie=et);}B=Ie.x,Y=Ie.y;}else {let Se=k,ke=t,Ie=k,He=r,et=1/0,ae=B,Xe=Y;for(let pe=0;pe<=1;pe+=.02){let at=1-pe,mt=at*at*at*e+3*at*at*pe*Se+3*at*pe*pe*Ie+pe*pe*pe*a,Pt=at*at*at*t+3*at*at*pe*ke+3*at*pe*pe*He+pe*pe*pe*r,Ce=Math.hypot(h.x-mt,h.y-Pt);Ce<et&&(et=Ce,ae=mt,Xe=Pt);}B=ae,Y=Xe;}function ye(Se,ke,Ie,He,et,ae){let Xe=et-Ie,pe=ae-He,at=Xe*Xe+pe*pe;if(at===0)return {x:Ie,y:He};let mt=((Se-Ie)*Xe+(ke-He)*pe)/at;return mt=Math.max(0,Math.min(1,mt)),{x:Ie+mt*Xe,y:He+mt*pe}}let Ge=Se=>{let ke=Se.currentTarget.ownerSVGElement;if(!ke)return;let Ie=ke.getScreenCTM();if(!Ie)return;let He=Ie.inverse();b({x:He.a*Se.clientX+He.c*Se.clientY+He.e,y:He.b*Se.clientX+He.d*Se.clientY+He.f});},U=()=>{g(false),b(null),c?.(false);},oe=()=>{g(true),c?.(true);},Z=Se=>s?jsxRuntime.jsxs(framerMotion.motion.g,{initial:Se,animate:{opacity:1,scale:1},transition:{duration:.15,ease:"easeOut"},onClick:ke=>{ke.stopPropagation(),s();},style:{cursor:"pointer",pointerEvents:"auto"},children:[jsxRuntime.jsx("circle",{cx:B,cy:Y,r:16,fill:"transparent",style:{cursor:"pointer"}}),jsxRuntime.jsx("circle",{cx:B,cy:Y,r:9,fill:Re,stroke:ee,strokeWidth:1.5,style:{pointerEvents:"none"}}),jsxRuntime.jsx("line",{x1:B-3,y1:Y-3,x2:B+3,y2:Y+3,stroke:ee,strokeWidth:1.5,strokeLinecap:"round",style:{pointerEvents:"none"}}),jsxRuntime.jsx("line",{x1:B+3,y1:Y-3,x2:B-3,y2:Y+3,stroke:ee,strokeWidth:1.5,strokeLinecap:"round",style:{pointerEvents:"none"}})]}):null;return i?jsxRuntime.jsxs("g",{"data-dependency-line":"true",onMouseLeave:U,onMouseMove:Ge,children:[jsxRuntime.jsx("path",{d:T,fill:"none",stroke:"transparent",strokeWidth:20,strokeLinecap:"round",style:{cursor:"pointer"}}),jsxRuntime.jsx("path",{d:T,fill:"none",stroke:J,strokeWidth:8,strokeLinecap:"round",opacity:.15,style:{pointerEvents:"none",filter:"blur(4px)"}}),jsxRuntime.jsx("path",{d:T,fill:"none",stroke:J,strokeWidth:2.5,strokeLinecap:"round",opacity:.9,style:{pointerEvents:"none"}}),jsxRuntime.jsx("path",{d:te,fill:J,stroke:"none",opacity:.9,style:{pointerEvents:"none"}}),jsxRuntime.jsx("circle",{cx:a,cy:r,r:4,fill:J,opacity:.9,style:{pointerEvents:"none"}}),Z({opacity:0,scale:.8})]}):l?jsxRuntime.jsxs("g",{"data-dependency-hover-overlay":"true",onMouseEnter:oe,onMouseLeave:U,onMouseMove:Ge,style:{cursor:s?"pointer":"default"},children:[jsxRuntime.jsx("path",{d:T,fill:"none",stroke:"transparent",strokeWidth:16,strokeLinecap:"round",style:{cursor:s?"pointer":"default"}}),jsxRuntime.jsx("path",{d:T,fill:"none",stroke:o.bgPrimary||"#1A1D21",strokeWidth:4,strokeLinecap:"round",style:{pointerEvents:"none"}}),jsxRuntime.jsx("path",{d:T,fill:"none",stroke:J,strokeWidth:5,strokeLinecap:"round",opacity:.12,style:{pointerEvents:"none"}}),jsxRuntime.jsx("path",{d:T,fill:"none",stroke:J,strokeWidth:1.5,strokeLinecap:"round",style:{pointerEvents:"none"}}),jsxRuntime.jsx("path",{d:te,fill:J,stroke:"none",style:{pointerEvents:"none"}}),jsxRuntime.jsx("circle",{cx:a,cy:r,r:3.5,fill:J,style:{pointerEvents:"none"}}),Z({opacity:0,scale:0})]}):jsxRuntime.jsxs("g",{"data-dependency-line":"true",onMouseEnter:oe,onMouseLeave:U,onMouseMove:Ge,style:{cursor:s?"pointer":"default"},children:[jsxRuntime.jsx("path",{d:T,fill:"none",stroke:"transparent",strokeWidth:16,strokeLinecap:"round",style:{cursor:s?"pointer":"default"}}),jsxRuntime.jsx(framerMotion.motion.path,{d:T,fill:"none",stroke:H,strokeWidth:F,strokeLinecap:"round",initial:{pathLength:0,opacity:0},animate:{pathLength:1,opacity:1},transition:{pathLength:{duration:.5,ease:"easeInOut"},opacity:{duration:.2}},style:{pointerEvents:"none",filter:p||"none"}}),jsxRuntime.jsx(framerMotion.motion.path,{d:te,fill:H,stroke:"none",initial:{opacity:0},animate:{opacity:1},transition:{duration:.2,delay:.3},style:{pointerEvents:"none"}}),jsxRuntime.jsx(framerMotion.motion.circle,{cx:a,cy:r,r:3,fill:H,initial:{scale:0},animate:{scale:1},transition:{delay:.3,duration:.15},style:{pointerEvents:"none"}})]})}function yi({task:e,x:t,y:a,theme:r,onClick:o}){let[s,n]=react.useState(false),i=16,c=l=>l.toLocaleDateString("en-US",{month:"short",day:"numeric",year:"numeric"});return jsxRuntime.jsxs("g",{"data-task-bar":"true",onMouseEnter:()=>n(true),onMouseLeave:()=>n(false),onClick:()=>o?.(e),style:{cursor:"pointer"},children:[e.isCriticalPath&&jsxRuntime.jsx(framerMotion.motion.circle,{cx:t,cy:a+16,r:i+4,fill:r.criticalPathLight,initial:{scale:0},animate:{scale:s?1.2:1},transition:{duration:.3}}),jsxRuntime.jsx(framerMotion.motion.rect,{x:t-i/2,y:a+16-i/2,width:i,height:i,fill:e.isCriticalPath?r.criticalPath:r.milestone,stroke:r.bgGrid,strokeWidth:2,transform:`rotate(45 ${t} ${a+16})`,initial:{scale:0,rotate:0},animate:{scale:s?1.15:1,rotate:45},transition:{duration:.3,type:"spring",stiffness:300,damping:20}}),s&&jsxRuntime.jsx(framerMotion.motion.rect,{x:t-(i+4)/2,y:a+16-(i+4)/2,width:i+4,height:i+4,fill:"none",stroke:e.isCriticalPath?r.criticalPath:r.milestone,strokeWidth:2,opacity:.5,transform:`rotate(45 ${t} ${a+16})`,initial:{scale:.8,opacity:0},animate:{scale:1,opacity:.5},transition:{duration:.2}}),jsxRuntime.jsx(framerMotion.AnimatePresence,{children:s&&jsxRuntime.jsxs(framerMotion.motion.g,{initial:{opacity:0,y:10},animate:{opacity:1,y:0},exit:{opacity:0,y:10},transition:{duration:.2},children:[jsxRuntime.jsx("rect",{x:t-80,y:a-50,width:160,height:44,rx:8,fill:r.bgSecondary,stroke:r.border,strokeWidth:1,filter:"drop-shadow(0 4px 12px rgba(0, 0, 0, 0.15))"}),jsxRuntime.jsx("path",{d:`M ${t-6} ${a-6} L ${t} ${a+4} L ${t+6} ${a-6}`,fill:r.bgSecondary,stroke:r.border,strokeWidth:1}),jsxRuntime.jsx("rect",{x:t-70,y:a-38,width:8,height:8,fill:e.isCriticalPath?r.criticalPath:r.milestone,transform:`rotate(45 ${t-66} ${a-34})`}),jsxRuntime.jsx("text",{x:t-55,y:a-32,fill:r.textPrimary,fontSize:"12",fontWeight:"600",fontFamily:"Inter, sans-serif",children:e.name.length>18?`${e.name.substring(0,18)}...`:e.name}),jsxRuntime.jsx("text",{x:t-55,y:a-18,fill:r.textTertiary,fontSize:"10",fontFamily:"Inter, sans-serif",children:c(e.startDate)}),e.isCriticalPath&&jsxRuntime.jsxs("g",{children:[jsxRuntime.jsx("rect",{x:t+10,y:a-40,width:60,height:16,rx:4,fill:r.criticalPathLight}),jsxRuntime.jsx("text",{x:t+40,y:a-30,textAnchor:"middle",fill:r.criticalPath,fontSize:"9",fontWeight:"700",fontFamily:"Inter, sans-serif",letterSpacing:"0.5",children:"CRITICAL"})]})]})})]})}var Pe={calculateEndDate:(e,t)=>{let a=new Date(e);return a.setDate(a.getDate()+t),a},calculateDuration:(e,t)=>{let a=t.getTime()-e.getTime();return Math.ceil(a/(1e3*60*60*24))},calculateWorkingDays:(e,t)=>{let a=0,r=new Date(e);for(;r<=t;){let o=r.getDay();o!==0&&o!==6&&a++,r.setDate(r.getDate()+1);}return a},addWorkingDays:(e,t)=>{let a=new Date(e),r=0;for(;r<t;){a.setDate(a.getDate()+1);let o=a.getDay();o!==0&&o!==6&&r++;}return a},isWeekend:e=>{let t=e.getDay();return t===0||t===6},validateDependencies:(e,t,a)=>{let r=new Map,o=l=>{l.forEach(m=>{m.dependencies&&r.set(m.id,m.dependencies),m.subtasks&&o(m.subtasks);});};o(e);let s=r.get(a)||[];r.set(a,[...s,t]);let n=new Set,i=new Set,c=l=>{if(!n.has(l)){n.add(l),i.add(l);let m=r.get(l)||[];for(let d of m){if(!n.has(d)&&c(d))return true;if(i.has(d))return true}}return i.delete(l),false};return c(a)},flattenTasks:e=>{let t=[],a=r=>{[...r].sort((s,n)=>(s.position??0)-(n.position??0)).forEach(s=>{t.push(s),s.subtasks&&s.subtasks.length>0&&a(s.subtasks);});};return a(e),t},findTaskById:(e,t)=>{for(let a of e){if(a.id===t)return a;if(a.subtasks){let r=Pe.findTaskById(a.subtasks,t);if(r)return r}}},getParentTasks:(e,t)=>{let a=[],r=Pe.findTaskById(e,t);if(!r||!r.parentId)return a;let o=r.parentId;for(;o;){let s=Pe.findTaskById(e,o);if(s)a.unshift(s),o=s.parentId;else break}return a},exportToJSON:e=>JSON.stringify(e,null,2),importFromJSON:e=>{try{let t=JSON.parse(e);if(!Array.isArray(t))throw new Error("Invalid JSON: expected an array of tasks");return t.forEach((a,r)=>{if(!a.id||!a.name)throw new Error(`Invalid task at index ${r}: missing required fields (id, name)`)}),t}catch(t){throw new Error(`Failed to import tasks: ${t instanceof Error?t.message:"Unknown error"}`)}},exportToCSV:e=>{let t=Pe.flattenTasks(e),r=[["ID","Name","Start Date","End Date","Progress","Status","Dependencies"].join(",")];return t.forEach(o=>{let s=[o.id,`"${o.name.replace(/"/g,'""')}"`,o.startDate?o.startDate.toISOString().split("T")[0]:"",o.endDate?o.endDate.toISOString().split("T")[0]:"",o.progress.toString(),o.status||"",o.dependencies?.join(";")||""];r.push(s.join(","));}),r.join(`
|
|
131
|
-
`)},formatDate:e=>{let t=e.getFullYear(),a=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return `${t}-${a}-${r}`},parseDate:e=>new Date(e),getTaskDateRange:e=>!e.startDate||!e.endDate?null:{start:e.startDate,end:e.endDate},getEarliestStartDate:e=>{let a=Pe.flattenTasks(e).filter(r=>r.startDate);return a.length===0?null:new Date(Math.min(...a.map(r=>r.startDate.getTime())))},getLatestEndDate:e=>{let a=Pe.flattenTasks(e).filter(r=>r.endDate);return a.length===0?null:new Date(Math.max(...a.map(r=>r.endDate.getTime())))},tasksOverlap:(e,t)=>!e.startDate||!e.endDate||!t.startDate||!t.endDate?false:e.startDate<=t.endDate&&t.startDate<=e.endDate,getDependentTasks:(e,t)=>Pe.flattenTasks(e).filter(r=>r.dependencies&&r.dependencies.includes(t)),getDependencyTasks:(e,t)=>{let a=Pe.findTaskById(e,t);return !a||!a.dependencies?[]:Pe.flattenTasks(e).filter(o=>a.dependencies.includes(o.id))},filterByStatus:(e,t)=>Pe.flattenTasks(e).filter(a=>a.status===t),filterByDateRange:(e,t,a)=>Pe.flattenTasks(e).filter(r=>!r.startDate||!r.endDate?false:r.startDate<=a&&r.endDate>=t),sortByStartDate:(e,t=true)=>[...e].sort((a,r)=>{if(!a.startDate||!r.startDate)return 0;let o=a.startDate.getTime()-r.startDate.getTime();return t?o:-o}),sortByEndDate:(e,t=true)=>[...e].sort((a,r)=>{if(!a.endDate||!r.endDate)return 0;let o=a.endDate.getTime()-r.endDate.getTime();return t?o:-o}),sortByProgress:(e,t=true)=>[...e].sort((a,r)=>{let o=a.progress-r.progress;return t?o:-o}),calculateTotalProgress:e=>{let t=Pe.flattenTasks(e);if(t.length===0)return 0;let a=t.reduce((r,o)=>r+o.progress,0);return Math.round(a/t.length)},getTaskByPath:(e,t)=>{let a=e,r;for(let o=0;o<t.length;o++){let s=t[o];if(!a||s===void 0||s>=a.length||(r=a[s],!r))return;o<t.length-1&&(a=r.subtasks||[]);}return r},cloneTask:(e,t)=>({...e,id:t||`${e.id}-copy`,subtasks:e.subtasks?.map(a=>Pe.cloneTask(a))}),exportToPDF:async(e,t="gantt-chart.pdf")=>{try{if(!e||e.length===0){alert("No tasks available to export to PDF");return}let{jsPDF:a}=await import('jspdf'),{default:r}=await import('jspdf-autotable'),o=new a,s=Pe.flattenTasks(e);if(s.length===0){alert("No tasks found to export");return}o.setFontSize(16),o.text("Gantt Chart - Task List",14,20);let n=[["Task Name","Start Date","End Date","Duration","Progress","Status"]],i=s.map(c=>{let l=c.startDate&&c.endDate?Pe.calculateDuration(c.startDate,c.endDate):0;return [c.name,c.startDate?Pe.formatDate(c.startDate):"N/A",c.endDate?Pe.formatDate(c.endDate):"N/A",l>0?`${l} days`:"N/A",`${c.progress}%`,c.status||"N/A"]});r(o,{head:n,body:i,startY:30,styles:{fontSize:9,cellPadding:3},headStyles:{fillColor:[66,139,202],textColor:255,fontStyle:"bold"},alternateRowStyles:{fillColor:[245,245,245]},columnStyles:{0:{cellWidth:60},1:{cellWidth:30},2:{cellWidth:30},3:{cellWidth:25},4:{cellWidth:20},5:{cellWidth:25}}}),o.save(t);}catch(a){throw a}},exportToExcel:async(e,t,a)=>{let r=await import('xlsx'),o=Pe.flattenTasks(e),s=a?.rateMap,n=a?.defaultRate||0,i=b=>{if(!s||!b.assignees||b.assignees.length===0)return n;let x=b.assignees.map(f=>f.id?s[f.id]:void 0).filter(f=>f!=null&&f>0);return x.length===0?n:x.reduce((f,y)=>f+y,0)/x.length},c=new Map,l=(b,x="")=>{[...b].sort((y,w)=>(y.position??0)-(w.position??0)).forEach((y,w)=>{let v=x?`${x}.${w+1}`:`${w+1}`;c.set(y.id,v),y.subtasks?.length&&l(y.subtasks,v);});};l(e);let m=s&&Object.keys(s).length>0,d=o.map(b=>{let x=b.startDate&&b.endDate?Pe.calculateDuration(b.startDate,b.endDate):0,f=b.effortMinutes,y=b.timeLoggedMinutes,w=b.soldEffortMinutes,v=typeof f=="number"?+(f/60).toFixed(1):0,T=typeof y=="number"?+(y/60).toFixed(1):0,C=typeof w=="number"?+(w/60).toFixed(1):0,D=i(b),k={WBS:c.get(b.id)||"","Task Name":b.name,"Start Date":b.startDate?Pe.formatDate(b.startDate):"","End Date":b.endDate?Pe.formatDate(b.endDate):"","Duration (days)":x>0?x:"","Progress (%)":b.progress,Status:b.status||"",Assignees:b.assignees?.map(I=>I.name).join(", ")||"","Estimated (h)":v||"","Logged (h)":T||"","Quoted (h)":C||""};return m&&(k["$ Estimated"]=v>0&&D>0?Math.round(v*D):"",k["$ Executed"]=T>0&&D>0?Math.round(T*D):"",k["$ Quoted"]=C>0&&D>0?Math.round(C*D):"",k["Rate ($/h)"]=D>0?D:""),k["Is Milestone"]=b.isMilestone?"Yes":"No",k}),p=r.utils.json_to_sheet(d),g=[{wch:10},{wch:40},{wch:12},{wch:12},{wch:15},{wch:12},{wch:15},{wch:30},{wch:14},{wch:12},{wch:12},...m?[{wch:14},{wch:14},{wch:14},{wch:12}]:[],{wch:12}];p["!cols"]=g;let h=r.utils.book_new();if(r.utils.book_append_sheet(h,p,"Gantt Tasks"),!t){let b=new Date,x=y=>String(y).padStart(2,"0");t=`Project_${`${b.getFullYear()}-${x(b.getMonth()+1)}-${x(b.getDate())}_${x(b.getHours())}${x(b.getMinutes())}`}.xlsx`;}r.writeFile(h,t);},exportToMSProject:(e,t="Gantt Project",a="project.xml")=>{let r=Pe.flattenTasks(e),o=new Map;r.forEach((p,g)=>{o.set(p.id,g+1);});let s=p=>p.toISOString().replace("Z",""),n=Pe.getEarliestStartDate(e)||new Date,i=Pe.getLatestEndDate(e)||new Date,c=r.map((p,g)=>{let h=o.get(p.id),b=p.startDate&&p.endDate?Pe.calculateDuration(p.startDate,p.endDate):0,x=(p.dependencies||[]).filter(f=>o.has(f)).map(f=>`
|
|
131
|
+
`)},formatDate:e=>{let t=e.getFullYear(),a=String(e.getMonth()+1).padStart(2,"0"),r=String(e.getDate()).padStart(2,"0");return `${t}-${a}-${r}`},parseDate:e=>new Date(e),getTaskDateRange:e=>!e.startDate||!e.endDate?null:{start:e.startDate,end:e.endDate},getEarliestStartDate:e=>{let a=Pe.flattenTasks(e).filter(r=>r.startDate);return a.length===0?null:new Date(Math.min(...a.map(r=>r.startDate.getTime())))},getLatestEndDate:e=>{let a=Pe.flattenTasks(e).filter(r=>r.endDate);return a.length===0?null:new Date(Math.max(...a.map(r=>r.endDate.getTime())))},tasksOverlap:(e,t)=>!e.startDate||!e.endDate||!t.startDate||!t.endDate?false:e.startDate<=t.endDate&&t.startDate<=e.endDate,getDependentTasks:(e,t)=>Pe.flattenTasks(e).filter(r=>r.dependencies&&r.dependencies.includes(t)),getDependencyTasks:(e,t)=>{let a=Pe.findTaskById(e,t);return !a||!a.dependencies?[]:Pe.flattenTasks(e).filter(o=>a.dependencies.includes(o.id))},filterByStatus:(e,t)=>Pe.flattenTasks(e).filter(a=>a.status===t),filterByDateRange:(e,t,a)=>Pe.flattenTasks(e).filter(r=>!r.startDate||!r.endDate?false:r.startDate<=a&&r.endDate>=t),sortByStartDate:(e,t=true)=>[...e].sort((a,r)=>{if(!a.startDate||!r.startDate)return 0;let o=a.startDate.getTime()-r.startDate.getTime();return t?o:-o}),sortByEndDate:(e,t=true)=>[...e].sort((a,r)=>{if(!a.endDate||!r.endDate)return 0;let o=a.endDate.getTime()-r.endDate.getTime();return t?o:-o}),sortByProgress:(e,t=true)=>[...e].sort((a,r)=>{let o=a.progress-r.progress;return t?o:-o}),calculateTotalProgress:e=>{let t=Pe.flattenTasks(e);if(t.length===0)return 0;let a=t.reduce((r,o)=>r+o.progress,0);return Math.round(a/t.length)},getTaskByPath:(e,t)=>{let a=e,r;for(let o=0;o<t.length;o++){let s=t[o];if(!a||s===void 0||s>=a.length||(r=a[s],!r))return;o<t.length-1&&(a=r.subtasks||[]);}return r},cloneTask:(e,t)=>({...e,id:t||`${e.id}-copy`,subtasks:e.subtasks?.map(a=>Pe.cloneTask(a))}),exportToPDF:async(e,t="gantt-chart.pdf")=>{try{if(!e||e.length===0){alert("No tasks available to export to PDF");return}let{jsPDF:a}=await import('jspdf'),{default:r}=await import('jspdf-autotable'),o=new a,s=Pe.flattenTasks(e);if(s.length===0){alert("No tasks found to export");return}o.setFontSize(16),o.text("Gantt Chart - Task List",14,20);let n=[["Task Name","Start Date","End Date","Duration","Progress","Status"]],i=s.map(c=>{let l=c.startDate&&c.endDate?Pe.calculateDuration(c.startDate,c.endDate):0;return [c.name,c.startDate?Pe.formatDate(c.startDate):"N/A",c.endDate?Pe.formatDate(c.endDate):"N/A",l>0?`${l} days`:"N/A",`${c.progress}%`,c.status||"N/A"]});r(o,{head:n,body:i,startY:30,styles:{fontSize:9,cellPadding:3},headStyles:{fillColor:[66,139,202],textColor:255,fontStyle:"bold"},alternateRowStyles:{fillColor:[245,245,245]},columnStyles:{0:{cellWidth:60},1:{cellWidth:30},2:{cellWidth:30},3:{cellWidth:25},4:{cellWidth:20},5:{cellWidth:25}}}),o.save(t);}catch(a){throw a}},exportToExcel:async(e,t,a)=>{let r=await import('xlsx'),o=Pe.flattenTasks(e),s=a?.rateMap,n=a?.defaultRate||0,i=b=>{if(!s||!b.assignees||b.assignees.length===0)return n;let x=b.assignees.map(f=>f.id?s[f.id]:void 0).filter(f=>f!=null&&f>0);return x.length===0?n:x.reduce((f,y)=>f+y,0)/x.length},c=new Map,l=(b,x="")=>{[...b].sort((y,w)=>(y.position??0)-(w.position??0)).forEach((y,w)=>{let v=x?`${x}.${w+1}`:`${w+1}`;c.set(y.id,v),y.subtasks?.length&&l(y.subtasks,v);});};l(e);let m=s&&Object.keys(s).length>0||o.some(b=>b._costRate>0),d=o.map(b=>{let x=b.startDate&&b.endDate?Pe.calculateDuration(b.startDate,b.endDate):0,f=b.effortMinutes,y=b.timeLoggedMinutes,w=b.soldEffortMinutes,v=typeof f=="number"?+(f/60).toFixed(1):0,T=typeof y=="number"?+(y/60).toFixed(1):0,C=typeof w=="number"?+(w/60).toFixed(1):0,D=b._costRate>0?b._costRate:i(b),k={WBS:c.get(b.id)||"","Task Name":b.name,"Start Date":b.startDate?Pe.formatDate(b.startDate):"","End Date":b.endDate?Pe.formatDate(b.endDate):"","Duration (days)":x>0?x:"","Progress (%)":b.progress,Status:b.status||"",Assignees:b.assignees?.map(I=>I.name).join(", ")||"","Estimated (h)":v||"","Logged (h)":T||"","Quoted (h)":C||""};return m&&(k["$ Estimated"]=v>0&&D>0?Math.round(v*D):"",k["$ Executed"]=T>0&&D>0?Math.round(T*D):"",k["$ Quoted"]=C>0&&D>0?Math.round(C*D):"",k["Rate ($/h)"]=D>0?D:""),k["Is Milestone"]=b.isMilestone?"Yes":"No",k}),p=r.utils.json_to_sheet(d),g=[{wch:10},{wch:40},{wch:12},{wch:12},{wch:15},{wch:12},{wch:15},{wch:30},{wch:14},{wch:12},{wch:12},...m?[{wch:14},{wch:14},{wch:14},{wch:12}]:[],{wch:12}];p["!cols"]=g;let h=r.utils.book_new();if(r.utils.book_append_sheet(h,p,"Gantt Tasks"),!t){let b=new Date,x=y=>String(y).padStart(2,"0");t=`Project_${`${b.getFullYear()}-${x(b.getMonth()+1)}-${x(b.getDate())}_${x(b.getHours())}${x(b.getMinutes())}`}.xlsx`;}r.writeFile(h,t);},exportToMSProject:(e,t="Gantt Project",a="project.xml")=>{let r=Pe.flattenTasks(e),o=new Map;r.forEach((p,g)=>{o.set(p.id,g+1);});let s=p=>p.toISOString().replace("Z",""),n=Pe.getEarliestStartDate(e)||new Date,i=Pe.getLatestEndDate(e)||new Date,c=r.map((p,g)=>{let h=o.get(p.id),b=p.startDate&&p.endDate?Pe.calculateDuration(p.startDate,p.endDate):0,x=(p.dependencies||[]).filter(f=>o.has(f)).map(f=>`
|
|
132
132
|
<PredecessorLink>
|
|
133
133
|
<PredecessorUID>${o.get(f)}</PredecessorUID>
|
|
134
134
|
<Type>1</Type>
|