@workiom/frappe-gantt 1.0.10 → 1.0.11
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/frappe-gantt.es.js +6 -2
- package/dist/frappe-gantt.umd.js +1 -1
- package/package.json +1 -1
- package/src/defaults.js +1 -0
- package/src/index.js +8 -0
package/dist/frappe-gantt.es.js
CHANGED
|
@@ -896,6 +896,7 @@ const y = [
|
|
|
896
896
|
infinite_padding: !0,
|
|
897
897
|
holidays: { "var(--g-weekend-highlight-color)": "weekend" },
|
|
898
898
|
ignore: [],
|
|
899
|
+
isRTL: !1,
|
|
899
900
|
language: "en",
|
|
900
901
|
lines: "both",
|
|
901
902
|
move_dependencies: !0,
|
|
@@ -930,7 +931,7 @@ const y = [
|
|
|
930
931
|
};
|
|
931
932
|
class j {
|
|
932
933
|
constructor(t, e, i) {
|
|
933
|
-
this.setup_wrapper(t), this.setup_options(i), this.setup_tasks(e), this.change_view_mode(), this.bind_events();
|
|
934
|
+
this.setup_wrapper(t), this.setup_options(i), this.apply_rtl_direction(), this.setup_tasks(e), this.change_view_mode(), this.bind_events();
|
|
934
935
|
}
|
|
935
936
|
setup_wrapper(t) {
|
|
936
937
|
let e, i;
|
|
@@ -961,6 +962,9 @@ class j {
|
|
|
961
962
|
append_to: this.$container
|
|
962
963
|
});
|
|
963
964
|
}
|
|
965
|
+
apply_rtl_direction() {
|
|
966
|
+
this.options.isRTL && (this.$container.style.direction = "ltr");
|
|
967
|
+
}
|
|
964
968
|
setup_options(t) {
|
|
965
969
|
this.original_options = t, t != null && t.view_modes && (t.view_modes = t.view_modes.map((i) => {
|
|
966
970
|
if (typeof i == "string") {
|
|
@@ -1003,7 +1007,7 @@ class j {
|
|
|
1003
1007
|
this.config.ignored_function = this.options.ignore;
|
|
1004
1008
|
}
|
|
1005
1009
|
update_options(t) {
|
|
1006
|
-
this.setup_options({ ...this.original_options, ...t }), this.change_view_mode(void 0, !0);
|
|
1010
|
+
this.setup_options({ ...this.original_options, ...t }), this.apply_rtl_direction(), this.change_view_mode(void 0, !0);
|
|
1007
1011
|
}
|
|
1008
1012
|
setup_tasks(t) {
|
|
1009
1013
|
this.tasks = t.map((e, i) => {
|
package/dist/frappe-gantt.umd.js
CHANGED
|
@@ -21,7 +21,7 @@
|
|
|
21
21
|
<div class="subtitle"></div>
|
|
22
22
|
<div class="details"></div>
|
|
23
23
|
<div class="actions"></div>
|
|
24
|
-
`,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:o=>this.title.innerHTML=o,get_subtitle:()=>this.subtitle,set_subtitle:o=>this.subtitle.innerHTML=o,get_details:()=>this.details,set_details:o=>this.details.innerHTML=o,add_action:(o,a)=>{let h=this.gantt.create_el({classes:"action-btn",type:"button",append_to:this.actions});typeof o=="function"&&(o=o(i)),h.innerHTML=o,h.onclick=d=>a(i,this.gantt,d)}});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 S(r){const t=r.getFullYear();return t-t%10+""}function O(r,t,e){let i=c.add(r,6,"day"),s=i.getMonth()!==r.getMonth()?"D MMM":"D",n=!t||r.getMonth()!==t.getMonth()?"D MMM":"D";return`${c.format(r,n,e)} - ${c.format(i,s,e)}`}const w=[{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()?c.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()?c.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()?c.format(r,"D MMM",e):c.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()?c.format(r,"D",e):"",upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?c.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:O,upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?c.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()?c.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||S(r)!==S(t)?S(r):"",lower_text:"YYYY",snap_at:"30d"}],I={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:"fixed",upper_header_height:45,lower_header_height:30,snap_at:null,infinite_padding:!0,holidays:{"var(--g-weekend-highlight-color)":"weekend"},ignore:[],language:"en",lines:"both",move_dependencies:!0,padding:18,popup:r=>{r.set_title(r.task.name),r.task.description?r.set_subtitle(r.task.description):r.set_subtitle("");const t=c.format(r.task._start,"MMM D",r.chart.options.language),e=c.format(c.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:w,is_weekend:r=>r.getDay()===0||r.getDay()===6};class X{constructor(t,e,i){this.setup_wrapper(t),this.setup_options(i),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=f("svg",{append_to:i,class:"gantt"}),this.$container=this.create_el({classes:"gantt-container",append_to:this.$svg.parentElement}),this.$container.appendChild(this.$svg),this.$popup_wrapper=this.create_el({classes:"popup-wrapper",append_to:this.$container})}setup_options(t){this.original_options=t,t!=null&&t.view_modes&&(t.view_modes=t.view_modes.map(i=>{if(typeof i=="string"){const s=w.find(n=>n.name===i);return s||console.error(`The view mode "${i}" is not predefined in Frappe Gantt. Please define the view mode object instead.`),s}return i}),t.view_mode=t.view_modes[0]),this.options={...I,...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 i in e){let s=this.options[e[i]];s!=="auto"&&this.$container.style.setProperty("--gv-"+i,s+"px")}if(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 i of this.options.ignore){if(typeof i=="function"){this.config.ignored_function=i;continue}typeof i=="string"&&(i==="weekend"?this.config.ignored_function=s=>s.getDay()==6||s.getDay()==0:this.config.ignored_dates.push(new Date(i+" ")))}}else this.config.ignored_function=this.options.ignore}update_options(t){this.setup_options({...this.original_options,...t}),this.change_view_mode(void 0,!0)}setup_tasks(t){this.tasks=t.map((e,i)=>{if(!e.start)return console.error(`task "${e.id}" doesn't have a start date`),!1;if(e._start=c.parse(e.start),e.end===void 0&&e.duration!==void 0&&(e.end=e._start,e.duration.split(" ").forEach(a=>{let{duration:h,scale:d}=c.parse_duration(a);e.end=c.add(e.end,h,d)})),!e.end)return console.error(`task "${e.id}" doesn't have an end date`),!1;if(e._end=c.parse(e.end),c.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(c.diff(e._end,e._start,"year")>10)return console.error(`the duration of task "${e.id}" is too long (above ten years)`),!1;if(e._index=i,c.get_date_values(e._end).slice(3).every(o=>o===0)&&(e._end=c.add(e._end,24,"hour")),typeof e.dependencies=="string"||!e.dependencies){let o=[];e.dependencies&&(o=e.dependencies.split(",").map(a=>a.trim().replaceAll(" ","_")).filter(a=>a)),e.dependencies=o}return e.id?typeof e.id=="string"?e.id=e.id.replaceAll(" ","_"):e.id=`${e.id}`:e.id=j(e),e}).filter(e=>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]=this.dependency_map[e]||[],this.dependency_map[e].push(t.id)}refresh(t){this.setup_tasks(t),this.change_view_mode()}update_task(t,e){let i=this.tasks.find(n=>n.id===t),s=this.bars[i._index];Object.assign(i,e),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}=c.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=c.start_of(e,this.config.unit),i=c.start_of(i,this.config.unit),!t)if(this.options.infinite_padding)this.gantt_start=c.add(e,-this.config.extend_by_units*3,this.config.unit),this.gantt_end=c.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(c.parse_duration);this.gantt_start=c.add(e,-s.duration,s.scale),this.gantt_end=c.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=c.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()}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]=f("g",{class:e,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="←"}make_grid(){this.make_grid_background(),this.make_grid_rows(),this.make_grid_header(),this.make_side_header()}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);f("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=f("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)f("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_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=f("g",{class:"lines_layer",append_to:this.layers.grid}),n=this.config.header_height;const o=this.dates.length*this.config.column_width,a=this.options.bar_height+this.options.padding;if(this.options.lines!=="vertical")for(let h=this.config.header_height;h<this.grid_height;h+=a)f("line",{x1:0,y1:n+a,x2:o,y2:n+a,class:"row-line",append_to:s}),n+=a;if(this.options.lines!=="horizontal")for(let h of this.dates){let d="tick";this.config.view_mode.thick_line&&this.config.view_mode.thick_line(h)&&(d+=" thick"),f("path",{d:`M ${t} ${e} v ${i}`,class:d,append_to:this.layers.grid}),this.view_is("month")?t+=c.get_days_in_month(h)*this.config.column_width/30:this.view_is("year")?t+=c.get_days_in_year(h)*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(o=>typeof o=="function");if(n&&(s=n),this.options.holidays.name){let o=new Date(i.date+" ");i=a=>o.getTime()===a.getTime(),t[o]=i.name}else i=o=>this.options.holidays[e].filter(a=>typeof a!="function").map(a=>{if(a.name){let h=new Date(a.date+" ");return t[h]=a.name,h.getTime()}return new Date(a+" ").getTime()}).includes(o.getTime())}for(let n=new Date(this.gantt_start);n<=this.gantt_end;n.setDate(n.getDate()+1))if(!(this.config.ignored_dates.find(o=>o.getTime()==n.getTime())||this.config.ignored_function&&this.config.ignored_function(n))&&(i(n)||s&&s(n))){const o=c.diff(n,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width,a=this.grid_height-this.config.header_height,h=c.format(n,"YYYY-MM-DD",this.options.language).replace(" ","_");if(t[n]){let d=this.create_el({classes:"holiday-label label_"+h,append_to:this.$extras});d.textContent=t[n]}f("rect",{x:Math.round(o),y:this.config.header_height,width:this.config.column_width/c.convert_scales(this.config.view_mode.step,"day"),height:a,class:"holiday-highlight "+h,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=c.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">
|
|
24
|
+
`,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:o=>this.title.innerHTML=o,get_subtitle:()=>this.subtitle,set_subtitle:o=>this.subtitle.innerHTML=o,get_details:()=>this.details,set_details:o=>this.details.innerHTML=o,add_action:(o,a)=>{let h=this.gantt.create_el({classes:"action-btn",type:"button",append_to:this.actions});typeof o=="function"&&(o=o(i)),h.innerHTML=o,h.onclick=d=>a(i,this.gantt,d)}});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 S(r){const t=r.getFullYear();return t-t%10+""}function O(r,t,e){let i=c.add(r,6,"day"),s=i.getMonth()!==r.getMonth()?"D MMM":"D",n=!t||r.getMonth()!==t.getMonth()?"D MMM":"D";return`${c.format(r,n,e)} - ${c.format(i,s,e)}`}const w=[{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()?c.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()?c.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()?c.format(r,"D MMM",e):c.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()?c.format(r,"D",e):"",upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?c.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:O,upper_text:(r,t,e)=>!t||r.getMonth()!==t.getMonth()?c.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()?c.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||S(r)!==S(t)?S(r):"",lower_text:"YYYY",snap_at:"30d"}],I={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:"fixed",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",move_dependencies:!0,padding:18,popup:r=>{r.set_title(r.task.name),r.task.description?r.set_subtitle(r.task.description):r.set_subtitle("");const t=c.format(r.task._start,"MMM D",r.chart.options.language),e=c.format(c.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:w,is_weekend:r=>r.getDay()===0||r.getDay()===6};class X{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=f("svg",{append_to:i,class:"gantt"}),this.$container=this.create_el({classes:"gantt-container",append_to:this.$svg.parentElement}),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){this.original_options=t,t!=null&&t.view_modes&&(t.view_modes=t.view_modes.map(i=>{if(typeof i=="string"){const s=w.find(n=>n.name===i);return s||console.error(`The view mode "${i}" is not predefined in Frappe Gantt. Please define the view mode object instead.`),s}return i}),t.view_mode=t.view_modes[0]),this.options={...I,...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 i in e){let s=this.options[e[i]];s!=="auto"&&this.$container.style.setProperty("--gv-"+i,s+"px")}if(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 i of this.options.ignore){if(typeof i=="function"){this.config.ignored_function=i;continue}typeof i=="string"&&(i==="weekend"?this.config.ignored_function=s=>s.getDay()==6||s.getDay()==0:this.config.ignored_dates.push(new Date(i+" ")))}}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)=>{if(!e.start)return console.error(`task "${e.id}" doesn't have a start date`),!1;if(e._start=c.parse(e.start),e.end===void 0&&e.duration!==void 0&&(e.end=e._start,e.duration.split(" ").forEach(a=>{let{duration:h,scale:d}=c.parse_duration(a);e.end=c.add(e.end,h,d)})),!e.end)return console.error(`task "${e.id}" doesn't have an end date`),!1;if(e._end=c.parse(e.end),c.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(c.diff(e._end,e._start,"year")>10)return console.error(`the duration of task "${e.id}" is too long (above ten years)`),!1;if(e._index=i,c.get_date_values(e._end).slice(3).every(o=>o===0)&&(e._end=c.add(e._end,24,"hour")),typeof e.dependencies=="string"||!e.dependencies){let o=[];e.dependencies&&(o=e.dependencies.split(",").map(a=>a.trim().replaceAll(" ","_")).filter(a=>a)),e.dependencies=o}return e.id?typeof e.id=="string"?e.id=e.id.replaceAll(" ","_"):e.id=`${e.id}`:e.id=j(e),e}).filter(e=>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]=this.dependency_map[e]||[],this.dependency_map[e].push(t.id)}refresh(t){this.setup_tasks(t),this.change_view_mode()}update_task(t,e){let i=this.tasks.find(n=>n.id===t),s=this.bars[i._index];Object.assign(i,e),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}=c.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=c.start_of(e,this.config.unit),i=c.start_of(i,this.config.unit),!t)if(this.options.infinite_padding)this.gantt_start=c.add(e,-this.config.extend_by_units*3,this.config.unit),this.gantt_end=c.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(c.parse_duration);this.gantt_start=c.add(e,-s.duration,s.scale),this.gantt_end=c.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=c.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()}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]=f("g",{class:e,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="←"}make_grid(){this.make_grid_background(),this.make_grid_rows(),this.make_grid_header(),this.make_side_header()}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);f("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=f("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)f("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_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=f("g",{class:"lines_layer",append_to:this.layers.grid}),n=this.config.header_height;const o=this.dates.length*this.config.column_width,a=this.options.bar_height+this.options.padding;if(this.options.lines!=="vertical")for(let h=this.config.header_height;h<this.grid_height;h+=a)f("line",{x1:0,y1:n+a,x2:o,y2:n+a,class:"row-line",append_to:s}),n+=a;if(this.options.lines!=="horizontal")for(let h of this.dates){let d="tick";this.config.view_mode.thick_line&&this.config.view_mode.thick_line(h)&&(d+=" thick"),f("path",{d:`M ${t} ${e} v ${i}`,class:d,append_to:this.layers.grid}),this.view_is("month")?t+=c.get_days_in_month(h)*this.config.column_width/30:this.view_is("year")?t+=c.get_days_in_year(h)*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(o=>typeof o=="function");if(n&&(s=n),this.options.holidays.name){let o=new Date(i.date+" ");i=a=>o.getTime()===a.getTime(),t[o]=i.name}else i=o=>this.options.holidays[e].filter(a=>typeof a!="function").map(a=>{if(a.name){let h=new Date(a.date+" ");return t[h]=a.name,h.getTime()}return new Date(a+" ").getTime()}).includes(o.getTime())}for(let n=new Date(this.gantt_start);n<=this.gantt_end;n.setDate(n.getDate()+1))if(!(this.config.ignored_dates.find(o=>o.getTime()==n.getTime())||this.config.ignored_function&&this.config.ignored_function(n))&&(i(n)||s&&s(n))){const o=c.diff(n,this.gantt_start,this.config.unit)/this.config.step*this.config.column_width,a=this.grid_height-this.config.header_height,h=c.format(n,"YYYY-MM-DD",this.options.language).replace(" ","_");if(t[n]){let d=this.create_el({classes:"holiday-label label_"+h,append_to:this.$extras});d.textContent=t[n]}f("rect",{x:Math.round(o),y:this.config.header_height,width:this.config.column_width/c.convert_scales(this.config.view_mode.step,"day"),height:a,class:"holiday-highlight "+h,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=c.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">
|
|
25
25
|
<path d="M-1,1 l2,-2
|
|
26
26
|
M0,4 l4,-4
|
|
27
27
|
M3,5 l2,-2"
|
package/package.json
CHANGED
package/src/defaults.js
CHANGED
package/src/index.js
CHANGED
|
@@ -13,6 +13,7 @@ export default class Gantt {
|
|
|
13
13
|
constructor(wrapper, tasks, options) {
|
|
14
14
|
this.setup_wrapper(wrapper);
|
|
15
15
|
this.setup_options(options);
|
|
16
|
+
this.apply_rtl_direction();
|
|
16
17
|
this.setup_tasks(tasks);
|
|
17
18
|
this.change_view_mode();
|
|
18
19
|
this.bind_events();
|
|
@@ -70,6 +71,12 @@ export default class Gantt {
|
|
|
70
71
|
});
|
|
71
72
|
}
|
|
72
73
|
|
|
74
|
+
apply_rtl_direction() {
|
|
75
|
+
if (this.options.isRTL) {
|
|
76
|
+
this.$container.style.direction = 'ltr';
|
|
77
|
+
}
|
|
78
|
+
}
|
|
79
|
+
|
|
73
80
|
setup_options(options) {
|
|
74
81
|
this.original_options = options;
|
|
75
82
|
if (options?.view_modes) {
|
|
@@ -134,6 +141,7 @@ export default class Gantt {
|
|
|
134
141
|
|
|
135
142
|
update_options(options) {
|
|
136
143
|
this.setup_options({ ...this.original_options, ...options });
|
|
144
|
+
this.apply_rtl_direction();
|
|
137
145
|
this.change_view_mode(undefined, true);
|
|
138
146
|
}
|
|
139
147
|
|