@workiom/frappe-gantt 1.0.24 → 1.0.26

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
@@ -72,10 +72,14 @@ gantt.tasks.append(...)
72
72
  gantt.tasks.refresh()
73
73
  ```
74
74
 
75
+ Each task object accepts an optional `bar_label` string. When defined (including an empty string) and the global `show_bar_label` option is `true`, the bar renders `bar_label` instead of `name`. Only `null` or `undefined` falls back to `name`. To hide bar labels entirely, set the `show_bar_label` option to `false`.
76
+
75
77
  ### Configuration
76
78
 
77
79
  Frappe Gantt offers a wide range of options to customize your chart.
78
80
 
81
+ > **v1.0.25 note:** Bar labels are now controlled by the `show_bar_label` option (default `true`) rather than by `task_column.enabled`. To preserve the previous behaviour of hiding bar labels when the task column is enabled, pass `show_bar_label: false` explicitly.
82
+
79
83
  | **Option** | **Description** | **Possible Values** | **Default** |
80
84
  | ------------------------ | ------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- |
81
85
  | `allow_dependency_creation` | Enables interactive dependency creation by dragging between connector circles on task bars. When enabled, hovering a bar reveals circles at its start and end; drag from one circle to another to create a typed dependency. | `true`, `false` | `true` |
@@ -104,6 +108,7 @@ Frappe Gantt offers a wide range of options to customize your chart.
104
108
  | `readonly_dates` | Disables editing task dates. | `true`, `false` | `false` |
105
109
  | `readonly` | Disables all editing features. | `true`, `false` | `false` |
106
110
  | `scroll_to` | Determines the starting point when chart is rendered. | `today`, `start`, `end`, or a date string. | `today` |
111
+ | `show_bar_label` | Whether to render the text label inside each task bar. When `true`, label text comes from `task.bar_label` when defined (including empty string), otherwise from `task.name`. | `true`, `false` | `true` |
107
112
  | `show_expected_progress` | Shows expected progress for tasks. | `true`, `false` | `false` |
108
113
  | `task_add_icon_position` | Position of the add task icon relative to task bar. | `null` (hidden), `'before'`, `'after'` | `null` |
109
114
  | `today_button` | Adds a button to navigate to today's date. | `true`, `false` | `true` |
@@ -772,7 +772,7 @@ class B {
772
772
  draw_label() {
773
773
  let t = this.x + this.$bar.getWidth() / 2;
774
774
  this.task.thumbnail && (t = this.x + this.image_size + 5);
775
- const e = this.gantt.options.task_column.enabled ? "" : this.task.name;
775
+ const e = this.gantt.options.show_bar_label ? this.task.bar_label ?? this.task.name : "";
776
776
  this.$bar_label = w("text", {
777
777
  x: t,
778
778
  y: this.y + this.height / 2,
@@ -1291,6 +1291,7 @@ const x = [
1291
1291
  readonly_dates: !1,
1292
1292
  readonly: !1,
1293
1293
  scroll_to: "today",
1294
+ show_bar_label: !0,
1294
1295
  show_expected_progress: !1,
1295
1296
  task_add_icon_position: null,
1296
1297
  today_button: !0,
@@ -98,12 +98,12 @@
98
98
  V ${s-o}
99
99
  a ${o} ${o} 0 0 1 ${-o} ${o}
100
100
  H ${e}
101
- m 5 -5 l -5 5 l 5 5`}_get_connected_bars(){const t=this.from_task.task.id,e=this.to_task.task.id;return Array.from(this.gantt.$svg.querySelectorAll(`[data-id="${CSS.escape(t)}"], [data-id="${CSS.escape(e)}"]`))}draw(){let t="";this.is_invalid?t="arrow-invalid":this.is_critical&&(t="arrow-critical"),this.element=w("path",{d:this.path,"data-from":this.from_task.task.id,"data-to":this.to_task.task.id,class:t}),this.hit_element=w("path",{d:this.path,stroke:"transparent","stroke-width":15,fill:"none",style:"pointer-events: stroke; cursor: pointer;"}),this.hit_element.addEventListener("mouseenter",()=>{this.is_hovered=!0,this.element.classList.add("arrow-hover");const e=this.is_invalid?"bar-arrow-invalid":this.is_critical?"bar-arrow-critical":"bar-arrow-hover";this._get_connected_bars().forEach(i=>{const s=i.querySelector(".bar");s&&s.classList.add(e)}),this._show_label()}),this.hit_element.addEventListener("mouseleave",()=>{this.is_hovered=!1,this.element.classList.remove("arrow-hover"),this._get_connected_bars().forEach(e=>{const i=e.querySelector(".bar");i&&(i.classList.remove("bar-arrow-hover"),this.is_active||i.classList.remove("bar-arrow-critical","bar-arrow-invalid"))}),!this.is_active&&!this.is_hovered&&this._hide_label()}),this.hit_element.addEventListener("click",e=>{e.stopPropagation(),this.is_active?this.gantt.set_active_arrow(null):this.gantt.set_active_arrow(this)})}_get_type_abbr(){return{"finish-to-start":"FS","start-to-start":"SS","finish-to-finish":"FF","start-to-finish":"SF"}[this.dependency_type]||"FS"}_show_label(){if(this.label_element)return;const t=this._get_type_abbr(),e=21,i=20,{x:s,y:n,side:a}=this.label_pos,o=a==="left"?s-10-e/2:s+10+e/2,d=n;this.label_element=w("g",{class:"arrow-type-label"});const h=w("rect",{x:o-e/2,y:d-i/2,width:e,height:i,rx:3}),_=w("text",{x:o,y:d,"dominant-baseline":"middle","text-anchor":"middle"});_.textContent=t,this.label_element.appendChild(h),this.label_element.appendChild(_),this.label_element.addEventListener("mouseenter",()=>{this.hit_element.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!1}))}),this.label_element.addEventListener("mouseleave",()=>{this.hit_element.dispatchEvent(new MouseEvent("mouseleave",{bubbles:!1}))}),this.label_element.addEventListener("click",l=>{l.stopPropagation(),this._toggle_type_dropdown()}),this.gantt.layers.arrow.appendChild(this.label_element)}_hide_label(){this.label_element&&(this.label_element.remove(),this.label_element=null)}_show_type_dropdown(){if(this.gantt.options.readonly||this.type_dropdown||(this.is_active||this.gantt.set_active_arrow(this),!this.label_element))return;const t=[{abbr:"FS",label:"Finish to Start",value:"finish-to-start"},{abbr:"SS",label:"Start to Start",value:"start-to-start"},{abbr:"FF",label:"Finish to Finish",value:"finish-to-finish"},{abbr:"SF",label:"Start to Finish",value:"start-to-finish"}];this.type_dropdown=document.createElement("div"),this.type_dropdown.className="arrow-type-dropdown",this.type_dropdown.addEventListener("click",a=>a.stopPropagation()),t.forEach(({abbr:a,label:o,value:d})=>{const h=document.createElement("div");h.className="arrow-type-option"+(d===this.dependency_type?" active":"");const _=document.createElement("strong");_.textContent=a;const l=document.createElement("span");l.textContent=o,h.appendChild(_),h.appendChild(l),h.addEventListener("click",p=>{p.stopPropagation(),this.gantt.change_dependency_type(this,d)}),this.type_dropdown.appendChild(h)}),this.gantt.$container.appendChild(this.type_dropdown);const e=this.label_element.getBoundingClientRect(),i=this.gantt.$container.getBoundingClientRect();this.type_dropdown.style.top=e.bottom-i.top+this.gantt.$container.scrollTop+"px",this.type_dropdown.style.left=e.left-i.left+this.gantt.$container.scrollLeft+"px";const s=this.label_element.querySelector("text"),n=this.label_element.querySelector("rect");if(s&&(s.textContent=this._get_type_abbr()+" ▾"),n){const o=parseFloat(n.getAttribute("width")),d=parseFloat(n.getAttribute("x"))+o/2;n.setAttribute("x",String(d-34/2)),n.setAttribute("width",String(34))}}_hide_type_dropdown(){var i,s;this.type_dropdown&&(this.type_dropdown.remove(),this.type_dropdown=null);const t=(i=this.label_element)==null?void 0:i.querySelector("text"),e=(s=this.label_element)==null?void 0:s.querySelector("rect");if(t&&(t.textContent=this._get_type_abbr()),e){const a=parseFloat(e.getAttribute("x"))+parseFloat(e.getAttribute("width"))/2;e.setAttribute("x",String(a-21/2)),e.setAttribute("width",String(21))}}_toggle_type_dropdown(){this.type_dropdown?this._hide_type_dropdown():this._show_type_dropdown()}activate(){this.is_active=!0,this.element.classList.add("arrow-active"),this._show_label();const t=this.is_invalid?"bar-arrow-invalid":this.is_critical?"bar-arrow-critical":"bar-arrow-active";this._get_connected_bars().forEach(e=>{const i=e.querySelector(".bar");i&&i.classList.add(t)})}deactivate(){this._hide_type_dropdown(),this.is_active=!1,this.element.classList.remove("arrow-active"),this._hide_label(),this._get_connected_bars().forEach(t=>{const e=t.querySelector(".bar");e&&e.classList.remove("bar-arrow-active","bar-arrow-critical","bar-arrow-invalid")})}update(){this.calculate_path(),this.element.setAttribute("d",this.path),this.hit_element.setAttribute("d",this.path),this.is_invalid=this.check_invalid_dependency();let t="";this.is_invalid?t="arrow-invalid":this.is_critical&&(t="arrow-critical"),this.is_hovered&&(t+=" arrow-hover"),this.is_active&&(t+=" arrow-active"),this.element.setAttribute("class",t.trim())}}class G{constructor(t,e){this.set_defaults(t,e),this.prepare_wrappers(),this.prepare_helpers(),this.refresh()}refresh(){this.bar_group.innerHTML="",this.handle_group.innerHTML="",this.task.custom_class?this.group.classList.add(this.task.custom_class):this.group.classList=["bar-wrapper"],this.unbind(),this.prepare_values(),this.draw(),this.bind()}set_defaults(t,e){this.action_completed=!1,this.gantt=t,this.task=e,this.name=this.name||"",this.is_dragging=!1,this.is_hovering_bar=!1,this.is_hovering_icon=!1,this.add_icon_hide_timeout=null}prepare_wrappers(){this.group=w("g",{class:"bar-wrapper"+(this.task.custom_class?" "+this.task.custom_class:""),"data-id":this.task.id}),this.bar_group=w("g",{class:"bar-group",append_to:this.group}),this.handle_group=w("g",{class:"handle-group",append_to:this.group})}prepare_values(){this.invalid=this.task.invalid,this.height=this.gantt.options.bar_height,this.image_size=this.height-5,(!this.task._start||!(this.task._start instanceof Date))&&(this.task._start=new Date(this.task.start)),(!this.task._end||!(this.task._end instanceof Date))&&(this.task._end=new Date(this.task.end)),this.compute_x(),this.compute_y(),this.compute_duration(),this.corner_radius=this.gantt.options.bar_corner_radius,this.width=this.gantt.config.column_width*this.duration,(!this.task.progress||this.task.progress<0)&&(this.task.progress=0),this.task.progress>100&&(this.task.progress=100)}prepare_helpers(){SVGElement.prototype.getX=function(){return+this.getAttribute("x")},SVGElement.prototype.getY=function(){return+this.getAttribute("y")},SVGElement.prototype.getWidth=function(){return+this.getAttribute("width")},SVGElement.prototype.getHeight=function(){return+this.getAttribute("height")},SVGElement.prototype.getEndX=function(){return this.getX()+this.getWidth()}}prepare_expected_progress_values(){this.compute_expected_progress(),this.expected_progress_width=this.gantt.options.column_width*this.duration*(this.expected_progress/100)||0}draw(){this.draw_bar(),this.draw_progress_bar(),this.gantt.options.show_expected_progress&&(this.prepare_expected_progress_values(),this.draw_expected_progress_bar()),this.draw_label(),this.draw_resize_handles(),this.task.thumbnail&&this.draw_thumbnail(),this.gantt.options.task_add_icon_position&&this.draw_add_task_icon(),this.draw_connector_circles()}draw_bar(){this.$bar=w("rect",{x:this.x,y:this.y,width:this.width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar",append_to:this.bar_group}),this.task.color&&(this.$bar.style.fill=this.task.color),X(this.$bar,"width",0,this.width),this.invalid&&this.$bar.classList.add("bar-invalid")}draw_expected_progress_bar(){this.invalid||(this.$expected_bar_progress=w("rect",{x:this.x,y:this.y,width:this.expected_progress_width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar-expected-progress",append_to:this.bar_group}),X(this.$expected_bar_progress,"width",0,this.expected_progress_width))}draw_progress_bar(){if(this.invalid)return;this.progress_width=this.calculate_progress_width();let t=this.corner_radius;/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(t=this.corner_radius+2),this.$bar_progress=w("rect",{x:this.x,y:this.y,width:this.progress_width,height:this.height,rx:t,ry:t,class:"bar-progress",append_to:this.bar_group}),this.task.color_progress&&(this.$bar_progress.style.fill=this.task.color_progress);const e=g.diff(this.task._start,this.gantt.gantt_start,this.gantt.config.unit)/this.gantt.config.step*this.gantt.config.column_width;this.$date_highlight&&this.$date_highlight.parentNode&&this.$date_highlight.parentNode.removeChild(this.$date_highlight);let i=this.gantt.create_el({classes:`date-range-highlight hide highlight-${CSS.escape(this.task.id)}`,width:this.width,left:e});this.$date_highlight=i,this.gantt.$lower_header.prepend(this.$date_highlight),X(this.$bar_progress,"width",0,this.progress_width)}calculate_progress_width(){const t=this.$bar.getWidth(),e=this.x+t,i=this.gantt.config.ignored_positions.reduce((d,h)=>d+(h>=this.x&&h<e),0)*this.gantt.config.column_width;let s=(t-i)*this.task.progress/100;const n=this.x+s,a=this.gantt.config.ignored_positions.reduce((d,h)=>d+(h>=this.x&&h<n),0)*this.gantt.config.column_width;s+=a;let o=this.gantt.get_ignored_region(this.x+s);for(;o.length;)s+=this.gantt.config.column_width,o=this.gantt.get_ignored_region(this.x+s);return this.progress_width=s,s}draw_label(){let t=this.x+this.$bar.getWidth()/2;this.task.thumbnail&&(t=this.x+this.image_size+5);const e=this.gantt.options.task_column.enabled?"":this.task.name;this.$bar_label=w("text",{x:t,y:this.y+this.height/2,innerHTML:e,class:"bar-label",append_to:this.bar_group}),this.task.color_text&&(this.$bar_label.style.fill=this.task.color_text),requestAnimationFrame(()=>this.update_label_position())}draw_thumbnail(){let t=10,e=2,i,s;i=w("defs",{append_to:this.bar_group}),w("rect",{id:"rect_"+this.task.id,x:this.x+t,y:this.y+e,width:this.image_size,height:this.image_size,rx:"15",class:"img_mask",append_to:i}),s=w("clipPath",{id:"clip_"+this.task.id,append_to:i}),w("use",{href:"#rect_"+this.task.id,append_to:s}),w("image",{x:this.x+t,y:this.y+e,width:this.image_size,height:this.image_size,class:"bar-img",href:this.task.thumbnail,clipPath:"clip_"+this.task.id,append_to:this.bar_group})}draw_add_task_icon(){this.icon_size=20,this.icon_padding=5;let i;if(this.gantt.options.task_add_icon_position==="before")i=this.x-20-5;else if(this.gantt.options.task_add_icon_position==="after")i=this.x+this.$bar.getWidth()+5;else return;const s=this.y+(this.height-20)/2;this.$add_icon_group=w("g",{class:"add-task-icon hide",append_to:this.handle_group}),this.$add_icon_circle=w("circle",{cx:i+20/2,cy:s+20/2,r:20/2,class:"add-task-icon-bg",append_to:this.$add_icon_group}),this.$add_icon_vertical=w("line",{x1:i+20/2,y1:s+5,x2:i+20/2,y2:s+20-5,class:"add-task-icon-plus",append_to:this.$add_icon_group}),this.$add_icon_horizontal=w("line",{x1:i+5,y1:s+20/2,x2:i+20-5,y2:s+20/2,class:"add-task-icon-plus",append_to:this.$add_icon_group}),u.on(this.$add_icon_group,"mousedown",n=>{n.stopPropagation()}),u.on(this.$add_icon_group,"mouseup",n=>{n.stopPropagation()}),u.on(this.$add_icon_group,"click",n=>{n.stopPropagation(),this.gantt.trigger_event("task_add",[this.task])}),u.on(this.$add_icon_group,"mouseenter",n=>{this.is_hovering_icon=!0,this.add_icon_hide_timeout&&(clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=null),this.$add_icon_group.classList.add("active"),this.$add_icon_group.classList.remove("hide"),n.stopPropagation()}),u.on(this.$add_icon_group,"mouseleave",()=>{this.is_hovering_icon=!1,this.$add_icon_group.classList.remove("active"),this.is_hovering_bar||this.$add_icon_group.classList.add("hide")})}draw_resize_handles(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar,e=8;if(this.handles=[],this.gantt.options.readonly_dates||(this.handles.push(w("rect",{x:t.getEndX()-e,y:t.getY()+(this.height-this.height*.8)/2,width:e,height:this.height*.8,rx:2,ry:2,class:"handle right",append_to:this.handle_group})),this.handles.push(w("rect",{x:t.getX()-e,y:t.getY()+(this.height-this.height*.8)/2,width:e,height:this.height*.8,rx:2,ry:2,class:"handle left",append_to:this.handle_group}))),!this.gantt.options.readonly_progress){const i=this.$bar_progress;this.$handle_progress=w("circle",{cx:i.getEndX(),cy:i.getY()+i.getHeight()/2,r:4.5,class:"handle progress",append_to:this.handle_group}),this.handles.push(this.$handle_progress)}for(let i of this.handles)u.on(i,"mouseenter",()=>i.classList.add("active")),u.on(i,"mouseleave",()=>i.classList.remove("active"))}draw_connector_circles(){if(this.$connector_start=null,this.$connector_end=null,!this.gantt.options.allow_dependency_creation||this.gantt.options.readonly)return;const t=this.gantt.options.isRTL,e=this.y+this.height/2,i=t?this.x+this.width:this.x,s=t?this.x:this.x+this.width;this.$connector_start=w("circle",{class:"connector-circle connector-start","data-endpoint":"start",cx:i,cy:e,r:4,append_to:this.handle_group}),this.$connector_end=w("circle",{class:"connector-circle connector-end","data-endpoint":"end",cx:s,cy:e,r:4,append_to:this.handle_group})}update_connector_circles(){if(!this.$connector_start)return;const t=this.gantt.options.isRTL,e=this.$bar.getX(),i=this.$bar.getWidth(),s=this.y+this.height/2,n=t?e+i:e,a=t?e:e+i;this.$connector_start.setAttribute("cx",n),this.$connector_start.setAttribute("cy",s),this.$connector_end.setAttribute("cx",a),this.$connector_end.setAttribute("cy",s)}bind(){this.invalid||this.setup_click_event()}unbind(){this.invalid||this.group&&this.event_listeners&&(this.event_listeners.forEach(({event:t,handler:e})=>{u.off(this.group,t,e)}),this.event_listeners=[])}setup_click_event(){this.event_listeners=[];let t=this.task.id;const e=p=>{this.gantt.trigger_event("hover",[this.task,p.screenX,p.screenY,p])};if(u.on(this.group,"mouseover",e),this.event_listeners.push({event:"mouseover",handler:e}),this.gantt.options.popup_on==="click"){const p=c=>{const m=c.offsetX||c.layerX;if(this.$handle_progress){const f=+this.$handle_progress.getAttribute("cx");if(f>m-1&&f<m+1||this.gantt.bar_being_dragged)return}this.gantt.show_popup({x:c.offsetX||c.layerX,y:c.offsetY||c.layerY,task:this.task,target:this.$bar})};u.on(this.group,"click",p),this.event_listeners.push({event:"click",handler:p})}let i;const s=p=>{i=setTimeout(()=>{this.gantt.options.popup_on==="hover"&&this.gantt.show_popup({x:p.offsetX||p.layerX,y:p.offsetY||p.layerY,task:this.task,target:this.$bar});const c=this.gantt.$container.querySelector(`.highlight-${CSS.escape(t)}`);c&&c.classList.remove("hide")},200),this.$add_icon_group&&(this.is_hovering_bar=!0,this.add_icon_hide_timeout&&(clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=null),this.is_dragging||this.$add_icon_group.classList.remove("hide"))};u.on(this.group,"mouseenter",s),this.event_listeners.push({event:"mouseenter",handler:s});const n=()=>{var c,m;clearTimeout(i),this.gantt.options.popup_on==="hover"&&((m=(c=this.gantt.popup)==null?void 0:c.hide)==null||m.call(c));const p=this.gantt.$container.querySelector(`.highlight-${CSS.escape(t)}`);p&&p.classList.add("hide"),this.$add_icon_group&&(this.is_hovering_bar=!1,this.add_icon_hide_timeout&&clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=setTimeout(()=>{this.is_hovering_icon||this.$add_icon_group.classList.add("hide")},200))};u.on(this.group,"mouseleave",n),this.event_listeners.push({event:"mouseleave",handler:n});const a=()=>{this.is_dragging=!0,this.hide_add_icon()};u.on(this.group,"mousedown",a),this.event_listeners.push({event:"mousedown",handler:a});const o=()=>{setTimeout(()=>{this.gantt.bar_being_dragged!==!0&&(this.is_dragging=!1,this.$add_icon_group&&this.is_hovering_bar&&this.$add_icon_group.classList.remove("hide"))},0)};u.on(this.group,"mouseup",o),this.event_listeners.push({event:"mouseup",handler:o});const d=()=>{this.action_completed||this.gantt.bar_being_dragged||this.gantt.trigger_event("click",[this.task])};u.on(this.group,"click",d),this.event_listeners.push({event:"click",handler:d});const h=()=>{this.action_completed||(this.group.classList.remove("active"),this.gantt.popup&&this.gantt.popup.parent.classList.remove("hide"),this.gantt.trigger_event("double_click",[this.task]))};u.on(this.group,"dblclick",h),this.event_listeners.push({event:"dblclick",handler:h});let _=!1;const l=p=>{if(!_)return _=!0,setTimeout(function(){_=!1},300),!1;p.preventDefault(),!this.action_completed&&(this.group.classList.remove("active"),this.gantt.popup&&this.gantt.popup.parent.classList.remove("hide"),this.gantt.trigger_event("double_click",[this.task]))};u.on(this.group,"touchstart",l),this.event_listeners.push({event:"touchstart",handler:l})}update_bar_position({x:t=null,width:e=null}){const i=this.$bar;t&&(this.update_attr(i,"x",t),this.x=t,this.$date_highlight.style.left=t+"px"),e>0&&(this.update_attr(i,"width",e),this.$date_highlight.style.width=e+"px"),this.update_label_position(),this.update_handle_position(),this.update_add_icon_position(),this.date_changed(),this.compute_duration(),this.gantt.options.show_expected_progress&&this.update_expected_progressbar_position(),this.update_progressbar_position(),this.update_arrow_position(),this.update_connector_circles()}update_label_position_on_horizontal_scroll({x:t,sx:e}){const i=this.gantt.$container,s=this.group.querySelector(".bar-label"),n=this.group.querySelector(".bar-img")||"",a=this.bar_group.querySelector(".img_mask")||"";let o=this.$bar.getX()+this.$bar.getWidth(),d=s.getX()+t,h=n&&n.getX()+t||0,_=n&&n.getBBox().width+7||7,l=d+s.getBBox().width+7,p=e+i.clientWidth/2;s.classList.contains("big")||(l<o&&t>0&&l<p||d-_>this.$bar.getX()&&t<0&&l>p)&&(s.setAttribute("x",d),n&&(n.setAttribute("x",h),a.setAttribute("x",h)))}date_changed(){let t=!1;const{new_start_date:e,new_end_date:i}=this.compute_start_end_date();Number(this.task._start)!==Number(e)&&(t=!0,this.task._start=e),Number(this.task._end)!==Number(i)&&(t=!0,this.task._end=i),t&&this.gantt.trigger_event("date_change",[this.task,e,g.add(i,-1,"second")])}progress_changed(){this.task.progress=this.compute_progress(),this.gantt.trigger_event("progress_change",[this.task,this.task.progress])}set_action_completed(){this.action_completed=!0,setTimeout(()=>this.action_completed=!1,10),this.is_dragging=!1,this.$add_icon_group&&this.is_hovering_bar&&this.$add_icon_group.classList.remove("hide")}compute_start_end_date(){const t=this.$bar,e=t.getX()/this.gantt.config.column_width;let i=g.add(this.gantt.gantt_start,e*this.gantt.config.step,this.gantt.config.unit);const s=t.getWidth()/this.gantt.config.column_width,n=g.add(i,s*this.gantt.config.step,this.gantt.config.unit);return{new_start_date:i,new_end_date:n}}compute_progress(){this.progress_width=this.$bar_progress.getWidth(),this.x=this.$bar_progress.getBBox().x;const t=this.x+this.progress_width,e=this.progress_width-this.gantt.config.ignored_positions.reduce((s,n)=>s+(n>=this.x&&n<=t),0)*this.gantt.config.column_width;if(e<0)return 0;const i=this.$bar.getWidth()-this.ignored_duration_raw*this.gantt.config.column_width;return parseInt(e/i*100,10)}compute_expected_progress(){this.expected_progress=g.diff(g.today(),this.task._start,"hour")/this.gantt.config.step,this.expected_progress=(this.expected_progress<this.duration?this.expected_progress:this.duration)*100/this.duration}compute_x(){const{column_width:t}=this.gantt.config,e=this.task._start,i=this.gantt.gantt_start;let n=g.diff(e,i,this.gantt.config.unit)/this.gantt.config.step*t;this.x=n}compute_y(){this.y=this.gantt.config.header_height+this.gantt.options.padding/2+this.task._index*(this.height+this.gantt.options.padding)}compute_duration(){let t=0,e=0;for(let i=new Date(this.task._start);i<this.task._end;i.setDate(i.getDate()+1))e++,!this.gantt.config.ignored_dates.find(s=>s.getTime()===i.getTime())&&(!this.gantt.config.ignored_function||!this.gantt.config.ignored_function(i))&&t++;this.task.actual_duration=t,this.task.ignored_duration=e-t,this.duration=g.convert_scales(e+"d",this.gantt.config.unit)/this.gantt.config.step,this.actual_duration_raw=g.convert_scales(t+"d",this.gantt.config.unit)/this.gantt.config.step,this.ignored_duration_raw=this.duration-this.actual_duration_raw}update_attr(t,e,i){return i=+i,isNaN(i)||t.setAttribute(e,i),t}update_expected_progressbar_position(){this.invalid||(this.$expected_bar_progress.setAttribute("x",this.$bar.getX()),this.compute_expected_progress(),this.$expected_bar_progress.setAttribute("width",this.gantt.config.column_width*this.actual_duration_raw*(this.expected_progress/100)||0))}update_progressbar_position(){this.invalid||this.gantt.options.readonly||(this.$bar_progress.setAttribute("x",this.$bar.getX()),this.$bar_progress.setAttribute("width",this.calculate_progress_width()))}update_label_position(){const t=this.bar_group.querySelector(".img_mask")||"",e=this.$bar,i=this.group.querySelector(".bar-label"),s=this.group.querySelector(".bar-img");let n=5,a=this.image_size+10;const o=i.getBBox().width,d=e.getWidth();o>d?(i.classList.add("big"),s?(s.setAttribute("x",e.getEndX()+n),t.setAttribute("x",e.getEndX()+n),i.setAttribute("x",e.getEndX()+a)):i.setAttribute("x",e.getEndX()+n)):(i.classList.remove("big"),s?(s.setAttribute("x",e.getX()+n),t.setAttribute("x",e.getX()+n),i.setAttribute("x",e.getX()+d/2+a)):i.setAttribute("x",e.getX()+d/2-o/2))}update_handle_position(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar;this.handle_group.querySelector(".handle.left").setAttribute("x",t.getX()),this.handle_group.querySelector(".handle.right").setAttribute("x",t.getEndX());const e=this.group.querySelector(".handle.progress");e&&e.setAttribute("cx",this.$bar_progress.getEndX())}update_add_icon_position(){if(!this.$add_icon_group)return;const t=this.icon_size,e=this.icon_padding;let i;if(this.gantt.options.task_add_icon_position==="before")i=this.x-t-e;else if(this.gantt.options.task_add_icon_position==="after")i=this.x+this.$bar.getWidth()+e;else return;const s=this.y+(this.height-t)/2;this.$add_icon_circle.setAttribute("cx",i+t/2),this.$add_icon_circle.setAttribute("cy",s+t/2),this.$add_icon_vertical.setAttribute("x1",i+t/2),this.$add_icon_vertical.setAttribute("y1",s+5),this.$add_icon_vertical.setAttribute("x2",i+t/2),this.$add_icon_vertical.setAttribute("y2",s+t-5),this.$add_icon_horizontal.setAttribute("x1",i+5),this.$add_icon_horizontal.setAttribute("y1",s+t/2),this.$add_icon_horizontal.setAttribute("x2",i+t-5),this.$add_icon_horizontal.setAttribute("y2",s+t/2)}hide_add_icon(){this.$add_icon_group&&this.$add_icon_group.classList.add("hide")}update_arrow_position(){this.arrows=this.arrows||[];for(let t of this.arrows)t.update()}}class I{constructor(t,e,i){this.parent=t,this.popup_func=e,this.gantt=i,this.make()}make(){this.parent.innerHTML=`
101
+ m 5 -5 l -5 5 l 5 5`}_get_connected_bars(){const t=this.from_task.task.id,e=this.to_task.task.id;return Array.from(this.gantt.$svg.querySelectorAll(`[data-id="${CSS.escape(t)}"], [data-id="${CSS.escape(e)}"]`))}draw(){let t="";this.is_invalid?t="arrow-invalid":this.is_critical&&(t="arrow-critical"),this.element=w("path",{d:this.path,"data-from":this.from_task.task.id,"data-to":this.to_task.task.id,class:t}),this.hit_element=w("path",{d:this.path,stroke:"transparent","stroke-width":15,fill:"none",style:"pointer-events: stroke; cursor: pointer;"}),this.hit_element.addEventListener("mouseenter",()=>{this.is_hovered=!0,this.element.classList.add("arrow-hover");const e=this.is_invalid?"bar-arrow-invalid":this.is_critical?"bar-arrow-critical":"bar-arrow-hover";this._get_connected_bars().forEach(i=>{const s=i.querySelector(".bar");s&&s.classList.add(e)}),this._show_label()}),this.hit_element.addEventListener("mouseleave",()=>{this.is_hovered=!1,this.element.classList.remove("arrow-hover"),this._get_connected_bars().forEach(e=>{const i=e.querySelector(".bar");i&&(i.classList.remove("bar-arrow-hover"),this.is_active||i.classList.remove("bar-arrow-critical","bar-arrow-invalid"))}),!this.is_active&&!this.is_hovered&&this._hide_label()}),this.hit_element.addEventListener("click",e=>{e.stopPropagation(),this.is_active?this.gantt.set_active_arrow(null):this.gantt.set_active_arrow(this)})}_get_type_abbr(){return{"finish-to-start":"FS","start-to-start":"SS","finish-to-finish":"FF","start-to-finish":"SF"}[this.dependency_type]||"FS"}_show_label(){if(this.label_element)return;const t=this._get_type_abbr(),e=21,i=20,{x:s,y:n,side:a}=this.label_pos,o=a==="left"?s-10-e/2:s+10+e/2,d=n;this.label_element=w("g",{class:"arrow-type-label"});const h=w("rect",{x:o-e/2,y:d-i/2,width:e,height:i,rx:3}),_=w("text",{x:o,y:d,"dominant-baseline":"middle","text-anchor":"middle"});_.textContent=t,this.label_element.appendChild(h),this.label_element.appendChild(_),this.label_element.addEventListener("mouseenter",()=>{this.hit_element.dispatchEvent(new MouseEvent("mouseenter",{bubbles:!1}))}),this.label_element.addEventListener("mouseleave",()=>{this.hit_element.dispatchEvent(new MouseEvent("mouseleave",{bubbles:!1}))}),this.label_element.addEventListener("click",l=>{l.stopPropagation(),this._toggle_type_dropdown()}),this.gantt.layers.arrow.appendChild(this.label_element)}_hide_label(){this.label_element&&(this.label_element.remove(),this.label_element=null)}_show_type_dropdown(){if(this.gantt.options.readonly||this.type_dropdown||(this.is_active||this.gantt.set_active_arrow(this),!this.label_element))return;const t=[{abbr:"FS",label:"Finish to Start",value:"finish-to-start"},{abbr:"SS",label:"Start to Start",value:"start-to-start"},{abbr:"FF",label:"Finish to Finish",value:"finish-to-finish"},{abbr:"SF",label:"Start to Finish",value:"start-to-finish"}];this.type_dropdown=document.createElement("div"),this.type_dropdown.className="arrow-type-dropdown",this.type_dropdown.addEventListener("click",a=>a.stopPropagation()),t.forEach(({abbr:a,label:o,value:d})=>{const h=document.createElement("div");h.className="arrow-type-option"+(d===this.dependency_type?" active":"");const _=document.createElement("strong");_.textContent=a;const l=document.createElement("span");l.textContent=o,h.appendChild(_),h.appendChild(l),h.addEventListener("click",p=>{p.stopPropagation(),this.gantt.change_dependency_type(this,d)}),this.type_dropdown.appendChild(h)}),this.gantt.$container.appendChild(this.type_dropdown);const e=this.label_element.getBoundingClientRect(),i=this.gantt.$container.getBoundingClientRect();this.type_dropdown.style.top=e.bottom-i.top+this.gantt.$container.scrollTop+"px",this.type_dropdown.style.left=e.left-i.left+this.gantt.$container.scrollLeft+"px";const s=this.label_element.querySelector("text"),n=this.label_element.querySelector("rect");if(s&&(s.textContent=this._get_type_abbr()+" ▾"),n){const o=parseFloat(n.getAttribute("width")),d=parseFloat(n.getAttribute("x"))+o/2;n.setAttribute("x",String(d-34/2)),n.setAttribute("width",String(34))}}_hide_type_dropdown(){var i,s;this.type_dropdown&&(this.type_dropdown.remove(),this.type_dropdown=null);const t=(i=this.label_element)==null?void 0:i.querySelector("text"),e=(s=this.label_element)==null?void 0:s.querySelector("rect");if(t&&(t.textContent=this._get_type_abbr()),e){const a=parseFloat(e.getAttribute("x"))+parseFloat(e.getAttribute("width"))/2;e.setAttribute("x",String(a-21/2)),e.setAttribute("width",String(21))}}_toggle_type_dropdown(){this.type_dropdown?this._hide_type_dropdown():this._show_type_dropdown()}activate(){this.is_active=!0,this.element.classList.add("arrow-active"),this._show_label();const t=this.is_invalid?"bar-arrow-invalid":this.is_critical?"bar-arrow-critical":"bar-arrow-active";this._get_connected_bars().forEach(e=>{const i=e.querySelector(".bar");i&&i.classList.add(t)})}deactivate(){this._hide_type_dropdown(),this.is_active=!1,this.element.classList.remove("arrow-active"),this._hide_label(),this._get_connected_bars().forEach(t=>{const e=t.querySelector(".bar");e&&e.classList.remove("bar-arrow-active","bar-arrow-critical","bar-arrow-invalid")})}update(){this.calculate_path(),this.element.setAttribute("d",this.path),this.hit_element.setAttribute("d",this.path),this.is_invalid=this.check_invalid_dependency();let t="";this.is_invalid?t="arrow-invalid":this.is_critical&&(t="arrow-critical"),this.is_hovered&&(t+=" arrow-hover"),this.is_active&&(t+=" arrow-active"),this.element.setAttribute("class",t.trim())}}class G{constructor(t,e){this.set_defaults(t,e),this.prepare_wrappers(),this.prepare_helpers(),this.refresh()}refresh(){this.bar_group.innerHTML="",this.handle_group.innerHTML="",this.task.custom_class?this.group.classList.add(this.task.custom_class):this.group.classList=["bar-wrapper"],this.unbind(),this.prepare_values(),this.draw(),this.bind()}set_defaults(t,e){this.action_completed=!1,this.gantt=t,this.task=e,this.name=this.name||"",this.is_dragging=!1,this.is_hovering_bar=!1,this.is_hovering_icon=!1,this.add_icon_hide_timeout=null}prepare_wrappers(){this.group=w("g",{class:"bar-wrapper"+(this.task.custom_class?" "+this.task.custom_class:""),"data-id":this.task.id}),this.bar_group=w("g",{class:"bar-group",append_to:this.group}),this.handle_group=w("g",{class:"handle-group",append_to:this.group})}prepare_values(){this.invalid=this.task.invalid,this.height=this.gantt.options.bar_height,this.image_size=this.height-5,(!this.task._start||!(this.task._start instanceof Date))&&(this.task._start=new Date(this.task.start)),(!this.task._end||!(this.task._end instanceof Date))&&(this.task._end=new Date(this.task.end)),this.compute_x(),this.compute_y(),this.compute_duration(),this.corner_radius=this.gantt.options.bar_corner_radius,this.width=this.gantt.config.column_width*this.duration,(!this.task.progress||this.task.progress<0)&&(this.task.progress=0),this.task.progress>100&&(this.task.progress=100)}prepare_helpers(){SVGElement.prototype.getX=function(){return+this.getAttribute("x")},SVGElement.prototype.getY=function(){return+this.getAttribute("y")},SVGElement.prototype.getWidth=function(){return+this.getAttribute("width")},SVGElement.prototype.getHeight=function(){return+this.getAttribute("height")},SVGElement.prototype.getEndX=function(){return this.getX()+this.getWidth()}}prepare_expected_progress_values(){this.compute_expected_progress(),this.expected_progress_width=this.gantt.options.column_width*this.duration*(this.expected_progress/100)||0}draw(){this.draw_bar(),this.draw_progress_bar(),this.gantt.options.show_expected_progress&&(this.prepare_expected_progress_values(),this.draw_expected_progress_bar()),this.draw_label(),this.draw_resize_handles(),this.task.thumbnail&&this.draw_thumbnail(),this.gantt.options.task_add_icon_position&&this.draw_add_task_icon(),this.draw_connector_circles()}draw_bar(){this.$bar=w("rect",{x:this.x,y:this.y,width:this.width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar",append_to:this.bar_group}),this.task.color&&(this.$bar.style.fill=this.task.color),X(this.$bar,"width",0,this.width),this.invalid&&this.$bar.classList.add("bar-invalid")}draw_expected_progress_bar(){this.invalid||(this.$expected_bar_progress=w("rect",{x:this.x,y:this.y,width:this.expected_progress_width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar-expected-progress",append_to:this.bar_group}),X(this.$expected_bar_progress,"width",0,this.expected_progress_width))}draw_progress_bar(){if(this.invalid)return;this.progress_width=this.calculate_progress_width();let t=this.corner_radius;/^((?!chrome|android).)*safari/i.test(navigator.userAgent)||(t=this.corner_radius+2),this.$bar_progress=w("rect",{x:this.x,y:this.y,width:this.progress_width,height:this.height,rx:t,ry:t,class:"bar-progress",append_to:this.bar_group}),this.task.color_progress&&(this.$bar_progress.style.fill=this.task.color_progress);const e=g.diff(this.task._start,this.gantt.gantt_start,this.gantt.config.unit)/this.gantt.config.step*this.gantt.config.column_width;this.$date_highlight&&this.$date_highlight.parentNode&&this.$date_highlight.parentNode.removeChild(this.$date_highlight);let i=this.gantt.create_el({classes:`date-range-highlight hide highlight-${CSS.escape(this.task.id)}`,width:this.width,left:e});this.$date_highlight=i,this.gantt.$lower_header.prepend(this.$date_highlight),X(this.$bar_progress,"width",0,this.progress_width)}calculate_progress_width(){const t=this.$bar.getWidth(),e=this.x+t,i=this.gantt.config.ignored_positions.reduce((d,h)=>d+(h>=this.x&&h<e),0)*this.gantt.config.column_width;let s=(t-i)*this.task.progress/100;const n=this.x+s,a=this.gantt.config.ignored_positions.reduce((d,h)=>d+(h>=this.x&&h<n),0)*this.gantt.config.column_width;s+=a;let o=this.gantt.get_ignored_region(this.x+s);for(;o.length;)s+=this.gantt.config.column_width,o=this.gantt.get_ignored_region(this.x+s);return this.progress_width=s,s}draw_label(){let t=this.x+this.$bar.getWidth()/2;this.task.thumbnail&&(t=this.x+this.image_size+5);const e=this.gantt.options.show_bar_label?this.task.bar_label??this.task.name:"";this.$bar_label=w("text",{x:t,y:this.y+this.height/2,innerHTML:e,class:"bar-label",append_to:this.bar_group}),this.task.color_text&&(this.$bar_label.style.fill=this.task.color_text),requestAnimationFrame(()=>this.update_label_position())}draw_thumbnail(){let t=10,e=2,i,s;i=w("defs",{append_to:this.bar_group}),w("rect",{id:"rect_"+this.task.id,x:this.x+t,y:this.y+e,width:this.image_size,height:this.image_size,rx:"15",class:"img_mask",append_to:i}),s=w("clipPath",{id:"clip_"+this.task.id,append_to:i}),w("use",{href:"#rect_"+this.task.id,append_to:s}),w("image",{x:this.x+t,y:this.y+e,width:this.image_size,height:this.image_size,class:"bar-img",href:this.task.thumbnail,clipPath:"clip_"+this.task.id,append_to:this.bar_group})}draw_add_task_icon(){this.icon_size=20,this.icon_padding=5;let i;if(this.gantt.options.task_add_icon_position==="before")i=this.x-20-5;else if(this.gantt.options.task_add_icon_position==="after")i=this.x+this.$bar.getWidth()+5;else return;const s=this.y+(this.height-20)/2;this.$add_icon_group=w("g",{class:"add-task-icon hide",append_to:this.handle_group}),this.$add_icon_circle=w("circle",{cx:i+20/2,cy:s+20/2,r:20/2,class:"add-task-icon-bg",append_to:this.$add_icon_group}),this.$add_icon_vertical=w("line",{x1:i+20/2,y1:s+5,x2:i+20/2,y2:s+20-5,class:"add-task-icon-plus",append_to:this.$add_icon_group}),this.$add_icon_horizontal=w("line",{x1:i+5,y1:s+20/2,x2:i+20-5,y2:s+20/2,class:"add-task-icon-plus",append_to:this.$add_icon_group}),u.on(this.$add_icon_group,"mousedown",n=>{n.stopPropagation()}),u.on(this.$add_icon_group,"mouseup",n=>{n.stopPropagation()}),u.on(this.$add_icon_group,"click",n=>{n.stopPropagation(),this.gantt.trigger_event("task_add",[this.task])}),u.on(this.$add_icon_group,"mouseenter",n=>{this.is_hovering_icon=!0,this.add_icon_hide_timeout&&(clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=null),this.$add_icon_group.classList.add("active"),this.$add_icon_group.classList.remove("hide"),n.stopPropagation()}),u.on(this.$add_icon_group,"mouseleave",()=>{this.is_hovering_icon=!1,this.$add_icon_group.classList.remove("active"),this.is_hovering_bar||this.$add_icon_group.classList.add("hide")})}draw_resize_handles(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar,e=8;if(this.handles=[],this.gantt.options.readonly_dates||(this.handles.push(w("rect",{x:t.getEndX()-e,y:t.getY()+(this.height-this.height*.8)/2,width:e,height:this.height*.8,rx:2,ry:2,class:"handle right",append_to:this.handle_group})),this.handles.push(w("rect",{x:t.getX()-e,y:t.getY()+(this.height-this.height*.8)/2,width:e,height:this.height*.8,rx:2,ry:2,class:"handle left",append_to:this.handle_group}))),!this.gantt.options.readonly_progress){const i=this.$bar_progress;this.$handle_progress=w("circle",{cx:i.getEndX(),cy:i.getY()+i.getHeight()/2,r:4.5,class:"handle progress",append_to:this.handle_group}),this.handles.push(this.$handle_progress)}for(let i of this.handles)u.on(i,"mouseenter",()=>i.classList.add("active")),u.on(i,"mouseleave",()=>i.classList.remove("active"))}draw_connector_circles(){if(this.$connector_start=null,this.$connector_end=null,!this.gantt.options.allow_dependency_creation||this.gantt.options.readonly)return;const t=this.gantt.options.isRTL,e=this.y+this.height/2,i=t?this.x+this.width:this.x,s=t?this.x:this.x+this.width;this.$connector_start=w("circle",{class:"connector-circle connector-start","data-endpoint":"start",cx:i,cy:e,r:4,append_to:this.handle_group}),this.$connector_end=w("circle",{class:"connector-circle connector-end","data-endpoint":"end",cx:s,cy:e,r:4,append_to:this.handle_group})}update_connector_circles(){if(!this.$connector_start)return;const t=this.gantt.options.isRTL,e=this.$bar.getX(),i=this.$bar.getWidth(),s=this.y+this.height/2,n=t?e+i:e,a=t?e:e+i;this.$connector_start.setAttribute("cx",n),this.$connector_start.setAttribute("cy",s),this.$connector_end.setAttribute("cx",a),this.$connector_end.setAttribute("cy",s)}bind(){this.invalid||this.setup_click_event()}unbind(){this.invalid||this.group&&this.event_listeners&&(this.event_listeners.forEach(({event:t,handler:e})=>{u.off(this.group,t,e)}),this.event_listeners=[])}setup_click_event(){this.event_listeners=[];let t=this.task.id;const e=p=>{this.gantt.trigger_event("hover",[this.task,p.screenX,p.screenY,p])};if(u.on(this.group,"mouseover",e),this.event_listeners.push({event:"mouseover",handler:e}),this.gantt.options.popup_on==="click"){const p=c=>{const m=c.offsetX||c.layerX;if(this.$handle_progress){const f=+this.$handle_progress.getAttribute("cx");if(f>m-1&&f<m+1||this.gantt.bar_being_dragged)return}this.gantt.show_popup({x:c.offsetX||c.layerX,y:c.offsetY||c.layerY,task:this.task,target:this.$bar})};u.on(this.group,"click",p),this.event_listeners.push({event:"click",handler:p})}let i;const s=p=>{i=setTimeout(()=>{this.gantt.options.popup_on==="hover"&&this.gantt.show_popup({x:p.offsetX||p.layerX,y:p.offsetY||p.layerY,task:this.task,target:this.$bar});const c=this.gantt.$container.querySelector(`.highlight-${CSS.escape(t)}`);c&&c.classList.remove("hide")},200),this.$add_icon_group&&(this.is_hovering_bar=!0,this.add_icon_hide_timeout&&(clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=null),this.is_dragging||this.$add_icon_group.classList.remove("hide"))};u.on(this.group,"mouseenter",s),this.event_listeners.push({event:"mouseenter",handler:s});const n=()=>{var c,m;clearTimeout(i),this.gantt.options.popup_on==="hover"&&((m=(c=this.gantt.popup)==null?void 0:c.hide)==null||m.call(c));const p=this.gantt.$container.querySelector(`.highlight-${CSS.escape(t)}`);p&&p.classList.add("hide"),this.$add_icon_group&&(this.is_hovering_bar=!1,this.add_icon_hide_timeout&&clearTimeout(this.add_icon_hide_timeout),this.add_icon_hide_timeout=setTimeout(()=>{this.is_hovering_icon||this.$add_icon_group.classList.add("hide")},200))};u.on(this.group,"mouseleave",n),this.event_listeners.push({event:"mouseleave",handler:n});const a=()=>{this.is_dragging=!0,this.hide_add_icon()};u.on(this.group,"mousedown",a),this.event_listeners.push({event:"mousedown",handler:a});const o=()=>{setTimeout(()=>{this.gantt.bar_being_dragged!==!0&&(this.is_dragging=!1,this.$add_icon_group&&this.is_hovering_bar&&this.$add_icon_group.classList.remove("hide"))},0)};u.on(this.group,"mouseup",o),this.event_listeners.push({event:"mouseup",handler:o});const d=()=>{this.action_completed||this.gantt.bar_being_dragged||this.gantt.trigger_event("click",[this.task])};u.on(this.group,"click",d),this.event_listeners.push({event:"click",handler:d});const h=()=>{this.action_completed||(this.group.classList.remove("active"),this.gantt.popup&&this.gantt.popup.parent.classList.remove("hide"),this.gantt.trigger_event("double_click",[this.task]))};u.on(this.group,"dblclick",h),this.event_listeners.push({event:"dblclick",handler:h});let _=!1;const l=p=>{if(!_)return _=!0,setTimeout(function(){_=!1},300),!1;p.preventDefault(),!this.action_completed&&(this.group.classList.remove("active"),this.gantt.popup&&this.gantt.popup.parent.classList.remove("hide"),this.gantt.trigger_event("double_click",[this.task]))};u.on(this.group,"touchstart",l),this.event_listeners.push({event:"touchstart",handler:l})}update_bar_position({x:t=null,width:e=null}){const i=this.$bar;t&&(this.update_attr(i,"x",t),this.x=t,this.$date_highlight.style.left=t+"px"),e>0&&(this.update_attr(i,"width",e),this.$date_highlight.style.width=e+"px"),this.update_label_position(),this.update_handle_position(),this.update_add_icon_position(),this.date_changed(),this.compute_duration(),this.gantt.options.show_expected_progress&&this.update_expected_progressbar_position(),this.update_progressbar_position(),this.update_arrow_position(),this.update_connector_circles()}update_label_position_on_horizontal_scroll({x:t,sx:e}){const i=this.gantt.$container,s=this.group.querySelector(".bar-label"),n=this.group.querySelector(".bar-img")||"",a=this.bar_group.querySelector(".img_mask")||"";let o=this.$bar.getX()+this.$bar.getWidth(),d=s.getX()+t,h=n&&n.getX()+t||0,_=n&&n.getBBox().width+7||7,l=d+s.getBBox().width+7,p=e+i.clientWidth/2;s.classList.contains("big")||(l<o&&t>0&&l<p||d-_>this.$bar.getX()&&t<0&&l>p)&&(s.setAttribute("x",d),n&&(n.setAttribute("x",h),a.setAttribute("x",h)))}date_changed(){let t=!1;const{new_start_date:e,new_end_date:i}=this.compute_start_end_date();Number(this.task._start)!==Number(e)&&(t=!0,this.task._start=e),Number(this.task._end)!==Number(i)&&(t=!0,this.task._end=i),t&&this.gantt.trigger_event("date_change",[this.task,e,g.add(i,-1,"second")])}progress_changed(){this.task.progress=this.compute_progress(),this.gantt.trigger_event("progress_change",[this.task,this.task.progress])}set_action_completed(){this.action_completed=!0,setTimeout(()=>this.action_completed=!1,10),this.is_dragging=!1,this.$add_icon_group&&this.is_hovering_bar&&this.$add_icon_group.classList.remove("hide")}compute_start_end_date(){const t=this.$bar,e=t.getX()/this.gantt.config.column_width;let i=g.add(this.gantt.gantt_start,e*this.gantt.config.step,this.gantt.config.unit);const s=t.getWidth()/this.gantt.config.column_width,n=g.add(i,s*this.gantt.config.step,this.gantt.config.unit);return{new_start_date:i,new_end_date:n}}compute_progress(){this.progress_width=this.$bar_progress.getWidth(),this.x=this.$bar_progress.getBBox().x;const t=this.x+this.progress_width,e=this.progress_width-this.gantt.config.ignored_positions.reduce((s,n)=>s+(n>=this.x&&n<=t),0)*this.gantt.config.column_width;if(e<0)return 0;const i=this.$bar.getWidth()-this.ignored_duration_raw*this.gantt.config.column_width;return parseInt(e/i*100,10)}compute_expected_progress(){this.expected_progress=g.diff(g.today(),this.task._start,"hour")/this.gantt.config.step,this.expected_progress=(this.expected_progress<this.duration?this.expected_progress:this.duration)*100/this.duration}compute_x(){const{column_width:t}=this.gantt.config,e=this.task._start,i=this.gantt.gantt_start;let n=g.diff(e,i,this.gantt.config.unit)/this.gantt.config.step*t;this.x=n}compute_y(){this.y=this.gantt.config.header_height+this.gantt.options.padding/2+this.task._index*(this.height+this.gantt.options.padding)}compute_duration(){let t=0,e=0;for(let i=new Date(this.task._start);i<this.task._end;i.setDate(i.getDate()+1))e++,!this.gantt.config.ignored_dates.find(s=>s.getTime()===i.getTime())&&(!this.gantt.config.ignored_function||!this.gantt.config.ignored_function(i))&&t++;this.task.actual_duration=t,this.task.ignored_duration=e-t,this.duration=g.convert_scales(e+"d",this.gantt.config.unit)/this.gantt.config.step,this.actual_duration_raw=g.convert_scales(t+"d",this.gantt.config.unit)/this.gantt.config.step,this.ignored_duration_raw=this.duration-this.actual_duration_raw}update_attr(t,e,i){return i=+i,isNaN(i)||t.setAttribute(e,i),t}update_expected_progressbar_position(){this.invalid||(this.$expected_bar_progress.setAttribute("x",this.$bar.getX()),this.compute_expected_progress(),this.$expected_bar_progress.setAttribute("width",this.gantt.config.column_width*this.actual_duration_raw*(this.expected_progress/100)||0))}update_progressbar_position(){this.invalid||this.gantt.options.readonly||(this.$bar_progress.setAttribute("x",this.$bar.getX()),this.$bar_progress.setAttribute("width",this.calculate_progress_width()))}update_label_position(){const t=this.bar_group.querySelector(".img_mask")||"",e=this.$bar,i=this.group.querySelector(".bar-label"),s=this.group.querySelector(".bar-img");let n=5,a=this.image_size+10;const o=i.getBBox().width,d=e.getWidth();o>d?(i.classList.add("big"),s?(s.setAttribute("x",e.getEndX()+n),t.setAttribute("x",e.getEndX()+n),i.setAttribute("x",e.getEndX()+a)):i.setAttribute("x",e.getEndX()+n)):(i.classList.remove("big"),s?(s.setAttribute("x",e.getX()+n),t.setAttribute("x",e.getX()+n),i.setAttribute("x",e.getX()+d/2+a)):i.setAttribute("x",e.getX()+d/2-o/2))}update_handle_position(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar;this.handle_group.querySelector(".handle.left").setAttribute("x",t.getX()),this.handle_group.querySelector(".handle.right").setAttribute("x",t.getEndX());const e=this.group.querySelector(".handle.progress");e&&e.setAttribute("cx",this.$bar_progress.getEndX())}update_add_icon_position(){if(!this.$add_icon_group)return;const t=this.icon_size,e=this.icon_padding;let i;if(this.gantt.options.task_add_icon_position==="before")i=this.x-t-e;else if(this.gantt.options.task_add_icon_position==="after")i=this.x+this.$bar.getWidth()+e;else return;const s=this.y+(this.height-t)/2;this.$add_icon_circle.setAttribute("cx",i+t/2),this.$add_icon_circle.setAttribute("cy",s+t/2),this.$add_icon_vertical.setAttribute("x1",i+t/2),this.$add_icon_vertical.setAttribute("y1",s+5),this.$add_icon_vertical.setAttribute("x2",i+t/2),this.$add_icon_vertical.setAttribute("y2",s+t-5),this.$add_icon_horizontal.setAttribute("x1",i+5),this.$add_icon_horizontal.setAttribute("y1",s+t/2),this.$add_icon_horizontal.setAttribute("x2",i+t-5),this.$add_icon_horizontal.setAttribute("y2",s+t/2)}hide_add_icon(){this.$add_icon_group&&this.$add_icon_group.classList.add("hide")}update_arrow_position(){this.arrows=this.arrows||[];for(let t of this.arrows)t.update()}}class I{constructor(t,e,i){this.parent=t,this.popup_func=e,this.gantt=i,this.make()}make(){this.parent.innerHTML=`
102
102
  <div class="title"></div>
103
103
  <div class="subtitle"></div>
104
104
  <div class="details"></div>
105
105
  <div class="actions"></div>
106
- `,this.hide(),this.title=this.parent.querySelector(".title"),this.subtitle=this.parent.querySelector(".subtitle"),this.details=this.parent.querySelector(".details"),this.actions=this.parent.querySelector(".actions")}show({x:t,y:e,task:i,target:s}){this.actions.innerHTML="";let n=this.popup_func({task:i,chart:this.gantt,get_title:()=>this.title,set_title:a=>this.title.innerHTML=a,get_subtitle:()=>this.subtitle,set_subtitle:a=>this.subtitle.innerHTML=a,get_details:()=>this.details,set_details:a=>this.details.innerHTML=a,add_action:(a,o)=>{let d=this.gantt.create_el({classes:"action-btn",type:"button",append_to:this.actions});typeof a=="function"&&(a=a(i)),d.innerHTML=a,d.onclick=h=>o(i,this.gantt,h)}});n!==!1&&(n&&(this.parent.innerHTML=n),this.actions.innerHTML===""?this.actions.remove():this.parent.appendChild(this.actions),this.parent.style.left=t+10+"px",this.parent.style.top=e-10+"px",this.parent.classList.remove("hide"))}hide(){this.parent.classList.add("hide")}}function C(r){const t=r.getFullYear();return t-t%10+""}function U(r,t,e){let i=g.add(r,6,"day"),s=i.getMonth()!==r.getMonth()?"D MMM":"D",n=!t||r.getMonth()!==t.getMonth()?"D MMM":"D";return`${g.format(r,n,e)} - ${g.format(i,s,e)}`}const x=[{name:"Hour",padding:"7d",step:"1h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D MMMM",e):"",upper_text_frequency:24},{name:"Quarter Day",padding:"7d",step:"6h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D MMM",e):"",upper_text_frequency:4},{name:"Half Day",padding:"14d",step:"12h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?r.getMonth()!==r.getMonth()?g.format(r,"D MMM",e):g.format(r,"D",e):"",upper_text_frequency:2},{name:"Day",padding:"7d",date_format:"YYYY-MM-DD",step:"1d",lower_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D",e):"",upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?g.format(r,"MMMM",e):"",thick_line:r=>r.getDay()===1},{name:"Week",padding:"1m",step:"7d",date_format:"YYYY-MM-DD",column_width:140,lower_text:U,upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?g.format(r,"MMMM",e):"",thick_line:r=>r.getDate()>=1&&r.getDate()<=7,upper_text_frequency:4},{name:"Month",padding:"2m",step:"1m",column_width:120,date_format:"YYYY-MM",lower_text:"MMMM",upper_text:(r,t,e)=>!t||r.getFullYear()!==t.getFullYear()?g.format(r,"YYYY",e):"",thick_line:r=>r.getMonth()%3===0,snap_at:"7d"},{name:"Year",padding:"2y",step:"1y",column_width:120,date_format:"YYYY",upper_text:(r,t,e)=>!t||C(r)!==C(t)?C(r):"",lower_text:"YYYY",snap_at:"30d"}],Q={allow_dependency_creation:!0,arrow_curve:5,auto_move_label:!1,bar_corner_radius:3,bar_height:30,container_height:"auto",column_width:null,critical_path:!1,date_format:"YYYY-MM-DD HH:mm",dependencies_type:"finish-to-start",dependency_shifting:"none",upper_header_height:45,lower_header_height:30,snap_at:null,infinite_padding:!0,holidays:{"var(--g-weekend-highlight-color)":"weekend"},ignore:[],isRTL:!1,language:"en",lines:"both",padding:18,popup:r=>{r.set_title(r.task.name),r.task.description?r.set_subtitle(r.task.description):r.set_subtitle("");const t=g.format(r.task._start,"MMM D",r.chart.options.language),e=g.format(g.add(r.task._end,-1,"second"),"MMM D",r.chart.options.language);r.set_details(`${t} - ${e} (${r.task.actual_duration} days${r.task.ignored_duration?" + "+r.task.ignored_duration+" excluded":""})<br/>Progress: ${Math.floor(r.task.progress*100)/100}%`)},popup_on:"click",readonly_progress:!1,readonly_dates:!1,readonly:!1,scroll_to:"today",show_expected_progress:!1,task_add_icon_position:null,today_button:!0,view_mode:"Day",view_mode_select:!1,view_modes:x,is_weekend:r=>r.getDay()===0||r.getDay()===6,task_column:{enabled:!1,width:200,header_text:"Task Name",content:null}};class P{constructor(t,e,i){this.setup_wrapper(t),this.setup_options(i),this.apply_rtl_direction(),this.setup_tasks(e),this.change_view_mode(),this.bind_events()}setup_wrapper(t){let e,i;if(typeof t=="string"){let s=document.querySelector(t);if(!s)throw new ReferenceError(`CSS selector "${t}" could not be found in DOM`);t=s}if(t instanceof HTMLElement)i=t,e=t.querySelector("svg");else if(t instanceof SVGElement)e=t;else throw new TypeError("Frappe Gantt only supports usage of a string CSS selector, HTML DOM element or SVG DOM element for the 'element' parameter");e?(this.$svg=e,this.$svg.classList.add("gantt")):this.$svg=w("svg",{append_to:i,class:"gantt"}),this.$wrapper=this.create_el({classes:"gantt-wrapper",append_to:this.$svg.parentElement}),this.$container=this.create_el({classes:"gantt-container",append_to:this.$wrapper}),this.$container.appendChild(this.$svg),this.$popup_wrapper=this.create_el({classes:"popup-wrapper",append_to:this.$container})}apply_rtl_direction(){this.options.isRTL&&(this.$container.style.direction="ltr")}setup_options(t){var i;this.original_options=t,t!=null&&t.view_modes&&(t.view_modes=t.view_modes.map(s=>{if(typeof s=="string"){const n=x.find(a=>a.name===s);return n||console.error(`The view mode "${s}" is not predefined in Frappe Gantt. Please define the view mode object instead.`),n}return s}),t.view_mode=t.view_modes[0]),this.options={...Q,...t};const e={"grid-height":"container_height","bar-height":"bar_height","lower-header-height":"lower_header_height","upper-header-height":"upper_header_height"};for(let s in e){let n=this.options[e[s]];n!=="auto"&&(this.$wrapper.style.setProperty("--gv-"+s,n+"px"),this.$container.style.setProperty("--gv-"+s,n+"px"))}if((i=this.options.task_column)!=null&&i.enabled&&(this.$wrapper.style.setProperty("--gv-task-column-width",this.options.task_column.width+"px"),this.$container.style.setProperty("--gv-task-column-width",this.options.task_column.width+"px")),this.config={ignored_dates:[],ignored_positions:[],extend_by_units:10},typeof this.options.ignore!="function"){typeof this.options.ignore=="string"&&(this.options.ignore=[this.options.ignore]);for(let s of this.options.ignore){if(typeof s=="function"){this.config.ignored_function=s;continue}typeof s=="string"&&(s==="weekend"?this.config.ignored_function=n=>n.getDay()==6||n.getDay()==0:this.config.ignored_dates.push(new Date(s+" ")))}}else this.config.ignored_function=this.options.ignore}update_options(t){this.setup_options({...this.original_options,...t}),this.apply_rtl_direction(),this.change_view_mode(void 0,!0)}setup_tasks(t){this.tasks=t.map((e,i)=>{var s;if(!e.start||!e.end)if(!e.start&&!e.end){if(!((s=this.options.task_column)!=null&&s.enabled))return console.warn(`task "${e.id||e.name}" has no dates and will be hidden (task column is disabled)`),!1;e._has_no_dates=!0,e._start=new Date,e._end=new Date,e._index=i}else{if(!e.start)return console.error(`task "${e.id}" doesn't have a start date`),!1;if(!e.end&&!e.duration)return console.error(`task "${e.id}" doesn't have an end date`),!1}if(!e._has_no_dates){if(e._start=g.parse(e.start),e.end===void 0&&e.duration!==void 0&&(e.end=e._start,e.duration.split(" ").forEach(d=>{let{duration:h,scale:_}=g.parse_duration(d);e.end=g.add(e.end,h,_)})),e._end=g.parse(e.end),g.diff(e._end,e._start,"year")<0)return console.error(`start of task can't be after end of task: in task "${e.id}"`),!1;if(g.diff(e._end,e._start,"year")>10)return console.error(`the duration of task "${e.id}" is too long (above ten years)`),!1;e._index=i,g.get_date_values(e._end).slice(3).every(o=>o===0)&&(e._end=g.add(e._end,24,"hour"))}return(typeof e.dependencies=="string"||Array.isArray(e.dependencies)&&e.dependencies.some(n=>typeof n=="string"))&&console.warn(`[frappe-gantt] Task "${e.id}": dependencies must be an array of {id, type?} objects. String format is no longer supported.`),Array.isArray(e.dependencies)||(e.dependencies=[]),e.dependencies=e.dependencies.filter(n=>n&&typeof n.id=="string").map(n=>({...n,id:n.id.replaceAll(" ","_")})),e.id?typeof e.id=="string"?e.id=e.id.replaceAll(" ","_"):e.id=`${e.id}`:e.id=B(e),e}).filter(e=>e).map((e,i)=>(e._index=i,e)),this.setup_dependencies()}setup_dependencies(){this.dependency_map={};for(let t of this.tasks)for(let e of t.dependencies)this.dependency_map[e.id]=this.dependency_map[e.id]||[],this.dependency_map[e.id].push(t.id)}refresh(t,e=!1){this.setup_tasks(t),this.change_view_mode(this.options.view_mode,e)}update_task(t,e){let i=this.tasks.find(a=>a.id===t),s=this.bars[i._index];const n=e.dependencies!==void 0;Object.assign(i,e),n&&(Array.isArray(i.dependencies)||(i.dependencies=[]),i.dependencies=i.dependencies.filter(a=>a&&typeof a.id=="string").map(a=>({...a,id:a.id.replaceAll(" ","_")})),this.setup_dependencies(),this.layers.arrow.innerHTML="",this.make_arrows(),this.map_arrows_on_bars()),s.refresh()}change_view_mode(t=this.options.view_mode,e=!1){typeof t=="string"&&(t=this.options.view_modes.find(n=>n.name===t));let i,s;e&&(i=this.$container.scrollLeft,s=this.options.scroll_to,this.options.scroll_to=null),this.options.view_mode=t.name,this.config.view_mode=t,this.update_view_scale(t),this.setup_dates(e),this.render(),e&&(this.$container.scrollLeft=i,this.options.scroll_to=s),this.trigger_event("view_change",[t])}update_view_scale(t){let{duration:e,scale:i}=g.parse_duration(t.step);this.config.step=e,this.config.unit=i,this.config.column_width=this.options.column_width||t.column_width||45,this.$container.style.setProperty("--gv-column-width",this.config.column_width+"px"),this.config.header_height=this.options.lower_header_height+this.options.upper_header_height+10}setup_dates(t=!1){this.setup_gantt_dates(t),this.setup_date_values()}setup_gantt_dates(t){let e,i;this.tasks.length||(e=new Date,i=new Date);for(let s of this.tasks)(!e||s._start<e)&&(e=s._start),(!i||s._end>i)&&(i=s._end);if(e=g.start_of(e,this.config.unit),i=g.start_of(i,this.config.unit),!t)if(this.options.infinite_padding)this.gantt_start=g.add(e,-this.config.extend_by_units*3,this.config.unit),this.gantt_end=g.add(i,this.config.extend_by_units*3,this.config.unit);else{typeof this.config.view_mode.padding=="string"&&(this.config.view_mode.padding=[this.config.view_mode.padding,this.config.view_mode.padding]);let[s,n]=this.config.view_mode.padding.map(g.parse_duration);this.gantt_start=g.add(e,-s.duration,s.scale),this.gantt_end=g.add(i,n.duration,n.scale)}this.config.date_format=this.config.view_mode.date_format||this.options.date_format,this.gantt_start.setHours(0,0,0,0)}setup_date_values(){let t=this.gantt_start;for(this.dates=[t];t<this.gantt_end;)t=g.add(t,this.config.step,this.config.unit),this.dates.push(t)}bind_events(){this.bind_grid_click(),this.bind_holiday_labels(),this.bind_bar_events(),this.bind_task_column_resize(),this.bind_task_column_scroll(),this.options.allow_dependency_creation&&this.bind_dependency_linking()}render(){this.clear(),this.setup_layers(),this.make_grid(),this.make_dates(),this.make_grid_extras(),this.make_bars(),this.make_arrows(),this.map_arrows_on_bars(),this.set_dimensions(),this.set_scroll_position(this.options.scroll_to)}setup_layers(){this.layers={};const t=["grid","arrow","progress","bar"];for(let e of t)this.layers[e]=w("g",{class:e,append_to:this.$svg});this.options.allow_dependency_creation&&(this.layers.linking=w("g",{class:"linking",append_to:this.$svg})),this.$extras=this.create_el({classes:"extras",append_to:this.$container}),this.$adjust=this.create_el({classes:"adjust hide",append_to:this.$extras,type:"button"}),this.$adjust.innerHTML="&larr;"}make_grid(){this.make_grid_background(),this.make_grid_rows(),this.make_grid_header(),this.make_side_header(),this.make_task_column()}make_grid_extras(){this.make_grid_highlights(),this.make_grid_ticks()}make_grid_background(){const t=this.dates.length*this.config.column_width,e=Math.max(this.config.header_height+this.options.padding+(this.options.bar_height+this.options.padding)*this.tasks.length-10,this.options.container_height!=="auto"?this.options.container_height:0);w("rect",{x:0,y:0,width:t,height:e,class:"grid-background",append_to:this.$svg}),u.attr(this.$svg,{height:e,width:"100%"}),this.grid_height=e,this.options.container_height==="auto"&&(this.$container.style.height=e+"px")}make_grid_rows(){const t=w("g",{append_to:this.layers.grid}),e=this.dates.length*this.config.column_width,i=this.options.bar_height+this.options.padding;this.config.header_height;for(let s=this.config.header_height;s<this.grid_height;s+=i)w("rect",{x:0,y:s,width:e,height:i,class:"grid-row",append_to:t})}make_grid_header(){this.$header=this.create_el({width:this.dates.length*this.config.column_width,classes:"grid-header",append_to:this.$container}),this.$upper_header=this.create_el({classes:"upper-header",append_to:this.$header}),this.$lower_header=this.create_el({classes:"lower-header",append_to:this.$header})}make_side_header(){if(this.$side_header=this.create_el({classes:"side-header"}),this.$upper_header.prepend(this.$side_header),this.options.view_mode_select){const t=document.createElement("select");t.classList.add("viewmode-select");const e=document.createElement("option");e.selected=!0,e.disabled=!0,e.textContent="Mode",t.appendChild(e);for(const i of this.options.view_modes){const s=document.createElement("option");s.value=i.name,s.textContent=i.name,i.name===this.config.view_mode.name&&(s.selected=!0),t.appendChild(s)}t.addEventListener("change",(function(){this.change_view_mode(t.value,!0)}).bind(this)),this.$side_header.appendChild(t)}if(this.options.today_button){let t=document.createElement("button");t.classList.add("today-button"),t.textContent="Today",t.onclick=this.scroll_current.bind(this),this.$side_header.prepend(t),this.$today_button=t}}make_task_column(){var i,s,n,a,o,d,h,_,l,p;if((i=this.$task_column)==null||i.remove(),!((s=this.options.task_column)!=null&&s.enabled)){(a=(n=this.$wrapper)==null?void 0:n.classList)==null||a.remove("has-task-column");return}(d=(o=this.$wrapper)==null?void 0:o.classList)==null||d.add("has-task-column"),this.$task_column=this.create_el({classes:"task-column",append_to:this.$wrapper}),this.$wrapper.insertBefore(this.$task_column,this.$container),this.$task_column_header=this.create_el({classes:"task-column-header",append_to:this.$task_column}),this.$task_column_header.textContent=this.options.task_column.header_text||"Task Name",this.$task_column_content=this.create_el({classes:"task-column-content",append_to:this.$task_column});const t=this.options.bar_height+this.options.padding,e=Math.max(this.tasks.length*t,this.grid_height-this.config.header_height);this.$task_column_content.style.minHeight=e+"px",this.$wrapper.style.setProperty("--gv-task-column-content-height",e+"px"),this.$container.style.setProperty("--gv-task-column-content-height",e+"px"),this.tasks.forEach(c=>{const m=this.options.bar_height+this.options.padding,f=this.create_el({classes:"task-row",append_to:this.$task_column_content});if(f.style.top=c._index*m-1+"px",f.style.height=m+"px",this.options.task_column.content&&typeof this.options.task_column.content=="function"){const b=this.options.task_column.content(c);typeof b=="string"?f.innerHTML=b:b instanceof HTMLElement&&f.appendChild(b)}else f.textContent=c.name,f.title=c.name;f.setAttribute("data-task-id",c.id)}),this.$task_column.style.width=this.options.task_column.width+"px",this.$task_column_resize_handle=this.create_el({classes:"task-column-resize-handle",append_to:this.$task_column}),this.options.isRTL?(_=(h=this.$wrapper)==null?void 0:h.classList)==null||_.add("rtl"):(p=(l=this.$wrapper)==null?void 0:l.classList)==null||p.remove("rtl")}make_grid_ticks(){if(this.options.lines==="none")return;let t=0,e=this.config.header_height,i=this.grid_height-this.config.header_height,s=w("g",{class:"lines_layer",append_to:this.layers.grid}),n=this.config.header_height;const a=this.dates.length*this.config.column_width,o=this.options.bar_height+this.options.padding;if(this.options.lines!=="vertical")for(let d=this.config.header_height;d<this.grid_height;d+=o)w("line",{x1:0,y1:n+o,x2:a,y2:n+o,class:"row-line",append_to:s}),n+=o;if(this.options.lines!=="horizontal")for(let d of this.dates){let h="tick";this.config.view_mode.thick_line&&this.config.view_mode.thick_line(d)&&(h+=" thick"),w("path",{d:`M ${t} ${e} v ${i}`,class:h,append_to:this.layers.grid}),this.view_is("month")?t+=g.get_days_in_month(d)*this.config.column_width/30:this.view_is("year")?t+=g.get_days_in_year(d)*this.config.column_width/365:t+=this.config.column_width}}highlight_holidays(){let t={};if(this.options.holidays)for(let e in this.options.holidays){let i=this.options.holidays[e];i==="weekend"&&(i=this.options.is_weekend);let s;if(typeof i=="object"){let n=i.find(a=>typeof a=="function");if(n&&(s=n),this.options.holidays.name){let a=new Date(i.date+" ");i=o=>a.getTime()===o.getTime(),t[a]=i.name}else i=a=>this.options.holidays[e].filter(o=>typeof o!="function").map(o=>{if(o.name){let d=new Date(o.date+" ");return t[d]=o.name,d.getTime()}return new Date(o+" ").getTime()}).includes(a.getTime())}for(let n=new Date(this.gantt_start);n<=this.gantt_end;n.setDate(n.getDate()+1))if(!(this.config.ignored_dates.find(a=>a.getTime()==n.getTime())||this.config.ignored_function&&this.config.ignored_function(n))&&(i(n)||s&&s(n))){const a=g.diff(n,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width,o=this.grid_height-this.config.header_height,d=g.format(n,"YYYY-MM-DD",this.options.language).replace(" ","_");if(t[n]){let h=this.create_el({classes:"holiday-label label_"+d,append_to:this.$extras});h.textContent=t[n]}w("rect",{x:Math.round(a),y:this.config.header_height,width:this.config.column_width/g.convert_scales(this.config.view_mode.step,"day"),height:o,class:"holiday-highlight "+d,style:`fill: ${e};`,append_to:this.layers.grid})}}}highlight_current(){const t=this.get_closest_date();if(!t)return;const[e,i]=t;i.classList.add("current-date-highlight");const n=g.diff(new Date,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width;this.$current_highlight=this.create_el({top:this.config.header_height,left:n,height:this.grid_height-this.config.header_height,classes:"current-highlight",append_to:this.$container}),this.$current_ball_highlight=this.create_el({top:this.config.header_height-6,left:n-2.5,width:6,height:6,classes:"current-ball-highlight",append_to:this.$header})}make_grid_highlights(){this.highlight_holidays(),this.config.ignored_positions=[];const t=(this.options.bar_height+this.options.padding)*this.tasks.length;this.layers.grid.innerHTML+=`<pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4">
106
+ `,this.hide(),this.title=this.parent.querySelector(".title"),this.subtitle=this.parent.querySelector(".subtitle"),this.details=this.parent.querySelector(".details"),this.actions=this.parent.querySelector(".actions")}show({x:t,y:e,task:i,target:s}){this.actions.innerHTML="";let n=this.popup_func({task:i,chart:this.gantt,get_title:()=>this.title,set_title:a=>this.title.innerHTML=a,get_subtitle:()=>this.subtitle,set_subtitle:a=>this.subtitle.innerHTML=a,get_details:()=>this.details,set_details:a=>this.details.innerHTML=a,add_action:(a,o)=>{let d=this.gantt.create_el({classes:"action-btn",type:"button",append_to:this.actions});typeof a=="function"&&(a=a(i)),d.innerHTML=a,d.onclick=h=>o(i,this.gantt,h)}});n!==!1&&(n&&(this.parent.innerHTML=n),this.actions.innerHTML===""?this.actions.remove():this.parent.appendChild(this.actions),this.parent.style.left=t+10+"px",this.parent.style.top=e-10+"px",this.parent.classList.remove("hide"))}hide(){this.parent.classList.add("hide")}}function C(r){const t=r.getFullYear();return t-t%10+""}function U(r,t,e){let i=g.add(r,6,"day"),s=i.getMonth()!==r.getMonth()?"D MMM":"D",n=!t||r.getMonth()!==t.getMonth()?"D MMM":"D";return`${g.format(r,n,e)} - ${g.format(i,s,e)}`}const x=[{name:"Hour",padding:"7d",step:"1h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D MMMM",e):"",upper_text_frequency:24},{name:"Quarter Day",padding:"7d",step:"6h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D MMM",e):"",upper_text_frequency:4},{name:"Half Day",padding:"14d",step:"12h",date_format:"YYYY-MM-DD HH:",lower_text:"HH",upper_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?r.getMonth()!==r.getMonth()?g.format(r,"D MMM",e):g.format(r,"D",e):"",upper_text_frequency:2},{name:"Day",padding:"7d",date_format:"YYYY-MM-DD",step:"1d",lower_text:(r,t,e)=>!t||r.getDate()!==t.getDate()?g.format(r,"D",e):"",upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?g.format(r,"MMMM",e):"",thick_line:r=>r.getDay()===1},{name:"Week",padding:"1m",step:"7d",date_format:"YYYY-MM-DD",column_width:140,lower_text:U,upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?g.format(r,"MMMM",e):"",thick_line:r=>r.getDate()>=1&&r.getDate()<=7,upper_text_frequency:4},{name:"Month",padding:"2m",step:"1m",column_width:120,date_format:"YYYY-MM",lower_text:"MMMM",upper_text:(r,t,e)=>!t||r.getFullYear()!==t.getFullYear()?g.format(r,"YYYY",e):"",thick_line:r=>r.getMonth()%3===0,snap_at:"7d"},{name:"Year",padding:"2y",step:"1y",column_width:120,date_format:"YYYY",upper_text:(r,t,e)=>!t||C(r)!==C(t)?C(r):"",lower_text:"YYYY",snap_at:"30d"}],Q={allow_dependency_creation:!0,arrow_curve:5,auto_move_label:!1,bar_corner_radius:3,bar_height:30,container_height:"auto",column_width:null,critical_path:!1,date_format:"YYYY-MM-DD HH:mm",dependencies_type:"finish-to-start",dependency_shifting:"none",upper_header_height:45,lower_header_height:30,snap_at:null,infinite_padding:!0,holidays:{"var(--g-weekend-highlight-color)":"weekend"},ignore:[],isRTL:!1,language:"en",lines:"both",padding:18,popup:r=>{r.set_title(r.task.name),r.task.description?r.set_subtitle(r.task.description):r.set_subtitle("");const t=g.format(r.task._start,"MMM D",r.chart.options.language),e=g.format(g.add(r.task._end,-1,"second"),"MMM D",r.chart.options.language);r.set_details(`${t} - ${e} (${r.task.actual_duration} days${r.task.ignored_duration?" + "+r.task.ignored_duration+" excluded":""})<br/>Progress: ${Math.floor(r.task.progress*100)/100}%`)},popup_on:"click",readonly_progress:!1,readonly_dates:!1,readonly:!1,scroll_to:"today",show_bar_label:!0,show_expected_progress:!1,task_add_icon_position:null,today_button:!0,view_mode:"Day",view_mode_select:!1,view_modes:x,is_weekend:r=>r.getDay()===0||r.getDay()===6,task_column:{enabled:!1,width:200,header_text:"Task Name",content:null}};class P{constructor(t,e,i){this.setup_wrapper(t),this.setup_options(i),this.apply_rtl_direction(),this.setup_tasks(e),this.change_view_mode(),this.bind_events()}setup_wrapper(t){let e,i;if(typeof t=="string"){let s=document.querySelector(t);if(!s)throw new ReferenceError(`CSS selector "${t}" could not be found in DOM`);t=s}if(t instanceof HTMLElement)i=t,e=t.querySelector("svg");else if(t instanceof SVGElement)e=t;else throw new TypeError("Frappe Gantt only supports usage of a string CSS selector, HTML DOM element or SVG DOM element for the 'element' parameter");e?(this.$svg=e,this.$svg.classList.add("gantt")):this.$svg=w("svg",{append_to:i,class:"gantt"}),this.$wrapper=this.create_el({classes:"gantt-wrapper",append_to:this.$svg.parentElement}),this.$container=this.create_el({classes:"gantt-container",append_to:this.$wrapper}),this.$container.appendChild(this.$svg),this.$popup_wrapper=this.create_el({classes:"popup-wrapper",append_to:this.$container})}apply_rtl_direction(){this.options.isRTL&&(this.$container.style.direction="ltr")}setup_options(t){var i;this.original_options=t,t!=null&&t.view_modes&&(t.view_modes=t.view_modes.map(s=>{if(typeof s=="string"){const n=x.find(a=>a.name===s);return n||console.error(`The view mode "${s}" is not predefined in Frappe Gantt. Please define the view mode object instead.`),n}return s}),t.view_mode=t.view_modes[0]),this.options={...Q,...t};const e={"grid-height":"container_height","bar-height":"bar_height","lower-header-height":"lower_header_height","upper-header-height":"upper_header_height"};for(let s in e){let n=this.options[e[s]];n!=="auto"&&(this.$wrapper.style.setProperty("--gv-"+s,n+"px"),this.$container.style.setProperty("--gv-"+s,n+"px"))}if((i=this.options.task_column)!=null&&i.enabled&&(this.$wrapper.style.setProperty("--gv-task-column-width",this.options.task_column.width+"px"),this.$container.style.setProperty("--gv-task-column-width",this.options.task_column.width+"px")),this.config={ignored_dates:[],ignored_positions:[],extend_by_units:10},typeof this.options.ignore!="function"){typeof this.options.ignore=="string"&&(this.options.ignore=[this.options.ignore]);for(let s of this.options.ignore){if(typeof s=="function"){this.config.ignored_function=s;continue}typeof s=="string"&&(s==="weekend"?this.config.ignored_function=n=>n.getDay()==6||n.getDay()==0:this.config.ignored_dates.push(new Date(s+" ")))}}else this.config.ignored_function=this.options.ignore}update_options(t){this.setup_options({...this.original_options,...t}),this.apply_rtl_direction(),this.change_view_mode(void 0,!0)}setup_tasks(t){this.tasks=t.map((e,i)=>{var s;if(!e.start||!e.end)if(!e.start&&!e.end){if(!((s=this.options.task_column)!=null&&s.enabled))return console.warn(`task "${e.id||e.name}" has no dates and will be hidden (task column is disabled)`),!1;e._has_no_dates=!0,e._start=new Date,e._end=new Date,e._index=i}else{if(!e.start)return console.error(`task "${e.id}" doesn't have a start date`),!1;if(!e.end&&!e.duration)return console.error(`task "${e.id}" doesn't have an end date`),!1}if(!e._has_no_dates){if(e._start=g.parse(e.start),e.end===void 0&&e.duration!==void 0&&(e.end=e._start,e.duration.split(" ").forEach(d=>{let{duration:h,scale:_}=g.parse_duration(d);e.end=g.add(e.end,h,_)})),e._end=g.parse(e.end),g.diff(e._end,e._start,"year")<0)return console.error(`start of task can't be after end of task: in task "${e.id}"`),!1;if(g.diff(e._end,e._start,"year")>10)return console.error(`the duration of task "${e.id}" is too long (above ten years)`),!1;e._index=i,g.get_date_values(e._end).slice(3).every(o=>o===0)&&(e._end=g.add(e._end,24,"hour"))}return(typeof e.dependencies=="string"||Array.isArray(e.dependencies)&&e.dependencies.some(n=>typeof n=="string"))&&console.warn(`[frappe-gantt] Task "${e.id}": dependencies must be an array of {id, type?} objects. String format is no longer supported.`),Array.isArray(e.dependencies)||(e.dependencies=[]),e.dependencies=e.dependencies.filter(n=>n&&typeof n.id=="string").map(n=>({...n,id:n.id.replaceAll(" ","_")})),e.id?typeof e.id=="string"?e.id=e.id.replaceAll(" ","_"):e.id=`${e.id}`:e.id=B(e),e}).filter(e=>e).map((e,i)=>(e._index=i,e)),this.setup_dependencies()}setup_dependencies(){this.dependency_map={};for(let t of this.tasks)for(let e of t.dependencies)this.dependency_map[e.id]=this.dependency_map[e.id]||[],this.dependency_map[e.id].push(t.id)}refresh(t,e=!1){this.setup_tasks(t),this.change_view_mode(this.options.view_mode,e)}update_task(t,e){let i=this.tasks.find(a=>a.id===t),s=this.bars[i._index];const n=e.dependencies!==void 0;Object.assign(i,e),n&&(Array.isArray(i.dependencies)||(i.dependencies=[]),i.dependencies=i.dependencies.filter(a=>a&&typeof a.id=="string").map(a=>({...a,id:a.id.replaceAll(" ","_")})),this.setup_dependencies(),this.layers.arrow.innerHTML="",this.make_arrows(),this.map_arrows_on_bars()),s.refresh()}change_view_mode(t=this.options.view_mode,e=!1){typeof t=="string"&&(t=this.options.view_modes.find(n=>n.name===t));let i,s;e&&(i=this.$container.scrollLeft,s=this.options.scroll_to,this.options.scroll_to=null),this.options.view_mode=t.name,this.config.view_mode=t,this.update_view_scale(t),this.setup_dates(e),this.render(),e&&(this.$container.scrollLeft=i,this.options.scroll_to=s),this.trigger_event("view_change",[t])}update_view_scale(t){let{duration:e,scale:i}=g.parse_duration(t.step);this.config.step=e,this.config.unit=i,this.config.column_width=this.options.column_width||t.column_width||45,this.$container.style.setProperty("--gv-column-width",this.config.column_width+"px"),this.config.header_height=this.options.lower_header_height+this.options.upper_header_height+10}setup_dates(t=!1){this.setup_gantt_dates(t),this.setup_date_values()}setup_gantt_dates(t){let e,i;this.tasks.length||(e=new Date,i=new Date);for(let s of this.tasks)(!e||s._start<e)&&(e=s._start),(!i||s._end>i)&&(i=s._end);if(e=g.start_of(e,this.config.unit),i=g.start_of(i,this.config.unit),!t)if(this.options.infinite_padding)this.gantt_start=g.add(e,-this.config.extend_by_units*3,this.config.unit),this.gantt_end=g.add(i,this.config.extend_by_units*3,this.config.unit);else{typeof this.config.view_mode.padding=="string"&&(this.config.view_mode.padding=[this.config.view_mode.padding,this.config.view_mode.padding]);let[s,n]=this.config.view_mode.padding.map(g.parse_duration);this.gantt_start=g.add(e,-s.duration,s.scale),this.gantt_end=g.add(i,n.duration,n.scale)}this.config.date_format=this.config.view_mode.date_format||this.options.date_format,this.gantt_start.setHours(0,0,0,0)}setup_date_values(){let t=this.gantt_start;for(this.dates=[t];t<this.gantt_end;)t=g.add(t,this.config.step,this.config.unit),this.dates.push(t)}bind_events(){this.bind_grid_click(),this.bind_holiday_labels(),this.bind_bar_events(),this.bind_task_column_resize(),this.bind_task_column_scroll(),this.options.allow_dependency_creation&&this.bind_dependency_linking()}render(){this.clear(),this.setup_layers(),this.make_grid(),this.make_dates(),this.make_grid_extras(),this.make_bars(),this.make_arrows(),this.map_arrows_on_bars(),this.set_dimensions(),this.set_scroll_position(this.options.scroll_to)}setup_layers(){this.layers={};const t=["grid","arrow","progress","bar"];for(let e of t)this.layers[e]=w("g",{class:e,append_to:this.$svg});this.options.allow_dependency_creation&&(this.layers.linking=w("g",{class:"linking",append_to:this.$svg})),this.$extras=this.create_el({classes:"extras",append_to:this.$container}),this.$adjust=this.create_el({classes:"adjust hide",append_to:this.$extras,type:"button"}),this.$adjust.innerHTML="&larr;"}make_grid(){this.make_grid_background(),this.make_grid_rows(),this.make_grid_header(),this.make_side_header(),this.make_task_column()}make_grid_extras(){this.make_grid_highlights(),this.make_grid_ticks()}make_grid_background(){const t=this.dates.length*this.config.column_width,e=Math.max(this.config.header_height+this.options.padding+(this.options.bar_height+this.options.padding)*this.tasks.length-10,this.options.container_height!=="auto"?this.options.container_height:0);w("rect",{x:0,y:0,width:t,height:e,class:"grid-background",append_to:this.$svg}),u.attr(this.$svg,{height:e,width:"100%"}),this.grid_height=e,this.options.container_height==="auto"&&(this.$container.style.height=e+"px")}make_grid_rows(){const t=w("g",{append_to:this.layers.grid}),e=this.dates.length*this.config.column_width,i=this.options.bar_height+this.options.padding;this.config.header_height;for(let s=this.config.header_height;s<this.grid_height;s+=i)w("rect",{x:0,y:s,width:e,height:i,class:"grid-row",append_to:t})}make_grid_header(){this.$header=this.create_el({width:this.dates.length*this.config.column_width,classes:"grid-header",append_to:this.$container}),this.$upper_header=this.create_el({classes:"upper-header",append_to:this.$header}),this.$lower_header=this.create_el({classes:"lower-header",append_to:this.$header})}make_side_header(){if(this.$side_header=this.create_el({classes:"side-header"}),this.$upper_header.prepend(this.$side_header),this.options.view_mode_select){const t=document.createElement("select");t.classList.add("viewmode-select");const e=document.createElement("option");e.selected=!0,e.disabled=!0,e.textContent="Mode",t.appendChild(e);for(const i of this.options.view_modes){const s=document.createElement("option");s.value=i.name,s.textContent=i.name,i.name===this.config.view_mode.name&&(s.selected=!0),t.appendChild(s)}t.addEventListener("change",(function(){this.change_view_mode(t.value,!0)}).bind(this)),this.$side_header.appendChild(t)}if(this.options.today_button){let t=document.createElement("button");t.classList.add("today-button"),t.textContent="Today",t.onclick=this.scroll_current.bind(this),this.$side_header.prepend(t),this.$today_button=t}}make_task_column(){var i,s,n,a,o,d,h,_,l,p;if((i=this.$task_column)==null||i.remove(),!((s=this.options.task_column)!=null&&s.enabled)){(a=(n=this.$wrapper)==null?void 0:n.classList)==null||a.remove("has-task-column");return}(d=(o=this.$wrapper)==null?void 0:o.classList)==null||d.add("has-task-column"),this.$task_column=this.create_el({classes:"task-column",append_to:this.$wrapper}),this.$wrapper.insertBefore(this.$task_column,this.$container),this.$task_column_header=this.create_el({classes:"task-column-header",append_to:this.$task_column}),this.$task_column_header.textContent=this.options.task_column.header_text||"Task Name",this.$task_column_content=this.create_el({classes:"task-column-content",append_to:this.$task_column});const t=this.options.bar_height+this.options.padding,e=Math.max(this.tasks.length*t,this.grid_height-this.config.header_height);this.$task_column_content.style.minHeight=e+"px",this.$wrapper.style.setProperty("--gv-task-column-content-height",e+"px"),this.$container.style.setProperty("--gv-task-column-content-height",e+"px"),this.tasks.forEach(c=>{const m=this.options.bar_height+this.options.padding,f=this.create_el({classes:"task-row",append_to:this.$task_column_content});if(f.style.top=c._index*m-1+"px",f.style.height=m+"px",this.options.task_column.content&&typeof this.options.task_column.content=="function"){const b=this.options.task_column.content(c);typeof b=="string"?f.innerHTML=b:b instanceof HTMLElement&&f.appendChild(b)}else f.textContent=c.name,f.title=c.name;f.setAttribute("data-task-id",c.id)}),this.$task_column.style.width=this.options.task_column.width+"px",this.$task_column_resize_handle=this.create_el({classes:"task-column-resize-handle",append_to:this.$task_column}),this.options.isRTL?(_=(h=this.$wrapper)==null?void 0:h.classList)==null||_.add("rtl"):(p=(l=this.$wrapper)==null?void 0:l.classList)==null||p.remove("rtl")}make_grid_ticks(){if(this.options.lines==="none")return;let t=0,e=this.config.header_height,i=this.grid_height-this.config.header_height,s=w("g",{class:"lines_layer",append_to:this.layers.grid}),n=this.config.header_height;const a=this.dates.length*this.config.column_width,o=this.options.bar_height+this.options.padding;if(this.options.lines!=="vertical")for(let d=this.config.header_height;d<this.grid_height;d+=o)w("line",{x1:0,y1:n+o,x2:a,y2:n+o,class:"row-line",append_to:s}),n+=o;if(this.options.lines!=="horizontal")for(let d of this.dates){let h="tick";this.config.view_mode.thick_line&&this.config.view_mode.thick_line(d)&&(h+=" thick"),w("path",{d:`M ${t} ${e} v ${i}`,class:h,append_to:this.layers.grid}),this.view_is("month")?t+=g.get_days_in_month(d)*this.config.column_width/30:this.view_is("year")?t+=g.get_days_in_year(d)*this.config.column_width/365:t+=this.config.column_width}}highlight_holidays(){let t={};if(this.options.holidays)for(let e in this.options.holidays){let i=this.options.holidays[e];i==="weekend"&&(i=this.options.is_weekend);let s;if(typeof i=="object"){let n=i.find(a=>typeof a=="function");if(n&&(s=n),this.options.holidays.name){let a=new Date(i.date+" ");i=o=>a.getTime()===o.getTime(),t[a]=i.name}else i=a=>this.options.holidays[e].filter(o=>typeof o!="function").map(o=>{if(o.name){let d=new Date(o.date+" ");return t[d]=o.name,d.getTime()}return new Date(o+" ").getTime()}).includes(a.getTime())}for(let n=new Date(this.gantt_start);n<=this.gantt_end;n.setDate(n.getDate()+1))if(!(this.config.ignored_dates.find(a=>a.getTime()==n.getTime())||this.config.ignored_function&&this.config.ignored_function(n))&&(i(n)||s&&s(n))){const a=g.diff(n,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width,o=this.grid_height-this.config.header_height,d=g.format(n,"YYYY-MM-DD",this.options.language).replace(" ","_");if(t[n]){let h=this.create_el({classes:"holiday-label label_"+d,append_to:this.$extras});h.textContent=t[n]}w("rect",{x:Math.round(a),y:this.config.header_height,width:this.config.column_width/g.convert_scales(this.config.view_mode.step,"day"),height:o,class:"holiday-highlight "+d,style:`fill: ${e};`,append_to:this.layers.grid})}}}highlight_current(){const t=this.get_closest_date();if(!t)return;const[e,i]=t;i.classList.add("current-date-highlight");const n=g.diff(new Date,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width;this.$current_highlight=this.create_el({top:this.config.header_height,left:n,height:this.grid_height-this.config.header_height,classes:"current-highlight",append_to:this.$container}),this.$current_ball_highlight=this.create_el({top:this.config.header_height-6,left:n-2.5,width:6,height:6,classes:"current-ball-highlight",append_to:this.$header})}make_grid_highlights(){this.highlight_holidays(),this.config.ignored_positions=[];const t=(this.options.bar_height+this.options.padding)*this.tasks.length;this.layers.grid.innerHTML+=`<pattern id="diagonalHatch" patternUnits="userSpaceOnUse" width="4" height="4">
107
107
  <path d="M-1,1 l2,-2
108
108
  M0,4 l4,-4
109
109
  M3,5 l2,-2"
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@workiom/frappe-gantt",
3
- "version": "1.0.24",
3
+ "version": "1.0.26",
4
4
  "description": "A simple, modern, interactive gantt library for the web",
5
5
  "main": "src/index.js",
6
6
  "type": "module",
package/src/bar.js CHANGED
@@ -239,8 +239,9 @@ export default class Bar {
239
239
  x_coord = this.x + this.image_size + 5;
240
240
  }
241
241
 
242
- // Hide text label when task_column is enabled
243
- const labelText = this.gantt.options.task_column.enabled ? '' : this.task.name;
242
+ const labelText = this.gantt.options.show_bar_label
243
+ ? (this.task.bar_label ?? this.task.name)
244
+ : '';
244
245
 
245
246
  this.$bar_label = createSVG('text', {
246
247
  x: x_coord,
package/src/defaults.js CHANGED
@@ -154,6 +154,7 @@ const DEFAULT_OPTIONS = {
154
154
  readonly_dates: false,
155
155
  readonly: false,
156
156
  scroll_to: 'today',
157
+ show_bar_label: true,
157
158
  show_expected_progress: false,
158
159
  task_add_icon_position: null,
159
160
  today_button: true,