@workiom/frappe-gantt 1.0.14 → 1.0.15

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.
@@ -1748,16 +1748,21 @@ class j {
1748
1748
  var _, c, g;
1749
1749
  t = !1, n = !1, s = !1, (g = (c = (_ = this.$container.querySelector(".visible")) == null ? void 0 : _.classList) == null ? void 0 : c.remove) == null || g.call(c, "visible");
1750
1750
  }), u.on(this.$svg, "mouseup", (_) => {
1751
+ const c = this.bar_being_dragged === !0;
1751
1752
  this.bar_being_dragged = null;
1752
- const c = [];
1753
- a.forEach((g) => {
1754
- g.$bar.finaldx && (g.date_changed(), g.compute_progress(), g.set_action_completed(), c.push({
1755
- task: g.task,
1756
- start: g.task._start,
1757
- end: l.add(g.task._end, -1, "second")
1758
- }));
1759
- }), this.options.critical_path && a.some((g) => g.$bar.finaldx) && (this.calculate_critical_path(), this.update_arrow_critical_path()), c.length > 0 && c.forEach(({ task: g, start: p, end: w }) => {
1760
- this.trigger_event("after_date_change", [g, p, w]);
1753
+ const g = [];
1754
+ a.forEach((p) => {
1755
+ if (!p.$bar.finaldx) {
1756
+ c && p.set_action_completed();
1757
+ return;
1758
+ }
1759
+ p.date_changed(), p.compute_progress(), p.set_action_completed(), g.push({
1760
+ task: p.task,
1761
+ start: p.task._start,
1762
+ end: l.add(p.task._end, -1, "second")
1763
+ });
1764
+ }), this.options.critical_path && a.some((p) => p.$bar.finaldx) && (this.calculate_critical_path(), this.update_arrow_critical_path()), g.length > 0 && g.forEach(({ task: p, start: w, end: m }) => {
1765
+ this.trigger_event("after_date_change", [p, w, m]);
1761
1766
  });
1762
1767
  }), this.bind_bar_progress();
1763
1768
  }
@@ -26,4 +26,4 @@
26
26
  M0,4 l4,-4
27
27
  M3,5 l2,-2"
28
28
  style="stroke:grey; stroke-width:0.3" />
29
- </pattern>`;for(let i=new Date(this.gantt_start);i<=this.gantt_end;i.setDate(i.getDate()+1)){if(!this.config.ignored_dates.find(s=>s.getTime()==i.getTime())&&(!this.config.ignored_function||!this.config.ignored_function(i)))continue;let n=l.convert_scales(l.diff(i,this.gantt_start)+"d",this.config.unit)/this.config.step;this.config.ignored_positions.push(n*this.config.column_width),f("rect",{x:n*this.config.column_width,y:this.config.header_height,width:this.config.column_width,height:t,class:"ignored-bar",style:"fill: url(#diagonalHatch);",append_to:this.$svg})}this.highlight_current(this.config.view_mode)}create_el({left:t,top:e,width:i,height:n,id:s,classes:o,append_to:a,type:h}){let d=document.createElement(h||"div");for(let _ of o.split(" "))d.classList.add(_);return d.style.top=e+"px",d.style.left=t+"px",s&&(d.id=s),i&&(d.style.width=i+"px"),n&&(d.style.height=n+"px"),a&&a.appendChild(d),d}make_dates(){this.get_dates_to_draw().forEach((t,e)=>{if(t.lower_text){let i=this.create_el({left:t.x,top:t.lower_y,classes:"lower-text date_"+D(t.formatted_date),append_to:this.$lower_header});i.innerText=t.lower_text}if(t.upper_text){let i=this.create_el({left:t.x,top:t.upper_y,classes:"upper-text",append_to:this.$upper_header});i.innerText=t.upper_text}}),this.upperTexts=Array.from(this.$container.querySelectorAll(".upper-text"))}get_dates_to_draw(){let t=null;return this.dates.map((i,n)=>{const s=this.get_date_info(i,t,n);return t=s,s})}get_date_info(t,e){let i=e?e.date:null;this.config.column_width;const n=e?e.x+e.column_width:0;let s=this.config.view_mode.upper_text,o=this.config.view_mode.lower_text;return s?typeof s=="string"&&(this.config.view_mode.upper_text=a=>l.format(a,s,this.options.language)):this.config.view_mode.upper_text=()=>"",o?typeof o=="string"&&(this.config.view_mode.lower_text=a=>l.format(a,o,this.options.language)):this.config.view_mode.lower_text=()=>"",{date:t,formatted_date:D(l.format(t,this.config.date_format,this.options.language)),column_width:this.config.column_width,x:n,upper_text:this.config.view_mode.upper_text(t,i,this.options.language),lower_text:this.config.view_mode.lower_text(t,i,this.options.language),upper_y:17,lower_y:this.options.upper_header_height+5}}make_bars(){this.bars=this.tasks.map(t=>{const e=new q(this,t);return this.layers.bar.appendChild(e.group),e})}make_arrows(){this.arrows=[],this.options.critical_path&&this.calculate_critical_path();for(let t of this.tasks){let e=[];e=t.dependencies.map(i=>{const n=this.get_task(i);if(!n)return;const s=new C(this,this.bars[n._index],this.bars[t._index]);return this.layers.arrow.appendChild(s.element),s}).filter(Boolean),this.arrows=this.arrows.concat(e)}}calculate_critical_path(){this.tasks.forEach(s=>s._is_critical=!1);const t={};this.tasks.forEach(s=>{t[s.id]={es:0,ef:0,ls:0,lf:0}});const e=s=>{if(t[s.id].ef>0)return t[s.id];let o=0;s.dependencies&&s.dependencies.length>0&&s.dependencies.forEach(h=>{const d=this.get_task(h);if(d){const _=e(d);o=Math.max(o,_.ef)}}),t[s.id].es=o;const a=l.diff(s._end,s._start,"hour")/24;return t[s.id].ef=o+a,t[s.id]};this.tasks.forEach(s=>e(s));const i=Math.max(...Object.values(t).map(s=>s.ef)),n=s=>{if(t[s.id].ls>0||t[s.id].lf>0)return t[s.id];const o=this.tasks.filter(d=>d.dependencies&&d.dependencies.includes(s.id));let a=i;o.length>0&&o.forEach(d=>{const _=n(d);a=Math.min(a,_.ls)});const h=l.diff(s._end,s._start,"hour")/24;return t[s.id].lf=a,t[s.id].ls=a-h,t[s.id]};this.tasks.forEach(s=>n(s)),this.tasks.forEach(s=>{const o=t[s.id],a=o.ls-o.es;s._is_critical=Math.abs(a)<.01})}update_arrow_critical_path(){this.arrows.forEach(t=>{t.from_task.task._is_critical===!0&&t.to_task.task._is_critical===!0?t.element.classList.add("arrow-critical"):t.element.classList.remove("arrow-critical")})}map_arrows_on_bars(){for(let t of this.bars)t.arrows=this.arrows.filter(e=>e.from_task.task.id===t.task.id||e.to_task.task.id===t.task.id)}set_dimensions(){const{width:t}=this.$svg.getBoundingClientRect(),e=this.$svg.querySelector(".grid .grid-row")?this.$svg.querySelector(".grid .grid-row").getAttribute("width"):0;t<e&&this.$svg.setAttribute("width",e)}set_scroll_position(t){if(this.options.infinite_padding&&(!t||t==="start")){let[o,...a]=this.get_start_end_positions();this.$container.scrollLeft=o;return}if(!t||t==="start")t=this.gantt_start;else if(t==="end")t=this.gantt_end;else{if(t==="today")return this.scroll_current();typeof t=="string"&&(t=l.parse(t))}const i=l.diff(t,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width;this.$container.scrollTo({left:i-this.config.column_width/6,behavior:"smooth"}),this.$current&&this.$current.classList.remove("current-upper"),this.current_date=l.add(this.gantt_start,this.$container.scrollLeft/this.config.column_width,this.config.unit);let n=this.config.view_mode.upper_text(this.current_date,null,this.options.language),s=this.upperTexts.find(o=>o.textContent===n);this.current_date=l.add(this.gantt_start,(this.$container.scrollLeft+s.clientWidth)/this.config.column_width,this.config.unit),n=this.config.view_mode.upper_text(this.current_date,null,this.options.language),s=this.upperTexts.find(o=>o.textContent===n),s.classList.add("current-upper"),this.$current=s}scroll_current(){let t=this.get_closest_date();t&&this.set_scroll_position(t[0])}get_closest_date(){let t=new Date;if(t<this.gantt_start||t>this.gantt_end)return null;let e=new Date,i=this.$container.querySelector(".date_"+D(l.format(e,this.config.date_format,this.options.language))),n=0;for(;!i&&n<this.config.step;)e=l.add(e,-1,this.config.unit),i=this.$container.querySelector(".date_"+D(l.format(e,this.config.date_format,this.options.language))),n++;return[new Date(l.format(e,this.config.date_format,this.options.language)+" "),i]}bind_grid_click(){u.on(this.$container,"click",".grid-row, .grid-header, .ignored-bar, .holiday-highlight",()=>{this.unselect_all(),this.hide_popup()})}bind_holiday_labels(){const t=this.$container.querySelectorAll(".holiday-highlight");for(let e of t){const i=this.$container.querySelector(".label_"+e.classList[1]);if(!i)continue;let n;e.onmouseenter=s=>{n=setTimeout(()=>{i.classList.add("show"),i.style.left=(s.offsetX||s.layerX)+"px",i.style.top=(s.offsetY||s.layerY)+"px"},300)},e.onmouseleave=s=>{clearTimeout(n),i.classList.remove("show")}}}get_start_end_positions(){if(!this.bars.length)return[0,0,0];let{x:t,width:e}=this.bars[0].group.getBBox(),i=t,n=t,s=t+e;return Array.prototype.forEach.call(this.bars,function({group:o},a){let{x:h,width:d}=o.getBBox();h<i&&(i=h),h>n&&(n=h),h+d>s&&(s=h+d)}),[i,n,s]}bind_bar_events(){let t=!1,e=0,i=0,n=!1,s=!1,o=null,a=[];this.bar_being_dragged=null;const h=()=>t||n||s;this.$svg.onclick=_=>{_.target.classList.contains("grid-row")&&this.unselect_all()};let d=0;if(u.on(this.$svg,"mousemove",".bar-wrapper, .handle",_=>{this.bar_being_dragged===!1&&Math.abs((_.offsetX||_.layerX)-d)>10&&(this.bar_being_dragged=!0)}),u.on(this.$svg,"mousedown",".bar-wrapper, .handle",(_,c)=>{const g=u.closest(".bar-wrapper",c);c.classList.contains("left")?(n=!0,c.classList.add("visible")):c.classList.contains("right")?(s=!0,c.classList.add("visible")):c.classList.contains("bar-wrapper")&&(t=!0),this.popup&&this.popup.hide(),e=_.offsetX||_.layerX,o=g.getAttribute("data-id");const w=this.get_bar(o).task.dependencies_type||this.options.dependencies_type;let m;this.options.move_dependencies&&w==="fixed"?m=[o,...this.get_all_dependent_tasks(o)]:m=[o],a=m.map(k=>this.get_bar(k)),this.bar_being_dragged=!1,d=e,a.forEach(k=>{const y=k.$bar;y.ox=y.getX(),y.oy=y.getY(),y.owidth=y.getWidth(),y.finaldx=0})}),this.options.infinite_padding){let _=!1;u.on(this.$container,"mousewheel",c=>{let g=this.$container.scrollWidth/2;if(!_&&c.currentTarget.scrollLeft<=g){let p=c.currentTarget.scrollLeft;_=!0,this.gantt_start=l.add(this.gantt_start,-this.config.extend_by_units,this.config.unit),this.setup_date_values(),this.render(),c.currentTarget.scrollLeft=p+this.config.column_width*this.config.extend_by_units,setTimeout(()=>_=!1,300)}if(!_&&c.currentTarget.scrollWidth-(c.currentTarget.scrollLeft+c.currentTarget.clientWidth)<=g){let p=c.currentTarget.scrollLeft;_=!0,this.gantt_end=l.add(this.gantt_end,this.config.extend_by_units,this.config.unit),this.setup_date_values(),this.render(),c.currentTarget.scrollLeft=p,setTimeout(()=>_=!1,300)}})}u.on(this.$container,"scroll",_=>{let c=[];const g=this.bars.map(({group:$})=>$.getAttribute("data-id"));let p;i&&(p=_.currentTarget.scrollLeft-i),this.current_date=l.add(this.gantt_start,_.currentTarget.scrollLeft/this.config.column_width*this.config.step,this.config.unit);let w=this.config.view_mode.upper_text(this.current_date,null,this.options.language),m=this.upperTexts.find($=>$.textContent===w);this.current_date=l.add(this.gantt_start,(_.currentTarget.scrollLeft+m.clientWidth)/this.config.column_width*this.config.step,this.config.unit),w=this.config.view_mode.upper_text(this.current_date,null,this.options.language),m=this.upperTexts.find($=>$.textContent===w),m!==this.$current&&(this.$current&&this.$current.classList.remove("current-upper"),m.classList.add("current-upper"),this.$current=m),i=_.currentTarget.scrollLeft;let[k,y,N]=this.get_start_end_positions();i>N+100?(this.$adjust.innerHTML="&larr;",this.$adjust.classList.remove("hide"),this.$adjust.onclick=()=>{this.$container.scrollTo({left:y,behavior:"smooth"})}):i+_.currentTarget.offsetWidth<k-100?(this.$adjust.innerHTML="&rarr;",this.$adjust.classList.remove("hide"),this.$adjust.onclick=()=>{this.$container.scrollTo({left:k,behavior:"smooth"})}):this.$adjust.classList.add("hide"),p&&(c=g.map($=>this.get_bar($)),this.options.auto_move_label&&c.forEach($=>{$.update_label_position_on_horizontal_scroll({x:p,sx:_.currentTarget.scrollLeft})}))}),u.on(this.$svg,"mousemove",_=>{if(!h())return;const c=(_.offsetX||_.layerX)-e;a.forEach(g=>{const p=g.$bar;p.finaldx=this.get_snap_position(c,p.ox),this.hide_popup(),n?o===g.task.id?g.update_bar_position({x:p.ox+p.finaldx,width:p.owidth-p.finaldx}):g.update_bar_position({x:p.ox+p.finaldx}):s?o===g.task.id&&g.update_bar_position({width:p.owidth+p.finaldx}):t&&!this.options.readonly&&!this.options.readonly_dates&&g.update_bar_position({x:p.ox+p.finaldx})})}),document.addEventListener("mouseup",()=>{var _,c,g;t=!1,n=!1,s=!1,(g=(c=(_=this.$container.querySelector(".visible"))==null?void 0:_.classList)==null?void 0:c.remove)==null||g.call(c,"visible")}),u.on(this.$svg,"mouseup",_=>{this.bar_being_dragged=null;const c=[];a.forEach(g=>{g.$bar.finaldx&&(g.date_changed(),g.compute_progress(),g.set_action_completed(),c.push({task:g.task,start:g.task._start,end:l.add(g.task._end,-1,"second")}))}),this.options.critical_path&&a.some(g=>g.$bar.finaldx)&&(this.calculate_critical_path(),this.update_arrow_critical_path()),c.length>0&&c.forEach(({task:g,start:p,end:w})=>{this.trigger_event("after_date_change",[g,p,w])})}),this.bind_bar_progress()}bind_bar_progress(){let t=0,e=null,i=null,n=null,s=null;u.on(this.$svg,"mousedown",".handle.progress",(a,h)=>{e=!0,t=a.offsetX||a.layerX;const _=u.closest(".bar-wrapper",h).getAttribute("data-id");i=this.get_bar(_),n=i.$bar_progress,s=i.$bar,n.finaldx=0,n.owidth=n.getWidth(),n.min_dx=-n.owidth,n.max_dx=s.getWidth()-n.getWidth()});const o=this.config.ignored_positions.map(a=>[a,a+this.config.column_width]);u.on(this.$svg,"mousemove",a=>{if(!e)return;let h=a.offsetX||a.layerX;if(h>t){let c=o.find(([g,p])=>h>=g&&h<p);for(;c;)h=c[1],c=o.find(([g,p])=>h>=g&&h<p)}else{let c=o.find(([g,p])=>h>g&&h<=p);for(;c;)h=c[0],c=o.find(([g,p])=>h>g&&h<=p)}let _=h-t;console.log(n),_>n.max_dx&&(_=n.max_dx),_<n.min_dx&&(_=n.min_dx),n.setAttribute("width",n.owidth+_),u.attr(i.$handle_progress,"cx",n.getEndX()),n.finaldx=_}),u.on(this.$svg,"mouseup",()=>{e=!1,n&&n.finaldx&&(n.finaldx=0,i.progress_changed(),i.set_action_completed(),i=null,n=null,s=null)})}get_all_dependent_tasks(t){let e=[],i=[t];for(;i.length;){const n=i.reduce((s,o)=>(s=s.concat(this.dependency_map[o]),s),[]);e=e.concat(n),i=n.filter(s=>!i.includes(s))}return e.filter(Boolean)}update_dependent_tasks_by_type(t){const e=t.task.dependencies_type||this.options.dependencies_type,i=[];return e==="fixed"||(this.dependency_map[t.task.id]||[]).forEach(s=>{const o=this.get_bar(s);if(!o)return;const a=o.task,h=a.dependencies_type||this.options.dependencies_type;let d,_;const c=l.diff(a._end,a._start,"hour");let g=!1;switch(h){case"finish-to-start":t.task._end>a._start&&(d=new Date(t.task._end),_=l.add(d,c,"hour"),g=!0);break;case"start-to-start":t.task._start>a._start&&(d=new Date(t.task._start),_=l.add(d,c,"hour"),g=!0);break;case"finish-to-finish":t.task._end>a._end&&(_=new Date(t.task._end),d=l.add(_,-c,"hour"),g=!0);break;case"start-to-finish":t.task._start>a._end&&(_=new Date(t.task._start),d=l.add(_,-c,"hour"),g=!0);break;default:return}if(!g)return;a._start=d,a._end=_,o.compute_x(),o.compute_duration(),o.update_bar_position({x:o.x,width:o.width}),this.trigger_event("date_change",[a,d,l.add(_,-1,"second")]),i.push({task:a,start:d,end:l.add(_,-1,"second")});const p=this.update_dependent_tasks_by_type(o);i.push(...p)}),i}get_snap_position(t,e){let i=1;const n=this.options.snap_at||this.config.view_mode.snap_at||"1d";if(n!=="unit"){const{duration:_,scale:c}=l.parse_duration(n);i=l.convert_scales(this.config.view_mode.step,c)/_}const s=t%(this.config.column_width/i);let o=t-s+(s<this.config.column_width/i*2?0:this.config.column_width/i),a=e+o;const h=o>0?1:-1;let d=this.get_ignored_region(a,h);for(;d.length;)a+=this.config.column_width*h,d=this.get_ignored_region(a,h),d.length||(a-=this.config.column_width*h);return a-e}get_ignored_region(t,e=1){return e===1?this.config.ignored_positions.filter(i=>t>i&&t<=i+this.config.column_width):this.config.ignored_positions.filter(i=>t>=i&&t<i+this.config.column_width)}unselect_all(){this.popup&&this.popup.parent.classList.add("hide"),this.$container.querySelectorAll(".date-range-highlight").forEach(t=>t.classList.add("hide"))}view_is(t){return typeof t=="string"?this.config.view_mode.name===t:Array.isArray(t)?t.some(view_is):this.config.view_mode.name===t.name}get_task(t){return this.tasks.find(e=>e.id===t)}get_bar(t){return this.bars.find(e=>e.task.id===t)}show_popup(t){this.options.popup!==!1&&(this.popup||(this.popup=new F(this.$popup_wrapper,this.options.popup,this)),this.popup.show(t))}hide_popup(){this.popup&&this.popup.hide()}trigger_event(t,e){this.options["on_"+t]&&this.options["on_"+t].apply(this,e)}get_oldest_starting_date(){return this.tasks.length?this.tasks.map(t=>t._start).reduce((t,e)=>e<=t?e:t):new Date}clear(){var t,e,i,n,s,o,a,h,d,_;this.$svg.innerHTML="",(e=(t=this.$header)==null?void 0:t.remove)==null||e.call(t),(n=(i=this.$side_header)==null?void 0:i.remove)==null||n.call(i),(o=(s=this.$current_highlight)==null?void 0:s.remove)==null||o.call(s),(h=(a=this.$extras)==null?void 0:a.remove)==null||h.call(a),(_=(d=this.popup)==null?void 0:d.hide)==null||_.call(d)}}X.VIEW_MODE={HOUR:b[0],QUARTER_DAY:b[1],HALF_DAY:b[2],DAY:b[3],WEEK:b[4],MONTH:b[5],YEAR:b[6]};function j(r){return r.name+"_"+Math.random().toString(36).slice(2,12)}function D(r){return r.replaceAll(" ","_").replaceAll(":","_").replaceAll(".","_")}return X});
29
+ </pattern>`;for(let i=new Date(this.gantt_start);i<=this.gantt_end;i.setDate(i.getDate()+1)){if(!this.config.ignored_dates.find(s=>s.getTime()==i.getTime())&&(!this.config.ignored_function||!this.config.ignored_function(i)))continue;let n=l.convert_scales(l.diff(i,this.gantt_start)+"d",this.config.unit)/this.config.step;this.config.ignored_positions.push(n*this.config.column_width),f("rect",{x:n*this.config.column_width,y:this.config.header_height,width:this.config.column_width,height:t,class:"ignored-bar",style:"fill: url(#diagonalHatch);",append_to:this.$svg})}this.highlight_current(this.config.view_mode)}create_el({left:t,top:e,width:i,height:n,id:s,classes:o,append_to:a,type:h}){let d=document.createElement(h||"div");for(let _ of o.split(" "))d.classList.add(_);return d.style.top=e+"px",d.style.left=t+"px",s&&(d.id=s),i&&(d.style.width=i+"px"),n&&(d.style.height=n+"px"),a&&a.appendChild(d),d}make_dates(){this.get_dates_to_draw().forEach((t,e)=>{if(t.lower_text){let i=this.create_el({left:t.x,top:t.lower_y,classes:"lower-text date_"+D(t.formatted_date),append_to:this.$lower_header});i.innerText=t.lower_text}if(t.upper_text){let i=this.create_el({left:t.x,top:t.upper_y,classes:"upper-text",append_to:this.$upper_header});i.innerText=t.upper_text}}),this.upperTexts=Array.from(this.$container.querySelectorAll(".upper-text"))}get_dates_to_draw(){let t=null;return this.dates.map((i,n)=>{const s=this.get_date_info(i,t,n);return t=s,s})}get_date_info(t,e){let i=e?e.date:null;this.config.column_width;const n=e?e.x+e.column_width:0;let s=this.config.view_mode.upper_text,o=this.config.view_mode.lower_text;return s?typeof s=="string"&&(this.config.view_mode.upper_text=a=>l.format(a,s,this.options.language)):this.config.view_mode.upper_text=()=>"",o?typeof o=="string"&&(this.config.view_mode.lower_text=a=>l.format(a,o,this.options.language)):this.config.view_mode.lower_text=()=>"",{date:t,formatted_date:D(l.format(t,this.config.date_format,this.options.language)),column_width:this.config.column_width,x:n,upper_text:this.config.view_mode.upper_text(t,i,this.options.language),lower_text:this.config.view_mode.lower_text(t,i,this.options.language),upper_y:17,lower_y:this.options.upper_header_height+5}}make_bars(){this.bars=this.tasks.map(t=>{const e=new q(this,t);return this.layers.bar.appendChild(e.group),e})}make_arrows(){this.arrows=[],this.options.critical_path&&this.calculate_critical_path();for(let t of this.tasks){let e=[];e=t.dependencies.map(i=>{const n=this.get_task(i);if(!n)return;const s=new C(this,this.bars[n._index],this.bars[t._index]);return this.layers.arrow.appendChild(s.element),s}).filter(Boolean),this.arrows=this.arrows.concat(e)}}calculate_critical_path(){this.tasks.forEach(s=>s._is_critical=!1);const t={};this.tasks.forEach(s=>{t[s.id]={es:0,ef:0,ls:0,lf:0}});const e=s=>{if(t[s.id].ef>0)return t[s.id];let o=0;s.dependencies&&s.dependencies.length>0&&s.dependencies.forEach(h=>{const d=this.get_task(h);if(d){const _=e(d);o=Math.max(o,_.ef)}}),t[s.id].es=o;const a=l.diff(s._end,s._start,"hour")/24;return t[s.id].ef=o+a,t[s.id]};this.tasks.forEach(s=>e(s));const i=Math.max(...Object.values(t).map(s=>s.ef)),n=s=>{if(t[s.id].ls>0||t[s.id].lf>0)return t[s.id];const o=this.tasks.filter(d=>d.dependencies&&d.dependencies.includes(s.id));let a=i;o.length>0&&o.forEach(d=>{const _=n(d);a=Math.min(a,_.ls)});const h=l.diff(s._end,s._start,"hour")/24;return t[s.id].lf=a,t[s.id].ls=a-h,t[s.id]};this.tasks.forEach(s=>n(s)),this.tasks.forEach(s=>{const o=t[s.id],a=o.ls-o.es;s._is_critical=Math.abs(a)<.01})}update_arrow_critical_path(){this.arrows.forEach(t=>{t.from_task.task._is_critical===!0&&t.to_task.task._is_critical===!0?t.element.classList.add("arrow-critical"):t.element.classList.remove("arrow-critical")})}map_arrows_on_bars(){for(let t of this.bars)t.arrows=this.arrows.filter(e=>e.from_task.task.id===t.task.id||e.to_task.task.id===t.task.id)}set_dimensions(){const{width:t}=this.$svg.getBoundingClientRect(),e=this.$svg.querySelector(".grid .grid-row")?this.$svg.querySelector(".grid .grid-row").getAttribute("width"):0;t<e&&this.$svg.setAttribute("width",e)}set_scroll_position(t){if(this.options.infinite_padding&&(!t||t==="start")){let[o,...a]=this.get_start_end_positions();this.$container.scrollLeft=o;return}if(!t||t==="start")t=this.gantt_start;else if(t==="end")t=this.gantt_end;else{if(t==="today")return this.scroll_current();typeof t=="string"&&(t=l.parse(t))}const i=l.diff(t,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width;this.$container.scrollTo({left:i-this.config.column_width/6,behavior:"smooth"}),this.$current&&this.$current.classList.remove("current-upper"),this.current_date=l.add(this.gantt_start,this.$container.scrollLeft/this.config.column_width,this.config.unit);let n=this.config.view_mode.upper_text(this.current_date,null,this.options.language),s=this.upperTexts.find(o=>o.textContent===n);this.current_date=l.add(this.gantt_start,(this.$container.scrollLeft+s.clientWidth)/this.config.column_width,this.config.unit),n=this.config.view_mode.upper_text(this.current_date,null,this.options.language),s=this.upperTexts.find(o=>o.textContent===n),s.classList.add("current-upper"),this.$current=s}scroll_current(){let t=this.get_closest_date();t&&this.set_scroll_position(t[0])}get_closest_date(){let t=new Date;if(t<this.gantt_start||t>this.gantt_end)return null;let e=new Date,i=this.$container.querySelector(".date_"+D(l.format(e,this.config.date_format,this.options.language))),n=0;for(;!i&&n<this.config.step;)e=l.add(e,-1,this.config.unit),i=this.$container.querySelector(".date_"+D(l.format(e,this.config.date_format,this.options.language))),n++;return[new Date(l.format(e,this.config.date_format,this.options.language)+" "),i]}bind_grid_click(){u.on(this.$container,"click",".grid-row, .grid-header, .ignored-bar, .holiday-highlight",()=>{this.unselect_all(),this.hide_popup()})}bind_holiday_labels(){const t=this.$container.querySelectorAll(".holiday-highlight");for(let e of t){const i=this.$container.querySelector(".label_"+e.classList[1]);if(!i)continue;let n;e.onmouseenter=s=>{n=setTimeout(()=>{i.classList.add("show"),i.style.left=(s.offsetX||s.layerX)+"px",i.style.top=(s.offsetY||s.layerY)+"px"},300)},e.onmouseleave=s=>{clearTimeout(n),i.classList.remove("show")}}}get_start_end_positions(){if(!this.bars.length)return[0,0,0];let{x:t,width:e}=this.bars[0].group.getBBox(),i=t,n=t,s=t+e;return Array.prototype.forEach.call(this.bars,function({group:o},a){let{x:h,width:d}=o.getBBox();h<i&&(i=h),h>n&&(n=h),h+d>s&&(s=h+d)}),[i,n,s]}bind_bar_events(){let t=!1,e=0,i=0,n=!1,s=!1,o=null,a=[];this.bar_being_dragged=null;const h=()=>t||n||s;this.$svg.onclick=_=>{_.target.classList.contains("grid-row")&&this.unselect_all()};let d=0;if(u.on(this.$svg,"mousemove",".bar-wrapper, .handle",_=>{this.bar_being_dragged===!1&&Math.abs((_.offsetX||_.layerX)-d)>10&&(this.bar_being_dragged=!0)}),u.on(this.$svg,"mousedown",".bar-wrapper, .handle",(_,c)=>{const g=u.closest(".bar-wrapper",c);c.classList.contains("left")?(n=!0,c.classList.add("visible")):c.classList.contains("right")?(s=!0,c.classList.add("visible")):c.classList.contains("bar-wrapper")&&(t=!0),this.popup&&this.popup.hide(),e=_.offsetX||_.layerX,o=g.getAttribute("data-id");const w=this.get_bar(o).task.dependencies_type||this.options.dependencies_type;let m;this.options.move_dependencies&&w==="fixed"?m=[o,...this.get_all_dependent_tasks(o)]:m=[o],a=m.map(k=>this.get_bar(k)),this.bar_being_dragged=!1,d=e,a.forEach(k=>{const y=k.$bar;y.ox=y.getX(),y.oy=y.getY(),y.owidth=y.getWidth(),y.finaldx=0})}),this.options.infinite_padding){let _=!1;u.on(this.$container,"mousewheel",c=>{let g=this.$container.scrollWidth/2;if(!_&&c.currentTarget.scrollLeft<=g){let p=c.currentTarget.scrollLeft;_=!0,this.gantt_start=l.add(this.gantt_start,-this.config.extend_by_units,this.config.unit),this.setup_date_values(),this.render(),c.currentTarget.scrollLeft=p+this.config.column_width*this.config.extend_by_units,setTimeout(()=>_=!1,300)}if(!_&&c.currentTarget.scrollWidth-(c.currentTarget.scrollLeft+c.currentTarget.clientWidth)<=g){let p=c.currentTarget.scrollLeft;_=!0,this.gantt_end=l.add(this.gantt_end,this.config.extend_by_units,this.config.unit),this.setup_date_values(),this.render(),c.currentTarget.scrollLeft=p,setTimeout(()=>_=!1,300)}})}u.on(this.$container,"scroll",_=>{let c=[];const g=this.bars.map(({group:$})=>$.getAttribute("data-id"));let p;i&&(p=_.currentTarget.scrollLeft-i),this.current_date=l.add(this.gantt_start,_.currentTarget.scrollLeft/this.config.column_width*this.config.step,this.config.unit);let w=this.config.view_mode.upper_text(this.current_date,null,this.options.language),m=this.upperTexts.find($=>$.textContent===w);this.current_date=l.add(this.gantt_start,(_.currentTarget.scrollLeft+m.clientWidth)/this.config.column_width*this.config.step,this.config.unit),w=this.config.view_mode.upper_text(this.current_date,null,this.options.language),m=this.upperTexts.find($=>$.textContent===w),m!==this.$current&&(this.$current&&this.$current.classList.remove("current-upper"),m.classList.add("current-upper"),this.$current=m),i=_.currentTarget.scrollLeft;let[k,y,N]=this.get_start_end_positions();i>N+100?(this.$adjust.innerHTML="&larr;",this.$adjust.classList.remove("hide"),this.$adjust.onclick=()=>{this.$container.scrollTo({left:y,behavior:"smooth"})}):i+_.currentTarget.offsetWidth<k-100?(this.$adjust.innerHTML="&rarr;",this.$adjust.classList.remove("hide"),this.$adjust.onclick=()=>{this.$container.scrollTo({left:k,behavior:"smooth"})}):this.$adjust.classList.add("hide"),p&&(c=g.map($=>this.get_bar($)),this.options.auto_move_label&&c.forEach($=>{$.update_label_position_on_horizontal_scroll({x:p,sx:_.currentTarget.scrollLeft})}))}),u.on(this.$svg,"mousemove",_=>{if(!h())return;const c=(_.offsetX||_.layerX)-e;a.forEach(g=>{const p=g.$bar;p.finaldx=this.get_snap_position(c,p.ox),this.hide_popup(),n?o===g.task.id?g.update_bar_position({x:p.ox+p.finaldx,width:p.owidth-p.finaldx}):g.update_bar_position({x:p.ox+p.finaldx}):s?o===g.task.id&&g.update_bar_position({width:p.owidth+p.finaldx}):t&&!this.options.readonly&&!this.options.readonly_dates&&g.update_bar_position({x:p.ox+p.finaldx})})}),document.addEventListener("mouseup",()=>{var _,c,g;t=!1,n=!1,s=!1,(g=(c=(_=this.$container.querySelector(".visible"))==null?void 0:_.classList)==null?void 0:c.remove)==null||g.call(c,"visible")}),u.on(this.$svg,"mouseup",_=>{const c=this.bar_being_dragged===!0;this.bar_being_dragged=null;const g=[];a.forEach(p=>{if(!p.$bar.finaldx){c&&p.set_action_completed();return}p.date_changed(),p.compute_progress(),p.set_action_completed(),g.push({task:p.task,start:p.task._start,end:l.add(p.task._end,-1,"second")})}),this.options.critical_path&&a.some(p=>p.$bar.finaldx)&&(this.calculate_critical_path(),this.update_arrow_critical_path()),g.length>0&&g.forEach(({task:p,start:w,end:m})=>{this.trigger_event("after_date_change",[p,w,m])})}),this.bind_bar_progress()}bind_bar_progress(){let t=0,e=null,i=null,n=null,s=null;u.on(this.$svg,"mousedown",".handle.progress",(a,h)=>{e=!0,t=a.offsetX||a.layerX;const _=u.closest(".bar-wrapper",h).getAttribute("data-id");i=this.get_bar(_),n=i.$bar_progress,s=i.$bar,n.finaldx=0,n.owidth=n.getWidth(),n.min_dx=-n.owidth,n.max_dx=s.getWidth()-n.getWidth()});const o=this.config.ignored_positions.map(a=>[a,a+this.config.column_width]);u.on(this.$svg,"mousemove",a=>{if(!e)return;let h=a.offsetX||a.layerX;if(h>t){let c=o.find(([g,p])=>h>=g&&h<p);for(;c;)h=c[1],c=o.find(([g,p])=>h>=g&&h<p)}else{let c=o.find(([g,p])=>h>g&&h<=p);for(;c;)h=c[0],c=o.find(([g,p])=>h>g&&h<=p)}let _=h-t;console.log(n),_>n.max_dx&&(_=n.max_dx),_<n.min_dx&&(_=n.min_dx),n.setAttribute("width",n.owidth+_),u.attr(i.$handle_progress,"cx",n.getEndX()),n.finaldx=_}),u.on(this.$svg,"mouseup",()=>{e=!1,n&&n.finaldx&&(n.finaldx=0,i.progress_changed(),i.set_action_completed(),i=null,n=null,s=null)})}get_all_dependent_tasks(t){let e=[],i=[t];for(;i.length;){const n=i.reduce((s,o)=>(s=s.concat(this.dependency_map[o]),s),[]);e=e.concat(n),i=n.filter(s=>!i.includes(s))}return e.filter(Boolean)}update_dependent_tasks_by_type(t){const e=t.task.dependencies_type||this.options.dependencies_type,i=[];return e==="fixed"||(this.dependency_map[t.task.id]||[]).forEach(s=>{const o=this.get_bar(s);if(!o)return;const a=o.task,h=a.dependencies_type||this.options.dependencies_type;let d,_;const c=l.diff(a._end,a._start,"hour");let g=!1;switch(h){case"finish-to-start":t.task._end>a._start&&(d=new Date(t.task._end),_=l.add(d,c,"hour"),g=!0);break;case"start-to-start":t.task._start>a._start&&(d=new Date(t.task._start),_=l.add(d,c,"hour"),g=!0);break;case"finish-to-finish":t.task._end>a._end&&(_=new Date(t.task._end),d=l.add(_,-c,"hour"),g=!0);break;case"start-to-finish":t.task._start>a._end&&(_=new Date(t.task._start),d=l.add(_,-c,"hour"),g=!0);break;default:return}if(!g)return;a._start=d,a._end=_,o.compute_x(),o.compute_duration(),o.update_bar_position({x:o.x,width:o.width}),this.trigger_event("date_change",[a,d,l.add(_,-1,"second")]),i.push({task:a,start:d,end:l.add(_,-1,"second")});const p=this.update_dependent_tasks_by_type(o);i.push(...p)}),i}get_snap_position(t,e){let i=1;const n=this.options.snap_at||this.config.view_mode.snap_at||"1d";if(n!=="unit"){const{duration:_,scale:c}=l.parse_duration(n);i=l.convert_scales(this.config.view_mode.step,c)/_}const s=t%(this.config.column_width/i);let o=t-s+(s<this.config.column_width/i*2?0:this.config.column_width/i),a=e+o;const h=o>0?1:-1;let d=this.get_ignored_region(a,h);for(;d.length;)a+=this.config.column_width*h,d=this.get_ignored_region(a,h),d.length||(a-=this.config.column_width*h);return a-e}get_ignored_region(t,e=1){return e===1?this.config.ignored_positions.filter(i=>t>i&&t<=i+this.config.column_width):this.config.ignored_positions.filter(i=>t>=i&&t<i+this.config.column_width)}unselect_all(){this.popup&&this.popup.parent.classList.add("hide"),this.$container.querySelectorAll(".date-range-highlight").forEach(t=>t.classList.add("hide"))}view_is(t){return typeof t=="string"?this.config.view_mode.name===t:Array.isArray(t)?t.some(view_is):this.config.view_mode.name===t.name}get_task(t){return this.tasks.find(e=>e.id===t)}get_bar(t){return this.bars.find(e=>e.task.id===t)}show_popup(t){this.options.popup!==!1&&(this.popup||(this.popup=new F(this.$popup_wrapper,this.options.popup,this)),this.popup.show(t))}hide_popup(){this.popup&&this.popup.hide()}trigger_event(t,e){this.options["on_"+t]&&this.options["on_"+t].apply(this,e)}get_oldest_starting_date(){return this.tasks.length?this.tasks.map(t=>t._start).reduce((t,e)=>e<=t?e:t):new Date}clear(){var t,e,i,n,s,o,a,h,d,_;this.$svg.innerHTML="",(e=(t=this.$header)==null?void 0:t.remove)==null||e.call(t),(n=(i=this.$side_header)==null?void 0:i.remove)==null||n.call(i),(o=(s=this.$current_highlight)==null?void 0:s.remove)==null||o.call(s),(h=(a=this.$extras)==null?void 0:a.remove)==null||h.call(a),(_=(d=this.popup)==null?void 0:d.hide)==null||_.call(d)}}X.VIEW_MODE={HOUR:b[0],QUARTER_DAY:b[1],HALF_DAY:b[2],DAY:b[3],WEEK:b[4],MONTH:b[5],YEAR:b[6]};function j(r){return r.name+"_"+Math.random().toString(36).slice(2,12)}function D(r){return r.replaceAll(" ","_").replaceAll(":","_").replaceAll(".","_")}return X});
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workiom/frappe-gantt",
3
- "version": "1.0.14",
3
+ "version": "1.0.15",
4
4
  "description": "A simple, modern, interactive gantt library for the web",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/index.js CHANGED
@@ -1443,12 +1443,20 @@ export default class Gantt {
1443
1443
  });
1444
1444
 
1445
1445
  $.on(this.$svg, 'mouseup', (e) => {
1446
+ const was_dragging = this.bar_being_dragged === true;
1446
1447
  this.bar_being_dragged = null;
1447
1448
  const tasks_changed = [];
1448
1449
 
1449
1450
  bars.forEach((bar) => {
1450
1451
  const $bar = bar.$bar;
1451
- if (!$bar.finaldx) return;
1452
+ if (!$bar.finaldx) {
1453
+ // No net movement, but if user was dragging, mark as completed
1454
+ // This prevents click events from firing after drag gestures
1455
+ if (was_dragging) {
1456
+ bar.set_action_completed();
1457
+ }
1458
+ return;
1459
+ }
1452
1460
  bar.date_changed();
1453
1461
  bar.compute_progress();
1454
1462
  bar.set_action_completed();