iris-gantt 1.4.3 → 1.4.5

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/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  A comprehensive, production-ready Gantt chart component built with React and TypeScript. Easy to install, simple to use, fully customizable, and responsive.
4
4
 
5
- ## 🆕 Version 1.4.3 (Latest)
5
+ ## 🆕 Version 1.4.5 (Latest)
6
6
 
7
7
  ### Included Changes
8
8
  - **Project-level OnHold applied to all tasks** — The `onHoldPeriods` prop now propagates the grey hatched on-hold bar to **all** task rows including `project`-type tasks. Previously, only child/standalone tasks showed the hold bar; now the entire project hierarchy displays it consistently.
@@ -1 +1 @@
1
- {"version":3,"file":"Gantt.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Gantt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,WAAW,EAA4B,QAAQ,EAAiB,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQhJ,OAAO,KAAK,EAEV,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,eAAe,EACf,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAGxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACnC;AA+aD,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA6wBtC,CAAC"}
1
+ {"version":3,"file":"Gantt.d.ts","sourceRoot":"","sources":["../../src/components/Gantt/Gantt.tsx"],"names":[],"mappings":"AAAA,OAAO,KAAsC,MAAM,OAAO,CAAC;AAQ3D,OAAO,KAAK,EAAE,WAAW,EAA4B,QAAQ,EAAiB,aAAa,EAAE,gBAAgB,EAAE,eAAe,EAAE,MAAM,SAAS,CAAC;AAQhJ,OAAO,KAAK,EAEV,IAAI,EACJ,SAAS,EACT,IAAI,EACJ,eAAe,EACf,iBAAiB,EAEjB,iBAAiB,EACjB,qBAAqB,EAEtB,MAAM,SAAS,CAAC;AACjB,OAAO,aAAa,CAAC;AAErB,MAAM,WAAW,UAAU;IACzB,KAAK,EAAE,SAAS,EAAE,CAAC;IACnB,KAAK,CAAC,EAAE,IAAI,EAAE,CAAC;IACf,MAAM,CAAC,EAAE,OAAO,CAAC,WAAW,CAAC,CAAC;IAC9B,QAAQ,CAAC,EAAE,OAAO,CAAC,aAAa,CAAC,CAAC;IAClC,WAAW,CAAC,EAAE,OAAO,CAAC,gBAAgB,CAAC,CAAC;IACxC,UAAU,CAAC,EAAE,OAAO,CAAC,eAAe,CAAC,CAAC;IACtC,iBAAiB,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,CAAC;IAC/C,aAAa,CAAC,EAAE,iBAAiB,EAAE,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,WAAW,CAAC,EAAE,eAAe,KAAK,IAAI,CAAC;IACnE,gBAAgB,CAAC,EAAE,CAAC,OAAO,EAAE,qBAAqB,KAAK,IAAI,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5E,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IACxC,YAAY,CAAC,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,CAAC;IACpC,YAAY,CAAC,EAAE,CAAC,MAAM,EAAE,MAAM,KAAK,IAAI,CAAC;IAGxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,EAAE,OAAO,CAAC;IAC9B,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;IACxB,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,SAAS,CAAC,EAAE,GAAG,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAC;CACnC;AA+aD,eAAO,MAAM,KAAK,EAAE,KAAK,CAAC,EAAE,CAAC,UAAU,CA+wBtC,CAAC"}
@@ -3610,8 +3610,6 @@ ${s + 1}. ${a.text}
3610
3610
  minColumnWidth: 60,
3611
3611
  autoSchedule: !1,
3612
3612
  criticalPath: !1,
3613
- baselines: !0,
3614
- // Always enabled
3615
3613
  weekends: !0,
3616
3614
  holidays: [],
3617
3615
  theme: pt,
@@ -3659,7 +3657,10 @@ ${s + 1}. ${a.text}
3659
3657
  // Marker size in pixels
3660
3658
  projectStartLineMarkerStyle: a.projectStartLineMarkerStyle || "triangle",
3661
3659
  // Marker style
3662
- ...a
3660
+ ...a,
3661
+ // IMPORTANT: Re-apply baselines after spread so undefined from config doesn't override the default.
3662
+ // baselines should always be true unless the user explicitly passes false.
3663
+ baselines: a.baselines !== !1
3663
3664
  };
3664
3665
  Xe(() => {
3665
3666
  const u = cn(R, ht);
@@ -28,4 +28,4 @@ ${s+1}. ${o.text}
28
28
  ${o.owner?`Owner: ${o.owner}`:""}
29
29
  `).join(`
30
30
  `)}
31
- `.trim();st(a,"gantt-report.txt","text/plain"),alert("PDF export is a simplified text version. For full PDF with charts, a PDF library would be needed.")},br=(e,a,o="png")=>{if(!document.getElementById(e)){alert("Could not find Gantt chart element to export");return}if(o==="svg"){alert("SVG export requires additional library. Use PNG or implement with dom-to-svg.");return}alert("Image export requires html2canvas library. Install with: npm install html2canvas")},st=(e,a,o)=>{const s=new Blob([e],{type:o}),r=URL.createObjectURL(s);Sr(r,a),URL.revokeObjectURL(r)},Sr=(e,a)=>{const o=document.createElement("a");o.href=e,o.download=a,document.body.appendChild(o),o.click(),document.body.removeChild(o)},vr=Object.freeze(Object.defineProperty({__proto__:null,exportToCSV:Ut,exportToExcel:qt,exportToImage:br,exportToJSON:Gt,exportToPDF:Jt,importFromJSON:e=>new Promise((a,o)=>{const s=new FileReader;s.onload=r=>{try{const h=r.target?.result,g=JSON.parse(h),l=g.tasks.map(i=>({...i,start:new Date(i.start),end:new Date(i.end)}));a({tasks:l,links:g.links||[]})}catch{o(new Error("Invalid JSON file"))}},s.onerror=()=>o(new Error("Failed to read file")),s.readAsText(e)})},Symbol.toStringTag,{value:"Module"})),Kt=(e,a)=>e.filter(o=>{if(a.searchText){const s=a.searchText.toLowerCase(),r=o.text.toLowerCase().includes(s),h=o.owner?.toLowerCase().includes(s),g=o.details?.toLowerCase().includes(s);if(!r&&!h&&!g)return!1}if(a.status!=="all"&&(o.progress===0?"not-started":o.progress===100?"completed":"in-progress")!==a.status||a.priority!=="all"&&o.priority!==a.priority||a.owner&&o.owner!==a.owner)return!1;if(a.dateRange){const s=o.start.getTime(),r=a.dateRange.start.getTime(),h=a.dateRange.end.getTime();if(s<r||s>h)return!1}return!0}),Ze=1440*60*1e3,Me=(e,a)=>{if(e instanceof Date){const o=new Date(e.getTime());return Number.isNaN(o.getTime())?new Date(a.getTime()):o}if(typeof e=="string"||typeof e=="number"){const o=new Date(e);if(!Number.isNaN(o.getTime()))return o}return new Date(a.getTime())},Tt=(e,a)=>{if(e==null||e==="")return a;const o=Number(e);return Number.isFinite(o)?o:a},jr=e=>{if(Array.isArray(e)){const a=e.map(o=>String(o).trim()).filter(Boolean);return a.length>0?a:void 0}if(typeof e=="string"){const a=e.split(/[|,]/).map(o=>o.trim()).filter(Boolean);return a.length>0?a:void 0}},Tr=e=>{if(Array.isArray(e)){const a=e.map(o=>String(o).trim()).filter(Boolean);return a.length>0?a:void 0}if(typeof e=="string"){const a=e.split(/\r?\n|\|/).map(o=>o.trim()).filter(Boolean);return a.length>0?a:void 0}},Dr=(e,a,o)=>{if(!Array.isArray(e)||e.length===0)return;const s=a.getTime(),r=o.getTime();return e.map(h=>{const g=Me(h?.start,a),l=Me(h?.end,o),i=Math.max(g.getTime(),s),x=Math.min(l.getTime(),r);return{start:new Date(i),end:new Date(x)}}).filter(h=>h.end.getTime()>h.start.getTime())},Mr=(e,a,o)=>{if(Array.isArray(e))return e.map(s=>{const r=Me(s?.start,a),h=Me(s?.end,o),g=h.getTime()<r.getTime()?r:h,l=Math.max(Math.ceil((g.getTime()-r.getTime())/Ze),0);return{start:r,end:g,duration:Tt(s?.duration,l)}}).filter(s=>s.end.getTime()>=s.start.getTime())},Er=e=>{const a=new Date,o=Me(e.start??e.startDate??e.start_date,a),s=Me(e.end??e.endDate??e.end_date,o),r=s.getTime()<o.getTime()?o:s,h=Me(e.plannedStart??e.planned_start??e.planned_start_date,o),g=Me(e.plannedEnd??e.planned_end??e.planned_end_date,r),l=g.getTime()<h.getTime()?h:g,i=Me(e.actualStart??e.actual_start??e.actual_start_date,o),x=Me(e.actualEnd??e.actual_end??e.actual_end_date,r),p=x.getTime()<i.getTime()?i:x,S=Math.max(Math.ceil((r.getTime()-o.getTime())/Ze),0),F=jr(e.dependencies??e.dependsOn??e.depends_on),y=Tr(e.dependencyRule??e.dependency_rule??e.dependencyRuleDescription??e.dependency_rule_description),D=Dr(e.onHoldPeriods??e.on_hold_periods,o,r);return{id:String(e.id),rawId:e.id,text:e.text||e.name||e.title||e.taskName||e.task_name||`Task ${String(e.id)}`,start:o,end:r,plannedStart:h,plannedEnd:l,actualStart:i,actualEnd:p,duration:Tt(e.duration,S),progress:Math.max(0,Math.min(100,Tt(e.progress??e.progressPercentage??e.progress_percentage,0))),type:e.type,parent:e.parent!==void 0&&e.parent!==null&&String(e.parent).length>0?String(e.parent):void 0,open:e.open,color:e.color,details:e.details,owner:e.owner||e.ownerName||e.owner_name,priority:e.priority,status:e.status??e.currentStatus??e.current_status,onHoldPeriods:D,dependencies:F,dependencyRule:y,segments:Mr(e.segments,o,r),sequence_id:e.sequence_id,stage_id:e.stage_id,tooltipConfig:e.tooltipConfig}},Lr=e=>Array.isArray(e)?e.map(Er):[],Fr=(e,a)=>{if(a.length===0)return e;const o=[...a].sort((s,r)=>s.start.getTime()-r.start.getTime());return e.map(s=>{if(s.onHoldPeriods&&s.onHoldPeriods.length>0||s.segments&&s.segments.length>0)return s;const r=s.start.getTime(),h=s.end.getTime(),g=h-r;if(g<=0){for(const T of o)if(r>=T.start.getTime()&&r<T.end.getTime())return{...s,start:new Date(T.end.getTime()),end:new Date(T.end.getTime())};return s}const l=o[o.length-1].end.getTime();if(r>=l)return s;const i=o[0].start.getTime();if(h<=i)return s;let x=r,p=0,S=0;const F=[],y=[];for(;p<g;){for(;S<o.length&&o[S].end.getTime()<=x;)S++;if(S<o.length){const T=o[S],$=T.start.getTime(),j=T.end.getTime();if(x<$){const m=$-x,A=Math.min(m,g-p);if(F.push({start:new Date(x),end:new Date(x+A),duration:Math.ceil(A/Ze)}),p+=A,x+=A,p>=g)break;y.push({start:new Date($),end:new Date(j)}),x=j,S++}else y.push({start:new Date(x),end:new Date(j)}),x=j,S++}else{const T=g-p;F.push({start:new Date(x),end:new Date(x+T),duration:Math.ceil(T/Ze)}),p=g}}if(y.length===0)return s;const D=F.length>0?F[F.length-1].end:s.end;return{...s,end:D,duration:Math.max(Math.ceil((D.getTime()-r)/Ze),0),segments:F,onHoldPeriods:y}})},Pr=e=>[{name:"index",label:"",width:40,align:"center"},{name:"text",label:e?.columnLabels?.name||"Name",width:250,align:"left",resize:!0},{name:"predecessors",label:e?.columnLabels?.dependsOn||"Depends on",width:120,align:"left"},{name:"duration",label:e?.columnLabels?.duration||"Duration",width:110,align:"left"},{name:"start",label:e?.columnLabels?.start||"Start",width:130,align:"left"}],Nr=[{unit:"month",step:1,format:"MMM"},{unit:"day",step:1,format:"D"}],kr={showTaskName:!0,showPlannedDates:!0,showActualDates:!0,showStatus:!0,showDependencyRule:!0,showProgress:!0,showOwner:!0,plannedLabel:"Planned",actualLabel:"Actual",statusLabel:"Status",dependencyRuleLabel:"Dependency Rule",progressLabel:"Progress",ownerLabel:"Owner",dateFormat:"MMM D, YYYY",dependencySeparator:" | ",emptyStatusText:"Not set",emptyOwnerText:"Not assigned",emptyDependencyRuleText:"No dependency rule"},Or={headerTitle:"Iris Gantt",showHeader:!0,showAddTaskButton:!0,showBaselineButton:!1,showZoomButtons:!0,showExportButtons:!0,showFilterSearch:!0,addTaskButtonText:"New Task",baselineButtonText:"Set Baseline",baselineButtonTextActive:"Baselines",zoomOutTooltip:"Zoom Out",zoomInTooltip:"Zoom In",resetZoomTooltip:"Reset Zoom",exportCSVTooltip:"Export to CSV",exportExcelTooltip:"Export to Excel",exportJSONTooltip:"Export to JSON",exportPDFTooltip:"Export to PDF",hideBaselinesTooltip:"Hide Baselines",showBaselinesTooltip:"Show Baselines",taskCreatorTitle:"Create New Task",taskCreatorOkText:"Create Task",taskCreatorCancelText:"Cancel",taskNameLabel:"Task Name",taskNamePlaceholder:"Enter task name",typeLabel:"Type",priorityLabel:"Priority",startDateLabel:"Start Date",durationLabel:"Duration (days)",colorLabel:"Color",progressLabel:"Progress (%)",ownerLabel:"Owner",ownerPlaceholder:"Assign to...",detailsLabel:"Details",detailsPlaceholder:"Add task description...",taskTypeOptions:{task:"Task",milestone:"Milestone",project:"Project"},priorityOptions:{low:"Low",medium:"Medium",high:"High"},taskEditorTitle:"Edit Task",taskEditorSaveText:"Save Changes",taskEditorCancelText:"Cancel",taskEditorDeleteText:"Delete",deleteConfirmTitle:"Delete Task",deleteConfirmContent:"This action cannot be undone.",deleteConfirmOkText:"Yes, Delete",deleteConfirmCancelText:"No",searchPlaceholder:"Search tasks...",allOwnersText:"All Owners",allStatusText:"All Status",allPriorityText:"All Priority",clearFiltersText:"Clear",statusOptions:{all:"All Status",notStarted:"Not Started",inProgress:"In Progress",completed:"Completed"},priorityFilterOptions:{all:"All Priority",low:"Low",medium:"Medium",high:"High"},columnLabels:{name:"Name",dependsOn:"Depends on",duration:"Duration",start:"Start"},taskNameRequired:"Please enter task name"},$r=({tasks:e=[],links:a=[],config:o={},uiConfig:s={},styleConfig:r={},iconConfig:h={},taskTooltipConfig:g={},onHoldPeriods:l,onTaskUpdate:i,onTaskDragUpdate:x,onTaskCreate:p,onTaskDelete:S,onLinkCreate:F,onLinkDelete:y,baselines:D})=>{const T={...Or,...s},$={...kr,...g},j=w.useMemo(()=>{const u={};return r.primary&&(u["--wx-gantt-primary"]=r.primary),r.primarySelected&&(u["--wx-gantt-primary-selected"]=r.primarySelected),r.success&&(u["--wx-gantt-success"]=r.success),r.warning&&(u["--wx-gantt-warning"]=r.warning),r.danger&&(u["--wx-gantt-danger"]=r.danger),r.background&&(u["--wx-gantt-background"]=r.background),r.backgroundAlt&&(u["--wx-gantt-background-alt"]=r.backgroundAlt),r.backgroundHover&&(u["--wx-gantt-background-hover"]=r.backgroundHover),r.selectColor&&(u["--wx-gantt-select-color"]=r.selectColor),r.taskColor&&(u["--wx-gantt-task-color"]=r.taskColor),r.taskFillColor&&(u["--wx-gantt-task-fill-color"]=r.taskFillColor),r.projectColor&&(u["--wx-gantt-project-color"]=r.projectColor),r.milestoneColor&&(u["--wx-gantt-milestone-color"]=r.milestoneColor),r.fontColor&&(u["--wx-gantt-font-color"]=r.fontColor),r.fontColorAlt&&(u["--wx-gantt-font-color-alt"]=r.fontColorAlt),r.iconColor&&(u["--wx-gantt-icon-color"]=r.iconColor),r.borderColor&&(u["--wx-gantt-border-color"]=r.borderColor),r.fontFamily&&(u["--wx-gantt-font-family"]=r.fontFamily),r.fontMono&&(u["--wx-gantt-font-mono"]=r.fontMono),r.fontSize&&(u["--wx-gantt-font-size"]=r.fontSize),r.fontWeight&&(u["--wx-gantt-font-weight"]=String(r.fontWeight)),r.lineHeight&&(u["--wx-gantt-line-height"]=String(r.lineHeight)),r.spacingXS&&(u["--gantt-spacing-xs"]=r.spacingXS),r.spacingSM&&(u["--gantt-spacing-sm"]=r.spacingSM),r.spacingMD&&(u["--gantt-spacing-md"]=r.spacingMD),r.spacingLG&&(u["--gantt-spacing-lg"]=r.spacingLG),r.customCSSVariables&&Object.entries(r.customCSSVariables).forEach(([M,n])=>{u[M.startsWith("--")?M:`--${M}`]=n}),u},[r]),m=w.useMemo(()=>{if(!l||l.length===0)return[];const u=new Date;return l.map(M=>({start:Me(M.start,u),end:Me(M.end,u)})).filter(M=>M.end.getTime()>M.start.getTime())},[l]),A=w.useMemo(()=>{const u=Lr(e);return Fr(u,m)},[e,m]),K=Array.isArray(a)?a:[],{tasks:k,links:U,setTasks:ee,setLinks:P,undo:J,redo:X,updateTask:E,createTask:W,deleteTask:Q,saveState:oe}=Ht(A,K),[H,he]=w.useState(k),[le,B]=w.useState(null),[ue,me]=w.useState(null),[ye,re]=w.useState(!1),[pe,Z]=w.useState(void 0),[be,ae]=w.useState(void 0),[ve,O]=w.useState(!1),[c,v]=w.useState(null),[C,N]=w.useState(null),[V,se]=w.useState(null),[G,de]=w.useState(null),[ie,je]=w.useState(null),[De,Ve]=w.useState(1),[Ae,Fe]=w.useState(()=>D&&D.size>0?D:A.length>0?Xt(A):new Map);w.useEffect(()=>{D&&D.size>0&&Fe(D)},[D]);const[it]=w.useState(o.theme||"light"),[lt,dt]=w.useState({searchText:"",status:"all",priority:"all",owner:""}),Qe=w.useRef(null),Xe=w.useRef(null),Dt=w.useRef(null),et=w.useRef(null),ke=w.useRef(null),ct=w.useRef(null),Ee={columns:o.columns||Pr(s),scales:Nr,readonly:!1,editable:!0,taskHeight:28,rowHeight:48,scaleHeight:28,columnWidth:80,minColumnWidth:60,autoSchedule:!1,criticalPath:!1,baselines:!0,weekends:!0,holidays:[],theme:it,locale:"en",showTodayLine:o.showTodayLine!==!1,todayLineColor:o.todayLineColor||"#ff4d4f",todayLineLabel:o.todayLineLabel!==void 0?o.todayLineLabel:"Today",todayLineWidth:o.todayLineWidth||1,todayLineStyle:o.todayLineStyle||"solid",todayLineOpacity:o.todayLineOpacity!==void 0?o.todayLineOpacity:1,todayLineLabelStyle:o.todayLineLabelStyle,showTodayLineMarker:o.showTodayLineMarker!==!1,todayLineMarkerSize:o.todayLineMarkerSize||8,todayLineMarkerStyle:o.todayLineMarkerStyle||"triangle",showProjectStartLine:o.showProjectStartLine!==!1,projectStartDate:o.projectStartDate,projectStartLineColor:o.projectStartLineColor||"#40a9ff",projectStartLineLabel:o.projectStartLineLabel!==void 0?o.projectStartLineLabel:"Start Project",projectStartLineWidth:o.projectStartLineWidth||1,projectStartLineStyle:o.projectStartLineStyle||"solid",projectStartLineOpacity:o.projectStartLineOpacity!==void 0?o.projectStartLineOpacity:1,projectStartLineLabelStyle:o.projectStartLineLabelStyle,showProjectStartLineMarker:o.showProjectStartLineMarker!==!1,projectStartLineMarkerSize:o.projectStartLineMarkerSize||8,projectStartLineMarkerStyle:o.projectStartLineMarkerStyle||"triangle",...o};w.useEffect(()=>{const u=Kt(k,lt);he((n=>{const d=[],b=L=>{if(!L)return!1;const I=n.find(R=>R.id===L);return I&&!I.open&&I.type==="project"?!0:b(I?.parent)};return n.forEach(L=>{b(L.parent)||d.push(L)}),d})(u))},[k,lt]);const Mt=w.useMemo(()=>{if(!k||!Array.isArray(k))return[];try{return Array.from(new Set(k.map(u=>u?.owner).filter(Boolean)))}catch(u){return console.warn("Error extracting owners:",u),[]}},[k]),Et=(()=>{const u=H.length>0?H:k;if(u.length===0){const L=new Date;return{start:_e(xe(L,-30,"day")),end:_e(xe(L,60,"day"))}}const M=u.map(L=>L.start.getTime()),n=u.map(L=>L.end.getTime()),d=new Date(Math.min(...M)),b=new Date(Math.max(...n));return{start:_e(xe(d,-7,"day")),end:_e(b)}})(),Lt=u=>{B(u)},Ft=(u,M)=>{if(Ee.readonly)return;u.preventDefault();const n=k.find(d=>d.id===M);n&&je({x:u.clientX,y:u.clientY,task:n})},tt=()=>{if(!ie?.task)return;const u=ie.task,M={...u,id:`task-${Date.now()}`,text:`${u.text} (Copy)`,start:xe(u.start,7,"day"),end:xe(u.end,7,"day")};W(M),p&&p(M)},Ue=u=>{if(!ie?.task)return;const M={...ie.task,type:u};E(M),i&&i(M)},Le=w.useCallback((u,M)=>{let n=[];return M.filter(b=>b.parent===u).forEach(b=>{n.push(b.id),n=[...n,...Le(b.id,M)]}),n},[]),qe=(u,M)=>(u??null)===(M??null),rt=(u,M,n,d)=>{if(!Ee.readonly)if(d==="reorder"){const b=H.findIndex(I=>I.id===u),L=Le(u,k);se({id:u,initialIndex:b,currentX:M,currentY:n,descendantIds:L}),document.body.classList.add("gantt-dragging")}else N(u)},ut=()=>{if(V&&G){const u=k.find(n=>n.id===V.id),M=k.find(n=>n.id===G.taskId);if(u&&M&&u.id!==M.id){const n=[u.id,...V.descendantIds];if(!n.includes(M.id)){const d=[...k],b=(G.position==="inside"?M.id:M.parent)??void 0,L=d.findIndex(Y=>Y.id===u.id);L!==-1&&(d[L]={...d[L],parent:b});const I=d.filter(Y=>n.includes(Y.id)),R=d.filter(Y=>!n.includes(Y.id));let _=R.findIndex(Y=>Y.id===M.id);if(G.position==="inside"){const Y=[M.id,...Le(M.id,R)],Ie=Y[Y.length-1];_=R.findIndex(kt=>kt.id===Ie)+1}else if(G.position==="below"){const Y=Le(M.id,R);Y.length>0?_=R.findIndex(Ie=>Ie.id===Y[Y.length-1])+1:_++}_<0&&(_=R.length);const z={tasks:[...k],links:[...U]};R.splice(_,0,...I),ee(R),oe("task_update",z,{tasks:R,links:U});const te=k.filter(Y=>qe(Y.parent,u.parent)).findIndex(Y=>Y.id===u.id)+1,Se=R.filter(Y=>qe(Y.parent,b)).findIndex(Y=>Y.id===u.id)+1,Oe={currentSequenceId:te,targetSequenceId:Se,targetStageId:b??null},Pe=R.find(Y=>Y.id===u.id);if(Pe){const Y={...Pe,sequence_id:Se,stage_id:b??null};i&&i(Y,Oe),x&&x({task:Y,previousTask:u,dragType:"reorder",reorderMeta:Oe})}}}}N(null),se(null),de(null),document.body.classList.remove("gantt-dragging")},nt=w.useRef(null),pt=w.useCallback(u=>{if(V){const{clientX:M,clientY:n}=u;nt.current&&cancelAnimationFrame(nt.current),nt.current=requestAnimationFrame(()=>{const d=Ee.rowHeight||48,b=Xe.current?.querySelector(".gantt-grid-body");if(!b||H.length===0){de(null);return}const L=b.getBoundingClientRect(),I=n-L.top+b.scrollTop;let R=Math.floor(I/d);R=Math.max(0,Math.min(R,H.length-1));const _=H[R];if(_){if(_.id===V.id||V.descendantIds.includes(_.id)){de(null),se(ce=>ce?{...ce,currentX:M,currentY:n}:null);return}const ge=I-R*d;let te="above";_.type!=="milestone"?ge<d*.3?te="above":ge>d*.7?te="below":te="inside":te=ge<d/2?"above":"below",de({taskId:_.id,position:te})}se(z=>z?{...z,currentX:M,currentY:n}:null)})}},[V,H,Ee.rowHeight]),ht=()=>{V&&ut()},mt=(u,M)=>{const n={...u,id:`task-${Date.now()}`,parent:M};W(n);const d={taskId:n.id,start:new Date(n.start),end:new Date(n.end)};Fe(b=>{const L=new Map(b);return L.set(n.id,d),L}),p&&p(n)},Be=u=>{E(u),i&&i(u)},ft=u=>{Q(u),Fe(M=>{const n=new Map(M);return n.delete(u),n}),S&&S(u)},gt=(u,M,n,d)=>{const b={id:`link-${Date.now()}`,source:u,target:M,type:n,lag:d};P([...U,b]),F&&F(b)},ot=u=>{const M=U.filter(n=>n.id!==u);P(M),y&&y(u)};w.useEffect(()=>{const u=new Map(Ae);let M=!1;k.forEach(d=>{Ae.has(d.id)||(u.set(d.id,{taskId:d.id,start:new Date(d.start),end:new Date(d.end)}),M=!0)});const n=new Set(k.map(d=>d.id));Ae.forEach((d,b)=>{n.has(b)||(u.delete(b),M=!0)}),M&&Fe(u)},[k]),w.useEffect(()=>{const u=M=>{(M.ctrlKey||M.metaKey)&&(M.key==="z"&&!M.shiftKey?(M.preventDefault(),J()):(M.key==="y"||M.key==="z"&&M.shiftKey)&&(M.preventDefault(),X()))};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[J,X]),w.useEffect(()=>{const u=Xe.current?.querySelector(".gantt-grid-body"),M=Qe.current?.querySelector(".gantt-timeline-body");if(!u||!M)return;const n=()=>{ke.current!=="timeline"&&(ke.current="grid",M.scrollTop=u.scrollTop,requestAnimationFrame(()=>{ke.current=null}))},d=()=>{ke.current!=="grid"&&(ke.current="timeline",u.scrollTop=M.scrollTop,requestAnimationFrame(()=>{ke.current=null}))};return u.addEventListener("scroll",n,{passive:!0}),M.addEventListener("scroll",d,{passive:!0}),()=>{u.removeEventListener("scroll",n),M.removeEventListener("scroll",d),ct.current&&clearTimeout(ct.current)}},[H]);const xt={height:o.containerHeight||"100%",minHeight:o.containerMinHeight||"400px"},Pt={"--gantt-row-height":`${Ee.rowHeight||48}px`},Nt=o.gridWidth?{"--gantt-grid-width":o.gridWidth}:{};return t.jsxs("div",{className:`gantt-page-wrapper theme-${it}`,style:{...xt,...j},children:[T.showHeader&&t.jsx("div",{className:"gantt-page-header",children:t.jsx("div",{className:"gantt-page-header-left",children:t.jsx("h1",{className:"gantt-page-title",children:T.headerTitle})})}),t.jsxs("div",{className:`gantt-container theme-${Ee.theme}`,ref:et,style:{...Nt,...Pt},children:[t.jsx(It,{zoomLevel:De,setZoomLevel:Ve,onExport:u=>{u==="csv"&&Ut(k),u==="excel"&&qt(k),u==="json"&&Gt(k,U),u==="pdf"&&Jt(k)},onFilterChange:u=>dt(u),owners:Mt||[],onAddTask:u=>{if(u){const M=k.find(n=>n.id===u);Z(u),ae(M?.text)}else Z(void 0),ae(void 0);re(!0)},uiConfig:T,iconConfig:h,styleConfig:r}),t.jsxs("div",{className:"gantt-layout",ref:Dt,onMouseMove:pt,onMouseUp:ht,onMouseLeave:ht,children:[t.jsx(St,{ref:Xe,tasks:H,columns:Ee.columns||[],selectedTask:le,onTaskClick:Lt,onTaskContextMenu:Ft,onTaskUpdate:Be,onTaskDragStart:rt,onAddTask:u=>{if(u){const M=k.find(n=>n.id===u);Z(u),ae(M?.text)}else Z(void 0),ae(void 0);re(!0)},onAddDependency:gt,onRemoveDependency:ot,onDependencyClick:u=>{const M=k.find(n=>n.id===u);M&&(v(M),O(!0))},links:U,allTasks:k,dropIndicator:G,reorderTask:V,iconConfig:h,styleConfig:r}),t.jsx(jt,{ref:Qe,tasks:H,links:U,range:Et,scales:Ee.scales,config:Ee,selectedTask:le,draggedTask:C,onTaskClick:()=>{},onTaskDragStart:()=>{},onTaskDragEnd:()=>{},onTaskUpdate:(u,M,n)=>{const d=k.find(I=>I.id===u);if(!d)return;const b={...d},L={...d,...M};Be(L),n&&x&&x({task:L,previousTask:b,dragType:n.dragType})},zoomLevel:De,baselines:Ae,taskTooltipConfig:$})]}),ye&&t.jsx(zt,{onCreateTask:mt,onClose:()=>{re(!1),Z(void 0),ae(void 0)},uiConfig:T,parentId:pe,parentTaskName:be,styleConfig:r}),ue&&t.jsx(Yt,{task:ue,onUpdate:Be,onDelete:ft,onClose:()=>me(null),uiConfig:T,styleConfig:r}),ve&&c&&t.jsx(Wt,{task:c,allTasks:k,links:U,onAddDependency:gt,onRemoveDependency:ot,onTaskUpdate:Be,onClose:()=>{O(!1),v(null)},styleConfig:r}),ie&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"gantt-context-menu-overlay",onClick:()=>je(null),onContextMenu:u=>{u.preventDefault(),je(null)}}),t.jsx(gr,{x:ie.x,y:ie.y,task:ie.task,onEdit:()=>{ie.task&&me(ie.task)},onDelete:()=>{ie.task&&ft(ie.task.id)},onCopy:tt,onDependencies:()=>{ie.task&&(v(ie.task),O(!0))},onConvertToMilestone:()=>Ue("milestone"),onConvertToTask:()=>Ue("task"),onConvertToProject:()=>Ue("project"),onClose:()=>je(null),onAutoSchedule:()=>{const u=Vt(k,U,{mode:"forward"});ee(u),je(null)},iconConfig:h,styleConfig:r})]}),V&&(()=>{const u=k.find(_=>_.id===V.id);if(!u)return null;const M=Number.isFinite(V.currentX)?V.currentX:0,n=Number.isFinite(V.currentY)?V.currentY:0,d=Ee.rowHeight||48,L=et.current?.getBoundingClientRect(),I=L?M-L.left+12:M+12,R=L?n-L.top+12:n+12;return t.jsxs("div",{className:"gantt-drag-preview",style:{height:d,top:R,left:I,position:"absolute",pointerEvents:"none",zIndex:9999,maxWidth:"420px"},children:[t.jsx("span",{className:"gantt-drag-preview-name",title:u.text,children:u.text}),V.descendantIds.length>0&&t.jsxs("span",{className:"gantt-drag-preview-count",children:["+",V.descendantIds.length]})]})})()]})]})},Cr=Object.freeze(Object.defineProperty({__proto__:null,calculateCriticalPath:(e,a)=>{const o=new Set,s=new Map,r=new Map,h=new Map;e.forEach(y=>{r.set(y.id,[]),h.set(y.id,[])}),a.forEach(y=>{y.type==="e2s"&&(r.get(y.source)?.push(y.target),h.get(y.target)?.push(y.source))});const g=new Map,l=new Map,i=(y,D=new Set)=>{if(D.has(y))return;D.add(y);const T=e.find(j=>j.id===y);if(!T)return;const $=h.get(y)||[];if($.length===0)g.set(y,0),l.set(y,T.duration);else{let j=0;$.forEach(m=>{i(m,D);const A=l.get(m)||0;j=Math.max(j,A)}),g.set(y,j),l.set(y,j+T.duration)}};e.forEach(y=>i(y.id));const x=new Map,p=new Map,S=Math.max(...Array.from(l.values())),F=(y,D=new Set)=>{if(D.has(y))return;D.add(y);const T=e.find(j=>j.id===y);if(!T)return;const $=r.get(y)||[];if($.length===0)p.set(y,S),x.set(y,S-T.duration);else{let j=1/0;$.forEach(m=>{F(m,D);const A=x.get(m)||0;j=Math.min(j,A)}),p.set(y,j),x.set(y,j-T.duration)}};return e.forEach(y=>F(y.id)),e.forEach(y=>{const D=g.get(y.id)||0,$=(x.get(y.id)||0)-D;s.set(y.id,$),Math.abs($)<.01&&o.add(y.id)}),{criticalTasks:o,taskFloats:s,projectDuration:S}},getTaskFloat:(e,a)=>a.taskFloats.get(e)||0,isCriticalTask:(e,a)=>a.criticalTasks.has(e)},Symbol.toStringTag,{value:"Module"}));q.AutoScheduler=wr,q.Chart=jt,q.CriticalPath=Cr,q.DependencyEditor=Wt,q.ExportUtils=vr,q.FilterSearch=Bt,q.Gantt=$r,q.Grid=St,q.TaskBar=Rt,q.TaskCreator=zt,q.TaskEditor=Yt,q.Timeline=vt,q.Toolbar=It,q.addToDate=xe,q.applyFilters=Kt,q.calculateDuration=nr,q.createBaseline=Xt,q.formatDate=we,q.getDaysBetween=ze,q.getEndOfDay=rr,q.getHoursBetween=_t,q.getStartOfDay=_e,q.isHoliday=wt,q.isWeekend=yt,q.useUndoRedo=Ht,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})}));
31
+ `.trim();st(a,"gantt-report.txt","text/plain"),alert("PDF export is a simplified text version. For full PDF with charts, a PDF library would be needed.")},br=(e,a,o="png")=>{if(!document.getElementById(e)){alert("Could not find Gantt chart element to export");return}if(o==="svg"){alert("SVG export requires additional library. Use PNG or implement with dom-to-svg.");return}alert("Image export requires html2canvas library. Install with: npm install html2canvas")},st=(e,a,o)=>{const s=new Blob([e],{type:o}),r=URL.createObjectURL(s);Sr(r,a),URL.revokeObjectURL(r)},Sr=(e,a)=>{const o=document.createElement("a");o.href=e,o.download=a,document.body.appendChild(o),o.click(),document.body.removeChild(o)},vr=Object.freeze(Object.defineProperty({__proto__:null,exportToCSV:Ut,exportToExcel:qt,exportToImage:br,exportToJSON:Gt,exportToPDF:Jt,importFromJSON:e=>new Promise((a,o)=>{const s=new FileReader;s.onload=r=>{try{const h=r.target?.result,g=JSON.parse(h),l=g.tasks.map(i=>({...i,start:new Date(i.start),end:new Date(i.end)}));a({tasks:l,links:g.links||[]})}catch{o(new Error("Invalid JSON file"))}},s.onerror=()=>o(new Error("Failed to read file")),s.readAsText(e)})},Symbol.toStringTag,{value:"Module"})),Kt=(e,a)=>e.filter(o=>{if(a.searchText){const s=a.searchText.toLowerCase(),r=o.text.toLowerCase().includes(s),h=o.owner?.toLowerCase().includes(s),g=o.details?.toLowerCase().includes(s);if(!r&&!h&&!g)return!1}if(a.status!=="all"&&(o.progress===0?"not-started":o.progress===100?"completed":"in-progress")!==a.status||a.priority!=="all"&&o.priority!==a.priority||a.owner&&o.owner!==a.owner)return!1;if(a.dateRange){const s=o.start.getTime(),r=a.dateRange.start.getTime(),h=a.dateRange.end.getTime();if(s<r||s>h)return!1}return!0}),Ze=1440*60*1e3,Me=(e,a)=>{if(e instanceof Date){const o=new Date(e.getTime());return Number.isNaN(o.getTime())?new Date(a.getTime()):o}if(typeof e=="string"||typeof e=="number"){const o=new Date(e);if(!Number.isNaN(o.getTime()))return o}return new Date(a.getTime())},Tt=(e,a)=>{if(e==null||e==="")return a;const o=Number(e);return Number.isFinite(o)?o:a},jr=e=>{if(Array.isArray(e)){const a=e.map(o=>String(o).trim()).filter(Boolean);return a.length>0?a:void 0}if(typeof e=="string"){const a=e.split(/[|,]/).map(o=>o.trim()).filter(Boolean);return a.length>0?a:void 0}},Tr=e=>{if(Array.isArray(e)){const a=e.map(o=>String(o).trim()).filter(Boolean);return a.length>0?a:void 0}if(typeof e=="string"){const a=e.split(/\r?\n|\|/).map(o=>o.trim()).filter(Boolean);return a.length>0?a:void 0}},Dr=(e,a,o)=>{if(!Array.isArray(e)||e.length===0)return;const s=a.getTime(),r=o.getTime();return e.map(h=>{const g=Me(h?.start,a),l=Me(h?.end,o),i=Math.max(g.getTime(),s),x=Math.min(l.getTime(),r);return{start:new Date(i),end:new Date(x)}}).filter(h=>h.end.getTime()>h.start.getTime())},Mr=(e,a,o)=>{if(Array.isArray(e))return e.map(s=>{const r=Me(s?.start,a),h=Me(s?.end,o),g=h.getTime()<r.getTime()?r:h,l=Math.max(Math.ceil((g.getTime()-r.getTime())/Ze),0);return{start:r,end:g,duration:Tt(s?.duration,l)}}).filter(s=>s.end.getTime()>=s.start.getTime())},Er=e=>{const a=new Date,o=Me(e.start??e.startDate??e.start_date,a),s=Me(e.end??e.endDate??e.end_date,o),r=s.getTime()<o.getTime()?o:s,h=Me(e.plannedStart??e.planned_start??e.planned_start_date,o),g=Me(e.plannedEnd??e.planned_end??e.planned_end_date,r),l=g.getTime()<h.getTime()?h:g,i=Me(e.actualStart??e.actual_start??e.actual_start_date,o),x=Me(e.actualEnd??e.actual_end??e.actual_end_date,r),p=x.getTime()<i.getTime()?i:x,S=Math.max(Math.ceil((r.getTime()-o.getTime())/Ze),0),F=jr(e.dependencies??e.dependsOn??e.depends_on),y=Tr(e.dependencyRule??e.dependency_rule??e.dependencyRuleDescription??e.dependency_rule_description),D=Dr(e.onHoldPeriods??e.on_hold_periods,o,r);return{id:String(e.id),rawId:e.id,text:e.text||e.name||e.title||e.taskName||e.task_name||`Task ${String(e.id)}`,start:o,end:r,plannedStart:h,plannedEnd:l,actualStart:i,actualEnd:p,duration:Tt(e.duration,S),progress:Math.max(0,Math.min(100,Tt(e.progress??e.progressPercentage??e.progress_percentage,0))),type:e.type,parent:e.parent!==void 0&&e.parent!==null&&String(e.parent).length>0?String(e.parent):void 0,open:e.open,color:e.color,details:e.details,owner:e.owner||e.ownerName||e.owner_name,priority:e.priority,status:e.status??e.currentStatus??e.current_status,onHoldPeriods:D,dependencies:F,dependencyRule:y,segments:Mr(e.segments,o,r),sequence_id:e.sequence_id,stage_id:e.stage_id,tooltipConfig:e.tooltipConfig}},Lr=e=>Array.isArray(e)?e.map(Er):[],Fr=(e,a)=>{if(a.length===0)return e;const o=[...a].sort((s,r)=>s.start.getTime()-r.start.getTime());return e.map(s=>{if(s.onHoldPeriods&&s.onHoldPeriods.length>0||s.segments&&s.segments.length>0)return s;const r=s.start.getTime(),h=s.end.getTime(),g=h-r;if(g<=0){for(const T of o)if(r>=T.start.getTime()&&r<T.end.getTime())return{...s,start:new Date(T.end.getTime()),end:new Date(T.end.getTime())};return s}const l=o[o.length-1].end.getTime();if(r>=l)return s;const i=o[0].start.getTime();if(h<=i)return s;let x=r,p=0,S=0;const F=[],y=[];for(;p<g;){for(;S<o.length&&o[S].end.getTime()<=x;)S++;if(S<o.length){const T=o[S],$=T.start.getTime(),j=T.end.getTime();if(x<$){const m=$-x,A=Math.min(m,g-p);if(F.push({start:new Date(x),end:new Date(x+A),duration:Math.ceil(A/Ze)}),p+=A,x+=A,p>=g)break;y.push({start:new Date($),end:new Date(j)}),x=j,S++}else y.push({start:new Date(x),end:new Date(j)}),x=j,S++}else{const T=g-p;F.push({start:new Date(x),end:new Date(x+T),duration:Math.ceil(T/Ze)}),p=g}}if(y.length===0)return s;const D=F.length>0?F[F.length-1].end:s.end;return{...s,end:D,duration:Math.max(Math.ceil((D.getTime()-r)/Ze),0),segments:F,onHoldPeriods:y}})},Pr=e=>[{name:"index",label:"",width:40,align:"center"},{name:"text",label:e?.columnLabels?.name||"Name",width:250,align:"left",resize:!0},{name:"predecessors",label:e?.columnLabels?.dependsOn||"Depends on",width:120,align:"left"},{name:"duration",label:e?.columnLabels?.duration||"Duration",width:110,align:"left"},{name:"start",label:e?.columnLabels?.start||"Start",width:130,align:"left"}],Nr=[{unit:"month",step:1,format:"MMM"},{unit:"day",step:1,format:"D"}],kr={showTaskName:!0,showPlannedDates:!0,showActualDates:!0,showStatus:!0,showDependencyRule:!0,showProgress:!0,showOwner:!0,plannedLabel:"Planned",actualLabel:"Actual",statusLabel:"Status",dependencyRuleLabel:"Dependency Rule",progressLabel:"Progress",ownerLabel:"Owner",dateFormat:"MMM D, YYYY",dependencySeparator:" | ",emptyStatusText:"Not set",emptyOwnerText:"Not assigned",emptyDependencyRuleText:"No dependency rule"},Or={headerTitle:"Iris Gantt",showHeader:!0,showAddTaskButton:!0,showBaselineButton:!1,showZoomButtons:!0,showExportButtons:!0,showFilterSearch:!0,addTaskButtonText:"New Task",baselineButtonText:"Set Baseline",baselineButtonTextActive:"Baselines",zoomOutTooltip:"Zoom Out",zoomInTooltip:"Zoom In",resetZoomTooltip:"Reset Zoom",exportCSVTooltip:"Export to CSV",exportExcelTooltip:"Export to Excel",exportJSONTooltip:"Export to JSON",exportPDFTooltip:"Export to PDF",hideBaselinesTooltip:"Hide Baselines",showBaselinesTooltip:"Show Baselines",taskCreatorTitle:"Create New Task",taskCreatorOkText:"Create Task",taskCreatorCancelText:"Cancel",taskNameLabel:"Task Name",taskNamePlaceholder:"Enter task name",typeLabel:"Type",priorityLabel:"Priority",startDateLabel:"Start Date",durationLabel:"Duration (days)",colorLabel:"Color",progressLabel:"Progress (%)",ownerLabel:"Owner",ownerPlaceholder:"Assign to...",detailsLabel:"Details",detailsPlaceholder:"Add task description...",taskTypeOptions:{task:"Task",milestone:"Milestone",project:"Project"},priorityOptions:{low:"Low",medium:"Medium",high:"High"},taskEditorTitle:"Edit Task",taskEditorSaveText:"Save Changes",taskEditorCancelText:"Cancel",taskEditorDeleteText:"Delete",deleteConfirmTitle:"Delete Task",deleteConfirmContent:"This action cannot be undone.",deleteConfirmOkText:"Yes, Delete",deleteConfirmCancelText:"No",searchPlaceholder:"Search tasks...",allOwnersText:"All Owners",allStatusText:"All Status",allPriorityText:"All Priority",clearFiltersText:"Clear",statusOptions:{all:"All Status",notStarted:"Not Started",inProgress:"In Progress",completed:"Completed"},priorityFilterOptions:{all:"All Priority",low:"Low",medium:"Medium",high:"High"},columnLabels:{name:"Name",dependsOn:"Depends on",duration:"Duration",start:"Start"},taskNameRequired:"Please enter task name"},$r=({tasks:e=[],links:a=[],config:o={},uiConfig:s={},styleConfig:r={},iconConfig:h={},taskTooltipConfig:g={},onHoldPeriods:l,onTaskUpdate:i,onTaskDragUpdate:x,onTaskCreate:p,onTaskDelete:S,onLinkCreate:F,onLinkDelete:y,baselines:D})=>{const T={...Or,...s},$={...kr,...g},j=w.useMemo(()=>{const u={};return r.primary&&(u["--wx-gantt-primary"]=r.primary),r.primarySelected&&(u["--wx-gantt-primary-selected"]=r.primarySelected),r.success&&(u["--wx-gantt-success"]=r.success),r.warning&&(u["--wx-gantt-warning"]=r.warning),r.danger&&(u["--wx-gantt-danger"]=r.danger),r.background&&(u["--wx-gantt-background"]=r.background),r.backgroundAlt&&(u["--wx-gantt-background-alt"]=r.backgroundAlt),r.backgroundHover&&(u["--wx-gantt-background-hover"]=r.backgroundHover),r.selectColor&&(u["--wx-gantt-select-color"]=r.selectColor),r.taskColor&&(u["--wx-gantt-task-color"]=r.taskColor),r.taskFillColor&&(u["--wx-gantt-task-fill-color"]=r.taskFillColor),r.projectColor&&(u["--wx-gantt-project-color"]=r.projectColor),r.milestoneColor&&(u["--wx-gantt-milestone-color"]=r.milestoneColor),r.fontColor&&(u["--wx-gantt-font-color"]=r.fontColor),r.fontColorAlt&&(u["--wx-gantt-font-color-alt"]=r.fontColorAlt),r.iconColor&&(u["--wx-gantt-icon-color"]=r.iconColor),r.borderColor&&(u["--wx-gantt-border-color"]=r.borderColor),r.fontFamily&&(u["--wx-gantt-font-family"]=r.fontFamily),r.fontMono&&(u["--wx-gantt-font-mono"]=r.fontMono),r.fontSize&&(u["--wx-gantt-font-size"]=r.fontSize),r.fontWeight&&(u["--wx-gantt-font-weight"]=String(r.fontWeight)),r.lineHeight&&(u["--wx-gantt-line-height"]=String(r.lineHeight)),r.spacingXS&&(u["--gantt-spacing-xs"]=r.spacingXS),r.spacingSM&&(u["--gantt-spacing-sm"]=r.spacingSM),r.spacingMD&&(u["--gantt-spacing-md"]=r.spacingMD),r.spacingLG&&(u["--gantt-spacing-lg"]=r.spacingLG),r.customCSSVariables&&Object.entries(r.customCSSVariables).forEach(([M,n])=>{u[M.startsWith("--")?M:`--${M}`]=n}),u},[r]),m=w.useMemo(()=>{if(!l||l.length===0)return[];const u=new Date;return l.map(M=>({start:Me(M.start,u),end:Me(M.end,u)})).filter(M=>M.end.getTime()>M.start.getTime())},[l]),A=w.useMemo(()=>{const u=Lr(e);return Fr(u,m)},[e,m]),K=Array.isArray(a)?a:[],{tasks:k,links:U,setTasks:ee,setLinks:P,undo:J,redo:X,updateTask:E,createTask:W,deleteTask:Q,saveState:oe}=Ht(A,K),[H,he]=w.useState(k),[le,B]=w.useState(null),[ue,me]=w.useState(null),[ye,re]=w.useState(!1),[pe,Z]=w.useState(void 0),[be,ae]=w.useState(void 0),[ve,O]=w.useState(!1),[c,v]=w.useState(null),[C,N]=w.useState(null),[V,se]=w.useState(null),[G,de]=w.useState(null),[ie,je]=w.useState(null),[De,Ve]=w.useState(1),[Ae,Fe]=w.useState(()=>D&&D.size>0?D:A.length>0?Xt(A):new Map);w.useEffect(()=>{D&&D.size>0&&Fe(D)},[D]);const[it]=w.useState(o.theme||"light"),[lt,dt]=w.useState({searchText:"",status:"all",priority:"all",owner:""}),Qe=w.useRef(null),Xe=w.useRef(null),Dt=w.useRef(null),et=w.useRef(null),ke=w.useRef(null),ct=w.useRef(null),Ee={columns:o.columns||Pr(s),scales:Nr,readonly:!1,editable:!0,taskHeight:28,rowHeight:48,scaleHeight:28,columnWidth:80,minColumnWidth:60,autoSchedule:!1,criticalPath:!1,weekends:!0,holidays:[],theme:it,locale:"en",showTodayLine:o.showTodayLine!==!1,todayLineColor:o.todayLineColor||"#ff4d4f",todayLineLabel:o.todayLineLabel!==void 0?o.todayLineLabel:"Today",todayLineWidth:o.todayLineWidth||1,todayLineStyle:o.todayLineStyle||"solid",todayLineOpacity:o.todayLineOpacity!==void 0?o.todayLineOpacity:1,todayLineLabelStyle:o.todayLineLabelStyle,showTodayLineMarker:o.showTodayLineMarker!==!1,todayLineMarkerSize:o.todayLineMarkerSize||8,todayLineMarkerStyle:o.todayLineMarkerStyle||"triangle",showProjectStartLine:o.showProjectStartLine!==!1,projectStartDate:o.projectStartDate,projectStartLineColor:o.projectStartLineColor||"#40a9ff",projectStartLineLabel:o.projectStartLineLabel!==void 0?o.projectStartLineLabel:"Start Project",projectStartLineWidth:o.projectStartLineWidth||1,projectStartLineStyle:o.projectStartLineStyle||"solid",projectStartLineOpacity:o.projectStartLineOpacity!==void 0?o.projectStartLineOpacity:1,projectStartLineLabelStyle:o.projectStartLineLabelStyle,showProjectStartLineMarker:o.showProjectStartLineMarker!==!1,projectStartLineMarkerSize:o.projectStartLineMarkerSize||8,projectStartLineMarkerStyle:o.projectStartLineMarkerStyle||"triangle",...o,baselines:o.baselines!==!1};w.useEffect(()=>{const u=Kt(k,lt);he((n=>{const d=[],b=L=>{if(!L)return!1;const I=n.find(R=>R.id===L);return I&&!I.open&&I.type==="project"?!0:b(I?.parent)};return n.forEach(L=>{b(L.parent)||d.push(L)}),d})(u))},[k,lt]);const Mt=w.useMemo(()=>{if(!k||!Array.isArray(k))return[];try{return Array.from(new Set(k.map(u=>u?.owner).filter(Boolean)))}catch(u){return console.warn("Error extracting owners:",u),[]}},[k]),Et=(()=>{const u=H.length>0?H:k;if(u.length===0){const L=new Date;return{start:_e(xe(L,-30,"day")),end:_e(xe(L,60,"day"))}}const M=u.map(L=>L.start.getTime()),n=u.map(L=>L.end.getTime()),d=new Date(Math.min(...M)),b=new Date(Math.max(...n));return{start:_e(xe(d,-7,"day")),end:_e(b)}})(),Lt=u=>{B(u)},Ft=(u,M)=>{if(Ee.readonly)return;u.preventDefault();const n=k.find(d=>d.id===M);n&&je({x:u.clientX,y:u.clientY,task:n})},tt=()=>{if(!ie?.task)return;const u=ie.task,M={...u,id:`task-${Date.now()}`,text:`${u.text} (Copy)`,start:xe(u.start,7,"day"),end:xe(u.end,7,"day")};W(M),p&&p(M)},Ue=u=>{if(!ie?.task)return;const M={...ie.task,type:u};E(M),i&&i(M)},Le=w.useCallback((u,M)=>{let n=[];return M.filter(b=>b.parent===u).forEach(b=>{n.push(b.id),n=[...n,...Le(b.id,M)]}),n},[]),qe=(u,M)=>(u??null)===(M??null),rt=(u,M,n,d)=>{if(!Ee.readonly)if(d==="reorder"){const b=H.findIndex(I=>I.id===u),L=Le(u,k);se({id:u,initialIndex:b,currentX:M,currentY:n,descendantIds:L}),document.body.classList.add("gantt-dragging")}else N(u)},ut=()=>{if(V&&G){const u=k.find(n=>n.id===V.id),M=k.find(n=>n.id===G.taskId);if(u&&M&&u.id!==M.id){const n=[u.id,...V.descendantIds];if(!n.includes(M.id)){const d=[...k],b=(G.position==="inside"?M.id:M.parent)??void 0,L=d.findIndex(Y=>Y.id===u.id);L!==-1&&(d[L]={...d[L],parent:b});const I=d.filter(Y=>n.includes(Y.id)),R=d.filter(Y=>!n.includes(Y.id));let _=R.findIndex(Y=>Y.id===M.id);if(G.position==="inside"){const Y=[M.id,...Le(M.id,R)],Ie=Y[Y.length-1];_=R.findIndex(kt=>kt.id===Ie)+1}else if(G.position==="below"){const Y=Le(M.id,R);Y.length>0?_=R.findIndex(Ie=>Ie.id===Y[Y.length-1])+1:_++}_<0&&(_=R.length);const z={tasks:[...k],links:[...U]};R.splice(_,0,...I),ee(R),oe("task_update",z,{tasks:R,links:U});const te=k.filter(Y=>qe(Y.parent,u.parent)).findIndex(Y=>Y.id===u.id)+1,Se=R.filter(Y=>qe(Y.parent,b)).findIndex(Y=>Y.id===u.id)+1,Oe={currentSequenceId:te,targetSequenceId:Se,targetStageId:b??null},Pe=R.find(Y=>Y.id===u.id);if(Pe){const Y={...Pe,sequence_id:Se,stage_id:b??null};i&&i(Y,Oe),x&&x({task:Y,previousTask:u,dragType:"reorder",reorderMeta:Oe})}}}}N(null),se(null),de(null),document.body.classList.remove("gantt-dragging")},nt=w.useRef(null),pt=w.useCallback(u=>{if(V){const{clientX:M,clientY:n}=u;nt.current&&cancelAnimationFrame(nt.current),nt.current=requestAnimationFrame(()=>{const d=Ee.rowHeight||48,b=Xe.current?.querySelector(".gantt-grid-body");if(!b||H.length===0){de(null);return}const L=b.getBoundingClientRect(),I=n-L.top+b.scrollTop;let R=Math.floor(I/d);R=Math.max(0,Math.min(R,H.length-1));const _=H[R];if(_){if(_.id===V.id||V.descendantIds.includes(_.id)){de(null),se(ce=>ce?{...ce,currentX:M,currentY:n}:null);return}const ge=I-R*d;let te="above";_.type!=="milestone"?ge<d*.3?te="above":ge>d*.7?te="below":te="inside":te=ge<d/2?"above":"below",de({taskId:_.id,position:te})}se(z=>z?{...z,currentX:M,currentY:n}:null)})}},[V,H,Ee.rowHeight]),ht=()=>{V&&ut()},mt=(u,M)=>{const n={...u,id:`task-${Date.now()}`,parent:M};W(n);const d={taskId:n.id,start:new Date(n.start),end:new Date(n.end)};Fe(b=>{const L=new Map(b);return L.set(n.id,d),L}),p&&p(n)},Be=u=>{E(u),i&&i(u)},ft=u=>{Q(u),Fe(M=>{const n=new Map(M);return n.delete(u),n}),S&&S(u)},gt=(u,M,n,d)=>{const b={id:`link-${Date.now()}`,source:u,target:M,type:n,lag:d};P([...U,b]),F&&F(b)},ot=u=>{const M=U.filter(n=>n.id!==u);P(M),y&&y(u)};w.useEffect(()=>{const u=new Map(Ae);let M=!1;k.forEach(d=>{Ae.has(d.id)||(u.set(d.id,{taskId:d.id,start:new Date(d.start),end:new Date(d.end)}),M=!0)});const n=new Set(k.map(d=>d.id));Ae.forEach((d,b)=>{n.has(b)||(u.delete(b),M=!0)}),M&&Fe(u)},[k]),w.useEffect(()=>{const u=M=>{(M.ctrlKey||M.metaKey)&&(M.key==="z"&&!M.shiftKey?(M.preventDefault(),J()):(M.key==="y"||M.key==="z"&&M.shiftKey)&&(M.preventDefault(),X()))};return window.addEventListener("keydown",u),()=>window.removeEventListener("keydown",u)},[J,X]),w.useEffect(()=>{const u=Xe.current?.querySelector(".gantt-grid-body"),M=Qe.current?.querySelector(".gantt-timeline-body");if(!u||!M)return;const n=()=>{ke.current!=="timeline"&&(ke.current="grid",M.scrollTop=u.scrollTop,requestAnimationFrame(()=>{ke.current=null}))},d=()=>{ke.current!=="grid"&&(ke.current="timeline",u.scrollTop=M.scrollTop,requestAnimationFrame(()=>{ke.current=null}))};return u.addEventListener("scroll",n,{passive:!0}),M.addEventListener("scroll",d,{passive:!0}),()=>{u.removeEventListener("scroll",n),M.removeEventListener("scroll",d),ct.current&&clearTimeout(ct.current)}},[H]);const xt={height:o.containerHeight||"100%",minHeight:o.containerMinHeight||"400px"},Pt={"--gantt-row-height":`${Ee.rowHeight||48}px`},Nt=o.gridWidth?{"--gantt-grid-width":o.gridWidth}:{};return t.jsxs("div",{className:`gantt-page-wrapper theme-${it}`,style:{...xt,...j},children:[T.showHeader&&t.jsx("div",{className:"gantt-page-header",children:t.jsx("div",{className:"gantt-page-header-left",children:t.jsx("h1",{className:"gantt-page-title",children:T.headerTitle})})}),t.jsxs("div",{className:`gantt-container theme-${Ee.theme}`,ref:et,style:{...Nt,...Pt},children:[t.jsx(It,{zoomLevel:De,setZoomLevel:Ve,onExport:u=>{u==="csv"&&Ut(k),u==="excel"&&qt(k),u==="json"&&Gt(k,U),u==="pdf"&&Jt(k)},onFilterChange:u=>dt(u),owners:Mt||[],onAddTask:u=>{if(u){const M=k.find(n=>n.id===u);Z(u),ae(M?.text)}else Z(void 0),ae(void 0);re(!0)},uiConfig:T,iconConfig:h,styleConfig:r}),t.jsxs("div",{className:"gantt-layout",ref:Dt,onMouseMove:pt,onMouseUp:ht,onMouseLeave:ht,children:[t.jsx(St,{ref:Xe,tasks:H,columns:Ee.columns||[],selectedTask:le,onTaskClick:Lt,onTaskContextMenu:Ft,onTaskUpdate:Be,onTaskDragStart:rt,onAddTask:u=>{if(u){const M=k.find(n=>n.id===u);Z(u),ae(M?.text)}else Z(void 0),ae(void 0);re(!0)},onAddDependency:gt,onRemoveDependency:ot,onDependencyClick:u=>{const M=k.find(n=>n.id===u);M&&(v(M),O(!0))},links:U,allTasks:k,dropIndicator:G,reorderTask:V,iconConfig:h,styleConfig:r}),t.jsx(jt,{ref:Qe,tasks:H,links:U,range:Et,scales:Ee.scales,config:Ee,selectedTask:le,draggedTask:C,onTaskClick:()=>{},onTaskDragStart:()=>{},onTaskDragEnd:()=>{},onTaskUpdate:(u,M,n)=>{const d=k.find(I=>I.id===u);if(!d)return;const b={...d},L={...d,...M};Be(L),n&&x&&x({task:L,previousTask:b,dragType:n.dragType})},zoomLevel:De,baselines:Ae,taskTooltipConfig:$})]}),ye&&t.jsx(zt,{onCreateTask:mt,onClose:()=>{re(!1),Z(void 0),ae(void 0)},uiConfig:T,parentId:pe,parentTaskName:be,styleConfig:r}),ue&&t.jsx(Yt,{task:ue,onUpdate:Be,onDelete:ft,onClose:()=>me(null),uiConfig:T,styleConfig:r}),ve&&c&&t.jsx(Wt,{task:c,allTasks:k,links:U,onAddDependency:gt,onRemoveDependency:ot,onTaskUpdate:Be,onClose:()=>{O(!1),v(null)},styleConfig:r}),ie&&t.jsxs(t.Fragment,{children:[t.jsx("div",{className:"gantt-context-menu-overlay",onClick:()=>je(null),onContextMenu:u=>{u.preventDefault(),je(null)}}),t.jsx(gr,{x:ie.x,y:ie.y,task:ie.task,onEdit:()=>{ie.task&&me(ie.task)},onDelete:()=>{ie.task&&ft(ie.task.id)},onCopy:tt,onDependencies:()=>{ie.task&&(v(ie.task),O(!0))},onConvertToMilestone:()=>Ue("milestone"),onConvertToTask:()=>Ue("task"),onConvertToProject:()=>Ue("project"),onClose:()=>je(null),onAutoSchedule:()=>{const u=Vt(k,U,{mode:"forward"});ee(u),je(null)},iconConfig:h,styleConfig:r})]}),V&&(()=>{const u=k.find(_=>_.id===V.id);if(!u)return null;const M=Number.isFinite(V.currentX)?V.currentX:0,n=Number.isFinite(V.currentY)?V.currentY:0,d=Ee.rowHeight||48,L=et.current?.getBoundingClientRect(),I=L?M-L.left+12:M+12,R=L?n-L.top+12:n+12;return t.jsxs("div",{className:"gantt-drag-preview",style:{height:d,top:R,left:I,position:"absolute",pointerEvents:"none",zIndex:9999,maxWidth:"420px"},children:[t.jsx("span",{className:"gantt-drag-preview-name",title:u.text,children:u.text}),V.descendantIds.length>0&&t.jsxs("span",{className:"gantt-drag-preview-count",children:["+",V.descendantIds.length]})]})})()]})]})},Cr=Object.freeze(Object.defineProperty({__proto__:null,calculateCriticalPath:(e,a)=>{const o=new Set,s=new Map,r=new Map,h=new Map;e.forEach(y=>{r.set(y.id,[]),h.set(y.id,[])}),a.forEach(y=>{y.type==="e2s"&&(r.get(y.source)?.push(y.target),h.get(y.target)?.push(y.source))});const g=new Map,l=new Map,i=(y,D=new Set)=>{if(D.has(y))return;D.add(y);const T=e.find(j=>j.id===y);if(!T)return;const $=h.get(y)||[];if($.length===0)g.set(y,0),l.set(y,T.duration);else{let j=0;$.forEach(m=>{i(m,D);const A=l.get(m)||0;j=Math.max(j,A)}),g.set(y,j),l.set(y,j+T.duration)}};e.forEach(y=>i(y.id));const x=new Map,p=new Map,S=Math.max(...Array.from(l.values())),F=(y,D=new Set)=>{if(D.has(y))return;D.add(y);const T=e.find(j=>j.id===y);if(!T)return;const $=r.get(y)||[];if($.length===0)p.set(y,S),x.set(y,S-T.duration);else{let j=1/0;$.forEach(m=>{F(m,D);const A=x.get(m)||0;j=Math.min(j,A)}),p.set(y,j),x.set(y,j-T.duration)}};return e.forEach(y=>F(y.id)),e.forEach(y=>{const D=g.get(y.id)||0,$=(x.get(y.id)||0)-D;s.set(y.id,$),Math.abs($)<.01&&o.add(y.id)}),{criticalTasks:o,taskFloats:s,projectDuration:S}},getTaskFloat:(e,a)=>a.taskFloats.get(e)||0,isCriticalTask:(e,a)=>a.criticalTasks.has(e)},Symbol.toStringTag,{value:"Module"}));q.AutoScheduler=wr,q.Chart=jt,q.CriticalPath=Cr,q.DependencyEditor=Wt,q.ExportUtils=vr,q.FilterSearch=Bt,q.Gantt=$r,q.Grid=St,q.TaskBar=Rt,q.TaskCreator=zt,q.TaskEditor=Yt,q.Timeline=vt,q.Toolbar=It,q.addToDate=xe,q.applyFilters=Kt,q.calculateDuration=nr,q.createBaseline=Xt,q.formatDate=we,q.getDaysBetween=ze,q.getEndOfDay=rr,q.getHoursBetween=_t,q.getStartOfDay=_e,q.isHoliday=wt,q.isWeekend=yt,q.useUndoRedo=Ht,Object.defineProperty(q,Symbol.toStringTag,{value:"Module"})}));
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "iris-gantt",
3
- "version": "1.4.3",
3
+ "version": "1.4.5",
4
4
  "description": "A comprehensive, production-ready Gantt chart component built with React and TypeScript. Easy to install, simple to use.",
5
5
  "keywords": [
6
6
  "gantt",