From a65bcff5c114bb6a93ecc71e7de643acb24a0f7d Mon Sep 17 00:00:00 2001 From: Safwan Samsudeen Date: Tue, 30 Apr 2024 06:24:33 +0530 Subject: [PATCH] feat: first round of tooling upgrades --- .gitignore | 1 + .yarnrc.yml | 1 + dist/frappe-gantt.css | 295 - dist/frappe-gantt.js | 3735 +++++-------- dist/frappe-gantt.js.map | 1 - dist/frappe-gantt.min.css | 1 - dist/frappe-gantt.min.js | 2 - dist/frappe-gantt.min.js.map | 1 - dist/frappe-gantt.umd.cjs | 23 + dist/style.css | 1 + index.html | 13 +- package-lock.json | 6265 +++++++++++++++++++++ package.json | 25 +- postcss.config.cjs | 4 + rollup.config.js | 37 - src/dark.css | 99 + src/dark.scss | 97 - src/{gantt.scss => gantt.css} | 259 +- src/index.js | 42 +- vite.config.js | 27 + yarn.lock | 9577 ++++++++++++++++++++------------- 21 files changed, 13565 insertions(+), 6941 deletions(-) create mode 100644 .yarnrc.yml delete mode 100644 dist/frappe-gantt.css delete mode 100644 dist/frappe-gantt.js.map delete mode 100644 dist/frappe-gantt.min.css delete mode 100644 dist/frappe-gantt.min.js delete mode 100644 dist/frappe-gantt.min.js.map create mode 100644 dist/frappe-gantt.umd.cjs create mode 100644 dist/style.css create mode 100644 package-lock.json create mode 100644 postcss.config.cjs delete mode 100644 rollup.config.js create mode 100644 src/dark.css delete mode 100644 src/dark.scss rename src/{gantt.scss => gantt.css} (56%) create mode 100644 vite.config.js diff --git a/.gitignore b/.gitignore index e16e811..8ee493f 100755 --- a/.gitignore +++ b/.gitignore @@ -25,6 +25,7 @@ build/Release # Dependency directory # https://www.npmjs.org/doc/misc/npm-faq.html#should-i-check-my-node_modules-folder-into-git node_modules +.yarn .DS_Store diff --git a/.yarnrc.yml b/.yarnrc.yml new file mode 100644 index 0000000..3186f3f --- /dev/null +++ b/.yarnrc.yml @@ -0,0 +1 @@ +nodeLinker: node-modules diff --git a/dist/frappe-gantt.css b/dist/frappe-gantt.css deleted file mode 100644 index be2bc91..0000000 --- a/dist/frappe-gantt.css +++ /dev/null @@ -1,295 +0,0 @@ -.dark > .gantt-container .gantt .grid-header { - fill: #252525; - stroke: #616161; -} -.dark > .gantt-container .gantt .grid-row { - fill: #252525; -} -.dark > .gantt-container .gantt .grid-row:nth-child(even) { - fill: #3e3e3e; -} -.dark > .gantt-container .gantt .row-line { - stroke: #3e3e3e; -} -.dark > .gantt-container .gantt .tick { - stroke: #616161; -} -.dark > .gantt-container .gantt .today-highlight { - opacity: 0.2; -} -.dark > .gantt-container .gantt .arrow { - stroke: #eee; -} -.dark > .gantt-container .gantt .bar { - fill: #616161; - stroke: none; -} -.dark > .gantt-container .gantt .bar-progress { - fill: #8a8aff; -} -.dark > .gantt-container .gantt .bar-invalid { - fill: transparent; - stroke: #c6ccd2; -} -.dark > .gantt-container .gantt .bar-invalid ~ .bar-label { - fill: #ececec; -} -.dark > .gantt-container .gantt .bar-label.big { - fill: #ececec; -} -.dark > .gantt-container .gantt .bar-wrapper:hover .bar { - fill: #6e6e6e; -} -.dark > .gantt-container .gantt .bar-wrapper:hover .bar-progress { - fill: #a4a4ff; -} -.dark > .gantt-container .gantt .bar-wrapper.active .bar { - fill: #6e6e6e; -} -.dark > .gantt-container .gantt .bar-wrapper.active .bar-progress { - fill: #a4a4ff; -} -.dark > .gantt-container .gantt .upper-text { - fill: #a2a2a2; -} -.dark > .gantt-container .gantt .lower-text { - fill: #f7f7f7; -} - -.dark > .gantt-container .popup-wrapper { - background-color: #333; -} -.dark > .gantt-container .popup-wrapper .title { - border-color: #a4a4ff; -} -.dark > .gantt-container .popup-wrapper .pointer { - border-top-color: #333; -} - -.gantt-container { - line-height: 14.5px; -} -.gantt-container .grid-header { - background-color: #ffffff; - position: sticky; - top: 0; - left: 0; - z-index: 10; -} -.gantt-container .lower-text, -.gantt-container .upper-text { - text-anchor: middle; - color: #111; -} -.gantt-container .upper-header { - height: 40px; -} -.gantt-container .lower-header { - height: 30px; -} -.gantt-container .lower-text { - font-size: 14px; - position: absolute; - width: fit-content; -} -.gantt-container .upper-text { - position: absolute; - width: fit-content; - font-weight: 500; - font-size: 16px; -} -.gantt-container .current-upper { - position: fixed; -} -.gantt-container .side-header { - position: fixed; - padding: 0 10px; - margin-right: 10px; - background: white; - line-height: 20px; - font-weight: 400; -} -.gantt-container .today-button, -.gantt-container .viewmode-select { - background: #f4f5f6; - text-align: -webkit-center; - text-align: center; - height: 25px; - border-radius: 8px; - border: none; - color: #111; - padding: 4px 10px; - border-radius: 8px; - height: 25px; -} -.gantt-container .viewmode-select { - outline: none !important; - padding: 4px 8px; - margin-right: 4px; - -webkit-appearance: none; - -moz-appearance: none; - text-indent: 1px; - text-overflow: ""; -} -.gantt-container .date-highlight { - background-color: #ebeef0; - border-radius: 12px; - position: absolute; - display: none; -} -.gantt-container .current-highlight { - position: absolute; - background: #2c94ec; - width: 1px; -} -.gantt-container .current-date-highlight { - background: #2c94ec; - color: #fff; - padding: 4px 8px; - border-radius: 200px; -} - -.gantt { - user-select: none; - -webkit-user-select: none; - position: absolute; -} -.gantt .grid-background { - fill: none; -} -.gantt .grid-row { - fill: #ffffff; -} -.gantt .row-line { - stroke: #ebeff2; -} -.gantt .tick { - stroke: #ebeef0; - stroke-width: 0.4; -} -.gantt .tick.thick { - stroke: #e0e0e0; - stroke-width: 0.7; -} -.gantt .holiday-highlight { - fill: #f9fafa; -} -.gantt .arrow { - fill: none; - stroke: #9fa9b1; - stroke-width: 1; -} -.gantt .bar-wrapper .bar { - fill: #fff; - stroke: #fff; - stroke-width: 0; - transition: stroke-width 0.3s ease; -} -.gantt .bar-progress { - fill: #ebeef0; -} -.gantt .bar-expected-progress { - fill: #c4c4e9; -} -.gantt .bar-invalid { - fill: transparent; - stroke: #fff; - stroke-width: 1; - stroke-dasharray: 5; -} -.gantt .bar-invalid ~ .bar-label { - fill: #fff; -} -.gantt .bar-label { - fill: #111; - dominant-baseline: central; - font-family: Helvetica; - font-size: 13px; - font-weight: 400; -} -.gantt .bar-label.big { - fill: #111; - text-anchor: start; -} -.gantt .bar-wrapper.important .bar { - fill: #94c4f4; -} -.gantt .bar-wrapper.important .bar-progress { - fill: #2c94ec; -} -.gantt .bar-wrapper.important .bar-label { - fill: #fff; -} -.gantt .bar-wrapper.important .handle { - fill: #94c4f4; -} -.gantt .bar-wrapper.important .handle.progress { - fill: #fff; -} -.gantt .handle { - fill: #dcdce4; - cursor: ew-resize; - opacity: 0; - visibility: hidden; - transition: opacity 0.3s ease; -} -.gantt .handle.progress { - fill: #666; -} -.gantt .bar-wrapper { - cursor: pointer; - outline: none; -} -.gantt .bar-wrapper.active .handle { - visibility: visible; - opacity: 1; -} -.gantt .bar-wrapper .bar { - -webkit-filter: drop-shadow(3px 3px 2px rgba(0, 0, 0, 0.7)); - filter: drop-shadow(0 0 2px rgba(17, 43, 66, 0.16)); - border-radius: 3px; -} -.gantt .bar-wrapper:hover .bar { - transition: transform 0.3s ease; -} -.gantt .bar-wrapper:hover .date-highlight { - display: block; -} -.gantt .hide { - display: none; -} - -.gantt-container { - position: relative; - overflow: auto; - font-size: 12px; - height: 500px; -} -.gantt-container .popup-wrapper { - position: absolute; - top: 0; - left: 0; - background: #171b1f; - padding: 10px; - border-radius: 5px; - width: max-content; -} -.gantt-container .popup-wrapper.hidden { - opacity: 0 !important; -} -.gantt-container .popup-wrapper .title { - margin-bottom: 5px; - text-align: -webkit-center; - text-align: center; - color: #fff; -} -.gantt-container .popup-wrapper .subtitle { - color: #98a1a9; -} -.gantt-container .popup-wrapper .pointer { - position: absolute; - height: 5px; - margin: 0 0 0 -5px; - border: 5px solid transparent; - border-bottom-color: rgba(0, 0, 0, 0.8); -} \ No newline at end of file diff --git a/dist/frappe-gantt.js b/dist/frappe-gantt.js index d1ee463..f6fab06 100644 --- a/dist/frappe-gantt.js +++ b/dist/frappe-gantt.js @@ -1,2506 +1,1263 @@ -var Gantt = (function () { - 'use strict'; - - const YEAR = 'year'; - const MONTH = 'month'; - const DAY = 'day'; - const HOUR = 'hour'; - const MINUTE = 'minute'; - const SECOND = 'second'; - const MILLISECOND = 'millisecond'; - - const SHORTENED = { - January: 'Jan', - February: 'Feb', - March: 'Mar', - April: 'Apr', - May: 'May', - June: 'Jun', - July: 'Jul', - August: 'Aug', - September: 'Sep', - October: 'Oct', - November: 'Nov', - December: 'Dec', - }; - - var date_utils = { - parse_duration(duration) { - const regex = /([0-9])+(y|m|d|h|min|s|ms)/gm; - const matches = regex.exec(duration); - - if (matches !== null) { - if (matches[2] === 'y') { - return { duration: parseInt(matches[1]), scale: `year` }; - } else if (matches[2] === 'm') { - return { duration: parseInt(matches[1]), scale: `month` }; - } else if (matches[2] === 'd') { - return { duration: parseInt(matches[1]), scale: `day` }; - } else if (matches[2] === 'h') { - return { duration: parseInt(matches[1]), scale: `hour` }; - } else if (matches[2] === 'min') { - return { duration: parseInt(matches[1]), scale: `minute` }; - } else if (matches[2] === 's') { - return { duration: parseInt(matches[1]), scale: `second` }; - } else if (matches[2] === 'ms') { - return { duration: parseInt(matches[1]), scale: `millisecond` }; - } - } - }, - parse(date, date_separator = '-', time_separator = /[.:]/) { - if (date instanceof Date) { - return date; - } - if (typeof date === 'string') { - let date_parts, time_parts; - const parts = date.split(' '); - date_parts = parts[0] - .split(date_separator) - .map((val) => parseInt(val, 10)); - time_parts = parts[1] && parts[1].split(time_separator); - - // month is 0 indexed - date_parts[1] = date_parts[1] ? date_parts[1] - 1 : 0; - - let vals = date_parts; - - if (time_parts && time_parts.length) { - if (time_parts.length === 4) { - time_parts[3] = '0.' + time_parts[3]; - time_parts[3] = parseFloat(time_parts[3]) * 1000; - } - vals = vals.concat(time_parts); - } - return new Date(...vals); - } - }, - - to_string(date, with_time = false) { - if (!(date instanceof Date)) { - throw new TypeError('Invalid argument type'); - } - const vals = this.get_date_values(date).map((val, i) => { - if (i === 1) { - // add 1 for month - val = val + 1; - } - - if (i === 6) { - return padStart(val + '', 3, '0'); - } - - return padStart(val + '', 2, '0'); - }); - const date_string = `${vals[0]}-${vals[1]}-${vals[2]}`; - const time_string = `${vals[3]}:${vals[4]}:${vals[5]}.${vals[6]}`; - - return date_string + (with_time ? ' ' + time_string : ''); - }, - - format(date, format_string = 'YYYY-MM-DD HH:mm:ss.SSS', lang = 'en') { - const dateTimeFormat = new Intl.DateTimeFormat(lang, { - month: 'long', - }); - const month_name = dateTimeFormat.format(date); - const month_name_capitalized = - month_name.charAt(0).toUpperCase() + month_name.slice(1); - - const values = this.get_date_values(date).map((d) => padStart(d, 2, 0)); - const format_map = { - YYYY: values[0], - MM: padStart(+values[1] + 1, 2, 0), - DD: values[2], - HH: values[3], - mm: values[4], - ss: values[5], - SSS: values[6], - D: values[2], - MMMM: month_name_capitalized, - MMM: SHORTENED[month_name_capitalized], - }; - - let str = format_string; - const formatted_values = []; - - Object.keys(format_map) - .sort((a, b) => b.length - a.length) // big string first - .forEach((key) => { - if (str.includes(key)) { - str = str.replaceAll(key, `$${formatted_values.length}`); - formatted_values.push(format_map[key]); - } - }); - - formatted_values.forEach((value, i) => { - str = str.replaceAll(`$${i}`, value); - }); - - return str; - }, - - diff(date_a, date_b, scale = DAY) { - let milliseconds, seconds, hours, minutes, days, months, years; - - milliseconds = date_a - date_b; - seconds = milliseconds / 1000; - minutes = seconds / 60; - hours = minutes / 60; - days = hours / 24; - months = days / 30; - years = months / 12; - - if (!scale.endsWith('s')) { - scale += 's'; - } - - return Math.floor( - { - milliseconds, - seconds, - minutes, - hours, - days, - months, - years, - }[scale], - ); - }, - - today() { - const vals = this.get_date_values(new Date()).slice(0, 3); - return new Date(...vals); - }, - - now() { - return new Date(); - }, - - add(date, qty, scale) { - qty = parseInt(qty, 10); - const vals = [ - date.getFullYear() + (scale === YEAR ? qty : 0), - date.getMonth() + (scale === MONTH ? qty : 0), - date.getDate() + (scale === DAY ? qty : 0), - date.getHours() + (scale === HOUR ? qty : 0), - date.getMinutes() + (scale === MINUTE ? qty : 0), - date.getSeconds() + (scale === SECOND ? qty : 0), - date.getMilliseconds() + (scale === MILLISECOND ? qty : 0), - ]; - return new Date(...vals); - }, - - start_of(date, scale) { - const scores = { - [YEAR]: 6, - [MONTH]: 5, - [DAY]: 4, - [HOUR]: 3, - [MINUTE]: 2, - [SECOND]: 1, - [MILLISECOND]: 0, - }; - - function should_reset(_scale) { - const max_score = scores[scale]; - return scores[_scale] <= max_score; - } - - const vals = [ - date.getFullYear(), - should_reset(YEAR) ? 0 : date.getMonth(), - should_reset(MONTH) ? 1 : date.getDate(), - should_reset(DAY) ? 0 : date.getHours(), - should_reset(HOUR) ? 0 : date.getMinutes(), - should_reset(MINUTE) ? 0 : date.getSeconds(), - should_reset(SECOND) ? 0 : date.getMilliseconds(), - ]; - - return new Date(...vals); - }, - - clone(date) { - return new Date(...this.get_date_values(date)); - }, - - get_date_values(date) { - return [ - date.getFullYear(), - date.getMonth(), - date.getDate(), - date.getHours(), - date.getMinutes(), - date.getSeconds(), - date.getMilliseconds(), - ]; - }, - - get_days_in_month(date) { - const no_of_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31]; - - const month = date.getMonth(); - - if (month !== 1) { - return no_of_days[month]; - } - - // Feb - const year = date.getFullYear(); - if ((year % 4 === 0 && year % 100 != 0) || year % 400 === 0) { - return 29; - } - return 28; - }, - }; - - // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart - function padStart(str, targetLength, padString) { - str = str + ''; - targetLength = targetLength >> 0; - padString = String(typeof padString !== 'undefined' ? padString : ' '); - if (str.length > targetLength) { - return String(str); - } else { - targetLength = targetLength - str.length; - if (targetLength > padString.length) { - padString += padString.repeat(targetLength / padString.length); - } - return padString.slice(0, targetLength) + String(str); - } +const D = "year", Y = "month", $ = "day", E = "hour", A = "minute", H = "second", L = "millisecond", W = { + January: "Jan", + February: "Feb", + March: "Mar", + April: "Apr", + May: "May", + June: "Jun", + July: "Jul", + August: "Aug", + September: "Sep", + October: "Oct", + November: "Nov", + December: "Dec" +}, h = { + parse_duration(o) { + const e = /([0-9])+(y|m|d|h|min|s|ms)/gm.exec(o); + if (e !== null) { + if (e[2] === "y") + return { duration: parseInt(e[1]), scale: "year" }; + if (e[2] === "m") + return { duration: parseInt(e[1]), scale: "month" }; + if (e[2] === "d") + return { duration: parseInt(e[1]), scale: "day" }; + if (e[2] === "h") + return { duration: parseInt(e[1]), scale: "hour" }; + if (e[2] === "min") + return { duration: parseInt(e[1]), scale: "minute" }; + if (e[2] === "s") + return { duration: parseInt(e[1]), scale: "second" }; + if (e[2] === "ms") + return { duration: parseInt(e[1]), scale: "millisecond" }; } - - function $(expr, con) { - return typeof expr === 'string' - ? (con || document).querySelector(expr) - : expr || null; + }, + parse(o, t = "-", e = /[.:]/) { + if (o instanceof Date) + return o; + if (typeof o == "string") { + let s, r; + const i = o.split(" "); + s = i[0].split(t).map((a) => parseInt(a, 10)), r = i[1] && i[1].split(e), s[1] = s[1] ? s[1] - 1 : 0; + let n = s; + return r && r.length && (r.length === 4 && (r[3] = "0." + r[3], r[3] = parseFloat(r[3]) * 1e3), n = n.concat(r)), new Date(...n); } - - function createSVG(tag, attrs) { - const elem = document.createElementNS('http://www.w3.org/2000/svg', tag); - for (let attr in attrs) { - if (attr === 'append_to') { - const parent = attrs.append_to; - parent.appendChild(elem); - } else if (attr === 'innerHTML') { - elem.innerHTML = attrs.innerHTML; - } else if (attr === 'clipPath') { - elem.setAttribute('clip-path', 'url(#' + attrs[attr] + ')'); - } else { - elem.setAttribute(attr, attrs[attr]); - } - } - return elem; + }, + to_string(o, t = !1) { + if (!(o instanceof Date)) + throw new TypeError("Invalid argument type"); + const e = this.get_date_values(o).map((i, n) => (n === 1 && (i = i + 1), n === 6 ? M(i + "", 3, "0") : M(i + "", 2, "0"))), s = `${e[0]}-${e[1]}-${e[2]}`, r = `${e[3]}:${e[4]}:${e[5]}.${e[6]}`; + return s + (t ? " " + r : ""); + }, + format(o, t = "YYYY-MM-DD HH:mm:ss.SSS", e = "en") { + const r = new Intl.DateTimeFormat(e, { + month: "long" + }).format(o), i = r.charAt(0).toUpperCase() + r.slice(1), n = this.get_date_values(o).map((g) => M(g, 2, 0)), a = { + YYYY: n[0], + MM: M(+n[1] + 1, 2, 0), + DD: n[2], + HH: n[3], + mm: n[4], + ss: n[5], + SSS: n[6], + D: n[2], + MMMM: i, + MMM: W[i] + }; + let p = t; + const _ = []; + return Object.keys(a).sort((g, c) => c.length - g.length).forEach((g) => { + p.includes(g) && (p = p.replaceAll(g, `$${_.length}`), _.push(a[g])); + }), _.forEach((g, c) => { + p = p.replaceAll(`$${c}`, g); + }), p; + }, + diff(o, t, e = $) { + let s, r, i, n, a, p, _; + return s = o - t, r = s / 1e3, n = r / 60, i = n / 60, a = i / 24, p = a / 30, _ = p / 12, e.endsWith("s") || (e += "s"), Math.floor( + { + milliseconds: s, + seconds: r, + minutes: n, + hours: i, + days: a, + months: p, + years: _ + }[e] + ); + }, + today() { + const o = this.get_date_values(/* @__PURE__ */ new Date()).slice(0, 3); + return new Date(...o); + }, + now() { + return /* @__PURE__ */ new Date(); + }, + add(o, t, e) { + t = parseInt(t, 10); + const s = [ + o.getFullYear() + (e === D ? t : 0), + o.getMonth() + (e === Y ? t : 0), + o.getDate() + (e === $ ? t : 0), + o.getHours() + (e === E ? t : 0), + o.getMinutes() + (e === A ? t : 0), + o.getSeconds() + (e === H ? t : 0), + o.getMilliseconds() + (e === L ? t : 0) + ]; + return new Date(...s); + }, + start_of(o, t) { + const e = { + [D]: 6, + [Y]: 5, + [$]: 4, + [E]: 3, + [A]: 2, + [H]: 1, + [L]: 0 + }; + function s(i) { + const n = e[t]; + return e[i] <= n; } - - function animateSVG(svgElement, attr, from, to) { - const animatedSvgElement = getAnimationElement(svgElement, attr, from, to); - - if (animatedSvgElement === svgElement) { - // triggered 2nd time programmatically - // trigger artificial click event - const event = document.createEvent('HTMLEvents'); - event.initEvent('click', true, true); - event.eventName = 'click'; - animatedSvgElement.dispatchEvent(event); - } + const r = [ + o.getFullYear(), + s(D) ? 0 : o.getMonth(), + s(Y) ? 1 : o.getDate(), + s($) ? 0 : o.getHours(), + s(E) ? 0 : o.getMinutes(), + s(A) ? 0 : o.getSeconds(), + s(H) ? 0 : o.getMilliseconds() + ]; + return new Date(...r); + }, + clone(o) { + return new Date(...this.get_date_values(o)); + }, + get_date_values(o) { + return [ + o.getFullYear(), + o.getMonth(), + o.getDate(), + o.getHours(), + o.getMinutes(), + o.getSeconds(), + o.getMilliseconds() + ]; + }, + get_days_in_month(o) { + const t = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31], e = o.getMonth(); + if (e !== 1) + return t[e]; + const s = o.getFullYear(); + return s % 4 === 0 && s % 100 != 0 || s % 400 === 0 ? 29 : 28; + } +}; +function M(o, t, e) { + return o = o + "", t = t >> 0, e = String(typeof e < "u" ? e : " "), o.length > t ? String(o) : (t = t - o.length, t > e.length && (e += e.repeat(t / e.length)), e.slice(0, t) + String(o)); +} +function l(o, t) { + return typeof o == "string" ? (t || document).querySelector(o) : o || null; +} +function u(o, t) { + const e = document.createElementNS("http://www.w3.org/2000/svg", o); + for (let s in t) + s === "append_to" ? t.append_to.appendChild(e) : s === "innerHTML" ? e.innerHTML = t.innerHTML : s === "clipPath" ? e.setAttribute("clip-path", "url(#" + t[s] + ")") : e.setAttribute(s, t[s]); + return e; +} +function S(o, t, e, s) { + const r = X(o, t, e, s); + if (r === o) { + const i = document.createEvent("HTMLEvents"); + i.initEvent("click", !0, !0), i.eventName = "click", r.dispatchEvent(i); + } +} +function X(o, t, e, s, r = "0.4s", i = "0.1s") { + const n = o.querySelector("animate"); + if (n) + return l.attr(n, { + attributeName: t, + from: e, + to: s, + dur: r, + begin: "click + " + i + // artificial click + }), o; + const a = u("animate", { + attributeName: t, + from: e, + to: s, + dur: r, + begin: i, + calcMode: "spline", + values: e + ";" + s, + keyTimes: "0; 1", + keySplines: O("ease-out") + }); + return o.appendChild(a), o; +} +function O(o) { + return { + ease: ".25 .1 .25 1", + linear: "0 0 1 1", + "ease-in": ".42 0 1 1", + "ease-out": "0 0 .58 1", + "ease-in-out": ".42 0 .58 1" + }[o]; +} +l.on = (o, t, e, s) => { + s ? l.delegate(o, t, e, s) : (s = e, l.bind(o, t, s)); +}; +l.off = (o, t, e) => { + o.removeEventListener(t, e); +}; +l.bind = (o, t, e) => { + t.split(/\s+/).forEach(function(s) { + o.addEventListener(s, e); + }); +}; +l.delegate = (o, t, e, s) => { + o.addEventListener(t, function(r) { + const i = r.target.closest(e); + i && (r.delegatedTarget = i, s.call(this, r, i)); + }); +}; +l.closest = (o, t) => t ? t.matches(o) ? t : l.closest(o, t.parentNode) : null; +l.attr = (o, t, e) => { + if (!e && typeof t == "string") + return o.getAttribute(t); + if (typeof t == "object") { + for (let s in t) + l.attr(o, s, t[s]); + return; + } + o.setAttribute(t, e); +}; +class C { + constructor(t, e) { + this.set_defaults(t, e), this.prepare(), this.draw(), this.bind(); + } + set_defaults(t, e) { + this.action_completed = !1, this.gantt = t, this.task = e; + } + prepare() { + this.prepare_values(), this.prepare_helpers(); + } + prepare_values() { + this.invalid = this.task.invalid, this.height = this.gantt.options.bar_height, this.image_size = this.height - 5, this.compute_x(), this.compute_y(), this.compute_duration(), this.corner_radius = this.gantt.options.bar_corner_radius, this.width = this.gantt.options.column_width * this.duration, this.progress_width = this.gantt.options.column_width * this.duration * (this.task.progress / 100) || 0, this.group = u("g", { + class: "bar-wrapper" + (this.task.custom_class ? " " + this.task.custom_class : "") + (this.task.important ? " important" : ""), + "data-id": this.task.id + }), this.bar_group = u("g", { + class: "bar-group", + append_to: this.group + }), this.handle_group = u("g", { + class: "handle-group", + append_to: this.group + }); + } + 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(); + } + draw_bar() { + this.$bar = u("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 + }), S(this.$bar, "width", 0, this.width), this.invalid && this.$bar.classList.add("bar-invalid"); + } + draw_expected_progress_bar() { + this.invalid || (this.$expected_bar_progress = u("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 + }), S( + this.$expected_bar_progress, + "width", + 0, + this.expected_progress_width + )); + } + draw_progress_bar() { + if (this.invalid) + return; + this.$bar_progress = u("rect", { + x: this.x, + y: this.y, + width: this.progress_width, + height: this.height, + rx: this.corner_radius, + ry: this.corner_radius, + class: "bar-progress", + append_to: this.bar_group + }); + const t = h.diff(this.task._start, this.gantt.gantt_start, "hour") / this.gantt.options.step * this.gantt.options.column_width; + let e = document.createElement("div"); + e.id = `${this.task.id}-highlight`, e.classList.add("date-highlight"), e.style.height = this.height * 0.8 + "px", e.style.width = this.width + "px", e.style.top = this.gantt.options.header_height - 25 + "px", e.style.left = t + "px", this.$date_highlight = e, this.gantt.$lower_header.prepend(e), S(this.$bar_progress, "width", 0, this.progress_width); + } + draw_label() { + let t = this.x + this.$bar.getWidth() / 2; + this.task.thumbnail && (t = this.x + this.image_size + 5), u("text", { + x: t, + y: this.y + this.height / 2, + innerHTML: this.task.name, + class: "bar-label", + append_to: this.bar_group + }), requestAnimationFrame(() => this.update_label_position()); + } + draw_thumbnail() { + let t = 10, e = 2, s, r; + s = u("defs", { + append_to: this.bar_group + }), u("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: s + }), r = u("clipPath", { + id: "clip_" + this.task.id, + append_to: s + }), u("use", { + href: "#rect_" + this.task.id, + append_to: r + }), u("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_resize_handles() { + if (this.invalid || this.gantt.options.readonly) + return; + const t = this.$bar, e = 8; + u("rect", { + x: t.getX() + t.getWidth() + e - 4, + y: t.getY() + 1, + width: e, + height: this.height - 2, + rx: this.corner_radius, + ry: this.corner_radius, + class: "handle right", + append_to: this.handle_group + }), u("rect", { + x: t.getX() - e - 4, + y: t.getY() + 1, + width: e, + height: this.height - 2, + rx: this.corner_radius, + ry: this.corner_radius, + class: "handle left", + append_to: this.handle_group + }), this.$handle_progress = u("polygon", { + points: this.get_progress_polygon_points().join(","), + class: "handle progress", + append_to: this.handle_group + }); + } + get_progress_polygon_points() { + const t = this.$bar_progress; + let e = 10, s = 15; + return [ + t.getEndX() - e / 2, + t.getY() + t.getHeight() / 2, + t.getEndX(), + t.getY() + t.getHeight() / 2 - s / 2, + t.getEndX() + e / 2, + t.getY() + t.getHeight() / 2, + t.getEndX(), + t.getY() + t.getHeight() / 2 + s / 2, + t.getEndX() - e / 2, + t.getY() + t.getHeight() / 2 + ]; + } + bind() { + this.invalid || this.setup_click_event(); + } + setup_click_event() { + let t = this.task.id; + l.on(this.group, "mouseover", (s) => { + this.gantt.trigger_event("hover", [ + this.task, + s.screenX, + s.screenY, + s + ]); + }); + let e; + l.on( + this.group, + "mouseenter", + (s) => e = setTimeout(() => { + this.show_popup(s.offsetX), document.querySelector( + `#${t}-highlight` + ).style.display = "block"; + }, 200) + ), l.on(this.group, "mouseleave", () => { + var s, r; + clearTimeout(e), (r = (s = this.gantt.popup) == null ? void 0 : s.hide) == null || r.call(s), document.querySelector(`#${t}-highlight`).style.display = "none"; + }), l.on(this.group, this.gantt.options.popup_trigger, () => { + this.gantt.trigger_event("click", [this.task]); + }), l.on(this.group, "dblclick", (s) => { + this.action_completed || this.gantt.trigger_event("double_click", [this.task]); + }); + } + show_popup(t) { + if (this.gantt.bar_being_dragged) + return; + const e = h.format( + this.task._start, + "MMM D", + this.gantt.options.language + ), s = h.format( + h.add(this.task._end, -1, "second"), + "MMM D", + this.gantt.options.language + ), r = `${e} - ${s}
Progress: ${this.task.progress}`; + this.gantt.show_popup({ + x: t, + target_element: this.$bar, + title: this.task.name, + subtitle: r, + task: this.task + }); + } + update_bar_position({ x: t = null, width: e = null }) { + const s = this.$bar; + if (t) { + if (!this.task.dependencies.map((n) => this.gantt.get_bar(n).$bar.getX()).reduce((n, a) => t >= a, t)) { + e = null; + return; + } + this.update_attr(s, "x", t), this.$date_highlight.style.left = t + "px"; } - - function getAnimationElement( - svgElement, - attr, - from, - to, - dur = '0.4s', - begin = '0.1s', - ) { - const animEl = svgElement.querySelector('animate'); - if (animEl) { - $.attr(animEl, { - attributeName: attr, - from, - to, - dur, - begin: 'click + ' + begin, // artificial click - }); - return svgElement; - } - - const animateElement = createSVG('animate', { - attributeName: attr, - from, - to, - dur, - begin, - calcMode: 'spline', - values: from + ';' + to, - keyTimes: '0; 1', - keySplines: cubic_bezier('ease-out'), - }); - svgElement.appendChild(animateElement); - - return svgElement; - } - - function cubic_bezier(name) { - return { - ease: '.25 .1 .25 1', - linear: '0 0 1 1', - 'ease-in': '.42 0 1 1', - 'ease-out': '0 0 .58 1', - 'ease-in-out': '.42 0 .58 1', - }[name]; - } - - $.on = (element, event, selector, callback) => { - if (!callback) { - callback = selector; - $.bind(element, event, callback); - } else { - $.delegate(element, event, selector, callback); - } - }; - - $.off = (element, event, handler) => { - element.removeEventListener(event, handler); - }; - - $.bind = (element, event, callback) => { - event.split(/\s+/).forEach(function (event) { - element.addEventListener(event, callback); - }); - }; - - $.delegate = (element, event, selector, callback) => { - element.addEventListener(event, function (e) { - const delegatedTarget = e.target.closest(selector); - if (delegatedTarget) { - e.delegatedTarget = delegatedTarget; - callback.call(this, e, delegatedTarget); - } - }); - }; - - $.closest = (selector, element) => { - if (!element) return null; - - if (element.matches(selector)) { - return element; - } - - return $.closest(selector, element.parentNode); - }; - - $.attr = (element, attr, value) => { - if (!value && typeof attr === 'string') { - return element.getAttribute(attr); - } - - if (typeof attr === 'object') { - for (let key in attr) { - $.attr(element, key, attr[key]); - } - return; - } - - element.setAttribute(attr, value); - }; - - class Bar { - constructor(gantt, task) { - this.set_defaults(gantt, task); - this.prepare(); - this.draw(); - this.bind(); - } - - set_defaults(gantt, task) { - this.action_completed = false; - this.gantt = gantt; - this.task = task; - } - - prepare() { - this.prepare_values(); - this.prepare_helpers(); - } - - prepare_values() { - this.invalid = this.task.invalid; - this.height = this.gantt.options.bar_height; - this.image_size = this.height - 5; - this.compute_x(); - this.compute_y(); - this.compute_duration(); - this.corner_radius = this.gantt.options.bar_corner_radius; - this.width = this.gantt.options.column_width * this.duration; - this.progress_width = - this.gantt.options.column_width * - this.duration * - (this.task.progress / 100) || 0; - this.group = createSVG('g', { - class: - 'bar-wrapper' + - (this.task.custom_class ? ' ' + this.task.custom_class : '') + - (this.task.important ? ' important' : ''), - 'data-id': this.task.id, - }); - this.bar_group = createSVG('g', { - class: 'bar-group', - append_to: this.group, - }); - this.handle_group = createSVG('g', { - class: 'handle-group', - append_to: this.group, - }); - } - - 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(); - if (this.gantt.options.show_expected_progress) { - this.prepare_expected_progress_values(); - this.draw_expected_progress_bar(); - } - this.draw_label(); - this.draw_resize_handles(); - - if (this.task.thumbnail) { - this.draw_thumbnail(); - } - } - - draw_bar() { - this.$bar = createSVG('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, - }); - - animateSVG(this.$bar, 'width', 0, this.width); - - if (this.invalid) { - this.$bar.classList.add('bar-invalid'); - } - } - - draw_expected_progress_bar() { - if (this.invalid) return; - this.$expected_bar_progress = createSVG('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, - }); - - animateSVG( - this.$expected_bar_progress, - 'width', - 0, - this.expected_progress_width, - ); - } - - draw_progress_bar() { - if (this.invalid) return; - this.$bar_progress = createSVG('rect', { - x: this.x, - y: this.y, - width: this.progress_width, - height: this.height, - rx: this.corner_radius, - ry: this.corner_radius, - class: 'bar-progress', - append_to: this.bar_group, - }); - const x = - (date_utils.diff(this.task._start, this.gantt.gantt_start, 'hour') / - this.gantt.options.step) * - this.gantt.options.column_width; - - let $date_highlight = document.createElement('div'); - $date_highlight.id = `${this.task.id}-highlight`; - $date_highlight.classList.add('date-highlight'); - $date_highlight.style.height = this.height * 0.8 + 'px'; - $date_highlight.style.width = this.width + 'px'; - $date_highlight.style.top = - this.gantt.options.header_height - 25 + 'px'; - $date_highlight.style.left = x + 'px'; - this.$date_highlight = $date_highlight; - this.gantt.$lower_header.prepend($date_highlight); - - animateSVG(this.$bar_progress, 'width', 0, this.progress_width); - } - - draw_label() { - let x_coord = this.x + this.$bar.getWidth() / 2; - - if (this.task.thumbnail) { - x_coord = this.x + this.image_size + 5; - } - - createSVG('text', { - x: x_coord, - y: this.y + this.height / 2, - innerHTML: this.task.name, - class: 'bar-label', - append_to: this.bar_group, - }); - // labels get BBox in the next tick - requestAnimationFrame(() => this.update_label_position()); - } - draw_thumbnail() { - let x_offset = 10, - y_offset = 2; - let defs, clipPath; - - defs = createSVG('defs', { - append_to: this.bar_group, - }); - - createSVG('rect', { - id: 'rect_' + this.task.id, - x: this.x + x_offset, - y: this.y + y_offset, - width: this.image_size, - height: this.image_size, - rx: '15', - class: 'img_mask', - append_to: defs, - }); - - clipPath = createSVG('clipPath', { - id: 'clip_' + this.task.id, - append_to: defs, - }); - - createSVG('use', { - href: '#rect_' + this.task.id, - append_to: clipPath, - }); - - createSVG('image', { - x: this.x + x_offset, - y: this.y + y_offset, - 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_resize_handles() { - if (this.invalid || this.gantt.options.readonly) return; - - const bar = this.$bar; - const handle_width = 8; - - createSVG('rect', { - x: bar.getX() + bar.getWidth() + handle_width - 4, - y: bar.getY() + 1, - width: handle_width, - height: this.height - 2, - rx: this.corner_radius, - ry: this.corner_radius, - class: 'handle right', - append_to: this.handle_group, - }); - - createSVG('rect', { - x: bar.getX() - handle_width - 4, - y: bar.getY() + 1, - width: handle_width, - height: this.height - 2, - rx: this.corner_radius, - ry: this.corner_radius, - class: 'handle left', - append_to: this.handle_group, - }); - - this.$handle_progress = createSVG('polygon', { - points: this.get_progress_polygon_points().join(','), - class: 'handle progress', - append_to: this.handle_group, - }); - } - - get_progress_polygon_points() { - const bar_progress = this.$bar_progress; - let icon_width = 10; - let icon_height = 15; - - return [ - bar_progress.getEndX() - icon_width / 2, - bar_progress.getY() + bar_progress.getHeight() / 2, - - bar_progress.getEndX(), - bar_progress.getY() + - bar_progress.getHeight() / 2 - - icon_height / 2, - - bar_progress.getEndX() + icon_width / 2, - bar_progress.getY() + bar_progress.getHeight() / 2, - - bar_progress.getEndX(), - bar_progress.getY() + - bar_progress.getHeight() / 2 + - icon_height / 2, - - bar_progress.getEndX() - icon_width / 2, - bar_progress.getY() + bar_progress.getHeight() / 2, - ]; - } - - bind() { - if (this.invalid) return; - this.setup_click_event(); - } - - setup_click_event() { - let task_id = this.task.id; - $.on(this.group, 'mouseover', (e) => { - this.gantt.trigger_event('hover', [ - this.task, - e.screenX, - e.screenY, - e, - ]); - }); - - let timeout; - $.on( - this.group, - 'mouseenter', - (e) => - (timeout = setTimeout(() => { - this.show_popup(e.offsetX); - document.querySelector( - `#${task_id}-highlight`, - ).style.display = 'block'; - }, 200)), - ); - - $.on(this.group, 'mouseleave', () => { - clearTimeout(timeout); - this.gantt.popup?.hide?.(); - document.querySelector(`#${task_id}-highlight`).style.display = - 'none'; - }); - - $.on(this.group, this.gantt.options.popup_trigger, () => { - this.gantt.trigger_event('click', [this.task]); - }); - - $.on(this.group, 'dblclick', (e) => { - if (this.action_completed) { - // just finished a move action, wait for a few seconds - return; - } - - this.gantt.trigger_event('double_click', [this.task]); - }); - } - - show_popup(x) { - if (this.gantt.bar_being_dragged) return; - - const start_date = date_utils.format( - this.task._start, - 'MMM D', - this.gantt.options.language, - ); - const end_date = date_utils.format( - date_utils.add(this.task._end, -1, 'second'), - 'MMM D', - this.gantt.options.language, - ); - const subtitle = `${start_date} - ${end_date}
Progress: ${this.task.progress}`; - - this.gantt.show_popup({ - x, - target_element: this.$bar, - title: this.task.name, - subtitle: subtitle, - task: this.task, - }); - } - - update_bar_position({ x = null, width = null }) { - const bar = this.$bar; - if (x) { - // get all x values of parent task - const xs = this.task.dependencies.map((dep) => { - return this.gantt.get_bar(dep).$bar.getX(); - }); - // child task must not go before parent - const valid_x = xs.reduce((_, curr) => { - return x >= curr; - }, x); - if (!valid_x) { - width = null; - return; - } - this.update_attr(bar, 'x', x); - this.$date_highlight.style.left = x + 'px'; - } - if (width) { - this.update_attr(bar, 'width', width); - this.$date_highlight.style.width = width + 'px'; - } - this.update_label_position(); - this.update_handle_position(); - if (this.gantt.options.show_expected_progress) { - this.date_changed(); - this.compute_duration(); - this.update_expected_progressbar_position(); - } - this.update_progressbar_position(); - this.update_arrow_position(); - } - - update_label_position_on_horizontal_scroll({ x, sx }) { - const container = document.querySelector('.gantt-container'); - const label = this.group.querySelector('.bar-label'); - const img = this.group.querySelector('.bar-img') || ''; - const img_mask = this.bar_group.querySelector('.img_mask') || ''; - - let barWidthLimit = this.$bar.getX() + this.$bar.getWidth(); - let newLabelX = label.getX() + x; - let newImgX = (img && img.getX() + x) || 0; - let imgWidth = (img && img.getBBox().width + 7) || 7; - let labelEndX = newLabelX + label.getBBox().width + 7; - let viewportCentral = sx + container.clientWidth / 2; - - if (label.classList.contains('big')) return; - - if (labelEndX < barWidthLimit && x > 0 && labelEndX < viewportCentral) { - label.setAttribute('x', newLabelX); - if (img) { - img.setAttribute('x', newImgX); - img_mask.setAttribute('x', newImgX); - } - } else if ( - newLabelX - imgWidth > this.$bar.getX() && - x < 0 && - labelEndX > viewportCentral - ) { - label.setAttribute('x', newLabelX); - if (img) { - img.setAttribute('x', newImgX); - img_mask.setAttribute('x', newImgX); - } - } - } - - date_changed() { - let changed = false; - const { new_start_date, new_end_date } = this.compute_start_end_date(); - - if (Number(this.task._start) !== Number(new_start_date)) { - changed = true; - this.task._start = new_start_date; - } - - if (Number(this.task._end) !== Number(new_end_date)) { - changed = true; - this.task._end = new_end_date; - } - - if (!changed) return; - - this.gantt.trigger_event('date_change', [ - this.task, - new_start_date, - date_utils.add(new_end_date, -1, 'second'), - ]); - } - - progress_changed() { - const new_progress = this.compute_progress(); - this.task.progress = new_progress; - this.gantt.trigger_event('progress_change', [this.task, new_progress]); - } - - set_action_completed() { - this.action_completed = true; - setTimeout(() => (this.action_completed = false), 1000); - } - - compute_start_end_date() { - const bar = this.$bar; - const x_in_units = bar.getX() / this.gantt.options.column_width; - const new_start_date = date_utils.add( - this.gantt.gantt_start, - x_in_units * this.gantt.options.step, - 'hour', - ); - const width_in_units = bar.getWidth() / this.gantt.options.column_width; - const new_end_date = date_utils.add( - new_start_date, - width_in_units * this.gantt.options.step, - 'hour', - ); - - return { new_start_date, new_end_date }; - } - - compute_progress() { - const progress = - (this.$bar_progress.getWidth() / this.$bar.getWidth()) * 100; - return parseInt(progress, 10); - } - - compute_expected_progress() { - this.expected_progress = - date_utils.diff(date_utils.today(), this.task._start, 'hour') / - this.gantt.options.step; - this.expected_progress = - ((this.expected_progress < this.duration - ? this.expected_progress - : this.duration) * - 100) / - this.duration; - } - - compute_x() { - const { step, column_width } = this.gantt.options; - const task_start = this.task._start; - const gantt_start = this.gantt.gantt_start; - - const diff = date_utils.diff(task_start, gantt_start, 'hour'); - let x = (diff / step) * column_width; - - if (this.gantt.view_is('Month')) { - const diff = date_utils.diff(task_start, gantt_start, 'day'); - x = (diff * column_width) / 30; - } - this.x = x; - } - - compute_y() { - this.y = - this.gantt.options.header_height + - this.gantt.options.padding + - this.task._index * (this.height + this.gantt.options.padding); - } - - compute_duration() { - this.duration = - date_utils.diff(this.task._end, this.task._start, 'hour') / - this.gantt.options.step; - } - - get_snap_position(dx) { - let odx = dx, - rem, - position; - - if (this.gantt.view_is('Week')) { - rem = dx % (this.gantt.options.column_width / 7); - position = - odx - - rem + - (rem < this.gantt.options.column_width / 14 - ? 0 - : this.gantt.options.column_width / 7); - } else if (this.gantt.view_is('Month')) { - rem = dx % (this.gantt.options.column_width / 30); - position = - odx - - rem + - (rem < this.gantt.options.column_width / 60 - ? 0 - : this.gantt.options.column_width / 30); - } else { - rem = dx % this.gantt.options.column_width; - position = - odx - - rem + - (rem < this.gantt.options.column_width / 2 - ? 0 - : this.gantt.options.column_width); - } - return position; - } - - update_attr(element, attr, value) { - value = +value; - if (!isNaN(value)) { - element.setAttribute(attr, value); - } - return element; - } - - update_expected_progressbar_position() { - if (this.invalid) return; - this.$expected_bar_progress.setAttribute('x', this.$bar.getX()); - this.compute_expected_progress(); - this.$expected_bar_progress.setAttribute( - 'width', - this.gantt.options.column_width * - this.duration * - (this.expected_progress / 100) || 0, - ); - } - - update_progressbar_position() { - if (this.invalid || this.gantt.options.readonly) return; - this.$bar_progress.setAttribute('x', this.$bar.getX()); - this.$bar_progress.setAttribute( - 'width', - this.$bar.getWidth() * (this.task.progress / 100), - ); - } - - update_label_position() { - const img_mask = this.bar_group.querySelector('.img_mask') || ''; - const bar = this.$bar, - label = this.group.querySelector('.bar-label'), - img = this.group.querySelector('.bar-img'); - - let padding = 5; - let x_offset_label_img = this.image_size + 10; - const labelWidth = label.getBBox().width; - const barWidth = bar.getWidth(); - if (labelWidth > barWidth) { - label.classList.add('big'); - if (img) { - img.setAttribute('x', bar.getX() + bar.getWidth() + padding); - img_mask.setAttribute( - 'x', - bar.getX() + bar.getWidth() + padding, - ); - label.setAttribute( - 'x', - bar.getX() + bar.getWidth() + x_offset_label_img, - ); - } else { - label.setAttribute('x', bar.getX() + bar.getWidth() + padding); - } - } else { - label.classList.remove('big'); - if (img) { - img.setAttribute('x', bar.getX() + padding); - img_mask.setAttribute('x', bar.getX() + padding); - label.setAttribute( - 'x', - bar.getX() + barWidth / 2 + x_offset_label_img, - ); - } else { - label.setAttribute( - 'x', - bar.getX() + barWidth / 2 - labelWidth / 2, - ); - } - } - } - - update_handle_position() { - if (this.invalid || this.gantt.options.readonly) return; - const bar = this.$bar; - this.handle_group - .querySelector('.handle.left') - .setAttribute('x', bar.getX() - 12); - this.handle_group - .querySelector('.handle.right') - .setAttribute('x', bar.getEndX() + 4); - const handle = this.group.querySelector('.handle.progress'); - handle && - handle.setAttribute('points', this.get_progress_polygon_points()); - } - - update_arrow_position() { - this.arrows = this.arrows || []; - for (let arrow of this.arrows) { - arrow.update(); - } - } - } - - class Arrow { - constructor(gantt, from_task, to_task) { - this.gantt = gantt; - this.from_task = from_task; - this.to_task = to_task; - - this.calculate_path(); - this.draw(); - } - - calculate_path() { - let start_x = - this.from_task.$bar.getX() + this.from_task.$bar.getWidth() / 2; - - const condition = () => - this.to_task.$bar.getX() < start_x + this.gantt.options.padding && - start_x > this.from_task.$bar.getX() + this.gantt.options.padding; - - while (condition()) { - start_x -= 10; - } - - const start_y = - this.gantt.options.header_height + - this.gantt.options.bar_height + - (this.gantt.options.padding + this.gantt.options.bar_height) * - this.from_task.task._index + - this.gantt.options.padding; - - const end_x = - this.to_task.$bar.getX() - this.gantt.options.padding / 2 - 7; - const end_y = - this.gantt.options.header_height + - this.gantt.options.bar_height / 2 + - (this.gantt.options.padding + this.gantt.options.bar_height) * - this.to_task.task._index + - this.gantt.options.padding; - - const from_is_below_to = - this.from_task.task._index > this.to_task.task._index; - const curve = this.gantt.options.arrow_curve; - const clockwise = from_is_below_to ? 1 : 0; - const curve_y = from_is_below_to ? -curve : curve; - const offset = from_is_below_to - ? end_y + this.gantt.options.arrow_curve - : end_y - this.gantt.options.arrow_curve; - - this.path = ` - M ${start_x} ${start_y} - V ${offset} - a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y} - L ${end_x} ${end_y} + e && (this.update_attr(s, "width", e), this.$date_highlight.style.width = e + "px"), this.update_label_position(), this.update_handle_position(), this.gantt.options.show_expected_progress && (this.date_changed(), this.compute_duration(), this.update_expected_progressbar_position()), this.update_progressbar_position(), this.update_arrow_position(); + } + update_label_position_on_horizontal_scroll({ x: t, sx: e }) { + const s = document.querySelector(".gantt-container"), r = this.group.querySelector(".bar-label"), i = this.group.querySelector(".bar-img") || "", n = this.bar_group.querySelector(".img_mask") || ""; + let a = this.$bar.getX() + this.$bar.getWidth(), p = r.getX() + t, _ = i && i.getX() + t || 0, g = i && i.getBBox().width + 7 || 7, c = p + r.getBBox().width + 7, f = e + s.clientWidth / 2; + r.classList.contains("big") || (c < a && t > 0 && c < f || p - g > this.$bar.getX() && t < 0 && c > f) && (r.setAttribute("x", p), i && (i.setAttribute("x", _), n.setAttribute("x", _))); + } + date_changed() { + let t = !1; + const { new_start_date: e, new_end_date: s } = this.compute_start_end_date(); + Number(this.task._start) !== Number(e) && (t = !0, this.task._start = e), Number(this.task._end) !== Number(s) && (t = !0, this.task._end = s), t && this.gantt.trigger_event("date_change", [ + this.task, + e, + h.add(s, -1, "second") + ]); + } + progress_changed() { + const t = this.compute_progress(); + this.task.progress = t, this.gantt.trigger_event("progress_change", [this.task, t]); + } + set_action_completed() { + this.action_completed = !0, setTimeout(() => this.action_completed = !1, 1e3); + } + compute_start_end_date() { + const t = this.$bar, e = t.getX() / this.gantt.options.column_width, s = h.add( + this.gantt.gantt_start, + e * this.gantt.options.step, + "hour" + ), r = t.getWidth() / this.gantt.options.column_width, i = h.add( + s, + r * this.gantt.options.step, + "hour" + ); + return { new_start_date: s, new_end_date: i }; + } + compute_progress() { + const t = this.$bar_progress.getWidth() / this.$bar.getWidth() * 100; + return parseInt(t, 10); + } + compute_expected_progress() { + this.expected_progress = h.diff(h.today(), this.task._start, "hour") / this.gantt.options.step, this.expected_progress = (this.expected_progress < this.duration ? this.expected_progress : this.duration) * 100 / this.duration; + } + compute_x() { + const { step: t, column_width: e } = this.gantt.options, s = this.task._start, r = this.gantt.gantt_start; + let n = h.diff(s, r, "hour") / t * e; + this.gantt.view_is("Month") && (n = h.diff(s, r, "day") * e / 30), this.x = n; + } + compute_y() { + this.y = this.gantt.options.header_height + this.gantt.options.padding + this.task._index * (this.height + this.gantt.options.padding); + } + compute_duration() { + this.duration = h.diff(this.task._end, this.task._start, "hour") / this.gantt.options.step; + } + get_snap_position(t) { + let e = t, s, r; + return this.gantt.view_is("Week") ? (s = t % (this.gantt.options.column_width / 7), r = e - s + (s < this.gantt.options.column_width / 14 ? 0 : this.gantt.options.column_width / 7)) : this.gantt.view_is("Month") ? (s = t % (this.gantt.options.column_width / 30), r = e - s + (s < this.gantt.options.column_width / 60 ? 0 : this.gantt.options.column_width / 30)) : (s = t % this.gantt.options.column_width, r = e - s + (s < this.gantt.options.column_width / 2 ? 0 : this.gantt.options.column_width)), r; + } + update_attr(t, e, s) { + return s = +s, isNaN(s) || t.setAttribute(e, s), 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.options.column_width * this.duration * (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.$bar.getWidth() * (this.task.progress / 100) + )); + } + update_label_position() { + const t = this.bar_group.querySelector(".img_mask") || "", e = this.$bar, s = this.group.querySelector(".bar-label"), r = this.group.querySelector(".bar-img"); + let i = 5, n = this.image_size + 10; + const a = s.getBBox().width, p = e.getWidth(); + a > p ? (s.classList.add("big"), r ? (r.setAttribute("x", e.getX() + e.getWidth() + i), t.setAttribute( + "x", + e.getX() + e.getWidth() + i + ), s.setAttribute( + "x", + e.getX() + e.getWidth() + n + )) : s.setAttribute("x", e.getX() + e.getWidth() + i)) : (s.classList.remove("big"), r ? (r.setAttribute("x", e.getX() + i), t.setAttribute("x", e.getX() + i), s.setAttribute( + "x", + e.getX() + p / 2 + n + )) : s.setAttribute( + "x", + e.getX() + p / 2 - a / 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() - 12), this.handle_group.querySelector(".handle.right").setAttribute("x", t.getEndX() + 4); + const e = this.group.querySelector(".handle.progress"); + e && e.setAttribute("points", this.get_progress_polygon_points()); + } + update_arrow_position() { + this.arrows = this.arrows || []; + for (let t of this.arrows) + t.update(); + } +} +class N { + constructor(t, e, s) { + this.gantt = t, this.from_task = e, this.to_task = s, this.calculate_path(), this.draw(); + } + calculate_path() { + let t = this.from_task.$bar.getX() + this.from_task.$bar.getWidth() / 2; + const e = () => this.to_task.$bar.getX() < t + this.gantt.options.padding && t > this.from_task.$bar.getX() + this.gantt.options.padding; + for (; e(); ) + t -= 10; + const s = this.gantt.options.header_height + this.gantt.options.bar_height + (this.gantt.options.padding + this.gantt.options.bar_height) * this.from_task.task._index + this.gantt.options.padding, r = this.to_task.$bar.getX() - this.gantt.options.padding / 2 - 7, i = this.gantt.options.header_height + this.gantt.options.bar_height / 2 + (this.gantt.options.padding + this.gantt.options.bar_height) * this.to_task.task._index + this.gantt.options.padding, n = this.from_task.task._index > this.to_task.task._index, a = this.gantt.options.arrow_curve, p = n ? 1 : 0, _ = n ? -a : a, g = n ? i + this.gantt.options.arrow_curve : i - this.gantt.options.arrow_curve; + if (this.path = ` + M ${t} ${s} + V ${g} + a ${a} ${a} 0 0 ${p} ${a} ${_} + L ${r} ${i} m -5 -5 l 5 5 - l -5 5`; - - if ( - this.to_task.$bar.getX() < - this.from_task.$bar.getX() + this.gantt.options.padding - ) { - const down_1 = this.gantt.options.padding / 2 - curve; - const down_2 = - this.to_task.$bar.getY() + - this.to_task.$bar.getHeight() / 2 - - curve_y; - const left = this.to_task.$bar.getX() - this.gantt.options.padding; - - this.path = ` - M ${start_x} ${start_y} - v ${down_1} - a ${curve} ${curve} 0 0 1 -${curve} ${curve} - H ${left} - a ${curve} ${curve} 0 0 ${clockwise} -${curve} ${curve_y} - V ${down_2} - a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y} - L ${end_x} ${end_y} + l -5 5`, this.to_task.$bar.getX() < this.from_task.$bar.getX() + this.gantt.options.padding) { + const c = this.gantt.options.padding / 2 - a, f = this.to_task.$bar.getY() + this.to_task.$bar.getHeight() / 2 - _, m = this.to_task.$bar.getX() - this.gantt.options.padding; + this.path = ` + M ${t} ${s} + v ${c} + a ${a} ${a} 0 0 1 -${a} ${a} + H ${m} + a ${a} ${a} 0 0 ${p} -${a} ${_} + V ${f} + a ${a} ${a} 0 0 ${p} ${a} ${_} + L ${r} ${i} m -5 -5 l 5 5 l -5 5`; - } - } - - draw() { - this.element = createSVG('path', { - d: this.path, - 'data-from': this.from_task.task.id, - 'data-to': this.to_task.task.id, - }); - } - - update() { - this.calculate_path(); - this.element.setAttribute('d', this.path); - } } - - class Popup { - constructor(parent, custom_html) { - this.parent = parent; - this.custom_html = custom_html; - this.make(); - } - - make() { - this.parent.innerHTML = ` + } + draw() { + this.element = u("path", { + d: this.path, + "data-from": this.from_task.task.id, + "data-to": this.to_task.task.id + }); + } + update() { + this.calculate_path(), this.element.setAttribute("d", this.path); + } +} +class R { + constructor(t, e) { + this.parent = t, this.custom_html = e, this.make(); + } + make() { + this.parent.innerHTML = `
- `; - - this.hide(); - - this.title = this.parent.querySelector('.title'); - this.subtitle = this.parent.querySelector('.subtitle'); - this.pointer = this.parent.querySelector('.pointer'); - } - - show(options) { - if (!options.target_element) { - throw new Error('target_element is required to show popup'); - } - const target_element = options.target_element; - - if (this.custom_html) { - let html = this.custom_html(options.task); - html += '
'; - this.parent.innerHTML = html; - this.pointer = this.parent.querySelector('.pointer'); - } else { - // set data - this.title.innerHTML = options.title; - this.subtitle.innerHTML = options.subtitle; - } - - // set position - let position_meta; - if (target_element instanceof HTMLElement) { - position_meta = target_element.getBoundingClientRect(); - } else if (target_element instanceof SVGElement) { - position_meta = options.target_element.getBBox(); - } - - this.parent.style.left = options.x - this.parent.clientWidth / 2 + 'px'; - this.parent.style.top = - position_meta.y + position_meta.height + 10 + 'px'; - - this.pointer.style.left = this.parent.clientWidth / 2 + 'px'; - this.pointer.style.top = '-15px'; - - // show - this.parent.style.opacity = 1; - } - - hide() { - this.parent.style.opacity = 0; - this.parent.style.left = 0; + `, this.hide(), this.title = this.parent.querySelector(".title"), this.subtitle = this.parent.querySelector(".subtitle"), this.pointer = this.parent.querySelector(".pointer"); + } + show(t) { + if (!t.target_element) + throw new Error("target_element is required to show popup"); + const e = t.target_element; + if (this.custom_html) { + let r = this.custom_html(t.task); + r += '
', this.parent.innerHTML = r, this.pointer = this.parent.querySelector(".pointer"); + } else + this.title.innerHTML = t.title, this.subtitle.innerHTML = t.subtitle; + let s; + e instanceof HTMLElement ? s = e.getBoundingClientRect() : e instanceof SVGElement && (s = t.target_element.getBBox()), this.parent.style.left = t.x - this.parent.clientWidth / 2 + "px", this.parent.style.top = s.y + s.height + 10 + "px", this.pointer.style.left = this.parent.clientWidth / 2 + "px", this.pointer.style.top = "-15px", this.parent.style.opacity = 1; + } + hide() { + this.parent.style.opacity = 0, this.parent.style.left = 0; + } +} +const d = { + HOUR: "Hour", + QUARTER_DAY: "Quarter Day", + HALF_DAY: "Half Day", + DAY: "Day", + WEEK: "Week", + MONTH: "Month", + YEAR: "Year" +}, F = { + HOUR: ["7d", "7d"], + QUARTER_DAY: ["7d", "7d"], + HALF_DAY: ["7d", "7d"], + DAY: ["1m", "1m"], + WEEK: ["1m", "1m"], + MONTH: ["1m", "1m"], + YEAR: ["2y", "2y"] +}, I = { + header_height: 65, + column_width: 30, + step: 24, + view_modes: [...Object.values(d)], + bar_height: 30, + bar_corner_radius: 3, + arrow_curve: 5, + padding: 18, + view_mode: "Day", + date_format: "YYYY-MM-DD", + popup_trigger: "click", + show_expected_progress: !1, + popup: null, + language: "en", + readonly: !1, + highlight_weekend: !0, + scroll_to: "start", + lines: "both", + auto_move_label: !0, + today_button: !0, + view_mode_select: !1 +}; +class q { + constructor(t, e, s) { + this.setup_wrapper(t), this.setup_options(s), this.setup_tasks(e), this.change_view_mode(), this.bind_events(); + } + setup_wrapper(t) { + let e, s; + if (typeof t == "string" && (t = document.querySelector(t)), t instanceof HTMLElement) + s = t, e = t.querySelector("svg"); + else if (t instanceof SVGElement) + e = t; + else + throw new TypeError( + "Frappé 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 = u("svg", { + append_to: s, + class: "gantt" + }), this.$container = document.createElement("div"), this.$container.classList.add("gantt-container"), this.$svg.parentElement.appendChild(this.$container), this.$container.appendChild(this.$svg), this.$popup_wrapper = document.createElement("div"), this.$popup_wrapper.classList.add("popup-wrapper"), this.$container.appendChild(this.$popup_wrapper); + } + setup_options(t) { + this.options = { ...I, ...t }, t.view_mode_padding || (t.view_mode_padding = {}); + for (let [e, s] of Object.entries(t.view_mode_padding)) + typeof s == "string" && (t.view_mode_padding[e] = [s, s]); + this.options.view_mode_padding = { + ...F, + ...t.view_mode_padding + }; + } + setup_tasks(t) { + this.tasks = t.map((e, s) => { + if (e._start = h.parse(e.start), e.end === void 0 && e.duration !== void 0 && (e.end = e._start, e.duration.split(" ").forEach((a) => { + let { duration: p, scale: _ } = h.parse_duration(a); + e.end = h.add(e.end, p, _); + })), e._end = h.parse(e.end), h.diff(e._end, e._start, "year") < 0) + throw Error( + "start of task can't be after end of task: in task #, " + (s + 1) + ); + if (h.diff(e._end, e._start, "year") > 10 && (e.end = null), e._index = s, !e.start && !e.end) { + const n = h.today(); + e._start = n, e._end = h.add(n, 2, "day"); + } + if (!e.start && e.end && (e._start = h.add(e._end, -2, "day")), e.start && !e.end && (e._end = h.add(e._start, 2, "day")), h.get_date_values(e._end).slice(3).every((n) => n === 0) && (e._end = h.add(e._end, 24, "hour")), (!e.start || !e.end) && (e.invalid = !0), typeof e.dependencies == "string" || !e.dependencies) { + let n = []; + e.dependencies && (n = e.dependencies.split(",").map((a) => a.trim().replaceAll(" ", "_")).filter((a) => a)), e.dependencies = n; + } + return e.id ? typeof e.id == "string" ? e.id = e.id.replaceAll(" ", "_") : e.id = `${e.id}` : e.id = z(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(); + } + change_view_mode(t = this.options.view_mode) { + this.update_view_scale(t), this.setup_dates(), this.render(), this.trigger_event("view_change", [t]); + } + update_view_scale(t) { + this.options.view_mode = t, t === d.HOUR ? (this.options.step = 24 / 24, this.options.column_width = 38) : t === d.DAY ? (this.options.step = 24, this.options.column_width = 38) : t === d.HALF_DAY ? (this.options.step = 24 / 2, this.options.column_width = 38) : t === d.QUARTER_DAY ? (this.options.step = 24 / 4, this.options.column_width = 38) : t === d.WEEK ? (this.options.step = 24 * 7, this.options.column_width = 140) : t === d.MONTH ? (this.options.step = 24 * 30, this.options.column_width = 120) : t === d.YEAR && (this.options.step = 24 * 365, this.options.column_width = 120); + } + setup_dates() { + this.setup_gantt_dates(), this.setup_date_values(); + } + setup_gantt_dates() { + this.gantt_start = this.gantt_end = null; + for (let a of this.tasks) + (!this.gantt_start || a._start < this.gantt_start) && (this.gantt_start = a._start), (!this.gantt_end || a._end > this.gantt_end) && (this.gantt_end = a._end); + let t, e; + this.gantt_start ? t = h.start_of(this.gantt_start, "day") : t = /* @__PURE__ */ new Date(), this.gantt_end ? e = h.start_of(this.gantt_end, "day") : e = /* @__PURE__ */ new Date(); + let s; + for (let [a, p] of Object.entries(d)) + p === this.options.view_mode && (s = a); + const [r, i] = this.options.view_mode_padding[s].map(h.parse_duration); + t = h.add( + t, + -r.duration, + r.scale + ); + let n; + this.view_is(d.YEAR) ? n = "YYYY" : this.view_is(d.MONTH) ? n = "YYYY-MM" : this.view_is(d.DAY) ? n = "YYYY-MM-DD" : n = "YYYY-MM-DD HH", this.gantt_start = h.parse( + h.format(t, n) + ), this.gantt_start.setHours(0, 0, 0, 0), this.gantt_end = h.add( + e, + i.duration, + i.scale + ); + } + setup_date_values() { + this.dates = []; + let t = null; + for (; t === null || t < this.gantt_end; ) + t ? this.view_is(d.YEAR) ? t = h.add(t, 1, "year") : this.view_is(d.MONTH) ? t = h.add(t, 1, "month") : t = h.add( + t, + this.options.step, + "hour" + ) : t = h.clone(this.gantt_start), this.dates.push(t); + } + bind_events() { + this.options.readonly || (this.bind_grid_click(), this.bind_bar_events()); + } + render() { + this.clear(), this.setup_layers(), this.make_grid(), this.make_dates(), this.make_bars(), this.make_grid_extras(), this.make_arrows(), this.map_arrows_on_bars(), this.set_width(), this.set_scroll_position(this.options.scroll_to); + } + setup_layers() { + this.layers = {}; + const t = ["grid", "arrow", "progress", "bar", "details"]; + for (let e of t) + this.layers[e] = u("g", { + class: e, + append_to: this.$svg + }); + } + make_grid() { + this.make_grid_background(), this.make_grid_rows(), this.make_grid_header(); + } + make_grid_extras() { + this.make_grid_highlights(), this.make_grid_ticks(); + } + make_grid_background() { + const t = this.dates.length * this.options.column_width, e = this.options.header_height + this.options.padding + (this.options.bar_height + this.options.padding) * this.tasks.length; + u("rect", { + x: 0, + y: 0, + width: t, + height: e, + class: "grid-background", + append_to: this.$svg + }), l.attr(this.$svg, { + height: e + this.options.padding + 100, + width: "100%" + }); + } + make_grid_rows() { + const t = u("g", { append_to: this.layers.grid }), e = this.dates.length * this.options.column_width, s = this.options.bar_height + this.options.padding; + let r = this.options.header_height + this.options.padding / 2; + for (let i of this.tasks) + u("rect", { + x: 0, + y: r, + width: e, + height: s, + class: "grid-row", + append_to: t + }), this.options.lines === "both" || this.options.lines, r += this.options.bar_height + this.options.padding; + } + make_grid_header() { + document.querySelector(".grid-header"); + let t = document.createElement("div"); + t.style.height = this.options.header_height + 10 + "px", t.style.width = this.dates.length * this.options.column_width + "px", t.classList.add("grid-header"), this.$header = t, this.$container.appendChild(t); + let e = document.createElement("div"); + e.classList.add("upper-header"), this.$upper_header = e, this.$header.appendChild(e); + let s = document.createElement("div"); + s.classList.add("lower-header"), this.$lower_header = s, this.$header.appendChild(s), this.make_side_header(); + } + make_side_header() { + let t = document.createElement("div"); + if (t.classList.add("side-header"), this.options.view_mode_select) { + const i = document.createElement("select"); + i.classList.add("viewmode-select"); + const n = document.createElement("option"); + n.selected = !0, n.disabled = !0, n.textContent = "Mode", i.appendChild(n); + for (const a in d) { + const p = document.createElement("option"); + p.value = d[a], p.textContent = d[a], i.appendChild(p); + } + i.addEventListener( + "change", + (function() { + this.change_view_mode(i.value); + }).bind(this) + ), t.appendChild(i); + } + if (this.options.today_button) { + let i = document.createElement("button"); + i.classList.add("today-button"), i.textContent = "Today", i.onclick = this.scroll_today.bind(this), t.appendChild(i); + } + this.$header.appendChild(t); + const { left: e, y: s } = this.$header.getBoundingClientRect(), r = Math.min( + this.$header.clientWidth, + this.$container.clientWidth + ); + t.style.left = e + this.$container.scrollLeft + r - t.clientWidth + "px", t.style.top = s + 10 + "px"; + } + make_grid_ticks() { + if (!["both", "vertical", "horizontal"].includes(this.options.lines)) + return; + let t = 0, e = this.options.header_height + this.options.padding / 2, s = (this.options.bar_height + this.options.padding) * this.tasks.length, r = u("g", { + class: "lines_layer", + append_to: this.layers.grid + }), i = this.options.header_height + this.options.padding / 2; + const n = this.dates.length * this.options.column_width, a = this.options.bar_height + this.options.padding; + if (this.options.lines !== "vertical") + for (let p of this.tasks) + u("line", { + x1: 0, + y1: i + a, + x2: n, + y2: i + a, + class: "row-line", + append_to: r + }), i += a; + if (this.options.lines !== "horizontal") + for (let p of this.dates) { + let _ = "tick"; + this.view_is(d.DAY) && p.getDate() === 1 && (_ += " thick"), this.view_is(d.WEEK) && p.getDate() >= 1 && p.getDate() < 8 && (_ += " thick"), this.view_is(d.MONTH) && p.getMonth() % 3 === 0 && (_ += " thick"), u("path", { + d: `M ${t} ${e} v ${s}`, + class: _, + append_to: this.layers.grid + }), this.view_is(d.MONTH) ? t += h.get_days_in_month(p) * this.options.column_width / 30 : t += this.options.column_width; + } + } + highlightWeekends() { + if (!(!this.view_is("Day") && !this.view_is("Half Day"))) { + for (let t = new Date(this.gantt_start); t <= this.gantt_end; t.setDate(t.getDate() + 1)) + if (t.getDay() === 0 || t.getDay() === 6) { + const e = h.diff(t, this.gantt_start, "hour") / this.options.step * this.options.column_width, s = (this.options.bar_height + this.options.padding) * this.tasks.length; + u("rect", { + x: e, + y: this.options.header_height + this.options.padding / 2, + width: (this.view_is("Day") ? 1 : 2) * this.options.column_width, + height: s, + class: "holiday-highlight", + append_to: this.layers.grid + }); } } - - const VIEW_MODE = { - HOUR: 'Hour', - QUARTER_DAY: 'Quarter Day', - HALF_DAY: 'Half Day', - DAY: 'Day', - WEEK: 'Week', - MONTH: 'Month', - YEAR: 'Year', - }; - - const VIEW_MODE_PADDING = { - HOUR: ['7d', '7d'], - QUARTER_DAY: ['7d', '7d'], - HALF_DAY: ['7d', '7d'], - DAY: ['1m', '1m'], - WEEK: ['1m', '1m'], - MONTH: ['1m', '1m'], - YEAR: ['2y', '2y'], - }; - - const DEFAULT_OPTIONS = { - header_height: 65, - column_width: 30, - step: 24, - view_modes: [...Object.values(VIEW_MODE)], - bar_height: 30, - bar_corner_radius: 3, - arrow_curve: 5, - padding: 18, - view_mode: 'Day', - date_format: 'YYYY-MM-DD', - popup_trigger: 'click', - show_expected_progress: false, - popup: null, - language: 'en', - readonly: false, - highlight_weekend: true, - scroll_to: 'start', - lines: 'both', - auto_move_label: true, - today_button: true, - view_mode_select: false, - }; - - class Gantt { - constructor(wrapper, tasks, options) { - this.setup_wrapper(wrapper); - this.setup_options(options); - this.setup_tasks(tasks); - // initialize with default view mode - this.change_view_mode(); - this.bind_events(); - } - - setup_wrapper(element) { - let svg_element, wrapper_element; - - // CSS Selector is passed - if (typeof element === 'string') { - element = document.querySelector(element); - } - - // get the SVGElement - if (element instanceof HTMLElement) { - wrapper_element = element; - svg_element = element.querySelector('svg'); - } else if (element instanceof SVGElement) { - svg_element = element; - } else { - throw new TypeError( - 'Frappé Gantt only supports usage of a string CSS selector,' + - " HTML DOM element or SVG DOM element for the 'element' parameter", - ); - } - - // svg element - if (!svg_element) { - // create it - this.$svg = createSVG('svg', { - append_to: wrapper_element, - class: 'gantt', - }); - } else { - this.$svg = svg_element; - this.$svg.classList.add('gantt'); - } - - // wrapper element - this.$container = document.createElement('div'); - this.$container.classList.add('gantt-container'); - - const parent_element = this.$svg.parentElement; - parent_element.appendChild(this.$container); - this.$container.appendChild(this.$svg); - - // popup wrapper - this.$popup_wrapper = document.createElement('div'); - this.$popup_wrapper.classList.add('popup-wrapper'); - this.$container.appendChild(this.$popup_wrapper); - } - - setup_options(options) { - this.options = { ...DEFAULT_OPTIONS, ...options }; - if (!options.view_mode_padding) options.view_mode_padding = {}; - for (let [key, value] of Object.entries(options.view_mode_padding)) { - if (typeof value === 'string') { - // Configure for single value given - options.view_mode_padding[key] = [value, value]; - } - } - - this.options.view_mode_padding = { - ...VIEW_MODE_PADDING, - ...options.view_mode_padding, - }; - } - - setup_tasks(tasks) { - // prepare tasks - this.tasks = tasks.map((task, i) => { - // convert to Date objects - task._start = date_utils.parse(task.start); - if (task.end === undefined && task.duration !== undefined) { - task.end = task._start; - let durations = task.duration.split(' '); - - durations.forEach((tmpDuration) => { - let { duration, scale } = - date_utils.parse_duration(tmpDuration); - task.end = date_utils.add(task.end, duration, scale); - }); - } - task._end = date_utils.parse(task.end); - let diff = date_utils.diff(task._end, task._start, 'year'); - if (diff < 0) { - throw Error( - "start of task can't be after end of task: in task #, " + - (i + 1), - ); - } - // make task invalid if duration too large - if (date_utils.diff(task._end, task._start, 'year') > 10) { - task.end = null; - } - - // cache index - task._index = i; - - // invalid dates - if (!task.start && !task.end) { - const today = date_utils.today(); - task._start = today; - task._end = date_utils.add(today, 2, 'day'); - } - - if (!task.start && task.end) { - task._start = date_utils.add(task._end, -2, 'day'); - } - - if (task.start && !task.end) { - task._end = date_utils.add(task._start, 2, 'day'); - } - - // if hours is not set, assume the last day is full day - // e.g: 2018-09-09 becomes 2018-09-09 23:59:59 - const task_end_values = date_utils.get_date_values(task._end); - if (task_end_values.slice(3).every((d) => d === 0)) { - task._end = date_utils.add(task._end, 24, 'hour'); - } - - // invalid flag - if (!task.start || !task.end) { - task.invalid = true; - } - - // dependencies - if (typeof task.dependencies === 'string' || !task.dependencies) { - let deps = []; - if (task.dependencies) { - deps = task.dependencies - .split(',') - .map((d) => d.trim().replaceAll(' ', '_')) - .filter((d) => d); - } - task.dependencies = deps; - } - - // uids - if (!task.id) { - task.id = generate_id(task); - } else if (typeof task.id === 'string') { - task.id = task.id.replaceAll(' ', '_'); - } else { - task.id = `${task.id}`; - } - - return task; - }); - - this.setup_dependencies(); - } - - setup_dependencies() { - this.dependency_map = {}; - for (let t of this.tasks) { - for (let d of t.dependencies) { - this.dependency_map[d] = this.dependency_map[d] || []; - this.dependency_map[d].push(t.id); - } - } - } - - refresh(tasks) { - this.setup_tasks(tasks); - this.change_view_mode(); - } - - change_view_mode(mode = this.options.view_mode) { - this.update_view_scale(mode); - this.setup_dates(); - this.render(); - // fire viewmode_change event - this.trigger_event('view_change', [mode]); - } - - update_view_scale(view_mode) { - this.options.view_mode = view_mode; - if (view_mode === VIEW_MODE.HOUR) { - this.options.step = 24 / 24; - this.options.column_width = 38; - } else if (view_mode === VIEW_MODE.DAY) { - this.options.step = 24; - this.options.column_width = 38; - } else if (view_mode === VIEW_MODE.HALF_DAY) { - this.options.step = 24 / 2; - this.options.column_width = 38; - } else if (view_mode === VIEW_MODE.QUARTER_DAY) { - this.options.step = 24 / 4; - this.options.column_width = 38; - } else if (view_mode === VIEW_MODE.WEEK) { - this.options.step = 24 * 7; - this.options.column_width = 140; - } else if (view_mode === VIEW_MODE.MONTH) { - this.options.step = 24 * 30; - this.options.column_width = 120; - } else if (view_mode === VIEW_MODE.YEAR) { - this.options.step = 24 * 365; - this.options.column_width = 120; - } - } - - setup_dates() { - this.setup_gantt_dates(); - this.setup_date_values(); - } - - setup_gantt_dates() { - this.gantt_start = this.gantt_end = null; - - for (let task of this.tasks) { - // set global start and end date - if (!this.gantt_start || task._start < this.gantt_start) { - this.gantt_start = task._start; - } - if (!this.gantt_end || task._end > this.gantt_end) { - this.gantt_end = task._end; - } - } - let gantt_start, gantt_end; - if (!this.gantt_start) gantt_start = new Date(); - else gantt_start = date_utils.start_of(this.gantt_start, 'day'); - if (!this.gantt_end) gantt_end = new Date(); - else gantt_end = date_utils.start_of(this.gantt_end, 'day'); - - // add date padding on both sides - let viewKey; - for (let [key, value] of Object.entries(VIEW_MODE)) { - if (value === this.options.view_mode) { - viewKey = key; - } - } - const [padding_start, padding_end] = this.options.view_mode_padding[ - viewKey - ].map(date_utils.parse_duration); - gantt_start = date_utils.add( - gantt_start, - -padding_start.duration, - padding_start.scale, - ); - - let format_string; - if (this.view_is(VIEW_MODE.YEAR)) { - format_string = 'YYYY'; - } else if (this.view_is(VIEW_MODE.MONTH)) { - format_string = 'YYYY-MM'; - } else if (this.view_is(VIEW_MODE.DAY)) { - format_string = 'YYYY-MM-DD'; - } else { - format_string = 'YYYY-MM-DD HH'; - } - this.gantt_start = date_utils.parse( - date_utils.format(gantt_start, format_string), - ); - this.gantt_start.setHours(0, 0, 0, 0); - this.gantt_end = date_utils.add( - gantt_end, - padding_end.duration, - padding_end.scale, - ); - } - - setup_date_values() { - this.dates = []; - let cur_date = null; - - while (cur_date === null || cur_date < this.gantt_end) { - if (!cur_date) { - cur_date = date_utils.clone(this.gantt_start); - } else { - if (this.view_is(VIEW_MODE.YEAR)) { - cur_date = date_utils.add(cur_date, 1, 'year'); - } else if (this.view_is(VIEW_MODE.MONTH)) { - cur_date = date_utils.add(cur_date, 1, 'month'); - } else { - cur_date = date_utils.add( - cur_date, - this.options.step, - 'hour', - ); - } - } - this.dates.push(cur_date); - } - } - - bind_events() { - if (this.options.readonly) return; - this.bind_grid_click(); - this.bind_bar_events(); - } - - render() { - this.clear(); - this.setup_layers(); - this.make_grid(); - this.make_dates(); - this.make_bars(); - this.make_grid_extras(); - this.make_arrows(); - this.map_arrows_on_bars(); - this.set_width(); - this.set_scroll_position(this.options.scroll_to); - } - - setup_layers() { - this.layers = {}; - const layers = ['grid', 'arrow', 'progress', 'bar', 'details']; - // make group layers - for (let layer of layers) { - this.layers[layer] = createSVG('g', { - class: layer, - append_to: this.$svg, - }); - } - } - - make_grid() { - this.make_grid_background(); - this.make_grid_rows(); - this.make_grid_header(); - } - - make_grid_extras() { - this.make_grid_highlights(); - this.make_grid_ticks(); - } - - make_grid_background() { - const grid_width = this.dates.length * this.options.column_width; - const grid_height = - this.options.header_height + - this.options.padding + - (this.options.bar_height + this.options.padding) * - this.tasks.length; - - createSVG('rect', { - x: 0, - y: 0, - width: grid_width, - height: grid_height, - class: 'grid-background', - append_to: this.$svg, - }); - - $.attr(this.$svg, { - height: grid_height + this.options.padding + 100, - width: '100%', - }); - } - - make_grid_rows() { - const rows_layer = createSVG('g', { append_to: this.layers.grid }); - - const row_width = this.dates.length * this.options.column_width; - const row_height = this.options.bar_height + this.options.padding; - - let row_y = this.options.header_height + this.options.padding / 2; - - for (let _ of this.tasks) { - createSVG('rect', { - x: 0, - y: row_y, - width: row_width, - height: row_height, - class: 'grid-row', - append_to: rows_layer, - }); - if ( - this.options.lines === 'both' || - this.options.lines === 'horizontal' - ) ; - - row_y += this.options.bar_height + this.options.padding; - } - } - - make_grid_header() { - document.querySelector('.grid-header'); - - let $header = document.createElement('div'); - $header.style.height = this.options.header_height + 10 + 'px'; - $header.style.width = - this.dates.length * this.options.column_width + 'px'; - $header.classList.add('grid-header'); - this.$header = $header; - this.$container.appendChild($header); - - let $upper_header = document.createElement('div'); - $upper_header.classList.add('upper-header'); - this.$upper_header = $upper_header; - this.$header.appendChild($upper_header); - - let $lower_header = document.createElement('div'); - $lower_header.classList.add('lower-header'); - this.$lower_header = $lower_header; - this.$header.appendChild($lower_header); - - this.make_side_header(); - } - - make_side_header() { - let $side_header = document.createElement('div'); - $side_header.classList.add('side-header'); - - // Create view mode change select - if (this.options.view_mode_select) { - const $select = document.createElement('select'); - $select.classList.add('viewmode-select'); - - const $el = document.createElement('option'); - $el.selected = true; - $el.disabled = true; - $el.textContent = 'Mode'; - $select.appendChild($el); - - for (const key in VIEW_MODE) { - const $option = document.createElement('option'); - $option.value = VIEW_MODE[key]; - $option.textContent = VIEW_MODE[key]; - $select.appendChild($option); - } - // $select.value = this.options.view_mode - $select.addEventListener( - 'change', - function () { - this.change_view_mode($select.value); - }.bind(this), - ); - $side_header.appendChild($select); - } - - // Create today button - if (this.options.today_button) { - let $today_button = document.createElement('button'); - $today_button.classList.add('today-button'); - $today_button.textContent = 'Today'; - $today_button.onclick = this.scroll_today.bind(this); - $side_header.appendChild($today_button); - } - - this.$header.appendChild($side_header); - const { left, y } = this.$header.getBoundingClientRect(); - const width = Math.min( - this.$header.clientWidth, - this.$container.clientWidth, - ); - $side_header.style.left = - left + - this.$container.scrollLeft + - width - - $side_header.clientWidth + - 'px'; - $side_header.style.top = y + 10 + 'px'; - } - - make_grid_ticks() { - if (!['both', 'vertical', 'horizontal'].includes(this.options.lines)) - return; - let tick_x = 0; - let tick_y = this.options.header_height + this.options.padding / 2; - let tick_height = - (this.options.bar_height + this.options.padding) * - this.tasks.length; - - let $lines_layer = createSVG('g', { - class: 'lines_layer', - append_to: this.layers.grid, - }); - - let row_y = this.options.header_height + this.options.padding / 2; - - const row_width = this.dates.length * this.options.column_width; - const row_height = this.options.bar_height + this.options.padding; - if (this.options.lines !== 'vertical') { - for (let _ of this.tasks) { - createSVG('line', { - x1: 0, - y1: row_y + row_height, - x2: row_width, - y2: row_y + row_height, - class: 'row-line', - append_to: $lines_layer, - }); - row_y += row_height; - } - } - if (this.options.lines === 'horizontal') return; - for (let date of this.dates) { - let tick_class = 'tick'; - // thick tick for monday - if (this.view_is(VIEW_MODE.DAY) && date.getDate() === 1) { - tick_class += ' thick'; - } - // thick tick for first week - if ( - this.view_is(VIEW_MODE.WEEK) && - date.getDate() >= 1 && - date.getDate() < 8 - ) { - tick_class += ' thick'; - } - // thick ticks for quarters - if (this.view_is(VIEW_MODE.MONTH) && date.getMonth() % 3 === 0) { - tick_class += ' thick'; - } - - createSVG('path', { - d: `M ${tick_x} ${tick_y} v ${tick_height}`, - class: tick_class, - append_to: this.layers.grid, - }); - - if (this.view_is(VIEW_MODE.MONTH)) { - tick_x += - (date_utils.get_days_in_month(date) * - this.options.column_width) / - 30; - } else { - tick_x += this.options.column_width; - } - } - } - - highlightWeekends() { - if (!this.view_is('Day') && !this.view_is('Half Day')) return; - for ( - let d = new Date(this.gantt_start); - d <= this.gantt_end; - d.setDate(d.getDate() + 1) - ) { - if (d.getDay() === 0 || d.getDay() === 6) { - const x = - (date_utils.diff(d, this.gantt_start, 'hour') / - this.options.step) * - this.options.column_width; - const height = - (this.options.bar_height + this.options.padding) * - this.tasks.length; - createSVG('rect', { - x, - y: this.options.header_height + this.options.padding / 2, - width: - (this.view_is('Day') ? 1 : 2) * - this.options.column_width, - height, - class: 'holiday-highlight', - append_to: this.layers.grid, - }); - } - } - } - - //compute the horizontal x distance - computeGridHighlightDimensions(view_mode) { - let x = this.options.column_width / 2; - - if (this.view_is(VIEW_MODE.DAY)) { - let today = date_utils.today(); - return { - x: - x + - (date_utils.diff(today, this.gantt_start, 'hour') / - this.options.step) * - this.options.column_width, - date: today, - }; - } - - for (let date of this.dates) { - const todayDate = new Date(); - const startDate = new Date(date); - const endDate = new Date(date); - switch (view_mode) { - case VIEW_MODE.WEEK: - endDate.setDate(date.getDate() + 7); - break; - case VIEW_MODE.MONTH: - endDate.setMonth(date.getMonth() + 1); - break; - case VIEW_MODE.YEAR: - endDate.setFullYear(date.getFullYear() + 1); - break; - } - if (todayDate >= startDate && todayDate <= endDate) { - return { x, date: startDate }; - } else { - x += this.options.column_width; - } - } - } - - make_grid_highlights() { - if (this.options.highlight_weekend) this.highlightWeekends(); - // highlight today's | week's | month's | year's - if ( - this.view_is(VIEW_MODE.DAY) || - this.view_is(VIEW_MODE.WEEK) || - this.view_is(VIEW_MODE.MONTH) || - this.view_is(VIEW_MODE.YEAR) - ) { - // Used as we must find the _end_ of session if view is not Day - const { x: left, date } = this.computeGridHighlightDimensions( - this.options.view_mode, - ); - const top = this.options.header_height + this.options.padding / 2; - const height = - (this.options.bar_height + this.options.padding) * - this.tasks.length; - this.$current_highlight = this.create_el({ - top, - left, - height, - classes: 'current-highlight', - append_to: this.$container, - }); - let $today = document.getElementById( - date_utils.format(date).replaceAll(' ', '_'), - ); - - $today.classList.add('current-date-highlight'); - $today.style.top = +$today.style.top.slice(0, -2) - 4 + 'px'; - $today.style.left = +$today.style.left.slice(0, -2) - 8 + 'px'; - } - } - - create_el({ left, top, width, height, id, classes, append_to }) { - let $el = document.createElement('div'); - $el.classList.add(classes); - $el.style.top = top + 'px'; - $el.style.left = left + 'px'; - if (id) $el.id = id; - if (width) $el.style.width = height + 'px'; - if (height) $el.style.height = height + 'px'; - append_to.appendChild($el); - return $el; - } - - make_dates() { - this.upper_texts_x = {}; - this.get_dates_to_draw().forEach((date, i) => { - let $lower_text = this.create_el({ - left: date.lower_x, - top: date.lower_y, - id: date.formatted_date, - classes: 'lower-text', - append_to: this.$lower_header, - }); - $lower_text.innerText = date.lower_text; - $lower_text.style.left = - +$lower_text.style.left.slice(0, -2) - - $lower_text.clientWidth / 2 + - 'px'; - - if (date.upper_text) { - this.upper_texts_x[date.upper_text] = date.upper_x; - let $upper_text = document.createElement('div'); - $upper_text.classList.add('upper-text'); - $upper_text.style.left = date.upper_x + 'px'; - $upper_text.style.top = date.upper_y + 'px'; - $upper_text.innerText = date.upper_text; - this.$upper_header.appendChild($upper_text); - - // remove out-of-bound dates - if (date.upper_x > this.layers.grid.getBBox().width) { - $upper_text.remove(); - } - } - }); - } - - get_dates_to_draw() { - let last_date = null; - const dates = this.dates.map((date, i) => { - const d = this.get_date_info(date, last_date, i); - last_date = d; - return d; - }); - return dates; - } - - get_date_info(date, last_date_info) { - let last_date = last_date_info - ? last_date_info.date - : date_utils.add(date, 1, 'day'); - const date_text = { - Hour_lower: date_utils.format(date, 'HH', this.options.language), - 'Quarter Day_lower': date_utils.format( - date, - 'HH', - this.options.language, - ), - 'Half Day_lower': date_utils.format( - date, - 'HH', - this.options.language, - ), - Day_lower: - date.getDate() !== last_date.getDate() - ? date_utils.format(date, 'D', this.options.language) - : '', - Week_lower: - date.getMonth() !== last_date.getMonth() - ? date_utils.format(date, 'D MMM', this.options.language) - : date_utils.format(date, 'D', this.options.language), - Month_lower: date_utils.format(date, 'MMMM', this.options.language), - Year_lower: date_utils.format(date, 'YYYY', this.options.language), - Hour_upper: - date.getDate() !== last_date.getDate() - ? date_utils.format(date, 'D MMMM', this.options.language) - : '', - 'Quarter Day_upper': - date.getDate() !== last_date.getDate() - ? date_utils.format(date, 'D MMM', this.options.language) - : '', - 'Half Day_upper': - date.getDate() !== last_date.getDate() - ? date.getMonth() !== last_date.getMonth() - ? date_utils.format( - date, - 'D MMM', - this.options.language, - ) - : date_utils.format(date, 'D', this.options.language) - : '', - Day_upper: - date.getMonth() !== last_date.getMonth() || !last_date_info - ? date_utils.format(date, 'MMMM', this.options.language) - : '', - Week_upper: - date.getMonth() !== last_date.getMonth() - ? date_utils.format(date, 'MMMM', this.options.language) - : '', - Month_upper: - date.getFullYear() !== last_date.getFullYear() - ? date_utils.format(date, 'YYYY', this.options.language) - : '', - Year_upper: - date.getFullYear() !== last_date.getFullYear() - ? date_utils.format(date, 'YYYY', this.options.language) - : '', - }; - let column_width = this.view_is(VIEW_MODE.MONTH) - ? (date_utils.get_days_in_month(date) * this.options.column_width) / - 30 - : this.options.column_width; - const base_pos = { - x: last_date_info - ? last_date_info.base_pos_x + last_date_info.column_width - : 0, - lower_y: this.options.header_height - 20, - upper_y: this.options.header_height - 50, - }; - const x_pos = { - Hour_lower: column_width / 2, - Hour_upper: column_width * 12, - 'Quarter Day_lower': column_width / 2, - 'Quarter Day_upper': column_width * 2, - 'Half Day_lower': column_width / 2, - 'Half Day_upper': column_width, - Day_lower: column_width / 2, - Day_upper: column_width / 2, - Week_lower: column_width / 2, - Week_upper: (column_width * 4) / 2, - Month_lower: column_width / 2, - Month_upper: column_width / 2, - Year_lower: column_width / 2, - Year_upper: (column_width * 30) / 2, - }; - return { - date, - formatted_date: date_utils.format(date).replaceAll(' ', '_'), - column_width, - base_pos_x: base_pos.x, - upper_text: this.options.lower_text - ? this.options.upper_text( - date, - this.options.view_mode, - date_text[`${this.options.view_mode}_upper`], - ) - : date_text[`${this.options.view_mode}_upper`], - lower_text: this.options.lower_text - ? this.options.lower_text( - date, - this.options.view_mode, - date_text[`${this.options.view_mode}_lower`], - ) - : date_text[`${this.options.view_mode}_lower`], - upper_x: base_pos.x + x_pos[`${this.options.view_mode}_upper`], - upper_y: base_pos.upper_y, - lower_x: base_pos.x + x_pos[`${this.options.view_mode}_lower`], - lower_y: base_pos.lower_y, - }; - } - - make_bars() { - this.bars = this.tasks.map((task) => { - const bar = new Bar(this, task); - this.layers.bar.appendChild(bar.group); - return bar; - }); - } - - make_arrows() { - this.arrows = []; - for (let task of this.tasks) { - let arrows = []; - arrows = task.dependencies - .map((task_id) => { - const dependency = this.get_task(task_id); - if (!dependency) return; - const arrow = new Arrow( - this, - this.bars[dependency._index], // from_task - this.bars[task._index], // to_task - ); - this.layers.arrow.appendChild(arrow.element); - return arrow; - }) - .filter(Boolean); // filter falsy values - this.arrows = this.arrows.concat(arrows); - } - } - - map_arrows_on_bars() { - for (let bar of this.bars) { - bar.arrows = this.arrows.filter((arrow) => { - return ( - arrow.from_task.task.id === bar.task.id || - arrow.to_task.task.id === bar.task.id - ); - }); - } - } - - set_width() { - const cur_width = this.$svg.getBoundingClientRect().width; - const actual_width = this.$svg.querySelector('.grid .grid-row') - ? this.$svg.querySelector('.grid .grid-row').getAttribute('width') - : 0; - if (cur_width < actual_width) { - this.$svg.setAttribute('width', actual_width); - } - } - - set_scroll_position(date) { - if (!date || date === 'start') { - date = this.gantt_start; - } else if (date === 'today') { - return this.scroll_today(); - } else if (typeof date === 'string') { - date = date_utils.parse(date); - } - - const parent_element = this.$svg.parentElement; - if (!parent_element) return; - - const hours_before_first_task = - date_utils.diff(date, this.gantt_start, 'hour') + 24; - - const scroll_pos = - (hours_before_first_task / this.options.step) * - this.options.column_width - - this.options.column_width; - parent_element.scrollTo({ left: scroll_pos, behavior: 'smooth' }); - } - - scroll_today() { - this.set_scroll_position(new Date()); - } - - bind_grid_click() { - $.on( - this.$svg, - this.options.popup_trigger, - '.grid-row, .grid-header', - () => { - this.unselect_all(); - this.hide_popup(); - }, - ); - } - - bind_bar_events() { - let is_dragging = false; - let x_on_start = 0; - let x_on_scroll_start = 0; - let y_on_start = 0; - let is_resizing_left = false; - let is_resizing_right = false; - let parent_bar_id = null; - let bars = []; // instanceof Bar - this.bar_being_dragged = null; - - function action_in_progress() { - return is_dragging || is_resizing_left || is_resizing_right; - } - - $.on(this.$svg, 'mousedown', '.bar-wrapper, .handle', (e, element) => { - const bar_wrapper = $.closest('.bar-wrapper', element); - bars.forEach((bar) => bar.group.classList.remove('active')); - - if (element.classList.contains('left')) { - is_resizing_left = true; - } else if (element.classList.contains('right')) { - is_resizing_right = true; - } else if (element.classList.contains('bar-wrapper')) { - is_dragging = true; - } - - bar_wrapper.classList.add('active'); - this.popup.parent.classList.add('hidden'); - - x_on_start = e.offsetX; - y_on_start = e.offsetY; - - parent_bar_id = bar_wrapper.getAttribute('data-id'); - const ids = [ - parent_bar_id, - ...this.get_all_dependent_tasks(parent_bar_id), - ]; - bars = ids.map((id) => this.get_bar(id)); - - this.bar_being_dragged = parent_bar_id; - - bars.forEach((bar) => { - const $bar = bar.$bar; - $bar.ox = $bar.getX(); - $bar.oy = $bar.getY(); - $bar.owidth = $bar.getWidth(); - $bar.finaldx = 0; - }); - }); - $.on(this.$container, 'scroll', (e) => { - let elements = document.querySelectorAll('.bar-wrapper'); - let localBars = []; - const ids = []; - let dx; - if (x_on_scroll_start) { - dx = e.currentTarget.scrollLeft - x_on_scroll_start; - } - - const daysSinceStart = - ((e.currentTarget.scrollLeft / this.options.column_width) * - this.options.step) / - 24; - let format_str = 'D MMM'; - if (['Year', 'Month'].includes(this.options.view_mode)) - format_str = 'YYYY'; - else if (['Day', 'Week'].includes(this.options.view_mode)) - format_str = 'MMMM'; - else if (this.view_is('Half Day')) format_str = 'D'; - else if (this.view_is('Hour')) format_str = 'D MMMM'; - - let currentUpper = date_utils.format( - date_utils.add(this.gantt_start, daysSinceStart, 'day'), - format_str, - ); - const upperTexts = Array.from( - document.querySelectorAll('.upper-text'), - ); - const $el = upperTexts.find( - (el) => el.textContent === currentUpper, - ); - if ($el && !$el.classList.contains('current-upper')) { - const $current = document.querySelector('.current-upper'); - if ($current) { - $current.classList.remove('current-upper'); - $current.style.left = - this.upper_texts_x[$current.textContent] + 'px'; - $current.style.top = this.options.header_height - 50 + 'px'; - } - - $el.classList.add('current-upper'); - let dimensions = this.$svg.getBoundingClientRect(); - $el.style.left = - dimensions.x + this.$container.scrollLeft + 10 + 'px'; - $el.style.top = - dimensions.y + this.options.header_height - 50 + 'px'; - } - - Array.prototype.forEach.call(elements, function (el, i) { - ids.push(el.getAttribute('data-id')); - }); - - if (dx) { - localBars = ids.map((id) => this.get_bar(id)); - if (this.options.auto_move_label) { - localBars.forEach((bar) => { - bar.update_label_position_on_horizontal_scroll({ - x: dx, - sx: e.currentTarget.scrollLeft, - }); - }); - } - } - - x_on_scroll_start = e.currentTarget.scrollLeft; - }); - - $.on(this.$svg, 'mousemove', (e) => { - if (!action_in_progress()) return; - const dx = e.offsetX - x_on_start; - e.offsetY - y_on_start; - - bars.forEach((bar) => { - const $bar = bar.$bar; - $bar.finaldx = this.get_snap_position(dx); - this.hide_popup(); - if (is_resizing_left) { - if (parent_bar_id === bar.task.id) { - bar.update_bar_position({ - x: $bar.ox + $bar.finaldx, - width: $bar.owidth - $bar.finaldx, - }); - } else { - bar.update_bar_position({ - x: $bar.ox + $bar.finaldx, - }); - } - } else if (is_resizing_right) { - if (parent_bar_id === bar.task.id) { - bar.update_bar_position({ - width: $bar.owidth + $bar.finaldx, - }); - } - } else if (is_dragging && !this.options.readonly) { - bar.update_bar_position({ x: $bar.ox + $bar.finaldx }); - } - }); - }); - - document.addEventListener('mouseup', (e) => { - is_dragging = false; - is_resizing_left = false; - is_resizing_right = false; - }); - - $.on(this.$svg, 'mouseup', (e) => { - this.bar_being_dragged = null; - bars.forEach((bar) => { - const $bar = bar.$bar; - if (!$bar.finaldx) return; - bar.date_changed(); - bar.set_action_completed(); - }); - }); - - this.bind_bar_progress(); - } - - bind_bar_progress() { - let x_on_start = 0; - let y_on_start = 0; - let is_resizing = null; - let bar = null; - let $bar_progress = null; - let $bar = null; - - $.on(this.$svg, 'mousedown', '.handle.progress', (e, handle) => { - is_resizing = true; - x_on_start = e.offsetX; - y_on_start = e.offsetY; - - const $bar_wrapper = $.closest('.bar-wrapper', handle); - const id = $bar_wrapper.getAttribute('data-id'); - bar = this.get_bar(id); - - $bar_progress = bar.$bar_progress; - $bar = bar.$bar; - - $bar_progress.finaldx = 0; - $bar_progress.owidth = $bar_progress.getWidth(); - $bar_progress.min_dx = -$bar_progress.getWidth(); - $bar_progress.max_dx = $bar.getWidth() - $bar_progress.getWidth(); - }); - - $.on(this.$svg, 'mousemove', (e) => { - if (!is_resizing) return; - let dx = e.offsetX - x_on_start; - e.offsetY - y_on_start; - - if (dx > $bar_progress.max_dx) { - dx = $bar_progress.max_dx; - } - if (dx < $bar_progress.min_dx) { - dx = $bar_progress.min_dx; - } - - const $handle = bar.$handle_progress; - $.attr($bar_progress, 'width', $bar_progress.owidth + dx); - $.attr($handle, 'points', bar.get_progress_polygon_points()); - $bar_progress.finaldx = dx; - }); - - $.on(this.$svg, 'mouseup', () => { - is_resizing = false; - if (!($bar_progress && $bar_progress.finaldx)) return; - - $bar_progress.finaldx = 0; - bar.progress_changed(); - bar.set_action_completed(); - bar = null; - $bar_progress = null; - $bar = null; - }); - } - - get_all_dependent_tasks(task_id) { - let out = []; - let to_process = [task_id]; - while (to_process.length) { - const deps = to_process.reduce((acc, curr) => { - acc = acc.concat(this.dependency_map[curr]); - return acc; - }, []); - - out = out.concat(deps); - to_process = deps.filter((d) => !to_process.includes(d)); - } - - return out.filter(Boolean); - } - - get_snap_position(dx) { - let odx = dx, - rem, - position; - - if (this.view_is(VIEW_MODE.WEEK)) { - rem = dx % (this.options.column_width / 7); - position = - odx - - rem + - (rem < this.options.column_width / 14 - ? 0 - : this.options.column_width / 7); - } else if (this.view_is(VIEW_MODE.MONTH)) { - rem = dx % (this.options.column_width / 30); - position = - odx - - rem + - (rem < this.options.column_width / 60 - ? 0 - : this.options.column_width / 30); - } else { - rem = dx % this.options.column_width; - position = - odx - - rem + - (rem < this.options.column_width / 2 - ? 0 - : this.options.column_width); - } - return position; - } - - unselect_all() { - [...this.$svg.querySelectorAll('.bar-wrapper')].forEach((el) => { - el.classList.remove('active'); - }); - this.popup.parent.classList.remove('hidden'); - } - - view_is(modes) { - if (typeof modes === 'string') { - return this.options.view_mode === modes; - } - - if (Array.isArray(modes)) { - return modes.some((mode) => this.options.view_mode === mode); - } - - return false; - } - - get_task(id) { - return this.tasks.find((task) => { - return task.id === id; - }); - } - - get_bar(id) { - return this.bars.find((bar) => { - return bar.task.id === id; - }); - } - - show_popup(options) { - if (this.options.popup === false) return; - if (!this.popup) { - this.popup = new Popup(this.$popup_wrapper, this.options.popup); - } - this.popup.show(options); - } - - hide_popup() { - this.popup && this.popup.hide(); - } - - trigger_event(event, args) { - if (this.options['on_' + event]) { - this.options['on_' + event].apply(null, args); - } - } - - /** - * Gets the oldest starting date from the list of tasks - * - * @returns Date - * @memberof Gantt - */ - get_oldest_starting_date() { - if (!this.tasks.length) return new Date(); - return this.tasks - .map((task) => task._start) - .reduce((prev_date, cur_date) => - cur_date <= prev_date ? cur_date : prev_date, - ); - } - - /** - * Clear all elements from the parent svg element - * - * @memberof Gantt - */ - clear() { - this.$svg.innerHTML = ''; - this.$header?.remove?.(); - this.$current_highlight?.remove?.(); - this.popup?.hide?.(); - } + } + //compute the horizontal x distance + computeGridHighlightDimensions(t) { + let e = this.options.column_width / 2; + if (this.view_is(d.DAY)) { + let s = h.today(); + return { + x: e + h.diff(s, this.gantt_start, "hour") / this.options.step * this.options.column_width, + date: s + }; } - - Gantt.VIEW_MODE = VIEW_MODE; - - function generate_id(task) { - return task.name + '_' + Math.random().toString(36).slice(2, 12); + for (let s of this.dates) { + const r = /* @__PURE__ */ new Date(), i = new Date(s), n = new Date(s); + switch (t) { + case d.WEEK: + n.setDate(s.getDate() + 7); + break; + case d.MONTH: + n.setMonth(s.getMonth() + 1); + break; + case d.YEAR: + n.setFullYear(s.getFullYear() + 1); + break; + } + if (r >= i && r <= n) + return { x: e, date: i }; + e += this.options.column_width; } - - return Gantt; - -})(); -//# sourceMappingURL=frappe-gantt.js.map + } + make_grid_highlights() { + if (this.options.highlight_weekend && this.highlightWeekends(), this.view_is(d.DAY) || this.view_is(d.WEEK) || this.view_is(d.MONTH) || this.view_is(d.YEAR)) { + const { x: t, date: e } = this.computeGridHighlightDimensions( + this.options.view_mode + ), s = this.options.header_height + this.options.padding / 2, r = (this.options.bar_height + this.options.padding) * this.tasks.length; + this.$current_highlight = this.create_el({ + top: s, + left: t, + height: r, + classes: "current-highlight", + append_to: this.$container + }); + let i = document.getElementById( + h.format(e).replaceAll(" ", "_") + ); + i.classList.add("current-date-highlight"), i.style.top = +i.style.top.slice(0, -2) - 4 + "px", i.style.left = +i.style.left.slice(0, -2) - 8 + "px"; + } + } + create_el({ left: t, top: e, width: s, height: r, id: i, classes: n, append_to: a }) { + let p = document.createElement("div"); + return p.classList.add(n), p.style.top = e + "px", p.style.left = t + "px", i && (p.id = i), s && (p.style.width = r + "px"), r && (p.style.height = r + "px"), a.appendChild(p), p; + } + make_dates() { + this.upper_texts_x = {}, this.get_dates_to_draw().forEach((t, e) => { + let s = this.create_el({ + left: t.lower_x, + top: t.lower_y, + id: t.formatted_date, + classes: "lower-text", + append_to: this.$lower_header + }); + if (s.innerText = t.lower_text, s.style.left = +s.style.left.slice(0, -2) - s.clientWidth / 2 + "px", t.upper_text) { + this.upper_texts_x[t.upper_text] = t.upper_x; + let r = document.createElement("div"); + r.classList.add("upper-text"), r.style.left = t.upper_x + "px", r.style.top = t.upper_y + "px", r.innerText = t.upper_text, this.$upper_header.appendChild(r), t.upper_x > this.layers.grid.getBBox().width && r.remove(); + } + }); + } + get_dates_to_draw() { + let t = null; + return this.dates.map((s, r) => { + const i = this.get_date_info(s, t, r); + return t = i, i; + }); + } + get_date_info(t, e) { + let s = e ? e.date : h.add(t, 1, "day"); + const r = { + Hour_lower: h.format(t, "HH", this.options.language), + "Quarter Day_lower": h.format( + t, + "HH", + this.options.language + ), + "Half Day_lower": h.format( + t, + "HH", + this.options.language + ), + Day_lower: t.getDate() !== s.getDate() ? h.format(t, "D", this.options.language) : "", + Week_lower: t.getMonth() !== s.getMonth() ? h.format(t, "D MMM", this.options.language) : h.format(t, "D", this.options.language), + Month_lower: h.format(t, "MMMM", this.options.language), + Year_lower: h.format(t, "YYYY", this.options.language), + Hour_upper: t.getDate() !== s.getDate() ? h.format(t, "D MMMM", this.options.language) : "", + "Quarter Day_upper": t.getDate() !== s.getDate() ? h.format(t, "D MMM", this.options.language) : "", + "Half Day_upper": t.getDate() !== s.getDate() ? t.getMonth() !== s.getMonth() ? h.format( + t, + "D MMM", + this.options.language + ) : h.format(t, "D", this.options.language) : "", + Day_upper: t.getMonth() !== s.getMonth() || !e ? h.format(t, "MMMM", this.options.language) : "", + Week_upper: t.getMonth() !== s.getMonth() ? h.format(t, "MMMM", this.options.language) : "", + Month_upper: t.getFullYear() !== s.getFullYear() ? h.format(t, "YYYY", this.options.language) : "", + Year_upper: t.getFullYear() !== s.getFullYear() ? h.format(t, "YYYY", this.options.language) : "" + }; + let i = this.view_is(d.MONTH) ? h.get_days_in_month(t) * this.options.column_width / 30 : this.options.column_width; + const n = { + x: e ? e.base_pos_x + e.column_width : 0, + lower_y: this.options.header_height - 20, + upper_y: this.options.header_height - 50 + }, a = { + Hour_lower: i / 2, + Hour_upper: i * 12, + "Quarter Day_lower": i / 2, + "Quarter Day_upper": i * 2, + "Half Day_lower": i / 2, + "Half Day_upper": i, + Day_lower: i / 2, + Day_upper: i / 2, + Week_lower: i / 2, + Week_upper: i * 4 / 2, + Month_lower: i / 2, + Month_upper: i / 2, + Year_lower: i / 2, + Year_upper: i * 30 / 2 + }; + return { + date: t, + formatted_date: h.format(t).replaceAll(" ", "_"), + column_width: i, + base_pos_x: n.x, + upper_text: this.options.lower_text ? this.options.upper_text( + t, + this.options.view_mode, + r[`${this.options.view_mode}_upper`] + ) : r[`${this.options.view_mode}_upper`], + lower_text: this.options.lower_text ? this.options.lower_text( + t, + this.options.view_mode, + r[`${this.options.view_mode}_lower`] + ) : r[`${this.options.view_mode}_lower`], + upper_x: n.x + a[`${this.options.view_mode}_upper`], + upper_y: n.upper_y, + lower_x: n.x + a[`${this.options.view_mode}_lower`], + lower_y: n.lower_y + }; + } + make_bars() { + this.bars = this.tasks.map((t) => { + const e = new C(this, t); + return this.layers.bar.appendChild(e.group), e; + }); + } + make_arrows() { + this.arrows = []; + for (let t of this.tasks) { + let e = []; + e = t.dependencies.map((s) => { + const r = this.get_task(s); + if (!r) + return; + const i = new N( + this, + this.bars[r._index], + // from_task + this.bars[t._index] + // to_task + ); + return this.layers.arrow.appendChild(i.element), i; + }).filter(Boolean), this.arrows = this.arrows.concat(e); + } + } + map_arrows_on_bars() { + for (let t of this.bars) + t.arrows = this.arrows.filter((e) => e.from_task.task.id === t.task.id || e.to_task.task.id === t.task.id); + } + set_width() { + const t = this.$svg.getBoundingClientRect().width, e = this.$svg.querySelector(".grid .grid-row") ? this.$svg.querySelector(".grid .grid-row").getAttribute("width") : 0; + t < e && this.$svg.setAttribute("width", e); + } + set_scroll_position(t) { + if (!t || t === "start") + t = this.gantt_start; + else { + if (t === "today") + return this.scroll_today(); + typeof t == "string" && (t = h.parse(t)); + } + const e = this.$svg.parentElement; + if (!e) + return; + const r = (h.diff(t, this.gantt_start, "hour") + 24) / this.options.step * this.options.column_width - this.options.column_width; + e.scrollTo({ left: r, behavior: "smooth" }); + } + scroll_today() { + this.set_scroll_position(/* @__PURE__ */ new Date()); + } + bind_grid_click() { + l.on( + this.$svg, + this.options.popup_trigger, + ".grid-row, .grid-header", + () => { + this.unselect_all(), this.hide_popup(); + } + ); + } + bind_bar_events() { + let t = !1, e = 0, s = 0, r = 0, i = !1, n = !1, a = null, p = []; + this.bar_being_dragged = null; + function _() { + return t || i || n; + } + l.on(this.$svg, "mousedown", ".bar-wrapper, .handle", (g, c) => { + const f = l.closest(".bar-wrapper", c); + p.forEach((b) => b.group.classList.remove("active")), c.classList.contains("left") ? i = !0 : c.classList.contains("right") ? n = !0 : c.classList.contains("bar-wrapper") && (t = !0), f.classList.add("active"), this.popup && this.popup.parent.classList.add("hidden"), e = g.offsetX, r = g.offsetY, a = f.getAttribute("data-id"), p = [ + a, + ...this.get_all_dependent_tasks(a) + ].map((b) => this.get_bar(b)), this.bar_being_dragged = a, p.forEach((b) => { + const y = b.$bar; + y.ox = y.getX(), y.oy = y.getY(), y.owidth = y.getWidth(), y.finaldx = 0; + }); + }), l.on(this.$container, "scroll", (g) => { + let c = document.querySelectorAll(".bar-wrapper"), f = []; + const m = []; + let b; + s && (b = g.currentTarget.scrollLeft - s); + const y = g.currentTarget.scrollLeft / this.options.column_width * this.options.step / 24; + let x = "D MMM"; + ["Year", "Month"].includes(this.options.view_mode) ? x = "YYYY" : ["Day", "Week"].includes(this.options.view_mode) ? x = "MMMM" : this.view_is("Half Day") ? x = "D" : this.view_is("Hour") && (x = "D MMMM"); + let T = h.format( + h.add(this.gantt_start, y, "day"), + x + ); + const v = Array.from( + document.querySelectorAll(".upper-text") + ).find( + (w) => w.textContent === T + ); + if (v && !v.classList.contains("current-upper")) { + const w = document.querySelector(".current-upper"); + w && (w.classList.remove("current-upper"), w.style.left = this.upper_texts_x[w.textContent] + "px", w.style.top = this.options.header_height - 50 + "px"), v.classList.add("current-upper"); + let k = this.$svg.getBoundingClientRect(); + v.style.left = k.x + this.$container.scrollLeft + 10 + "px", v.style.top = k.y + this.options.header_height - 50 + "px"; + } + Array.prototype.forEach.call(c, function(w, k) { + m.push(w.getAttribute("data-id")); + }), b && (f = m.map((w) => this.get_bar(w)), this.options.auto_move_label && f.forEach((w) => { + w.update_label_position_on_horizontal_scroll({ + x: b, + sx: g.currentTarget.scrollLeft + }); + })), s = g.currentTarget.scrollLeft; + }), l.on(this.$svg, "mousemove", (g) => { + if (!_()) + return; + const c = g.offsetX - e; + g.offsetY - r, p.forEach((f) => { + const m = f.$bar; + m.finaldx = this.get_snap_position(c), this.hide_popup(), i ? a === f.task.id ? f.update_bar_position({ + x: m.ox + m.finaldx, + width: m.owidth - m.finaldx + }) : f.update_bar_position({ + x: m.ox + m.finaldx + }) : n ? a === f.task.id && f.update_bar_position({ + width: m.owidth + m.finaldx + }) : t && !this.options.readonly && f.update_bar_position({ x: m.ox + m.finaldx }); + }); + }), document.addEventListener("mouseup", (g) => { + t = !1, i = !1, n = !1; + }), l.on(this.$svg, "mouseup", (g) => { + this.bar_being_dragged = null, p.forEach((c) => { + c.$bar.finaldx && (c.date_changed(), c.set_action_completed()); + }); + }), this.bind_bar_progress(); + } + bind_bar_progress() { + let t = 0, e = 0, s = null, r = null, i = null, n = null; + l.on(this.$svg, "mousedown", ".handle.progress", (a, p) => { + s = !0, t = a.offsetX, e = a.offsetY; + const g = l.closest(".bar-wrapper", p).getAttribute("data-id"); + r = this.get_bar(g), i = r.$bar_progress, n = r.$bar, i.finaldx = 0, i.owidth = i.getWidth(), i.min_dx = -i.getWidth(), i.max_dx = n.getWidth() - i.getWidth(); + }), l.on(this.$svg, "mousemove", (a) => { + if (!s) + return; + let p = a.offsetX - t; + a.offsetY - e, p > i.max_dx && (p = i.max_dx), p < i.min_dx && (p = i.min_dx); + const _ = r.$handle_progress; + l.attr(i, "width", i.owidth + p), l.attr(_, "points", r.get_progress_polygon_points()), i.finaldx = p; + }), l.on(this.$svg, "mouseup", () => { + s = !1, i && i.finaldx && (i.finaldx = 0, r.progress_changed(), r.set_action_completed(), r = null, i = null, n = null); + }); + } + get_all_dependent_tasks(t) { + let e = [], s = [t]; + for (; s.length; ) { + const r = s.reduce((i, n) => (i = i.concat(this.dependency_map[n]), i), []); + e = e.concat(r), s = r.filter((i) => !s.includes(i)); + } + return e.filter(Boolean); + } + get_snap_position(t) { + let e = t, s, r; + return this.view_is(d.WEEK) ? (s = t % (this.options.column_width / 7), r = e - s + (s < this.options.column_width / 14 ? 0 : this.options.column_width / 7)) : this.view_is(d.MONTH) ? (s = t % (this.options.column_width / 30), r = e - s + (s < this.options.column_width / 60 ? 0 : this.options.column_width / 30)) : (s = t % this.options.column_width, r = e - s + (s < this.options.column_width / 2 ? 0 : this.options.column_width)), r; + } + unselect_all() { + [...this.$svg.querySelectorAll(".bar-wrapper")].forEach((t) => { + t.classList.remove("active"); + }), this.popup && this.popup.parent.classList.remove("hidden"); + } + view_is(t) { + return typeof t == "string" ? this.options.view_mode === t : Array.isArray(t) ? t.some((e) => this.options.view_mode === e) : !1; + } + get_task(t) { + return this.tasks.find((e) => e.id === t); + } + get_bar(t) { + return this.bars.find((e) => e.task.id === t); + } + show_popup(t) { + this.options.popup !== !1 && (this.popup || (this.popup = new R(this.$popup_wrapper, this.options.popup)), this.popup.show(t)); + } + hide_popup() { + this.popup && this.popup.hide(); + } + trigger_event(t, e) { + this.options["on_" + t] && this.options["on_" + t].apply(null, e); + } + /** + * Gets the oldest starting date from the list of tasks + * + * @returns Date + * @memberof Gantt + */ + get_oldest_starting_date() { + return this.tasks.length ? this.tasks.map((t) => t._start).reduce( + (t, e) => e <= t ? e : t + ) : /* @__PURE__ */ new Date(); + } + /** + * Clear all elements from the parent svg element + * + * @memberof Gantt + */ + clear() { + var t, e, s, r, i, n; + this.$svg.innerHTML = "", (e = (t = this.$header) == null ? void 0 : t.remove) == null || e.call(t), (r = (s = this.$current_highlight) == null ? void 0 : s.remove) == null || r.call(s), (n = (i = this.popup) == null ? void 0 : i.hide) == null || n.call(i); + } +} +q.VIEW_MODE = d; +function z(o) { + return o.name + "_" + Math.random().toString(36).slice(2, 12); +} +export { + q as default +}; diff --git a/dist/frappe-gantt.js.map b/dist/frappe-gantt.js.map deleted file mode 100644 index 7905c47..0000000 --- a/dist/frappe-gantt.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"frappe-gantt.js","sources":["../src/date_utils.js","../src/svg_utils.js","../src/bar.js","../src/arrow.js","../src/popup.js","../src/index.js"],"sourcesContent":["const YEAR = 'year';\nconst MONTH = 'month';\nconst DAY = 'day';\nconst HOUR = 'hour';\nconst MINUTE = 'minute';\nconst SECOND = 'second';\nconst MILLISECOND = 'millisecond';\n\nconst SHORTENED = {\n January: 'Jan',\n February: 'Feb',\n March: 'Mar',\n April: 'Apr',\n May: 'May',\n June: 'Jun',\n July: 'Jul',\n August: 'Aug',\n September: 'Sep',\n October: 'Oct',\n November: 'Nov',\n December: 'Dec',\n};\n\nexport default {\n parse_duration(duration) {\n const regex = /([0-9])+(y|m|d|h|min|s|ms)/gm;\n const matches = regex.exec(duration);\n\n if (matches !== null) {\n if (matches[2] === 'y') {\n return { duration: parseInt(matches[1]), scale: `year` };\n } else if (matches[2] === 'm') {\n return { duration: parseInt(matches[1]), scale: `month` };\n } else if (matches[2] === 'd') {\n return { duration: parseInt(matches[1]), scale: `day` };\n } else if (matches[2] === 'h') {\n return { duration: parseInt(matches[1]), scale: `hour` };\n } else if (matches[2] === 'min') {\n return { duration: parseInt(matches[1]), scale: `minute` };\n } else if (matches[2] === 's') {\n return { duration: parseInt(matches[1]), scale: `second` };\n } else if (matches[2] === 'ms') {\n return { duration: parseInt(matches[1]), scale: `millisecond` };\n }\n }\n },\n parse(date, date_separator = '-', time_separator = /[.:]/) {\n if (date instanceof Date) {\n return date;\n }\n if (typeof date === 'string') {\n let date_parts, time_parts;\n const parts = date.split(' ');\n date_parts = parts[0]\n .split(date_separator)\n .map((val) => parseInt(val, 10));\n time_parts = parts[1] && parts[1].split(time_separator);\n\n // month is 0 indexed\n date_parts[1] = date_parts[1] ? date_parts[1] - 1 : 0;\n\n let vals = date_parts;\n\n if (time_parts && time_parts.length) {\n if (time_parts.length === 4) {\n time_parts[3] = '0.' + time_parts[3];\n time_parts[3] = parseFloat(time_parts[3]) * 1000;\n }\n vals = vals.concat(time_parts);\n }\n return new Date(...vals);\n }\n },\n\n to_string(date, with_time = false) {\n if (!(date instanceof Date)) {\n throw new TypeError('Invalid argument type');\n }\n const vals = this.get_date_values(date).map((val, i) => {\n if (i === 1) {\n // add 1 for month\n val = val + 1;\n }\n\n if (i === 6) {\n return padStart(val + '', 3, '0');\n }\n\n return padStart(val + '', 2, '0');\n });\n const date_string = `${vals[0]}-${vals[1]}-${vals[2]}`;\n const time_string = `${vals[3]}:${vals[4]}:${vals[5]}.${vals[6]}`;\n\n return date_string + (with_time ? ' ' + time_string : '');\n },\n\n format(date, format_string = 'YYYY-MM-DD HH:mm:ss.SSS', lang = 'en') {\n const dateTimeFormat = new Intl.DateTimeFormat(lang, {\n month: 'long',\n });\n const month_name = dateTimeFormat.format(date);\n const month_name_capitalized =\n month_name.charAt(0).toUpperCase() + month_name.slice(1);\n\n const values = this.get_date_values(date).map((d) => padStart(d, 2, 0));\n const format_map = {\n YYYY: values[0],\n MM: padStart(+values[1] + 1, 2, 0),\n DD: values[2],\n HH: values[3],\n mm: values[4],\n ss: values[5],\n SSS: values[6],\n D: values[2],\n MMMM: month_name_capitalized,\n MMM: SHORTENED[month_name_capitalized],\n };\n\n let str = format_string;\n const formatted_values = [];\n\n Object.keys(format_map)\n .sort((a, b) => b.length - a.length) // big string first\n .forEach((key) => {\n if (str.includes(key)) {\n str = str.replaceAll(key, `$${formatted_values.length}`);\n formatted_values.push(format_map[key]);\n }\n });\n\n formatted_values.forEach((value, i) => {\n str = str.replaceAll(`$${i}`, value);\n });\n\n return str;\n },\n\n diff(date_a, date_b, scale = DAY) {\n let milliseconds, seconds, hours, minutes, days, months, years;\n\n milliseconds = date_a - date_b;\n seconds = milliseconds / 1000;\n minutes = seconds / 60;\n hours = minutes / 60;\n days = hours / 24;\n months = days / 30;\n years = months / 12;\n\n if (!scale.endsWith('s')) {\n scale += 's';\n }\n\n return Math.floor(\n {\n milliseconds,\n seconds,\n minutes,\n hours,\n days,\n months,\n years,\n }[scale],\n );\n },\n\n today() {\n const vals = this.get_date_values(new Date()).slice(0, 3);\n return new Date(...vals);\n },\n\n now() {\n return new Date();\n },\n\n add(date, qty, scale) {\n qty = parseInt(qty, 10);\n const vals = [\n date.getFullYear() + (scale === YEAR ? qty : 0),\n date.getMonth() + (scale === MONTH ? qty : 0),\n date.getDate() + (scale === DAY ? qty : 0),\n date.getHours() + (scale === HOUR ? qty : 0),\n date.getMinutes() + (scale === MINUTE ? qty : 0),\n date.getSeconds() + (scale === SECOND ? qty : 0),\n date.getMilliseconds() + (scale === MILLISECOND ? qty : 0),\n ];\n return new Date(...vals);\n },\n\n start_of(date, scale) {\n const scores = {\n [YEAR]: 6,\n [MONTH]: 5,\n [DAY]: 4,\n [HOUR]: 3,\n [MINUTE]: 2,\n [SECOND]: 1,\n [MILLISECOND]: 0,\n };\n\n function should_reset(_scale) {\n const max_score = scores[scale];\n return scores[_scale] <= max_score;\n }\n\n const vals = [\n date.getFullYear(),\n should_reset(YEAR) ? 0 : date.getMonth(),\n should_reset(MONTH) ? 1 : date.getDate(),\n should_reset(DAY) ? 0 : date.getHours(),\n should_reset(HOUR) ? 0 : date.getMinutes(),\n should_reset(MINUTE) ? 0 : date.getSeconds(),\n should_reset(SECOND) ? 0 : date.getMilliseconds(),\n ];\n\n return new Date(...vals);\n },\n\n clone(date) {\n return new Date(...this.get_date_values(date));\n },\n\n get_date_values(date) {\n return [\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n ];\n },\n\n get_days_in_month(date) {\n const no_of_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n const month = date.getMonth();\n\n if (month !== 1) {\n return no_of_days[month];\n }\n\n // Feb\n const year = date.getFullYear();\n if ((year % 4 === 0 && year % 100 != 0) || year % 400 === 0) {\n return 29;\n }\n return 28;\n },\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart\nfunction padStart(str, targetLength, padString) {\n str = str + '';\n targetLength = targetLength >> 0;\n padString = String(typeof padString !== 'undefined' ? padString : ' ');\n if (str.length > targetLength) {\n return String(str);\n } else {\n targetLength = targetLength - str.length;\n if (targetLength > padString.length) {\n padString += padString.repeat(targetLength / padString.length);\n }\n return padString.slice(0, targetLength) + String(str);\n }\n}\n","export function $(expr, con) {\n return typeof expr === 'string'\n ? (con || document).querySelector(expr)\n : expr || null;\n}\n\nexport function createSVG(tag, attrs) {\n const elem = document.createElementNS('http://www.w3.org/2000/svg', tag);\n for (let attr in attrs) {\n if (attr === 'append_to') {\n const parent = attrs.append_to;\n parent.appendChild(elem);\n } else if (attr === 'innerHTML') {\n elem.innerHTML = attrs.innerHTML;\n } else if (attr === 'clipPath') {\n elem.setAttribute('clip-path', 'url(#' + attrs[attr] + ')');\n } else {\n elem.setAttribute(attr, attrs[attr]);\n }\n }\n return elem;\n}\n\nexport function animateSVG(svgElement, attr, from, to) {\n const animatedSvgElement = getAnimationElement(svgElement, attr, from, to);\n\n if (animatedSvgElement === svgElement) {\n // triggered 2nd time programmatically\n // trigger artificial click event\n const event = document.createEvent('HTMLEvents');\n event.initEvent('click', true, true);\n event.eventName = 'click';\n animatedSvgElement.dispatchEvent(event);\n }\n}\n\nfunction getAnimationElement(\n svgElement,\n attr,\n from,\n to,\n dur = '0.4s',\n begin = '0.1s',\n) {\n const animEl = svgElement.querySelector('animate');\n if (animEl) {\n $.attr(animEl, {\n attributeName: attr,\n from,\n to,\n dur,\n begin: 'click + ' + begin, // artificial click\n });\n return svgElement;\n }\n\n const animateElement = createSVG('animate', {\n attributeName: attr,\n from,\n to,\n dur,\n begin,\n calcMode: 'spline',\n values: from + ';' + to,\n keyTimes: '0; 1',\n keySplines: cubic_bezier('ease-out'),\n });\n svgElement.appendChild(animateElement);\n\n return svgElement;\n}\n\nfunction cubic_bezier(name) {\n return {\n ease: '.25 .1 .25 1',\n linear: '0 0 1 1',\n 'ease-in': '.42 0 1 1',\n 'ease-out': '0 0 .58 1',\n 'ease-in-out': '.42 0 .58 1',\n }[name];\n}\n\n$.on = (element, event, selector, callback) => {\n if (!callback) {\n callback = selector;\n $.bind(element, event, callback);\n } else {\n $.delegate(element, event, selector, callback);\n }\n};\n\n$.off = (element, event, handler) => {\n element.removeEventListener(event, handler);\n};\n\n$.bind = (element, event, callback) => {\n event.split(/\\s+/).forEach(function (event) {\n element.addEventListener(event, callback);\n });\n};\n\n$.delegate = (element, event, selector, callback) => {\n element.addEventListener(event, function (e) {\n const delegatedTarget = e.target.closest(selector);\n if (delegatedTarget) {\n e.delegatedTarget = delegatedTarget;\n callback.call(this, e, delegatedTarget);\n }\n });\n};\n\n$.closest = (selector, element) => {\n if (!element) return null;\n\n if (element.matches(selector)) {\n return element;\n }\n\n return $.closest(selector, element.parentNode);\n};\n\n$.attr = (element, attr, value) => {\n if (!value && typeof attr === 'string') {\n return element.getAttribute(attr);\n }\n\n if (typeof attr === 'object') {\n for (let key in attr) {\n $.attr(element, key, attr[key]);\n }\n return;\n }\n\n element.setAttribute(attr, value);\n};\n","import date_utils from './date_utils';\nimport { $, createSVG, animateSVG } from './svg_utils';\n\nexport default class Bar {\n constructor(gantt, task) {\n this.set_defaults(gantt, task);\n this.prepare();\n this.draw();\n this.bind();\n }\n\n set_defaults(gantt, task) {\n this.action_completed = false;\n this.gantt = gantt;\n this.task = task;\n }\n\n prepare() {\n this.prepare_values();\n this.prepare_helpers();\n }\n\n prepare_values() {\n this.invalid = this.task.invalid;\n this.height = this.gantt.options.bar_height;\n this.image_size = this.height - 5;\n this.compute_x();\n this.compute_y();\n this.compute_duration();\n this.corner_radius = this.gantt.options.bar_corner_radius;\n this.width = this.gantt.options.column_width * this.duration;\n this.progress_width =\n this.gantt.options.column_width *\n this.duration *\n (this.task.progress / 100) || 0;\n this.group = createSVG('g', {\n class:\n 'bar-wrapper' +\n (this.task.custom_class ? ' ' + this.task.custom_class : '') +\n (this.task.important ? ' important' : ''),\n 'data-id': this.task.id,\n });\n this.bar_group = createSVG('g', {\n class: 'bar-group',\n append_to: this.group,\n });\n this.handle_group = createSVG('g', {\n class: 'handle-group',\n append_to: this.group,\n });\n }\n\n prepare_helpers() {\n SVGElement.prototype.getX = function () {\n return +this.getAttribute('x');\n };\n SVGElement.prototype.getY = function () {\n return +this.getAttribute('y');\n };\n SVGElement.prototype.getWidth = function () {\n return +this.getAttribute('width');\n };\n SVGElement.prototype.getHeight = function () {\n return +this.getAttribute('height');\n };\n SVGElement.prototype.getEndX = function () {\n return this.getX() + this.getWidth();\n };\n }\n\n prepare_expected_progress_values() {\n this.compute_expected_progress();\n this.expected_progress_width =\n this.gantt.options.column_width *\n this.duration *\n (this.expected_progress / 100) || 0;\n }\n\n draw() {\n this.draw_bar();\n this.draw_progress_bar();\n if (this.gantt.options.show_expected_progress) {\n this.prepare_expected_progress_values();\n this.draw_expected_progress_bar();\n }\n this.draw_label();\n this.draw_resize_handles();\n\n if (this.task.thumbnail) {\n this.draw_thumbnail();\n }\n }\n\n draw_bar() {\n this.$bar = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar',\n append_to: this.bar_group,\n });\n\n animateSVG(this.$bar, 'width', 0, this.width);\n\n if (this.invalid) {\n this.$bar.classList.add('bar-invalid');\n }\n }\n\n draw_expected_progress_bar() {\n if (this.invalid) return;\n this.$expected_bar_progress = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.expected_progress_width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar-expected-progress',\n append_to: this.bar_group,\n });\n\n animateSVG(\n this.$expected_bar_progress,\n 'width',\n 0,\n this.expected_progress_width,\n );\n }\n\n draw_progress_bar() {\n if (this.invalid) return;\n this.$bar_progress = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.progress_width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar-progress',\n append_to: this.bar_group,\n });\n const x =\n (date_utils.diff(this.task._start, this.gantt.gantt_start, 'hour') /\n this.gantt.options.step) *\n this.gantt.options.column_width;\n\n let $date_highlight = document.createElement('div');\n $date_highlight.id = `${this.task.id}-highlight`;\n $date_highlight.classList.add('date-highlight');\n $date_highlight.style.height = this.height * 0.8 + 'px';\n $date_highlight.style.width = this.width + 'px';\n $date_highlight.style.top =\n this.gantt.options.header_height - 25 + 'px';\n $date_highlight.style.left = x + 'px';\n this.$date_highlight = $date_highlight;\n this.gantt.$lower_header.prepend($date_highlight);\n\n animateSVG(this.$bar_progress, 'width', 0, this.progress_width);\n }\n\n draw_label() {\n let x_coord = this.x + this.$bar.getWidth() / 2;\n\n if (this.task.thumbnail) {\n x_coord = this.x + this.image_size + 5;\n }\n\n createSVG('text', {\n x: x_coord,\n y: this.y + this.height / 2,\n innerHTML: this.task.name,\n class: 'bar-label',\n append_to: this.bar_group,\n });\n // labels get BBox in the next tick\n requestAnimationFrame(() => this.update_label_position());\n }\n draw_thumbnail() {\n let x_offset = 10,\n y_offset = 2;\n let defs, clipPath;\n\n defs = createSVG('defs', {\n append_to: this.bar_group,\n });\n\n createSVG('rect', {\n id: 'rect_' + this.task.id,\n x: this.x + x_offset,\n y: this.y + y_offset,\n width: this.image_size,\n height: this.image_size,\n rx: '15',\n class: 'img_mask',\n append_to: defs,\n });\n\n clipPath = createSVG('clipPath', {\n id: 'clip_' + this.task.id,\n append_to: defs,\n });\n\n createSVG('use', {\n href: '#rect_' + this.task.id,\n append_to: clipPath,\n });\n\n createSVG('image', {\n x: this.x + x_offset,\n y: this.y + y_offset,\n width: this.image_size,\n height: this.image_size,\n class: 'bar-img',\n href: this.task.thumbnail,\n clipPath: 'clip_' + this.task.id,\n append_to: this.bar_group,\n });\n }\n\n draw_resize_handles() {\n if (this.invalid || this.gantt.options.readonly) return;\n\n const bar = this.$bar;\n const handle_width = 8;\n\n createSVG('rect', {\n x: bar.getX() + bar.getWidth() + handle_width - 4,\n y: bar.getY() + 1,\n width: handle_width,\n height: this.height - 2,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'handle right',\n append_to: this.handle_group,\n });\n\n createSVG('rect', {\n x: bar.getX() - handle_width - 4,\n y: bar.getY() + 1,\n width: handle_width,\n height: this.height - 2,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'handle left',\n append_to: this.handle_group,\n });\n\n this.$handle_progress = createSVG('polygon', {\n points: this.get_progress_polygon_points().join(','),\n class: 'handle progress',\n append_to: this.handle_group,\n });\n }\n\n get_progress_polygon_points() {\n const bar_progress = this.$bar_progress;\n let icon_width = 10;\n let icon_height = 15;\n\n return [\n bar_progress.getEndX() - icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n\n bar_progress.getEndX(),\n bar_progress.getY() +\n bar_progress.getHeight() / 2 -\n icon_height / 2,\n\n bar_progress.getEndX() + icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n\n bar_progress.getEndX(),\n bar_progress.getY() +\n bar_progress.getHeight() / 2 +\n icon_height / 2,\n\n bar_progress.getEndX() - icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n ];\n }\n\n bind() {\n if (this.invalid) return;\n this.setup_click_event();\n }\n\n setup_click_event() {\n let task_id = this.task.id;\n $.on(this.group, 'mouseover', (e) => {\n this.gantt.trigger_event('hover', [\n this.task,\n e.screenX,\n e.screenY,\n e,\n ]);\n });\n\n let timeout;\n $.on(\n this.group,\n 'mouseenter',\n (e) =>\n (timeout = setTimeout(() => {\n this.show_popup(e.offsetX);\n document.querySelector(\n `#${task_id}-highlight`,\n ).style.display = 'block';\n }, 200)),\n );\n\n $.on(this.group, 'mouseleave', () => {\n clearTimeout(timeout);\n this.gantt.popup?.hide?.();\n document.querySelector(`#${task_id}-highlight`).style.display =\n 'none';\n });\n\n $.on(this.group, this.gantt.options.popup_trigger, () => {\n this.gantt.trigger_event('click', [this.task]);\n });\n\n $.on(this.group, 'dblclick', (e) => {\n if (this.action_completed) {\n // just finished a move action, wait for a few seconds\n return;\n }\n\n this.gantt.trigger_event('double_click', [this.task]);\n });\n }\n\n show_popup(x) {\n if (this.gantt.bar_being_dragged) return;\n\n const start_date = date_utils.format(\n this.task._start,\n 'MMM D',\n this.gantt.options.language,\n );\n const end_date = date_utils.format(\n date_utils.add(this.task._end, -1, 'second'),\n 'MMM D',\n this.gantt.options.language,\n );\n const subtitle = `${start_date} - ${end_date}
Progress: ${this.task.progress}`;\n\n this.gantt.show_popup({\n x,\n target_element: this.$bar,\n title: this.task.name,\n subtitle: subtitle,\n task: this.task,\n });\n }\n\n update_bar_position({ x = null, width = null }) {\n const bar = this.$bar;\n if (x) {\n // get all x values of parent task\n const xs = this.task.dependencies.map((dep) => {\n return this.gantt.get_bar(dep).$bar.getX();\n });\n // child task must not go before parent\n const valid_x = xs.reduce((_, curr) => {\n return x >= curr;\n }, x);\n if (!valid_x) {\n width = null;\n return;\n }\n this.update_attr(bar, 'x', x);\n this.$date_highlight.style.left = x + 'px';\n }\n if (width) {\n this.update_attr(bar, 'width', width);\n this.$date_highlight.style.width = width + 'px';\n }\n this.update_label_position();\n this.update_handle_position();\n if (this.gantt.options.show_expected_progress) {\n this.date_changed();\n this.compute_duration();\n this.update_expected_progressbar_position();\n }\n this.update_progressbar_position();\n this.update_arrow_position();\n }\n\n update_label_position_on_horizontal_scroll({ x, sx }) {\n const container = document.querySelector('.gantt-container');\n const label = this.group.querySelector('.bar-label');\n const img = this.group.querySelector('.bar-img') || '';\n const img_mask = this.bar_group.querySelector('.img_mask') || '';\n\n let barWidthLimit = this.$bar.getX() + this.$bar.getWidth();\n let newLabelX = label.getX() + x;\n let newImgX = (img && img.getX() + x) || 0;\n let imgWidth = (img && img.getBBox().width + 7) || 7;\n let labelEndX = newLabelX + label.getBBox().width + 7;\n let viewportCentral = sx + container.clientWidth / 2;\n\n if (label.classList.contains('big')) return;\n\n if (labelEndX < barWidthLimit && x > 0 && labelEndX < viewportCentral) {\n label.setAttribute('x', newLabelX);\n if (img) {\n img.setAttribute('x', newImgX);\n img_mask.setAttribute('x', newImgX);\n }\n } else if (\n newLabelX - imgWidth > this.$bar.getX() &&\n x < 0 &&\n labelEndX > viewportCentral\n ) {\n label.setAttribute('x', newLabelX);\n if (img) {\n img.setAttribute('x', newImgX);\n img_mask.setAttribute('x', newImgX);\n }\n }\n }\n\n date_changed() {\n let changed = false;\n const { new_start_date, new_end_date } = this.compute_start_end_date();\n\n if (Number(this.task._start) !== Number(new_start_date)) {\n changed = true;\n this.task._start = new_start_date;\n }\n\n if (Number(this.task._end) !== Number(new_end_date)) {\n changed = true;\n this.task._end = new_end_date;\n }\n\n if (!changed) return;\n\n this.gantt.trigger_event('date_change', [\n this.task,\n new_start_date,\n date_utils.add(new_end_date, -1, 'second'),\n ]);\n }\n\n progress_changed() {\n const new_progress = this.compute_progress();\n this.task.progress = new_progress;\n this.gantt.trigger_event('progress_change', [this.task, new_progress]);\n }\n\n set_action_completed() {\n this.action_completed = true;\n setTimeout(() => (this.action_completed = false), 1000);\n }\n\n compute_start_end_date() {\n const bar = this.$bar;\n const x_in_units = bar.getX() / this.gantt.options.column_width;\n const new_start_date = date_utils.add(\n this.gantt.gantt_start,\n x_in_units * this.gantt.options.step,\n 'hour',\n );\n const width_in_units = bar.getWidth() / this.gantt.options.column_width;\n const new_end_date = date_utils.add(\n new_start_date,\n width_in_units * this.gantt.options.step,\n 'hour',\n );\n\n return { new_start_date, new_end_date };\n }\n\n compute_progress() {\n const progress =\n (this.$bar_progress.getWidth() / this.$bar.getWidth()) * 100;\n return parseInt(progress, 10);\n }\n\n compute_expected_progress() {\n this.expected_progress =\n date_utils.diff(date_utils.today(), this.task._start, 'hour') /\n this.gantt.options.step;\n this.expected_progress =\n ((this.expected_progress < this.duration\n ? this.expected_progress\n : this.duration) *\n 100) /\n this.duration;\n }\n\n compute_x() {\n const { step, column_width } = this.gantt.options;\n const task_start = this.task._start;\n const gantt_start = this.gantt.gantt_start;\n\n const diff = date_utils.diff(task_start, gantt_start, 'hour');\n let x = (diff / step) * column_width;\n\n if (this.gantt.view_is('Month')) {\n const diff = date_utils.diff(task_start, gantt_start, 'day');\n x = (diff * column_width) / 30;\n }\n this.x = x;\n }\n\n compute_y() {\n this.y =\n this.gantt.options.header_height +\n this.gantt.options.padding +\n this.task._index * (this.height + this.gantt.options.padding);\n }\n\n compute_duration() {\n this.duration =\n date_utils.diff(this.task._end, this.task._start, 'hour') /\n this.gantt.options.step;\n }\n\n get_snap_position(dx) {\n let odx = dx,\n rem,\n position;\n\n if (this.gantt.view_is('Week')) {\n rem = dx % (this.gantt.options.column_width / 7);\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 14\n ? 0\n : this.gantt.options.column_width / 7);\n } else if (this.gantt.view_is('Month')) {\n rem = dx % (this.gantt.options.column_width / 30);\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 60\n ? 0\n : this.gantt.options.column_width / 30);\n } else {\n rem = dx % this.gantt.options.column_width;\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 2\n ? 0\n : this.gantt.options.column_width);\n }\n return position;\n }\n\n update_attr(element, attr, value) {\n value = +value;\n if (!isNaN(value)) {\n element.setAttribute(attr, value);\n }\n return element;\n }\n\n update_expected_progressbar_position() {\n if (this.invalid) return;\n this.$expected_bar_progress.setAttribute('x', this.$bar.getX());\n this.compute_expected_progress();\n this.$expected_bar_progress.setAttribute(\n 'width',\n this.gantt.options.column_width *\n this.duration *\n (this.expected_progress / 100) || 0,\n );\n }\n\n update_progressbar_position() {\n if (this.invalid || this.gantt.options.readonly) return;\n this.$bar_progress.setAttribute('x', this.$bar.getX());\n this.$bar_progress.setAttribute(\n 'width',\n this.$bar.getWidth() * (this.task.progress / 100),\n );\n }\n\n update_label_position() {\n const img_mask = this.bar_group.querySelector('.img_mask') || '';\n const bar = this.$bar,\n label = this.group.querySelector('.bar-label'),\n img = this.group.querySelector('.bar-img');\n\n let padding = 5;\n let x_offset_label_img = this.image_size + 10;\n const labelWidth = label.getBBox().width;\n const barWidth = bar.getWidth();\n if (labelWidth > barWidth) {\n label.classList.add('big');\n if (img) {\n img.setAttribute('x', bar.getX() + bar.getWidth() + padding);\n img_mask.setAttribute(\n 'x',\n bar.getX() + bar.getWidth() + padding,\n );\n label.setAttribute(\n 'x',\n bar.getX() + bar.getWidth() + x_offset_label_img,\n );\n } else {\n label.setAttribute('x', bar.getX() + bar.getWidth() + padding);\n }\n } else {\n label.classList.remove('big');\n if (img) {\n img.setAttribute('x', bar.getX() + padding);\n img_mask.setAttribute('x', bar.getX() + padding);\n label.setAttribute(\n 'x',\n bar.getX() + barWidth / 2 + x_offset_label_img,\n );\n } else {\n label.setAttribute(\n 'x',\n bar.getX() + barWidth / 2 - labelWidth / 2,\n );\n }\n }\n }\n\n update_handle_position() {\n if (this.invalid || this.gantt.options.readonly) return;\n const bar = this.$bar;\n this.handle_group\n .querySelector('.handle.left')\n .setAttribute('x', bar.getX() - 12);\n this.handle_group\n .querySelector('.handle.right')\n .setAttribute('x', bar.getEndX() + 4);\n const handle = this.group.querySelector('.handle.progress');\n handle &&\n handle.setAttribute('points', this.get_progress_polygon_points());\n }\n\n update_arrow_position() {\n this.arrows = this.arrows || [];\n for (let arrow of this.arrows) {\n arrow.update();\n }\n }\n}\n\nfunction isFunction(functionToCheck) {\n let getType = {};\n return (\n functionToCheck &&\n getType.toString.call(functionToCheck) === '[object Function]'\n );\n}\n","import { createSVG } from './svg_utils';\n\nexport default class Arrow {\n constructor(gantt, from_task, to_task) {\n this.gantt = gantt;\n this.from_task = from_task;\n this.to_task = to_task;\n\n this.calculate_path();\n this.draw();\n }\n\n calculate_path() {\n let start_x =\n this.from_task.$bar.getX() + this.from_task.$bar.getWidth() / 2;\n\n const condition = () =>\n this.to_task.$bar.getX() < start_x + this.gantt.options.padding &&\n start_x > this.from_task.$bar.getX() + this.gantt.options.padding;\n\n while (condition()) {\n start_x -= 10;\n }\n\n const start_y =\n this.gantt.options.header_height +\n this.gantt.options.bar_height +\n (this.gantt.options.padding + this.gantt.options.bar_height) *\n this.from_task.task._index +\n this.gantt.options.padding;\n\n const end_x =\n this.to_task.$bar.getX() - this.gantt.options.padding / 2 - 7;\n const end_y =\n this.gantt.options.header_height +\n this.gantt.options.bar_height / 2 +\n (this.gantt.options.padding + this.gantt.options.bar_height) *\n this.to_task.task._index +\n this.gantt.options.padding;\n\n const from_is_below_to =\n this.from_task.task._index > this.to_task.task._index;\n const curve = this.gantt.options.arrow_curve;\n const clockwise = from_is_below_to ? 1 : 0;\n const curve_y = from_is_below_to ? -curve : curve;\n const offset = from_is_below_to\n ? end_y + this.gantt.options.arrow_curve\n : end_y - this.gantt.options.arrow_curve;\n\n this.path = `\n M ${start_x} ${start_y}\n V ${offset}\n a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n L ${end_x} ${end_y}\n m -5 -5\n l 5 5\n l -5 5`;\n\n if (\n this.to_task.$bar.getX() <\n this.from_task.$bar.getX() + this.gantt.options.padding\n ) {\n const down_1 = this.gantt.options.padding / 2 - curve;\n const down_2 =\n this.to_task.$bar.getY() +\n this.to_task.$bar.getHeight() / 2 -\n curve_y;\n const left = this.to_task.$bar.getX() - this.gantt.options.padding;\n\n this.path = `\n M ${start_x} ${start_y}\n v ${down_1}\n a ${curve} ${curve} 0 0 1 -${curve} ${curve}\n H ${left}\n a ${curve} ${curve} 0 0 ${clockwise} -${curve} ${curve_y}\n V ${down_2}\n a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n L ${end_x} ${end_y}\n m -5 -5\n l 5 5\n l -5 5`;\n }\n }\n\n draw() {\n this.element = createSVG('path', {\n d: this.path,\n 'data-from': this.from_task.task.id,\n 'data-to': this.to_task.task.id,\n });\n }\n\n update() {\n this.calculate_path();\n this.element.setAttribute('d', this.path);\n }\n}\n","export default class Popup {\n constructor(parent, custom_html) {\n this.parent = parent;\n this.custom_html = custom_html;\n this.make();\n }\n\n make() {\n this.parent.innerHTML = `\n
\n
\n
\n `;\n\n this.hide();\n\n this.title = this.parent.querySelector('.title');\n this.subtitle = this.parent.querySelector('.subtitle');\n this.pointer = this.parent.querySelector('.pointer');\n }\n\n show(options) {\n if (!options.target_element) {\n throw new Error('target_element is required to show popup');\n }\n const target_element = options.target_element;\n\n if (this.custom_html) {\n let html = this.custom_html(options.task);\n html += '
';\n this.parent.innerHTML = html;\n this.pointer = this.parent.querySelector('.pointer');\n } else {\n // set data\n this.title.innerHTML = options.title;\n this.subtitle.innerHTML = options.subtitle;\n }\n\n // set position\n let position_meta;\n if (target_element instanceof HTMLElement) {\n position_meta = target_element.getBoundingClientRect();\n } else if (target_element instanceof SVGElement) {\n position_meta = options.target_element.getBBox();\n }\n\n this.parent.style.left = options.x - this.parent.clientWidth / 2 + 'px';\n this.parent.style.top =\n position_meta.y + position_meta.height + 10 + 'px';\n\n this.pointer.style.left = this.parent.clientWidth / 2 + 'px';\n this.pointer.style.top = '-15px';\n\n // show\n this.parent.style.opacity = 1;\n }\n\n hide() {\n this.parent.style.opacity = 0;\n this.parent.style.left = 0;\n }\n}\n","import date_utils from './date_utils';\nimport { $, createSVG } from './svg_utils';\nimport Bar from './bar';\nimport Arrow from './arrow';\nimport Popup from './popup';\n\nimport './gantt.scss';\n\nconst VIEW_MODE = {\n HOUR: 'Hour',\n QUARTER_DAY: 'Quarter Day',\n HALF_DAY: 'Half Day',\n DAY: 'Day',\n WEEK: 'Week',\n MONTH: 'Month',\n YEAR: 'Year',\n};\n\nconst VIEW_MODE_PADDING = {\n HOUR: ['7d', '7d'],\n QUARTER_DAY: ['7d', '7d'],\n HALF_DAY: ['7d', '7d'],\n DAY: ['1m', '1m'],\n WEEK: ['1m', '1m'],\n MONTH: ['1m', '1m'],\n YEAR: ['2y', '2y'],\n};\n\nconst DEFAULT_OPTIONS = {\n header_height: 65,\n column_width: 30,\n step: 24,\n view_modes: [...Object.values(VIEW_MODE)],\n bar_height: 30,\n bar_corner_radius: 3,\n arrow_curve: 5,\n padding: 18,\n view_mode: 'Day',\n date_format: 'YYYY-MM-DD',\n popup_trigger: 'click',\n show_expected_progress: false,\n popup: null,\n language: 'en',\n readonly: false,\n highlight_weekend: true,\n scroll_to: 'start',\n lines: 'both',\n auto_move_label: true,\n today_button: true,\n view_mode_select: false,\n};\n\nexport default class Gantt {\n constructor(wrapper, tasks, options) {\n this.setup_wrapper(wrapper);\n this.setup_options(options);\n this.setup_tasks(tasks);\n // initialize with default view mode\n this.change_view_mode();\n this.bind_events();\n }\n\n setup_wrapper(element) {\n let svg_element, wrapper_element;\n\n // CSS Selector is passed\n if (typeof element === 'string') {\n element = document.querySelector(element);\n }\n\n // get the SVGElement\n if (element instanceof HTMLElement) {\n wrapper_element = element;\n svg_element = element.querySelector('svg');\n } else if (element instanceof SVGElement) {\n svg_element = element;\n } else {\n throw new TypeError(\n 'Frappé Gantt only supports usage of a string CSS selector,' +\n \" HTML DOM element or SVG DOM element for the 'element' parameter\",\n );\n }\n\n // svg element\n if (!svg_element) {\n // create it\n this.$svg = createSVG('svg', {\n append_to: wrapper_element,\n class: 'gantt',\n });\n } else {\n this.$svg = svg_element;\n this.$svg.classList.add('gantt');\n }\n\n // wrapper element\n this.$container = document.createElement('div');\n this.$container.classList.add('gantt-container');\n\n const parent_element = this.$svg.parentElement;\n parent_element.appendChild(this.$container);\n this.$container.appendChild(this.$svg);\n\n // popup wrapper\n this.$popup_wrapper = document.createElement('div');\n this.$popup_wrapper.classList.add('popup-wrapper');\n this.$container.appendChild(this.$popup_wrapper);\n }\n\n setup_options(options) {\n this.options = { ...DEFAULT_OPTIONS, ...options };\n if (!options.view_mode_padding) options.view_mode_padding = {};\n for (let [key, value] of Object.entries(options.view_mode_padding)) {\n if (typeof value === 'string') {\n // Configure for single value given\n options.view_mode_padding[key] = [value, value];\n }\n }\n\n this.options.view_mode_padding = {\n ...VIEW_MODE_PADDING,\n ...options.view_mode_padding,\n };\n }\n\n setup_tasks(tasks) {\n // prepare tasks\n this.tasks = tasks.map((task, i) => {\n // convert to Date objects\n task._start = date_utils.parse(task.start);\n if (task.end === undefined && task.duration !== undefined) {\n task.end = task._start;\n let durations = task.duration.split(' ');\n\n durations.forEach((tmpDuration) => {\n let { duration, scale } =\n date_utils.parse_duration(tmpDuration);\n task.end = date_utils.add(task.end, duration, scale);\n });\n }\n task._end = date_utils.parse(task.end);\n let diff = date_utils.diff(task._end, task._start, 'year');\n if (diff < 0) {\n throw Error(\n \"start of task can't be after end of task: in task #, \" +\n (i + 1),\n );\n }\n // make task invalid if duration too large\n if (date_utils.diff(task._end, task._start, 'year') > 10) {\n task.end = null;\n }\n\n // cache index\n task._index = i;\n\n // invalid dates\n if (!task.start && !task.end) {\n const today = date_utils.today();\n task._start = today;\n task._end = date_utils.add(today, 2, 'day');\n }\n\n if (!task.start && task.end) {\n task._start = date_utils.add(task._end, -2, 'day');\n }\n\n if (task.start && !task.end) {\n task._end = date_utils.add(task._start, 2, 'day');\n }\n\n // if hours is not set, assume the last day is full day\n // e.g: 2018-09-09 becomes 2018-09-09 23:59:59\n const task_end_values = date_utils.get_date_values(task._end);\n if (task_end_values.slice(3).every((d) => d === 0)) {\n task._end = date_utils.add(task._end, 24, 'hour');\n }\n\n // invalid flag\n if (!task.start || !task.end) {\n task.invalid = true;\n }\n\n // dependencies\n if (typeof task.dependencies === 'string' || !task.dependencies) {\n let deps = [];\n if (task.dependencies) {\n deps = task.dependencies\n .split(',')\n .map((d) => d.trim().replaceAll(' ', '_'))\n .filter((d) => d);\n }\n task.dependencies = deps;\n }\n\n // uids\n if (!task.id) {\n task.id = generate_id(task);\n } else if (typeof task.id === 'string') {\n task.id = task.id.replaceAll(' ', '_');\n } else {\n task.id = `${task.id}`;\n }\n\n return task;\n });\n\n this.setup_dependencies();\n }\n\n setup_dependencies() {\n this.dependency_map = {};\n for (let t of this.tasks) {\n for (let d of t.dependencies) {\n this.dependency_map[d] = this.dependency_map[d] || [];\n this.dependency_map[d].push(t.id);\n }\n }\n }\n\n refresh(tasks) {\n this.setup_tasks(tasks);\n this.change_view_mode();\n }\n\n change_view_mode(mode = this.options.view_mode) {\n this.update_view_scale(mode);\n this.setup_dates();\n this.render();\n // fire viewmode_change event\n this.trigger_event('view_change', [mode]);\n }\n\n update_view_scale(view_mode) {\n this.options.view_mode = view_mode;\n if (view_mode === VIEW_MODE.HOUR) {\n this.options.step = 24 / 24;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.DAY) {\n this.options.step = 24;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.HALF_DAY) {\n this.options.step = 24 / 2;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.QUARTER_DAY) {\n this.options.step = 24 / 4;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.WEEK) {\n this.options.step = 24 * 7;\n this.options.column_width = 140;\n } else if (view_mode === VIEW_MODE.MONTH) {\n this.options.step = 24 * 30;\n this.options.column_width = 120;\n } else if (view_mode === VIEW_MODE.YEAR) {\n this.options.step = 24 * 365;\n this.options.column_width = 120;\n }\n }\n\n setup_dates() {\n this.setup_gantt_dates();\n this.setup_date_values();\n }\n\n setup_gantt_dates() {\n this.gantt_start = this.gantt_end = null;\n\n for (let task of this.tasks) {\n // set global start and end date\n if (!this.gantt_start || task._start < this.gantt_start) {\n this.gantt_start = task._start;\n }\n if (!this.gantt_end || task._end > this.gantt_end) {\n this.gantt_end = task._end;\n }\n }\n let gantt_start, gantt_end;\n if (!this.gantt_start) gantt_start = new Date();\n else gantt_start = date_utils.start_of(this.gantt_start, 'day');\n if (!this.gantt_end) gantt_end = new Date();\n else gantt_end = date_utils.start_of(this.gantt_end, 'day');\n\n // add date padding on both sides\n let viewKey;\n for (let [key, value] of Object.entries(VIEW_MODE)) {\n if (value === this.options.view_mode) {\n viewKey = key;\n }\n }\n const [padding_start, padding_end] = this.options.view_mode_padding[\n viewKey\n ].map(date_utils.parse_duration);\n gantt_start = date_utils.add(\n gantt_start,\n -padding_start.duration,\n padding_start.scale,\n );\n\n let format_string;\n if (this.view_is(VIEW_MODE.YEAR)) {\n format_string = 'YYYY';\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n format_string = 'YYYY-MM';\n } else if (this.view_is(VIEW_MODE.DAY)) {\n format_string = 'YYYY-MM-DD';\n } else {\n format_string = 'YYYY-MM-DD HH';\n }\n this.gantt_start = date_utils.parse(\n date_utils.format(gantt_start, format_string),\n );\n this.gantt_start.setHours(0, 0, 0, 0);\n this.gantt_end = date_utils.add(\n gantt_end,\n padding_end.duration,\n padding_end.scale,\n );\n }\n\n setup_date_values() {\n this.dates = [];\n let cur_date = null;\n\n while (cur_date === null || cur_date < this.gantt_end) {\n if (!cur_date) {\n cur_date = date_utils.clone(this.gantt_start);\n } else {\n if (this.view_is(VIEW_MODE.YEAR)) {\n cur_date = date_utils.add(cur_date, 1, 'year');\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n cur_date = date_utils.add(cur_date, 1, 'month');\n } else {\n cur_date = date_utils.add(\n cur_date,\n this.options.step,\n 'hour',\n );\n }\n }\n this.dates.push(cur_date);\n }\n }\n\n bind_events() {\n if (this.options.readonly) return;\n this.bind_grid_click();\n this.bind_bar_events();\n }\n\n render() {\n this.clear();\n this.setup_layers();\n this.make_grid();\n this.make_dates();\n this.make_bars();\n this.make_grid_extras();\n this.make_arrows();\n this.map_arrows_on_bars();\n this.set_width();\n this.set_scroll_position(this.options.scroll_to);\n }\n\n setup_layers() {\n this.layers = {};\n const layers = ['grid', 'arrow', 'progress', 'bar', 'details'];\n // make group layers\n for (let layer of layers) {\n this.layers[layer] = createSVG('g', {\n class: layer,\n append_to: this.$svg,\n });\n }\n }\n\n make_grid() {\n this.make_grid_background();\n this.make_grid_rows();\n this.make_grid_header();\n }\n\n make_grid_extras() {\n this.make_grid_highlights();\n this.make_grid_ticks();\n }\n\n make_grid_background() {\n const grid_width = this.dates.length * this.options.column_width;\n const grid_height =\n this.options.header_height +\n this.options.padding +\n (this.options.bar_height + this.options.padding) *\n this.tasks.length;\n\n createSVG('rect', {\n x: 0,\n y: 0,\n width: grid_width,\n height: grid_height,\n class: 'grid-background',\n append_to: this.$svg,\n });\n\n $.attr(this.$svg, {\n height: grid_height + this.options.padding + 100,\n width: '100%',\n });\n }\n\n make_grid_rows() {\n const rows_layer = createSVG('g', { append_to: this.layers.grid });\n\n const row_width = this.dates.length * this.options.column_width;\n const row_height = this.options.bar_height + this.options.padding;\n\n let row_y = this.options.header_height + this.options.padding / 2;\n\n for (let _ of this.tasks) {\n createSVG('rect', {\n x: 0,\n y: row_y,\n width: row_width,\n height: row_height,\n class: 'grid-row',\n append_to: rows_layer,\n });\n if (\n this.options.lines === 'both' ||\n this.options.lines === 'horizontal'\n ) {\n }\n\n row_y += this.options.bar_height + this.options.padding;\n }\n }\n\n make_grid_header() {\n const curHeader = document.querySelector('.grid-header');\n\n let $header = document.createElement('div');\n $header.style.height = this.options.header_height + 10 + 'px';\n $header.style.width =\n this.dates.length * this.options.column_width + 'px';\n $header.classList.add('grid-header');\n this.$header = $header;\n this.$container.appendChild($header);\n\n let $upper_header = document.createElement('div');\n $upper_header.classList.add('upper-header');\n this.$upper_header = $upper_header;\n this.$header.appendChild($upper_header);\n\n let $lower_header = document.createElement('div');\n $lower_header.classList.add('lower-header');\n this.$lower_header = $lower_header;\n this.$header.appendChild($lower_header);\n\n this.make_side_header();\n }\n\n make_side_header() {\n let $side_header = document.createElement('div');\n $side_header.classList.add('side-header');\n\n // Create view mode change select\n if (this.options.view_mode_select) {\n const $select = document.createElement('select');\n $select.classList.add('viewmode-select');\n\n const $el = document.createElement('option');\n $el.selected = true;\n $el.disabled = true;\n $el.textContent = 'Mode';\n $select.appendChild($el);\n\n for (const key in VIEW_MODE) {\n const $option = document.createElement('option');\n $option.value = VIEW_MODE[key];\n $option.textContent = VIEW_MODE[key];\n $select.appendChild($option);\n }\n // $select.value = this.options.view_mode\n $select.addEventListener(\n 'change',\n function () {\n this.change_view_mode($select.value);\n }.bind(this),\n );\n $side_header.appendChild($select);\n }\n\n // Create today button\n if (this.options.today_button) {\n let $today_button = document.createElement('button');\n $today_button.classList.add('today-button');\n $today_button.textContent = 'Today';\n $today_button.onclick = this.scroll_today.bind(this);\n $side_header.appendChild($today_button);\n }\n\n this.$header.appendChild($side_header);\n const { left, y } = this.$header.getBoundingClientRect();\n const width = Math.min(\n this.$header.clientWidth,\n this.$container.clientWidth,\n );\n $side_header.style.left =\n left +\n this.$container.scrollLeft +\n width -\n $side_header.clientWidth +\n 'px';\n $side_header.style.top = y + 10 + 'px';\n }\n\n make_grid_ticks() {\n if (!['both', 'vertical', 'horizontal'].includes(this.options.lines))\n return;\n let tick_x = 0;\n let tick_y = this.options.header_height + this.options.padding / 2;\n let tick_height =\n (this.options.bar_height + this.options.padding) *\n this.tasks.length;\n\n let $lines_layer = createSVG('g', {\n class: 'lines_layer',\n append_to: this.layers.grid,\n });\n\n let row_y = this.options.header_height + this.options.padding / 2;\n\n const row_width = this.dates.length * this.options.column_width;\n const row_height = this.options.bar_height + this.options.padding;\n if (this.options.lines !== 'vertical') {\n for (let _ of this.tasks) {\n createSVG('line', {\n x1: 0,\n y1: row_y + row_height,\n x2: row_width,\n y2: row_y + row_height,\n class: 'row-line',\n append_to: $lines_layer,\n });\n row_y += row_height;\n }\n }\n if (this.options.lines === 'horizontal') return;\n for (let date of this.dates) {\n let tick_class = 'tick';\n // thick tick for monday\n if (this.view_is(VIEW_MODE.DAY) && date.getDate() === 1) {\n tick_class += ' thick';\n }\n // thick tick for first week\n if (\n this.view_is(VIEW_MODE.WEEK) &&\n date.getDate() >= 1 &&\n date.getDate() < 8\n ) {\n tick_class += ' thick';\n }\n // thick ticks for quarters\n if (this.view_is(VIEW_MODE.MONTH) && date.getMonth() % 3 === 0) {\n tick_class += ' thick';\n }\n\n createSVG('path', {\n d: `M ${tick_x} ${tick_y} v ${tick_height}`,\n class: tick_class,\n append_to: this.layers.grid,\n });\n\n if (this.view_is(VIEW_MODE.MONTH)) {\n tick_x +=\n (date_utils.get_days_in_month(date) *\n this.options.column_width) /\n 30;\n } else {\n tick_x += this.options.column_width;\n }\n }\n }\n\n highlightWeekends() {\n if (!this.view_is('Day') && !this.view_is('Half Day')) return;\n for (\n let d = new Date(this.gantt_start);\n d <= this.gantt_end;\n d.setDate(d.getDate() + 1)\n ) {\n if (d.getDay() === 0 || d.getDay() === 6) {\n const x =\n (date_utils.diff(d, this.gantt_start, 'hour') /\n this.options.step) *\n this.options.column_width;\n const height =\n (this.options.bar_height + this.options.padding) *\n this.tasks.length;\n createSVG('rect', {\n x,\n y: this.options.header_height + this.options.padding / 2,\n width:\n (this.view_is('Day') ? 1 : 2) *\n this.options.column_width,\n height,\n class: 'holiday-highlight',\n append_to: this.layers.grid,\n });\n }\n }\n }\n\n //compute the horizontal x distance\n computeGridHighlightDimensions(view_mode) {\n let x = this.options.column_width / 2;\n\n if (this.view_is(VIEW_MODE.DAY)) {\n let today = date_utils.today();\n return {\n x:\n x +\n (date_utils.diff(today, this.gantt_start, 'hour') /\n this.options.step) *\n this.options.column_width,\n date: today,\n };\n }\n\n for (let date of this.dates) {\n const todayDate = new Date();\n const startDate = new Date(date);\n const endDate = new Date(date);\n switch (view_mode) {\n case VIEW_MODE.WEEK:\n endDate.setDate(date.getDate() + 7);\n break;\n case VIEW_MODE.MONTH:\n endDate.setMonth(date.getMonth() + 1);\n break;\n case VIEW_MODE.YEAR:\n endDate.setFullYear(date.getFullYear() + 1);\n break;\n }\n if (todayDate >= startDate && todayDate <= endDate) {\n return { x, date: startDate };\n } else {\n x += this.options.column_width;\n }\n }\n }\n\n make_grid_highlights() {\n if (this.options.highlight_weekend) this.highlightWeekends();\n // highlight today's | week's | month's | year's\n if (\n this.view_is(VIEW_MODE.DAY) ||\n this.view_is(VIEW_MODE.WEEK) ||\n this.view_is(VIEW_MODE.MONTH) ||\n this.view_is(VIEW_MODE.YEAR)\n ) {\n // Used as we must find the _end_ of session if view is not Day\n const { x: left, date } = this.computeGridHighlightDimensions(\n this.options.view_mode,\n );\n const top = this.options.header_height + this.options.padding / 2;\n const height =\n (this.options.bar_height + this.options.padding) *\n this.tasks.length;\n this.$current_highlight = this.create_el({\n top,\n left,\n height,\n classes: 'current-highlight',\n append_to: this.$container,\n });\n let $today = document.getElementById(\n date_utils.format(date).replaceAll(' ', '_'),\n );\n\n $today.classList.add('current-date-highlight');\n $today.style.top = +$today.style.top.slice(0, -2) - 4 + 'px';\n $today.style.left = +$today.style.left.slice(0, -2) - 8 + 'px';\n }\n }\n\n create_el({ left, top, width, height, id, classes, append_to }) {\n let $el = document.createElement('div');\n $el.classList.add(classes);\n $el.style.top = top + 'px';\n $el.style.left = left + 'px';\n if (id) $el.id = id;\n if (width) $el.style.width = height + 'px';\n if (height) $el.style.height = height + 'px';\n append_to.appendChild($el);\n return $el;\n }\n\n make_dates() {\n this.upper_texts_x = {};\n this.get_dates_to_draw().forEach((date, i) => {\n let $lower_text = this.create_el({\n left: date.lower_x,\n top: date.lower_y,\n id: date.formatted_date,\n classes: 'lower-text',\n append_to: this.$lower_header,\n });\n $lower_text.innerText = date.lower_text;\n $lower_text.style.left =\n +$lower_text.style.left.slice(0, -2) -\n $lower_text.clientWidth / 2 +\n 'px';\n\n if (date.upper_text) {\n this.upper_texts_x[date.upper_text] = date.upper_x;\n let $upper_text = document.createElement('div');\n $upper_text.classList.add('upper-text');\n $upper_text.style.left = date.upper_x + 'px';\n $upper_text.style.top = date.upper_y + 'px';\n $upper_text.innerText = date.upper_text;\n this.$upper_header.appendChild($upper_text);\n\n // remove out-of-bound dates\n if (date.upper_x > this.layers.grid.getBBox().width) {\n $upper_text.remove();\n }\n }\n });\n }\n\n get_dates_to_draw() {\n let last_date = null;\n const dates = this.dates.map((date, i) => {\n const d = this.get_date_info(date, last_date, i);\n last_date = d;\n return d;\n });\n return dates;\n }\n\n get_date_info(date, last_date_info) {\n let last_date = last_date_info\n ? last_date_info.date\n : date_utils.add(date, 1, 'day');\n const date_text = {\n Hour_lower: date_utils.format(date, 'HH', this.options.language),\n 'Quarter Day_lower': date_utils.format(\n date,\n 'HH',\n this.options.language,\n ),\n 'Half Day_lower': date_utils.format(\n date,\n 'HH',\n this.options.language,\n ),\n Day_lower:\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, 'D', this.options.language)\n : '',\n Week_lower:\n date.getMonth() !== last_date.getMonth()\n ? date_utils.format(date, 'D MMM', this.options.language)\n : date_utils.format(date, 'D', this.options.language),\n Month_lower: date_utils.format(date, 'MMMM', this.options.language),\n Year_lower: date_utils.format(date, 'YYYY', this.options.language),\n Hour_upper:\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, 'D MMMM', this.options.language)\n : '',\n 'Quarter Day_upper':\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, 'D MMM', this.options.language)\n : '',\n 'Half Day_upper':\n date.getDate() !== last_date.getDate()\n ? date.getMonth() !== last_date.getMonth()\n ? date_utils.format(\n date,\n 'D MMM',\n this.options.language,\n )\n : date_utils.format(date, 'D', this.options.language)\n : '',\n Day_upper:\n date.getMonth() !== last_date.getMonth() || !last_date_info\n ? date_utils.format(date, 'MMMM', this.options.language)\n : '',\n Week_upper:\n date.getMonth() !== last_date.getMonth()\n ? date_utils.format(date, 'MMMM', this.options.language)\n : '',\n Month_upper:\n date.getFullYear() !== last_date.getFullYear()\n ? date_utils.format(date, 'YYYY', this.options.language)\n : '',\n Year_upper:\n date.getFullYear() !== last_date.getFullYear()\n ? date_utils.format(date, 'YYYY', this.options.language)\n : '',\n };\n let column_width = this.view_is(VIEW_MODE.MONTH)\n ? (date_utils.get_days_in_month(date) * this.options.column_width) /\n 30\n : this.options.column_width;\n const base_pos = {\n x: last_date_info\n ? last_date_info.base_pos_x + last_date_info.column_width\n : 0,\n lower_y: this.options.header_height - 20,\n upper_y: this.options.header_height - 50,\n };\n const x_pos = {\n Hour_lower: column_width / 2,\n Hour_upper: column_width * 12,\n 'Quarter Day_lower': column_width / 2,\n 'Quarter Day_upper': column_width * 2,\n 'Half Day_lower': column_width / 2,\n 'Half Day_upper': column_width,\n Day_lower: column_width / 2,\n Day_upper: column_width / 2,\n Week_lower: column_width / 2,\n Week_upper: (column_width * 4) / 2,\n Month_lower: column_width / 2,\n Month_upper: column_width / 2,\n Year_lower: column_width / 2,\n Year_upper: (column_width * 30) / 2,\n };\n return {\n date,\n formatted_date: date_utils.format(date).replaceAll(' ', '_'),\n column_width,\n base_pos_x: base_pos.x,\n upper_text: this.options.lower_text\n ? this.options.upper_text(\n date,\n this.options.view_mode,\n date_text[`${this.options.view_mode}_upper`],\n )\n : date_text[`${this.options.view_mode}_upper`],\n lower_text: this.options.lower_text\n ? this.options.lower_text(\n date,\n this.options.view_mode,\n date_text[`${this.options.view_mode}_lower`],\n )\n : date_text[`${this.options.view_mode}_lower`],\n upper_x: base_pos.x + x_pos[`${this.options.view_mode}_upper`],\n upper_y: base_pos.upper_y,\n lower_x: base_pos.x + x_pos[`${this.options.view_mode}_lower`],\n lower_y: base_pos.lower_y,\n };\n }\n\n make_bars() {\n this.bars = this.tasks.map((task) => {\n const bar = new Bar(this, task);\n this.layers.bar.appendChild(bar.group);\n return bar;\n });\n }\n\n make_arrows() {\n this.arrows = [];\n for (let task of this.tasks) {\n let arrows = [];\n arrows = task.dependencies\n .map((task_id) => {\n const dependency = this.get_task(task_id);\n if (!dependency) return;\n const arrow = new Arrow(\n this,\n this.bars[dependency._index], // from_task\n this.bars[task._index], // to_task\n );\n this.layers.arrow.appendChild(arrow.element);\n return arrow;\n })\n .filter(Boolean); // filter falsy values\n this.arrows = this.arrows.concat(arrows);\n }\n }\n\n map_arrows_on_bars() {\n for (let bar of this.bars) {\n bar.arrows = this.arrows.filter((arrow) => {\n return (\n arrow.from_task.task.id === bar.task.id ||\n arrow.to_task.task.id === bar.task.id\n );\n });\n }\n }\n\n set_width() {\n const cur_width = this.$svg.getBoundingClientRect().width;\n const actual_width = this.$svg.querySelector('.grid .grid-row')\n ? this.$svg.querySelector('.grid .grid-row').getAttribute('width')\n : 0;\n if (cur_width < actual_width) {\n this.$svg.setAttribute('width', actual_width);\n }\n }\n\n set_scroll_position(date) {\n if (!date || date === 'start') {\n date = this.gantt_start;\n } else if (date === 'today') {\n return this.scroll_today();\n } else if (typeof date === 'string') {\n date = date_utils.parse(date);\n }\n\n const parent_element = this.$svg.parentElement;\n if (!parent_element) return;\n\n const hours_before_first_task =\n date_utils.diff(date, this.gantt_start, 'hour') + 24;\n\n const scroll_pos =\n (hours_before_first_task / this.options.step) *\n this.options.column_width -\n this.options.column_width;\n parent_element.scrollTo({ left: scroll_pos, behavior: 'smooth' });\n }\n\n scroll_today() {\n this.set_scroll_position(new Date());\n }\n\n bind_grid_click() {\n $.on(\n this.$svg,\n this.options.popup_trigger,\n '.grid-row, .grid-header',\n () => {\n this.unselect_all();\n this.hide_popup();\n },\n );\n }\n\n bind_bar_events() {\n let is_dragging = false;\n let x_on_start = 0;\n let x_on_scroll_start = 0;\n let y_on_start = 0;\n let is_resizing_left = false;\n let is_resizing_right = false;\n let parent_bar_id = null;\n let bars = []; // instanceof Bar\n this.bar_being_dragged = null;\n\n function action_in_progress() {\n return is_dragging || is_resizing_left || is_resizing_right;\n }\n\n $.on(this.$svg, 'mousedown', '.bar-wrapper, .handle', (e, element) => {\n const bar_wrapper = $.closest('.bar-wrapper', element);\n bars.forEach((bar) => bar.group.classList.remove('active'));\n\n if (element.classList.contains('left')) {\n is_resizing_left = true;\n } else if (element.classList.contains('right')) {\n is_resizing_right = true;\n } else if (element.classList.contains('bar-wrapper')) {\n is_dragging = true;\n }\n\n bar_wrapper.classList.add('active');\n this.popup.parent.classList.add('hidden');\n\n x_on_start = e.offsetX;\n y_on_start = e.offsetY;\n\n parent_bar_id = bar_wrapper.getAttribute('data-id');\n const ids = [\n parent_bar_id,\n ...this.get_all_dependent_tasks(parent_bar_id),\n ];\n bars = ids.map((id) => this.get_bar(id));\n\n this.bar_being_dragged = parent_bar_id;\n\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n $bar.ox = $bar.getX();\n $bar.oy = $bar.getY();\n $bar.owidth = $bar.getWidth();\n $bar.finaldx = 0;\n });\n });\n $.on(this.$container, 'scroll', (e) => {\n let elements = document.querySelectorAll('.bar-wrapper');\n let localBars = [];\n const ids = [];\n let dx;\n if (x_on_scroll_start) {\n dx = e.currentTarget.scrollLeft - x_on_scroll_start;\n }\n\n const daysSinceStart =\n ((e.currentTarget.scrollLeft / this.options.column_width) *\n this.options.step) /\n 24;\n let format_str = 'D MMM';\n if (['Year', 'Month'].includes(this.options.view_mode))\n format_str = 'YYYY';\n else if (['Day', 'Week'].includes(this.options.view_mode))\n format_str = 'MMMM';\n else if (this.view_is('Half Day')) format_str = 'D';\n else if (this.view_is('Hour')) format_str = 'D MMMM';\n\n let currentUpper = date_utils.format(\n date_utils.add(this.gantt_start, daysSinceStart, 'day'),\n format_str,\n );\n const upperTexts = Array.from(\n document.querySelectorAll('.upper-text'),\n );\n const $el = upperTexts.find(\n (el) => el.textContent === currentUpper,\n );\n if ($el && !$el.classList.contains('current-upper')) {\n const $current = document.querySelector('.current-upper');\n if ($current) {\n $current.classList.remove('current-upper');\n $current.style.left =\n this.upper_texts_x[$current.textContent] + 'px';\n $current.style.top = this.options.header_height - 50 + 'px';\n }\n\n $el.classList.add('current-upper');\n let dimensions = this.$svg.getBoundingClientRect();\n $el.style.left =\n dimensions.x + this.$container.scrollLeft + 10 + 'px';\n $el.style.top =\n dimensions.y + this.options.header_height - 50 + 'px';\n }\n\n Array.prototype.forEach.call(elements, function (el, i) {\n ids.push(el.getAttribute('data-id'));\n });\n\n if (dx) {\n localBars = ids.map((id) => this.get_bar(id));\n if (this.options.auto_move_label) {\n localBars.forEach((bar) => {\n bar.update_label_position_on_horizontal_scroll({\n x: dx,\n sx: e.currentTarget.scrollLeft,\n });\n });\n }\n }\n\n x_on_scroll_start = e.currentTarget.scrollLeft;\n });\n\n $.on(this.$svg, 'mousemove', (e) => {\n if (!action_in_progress()) return;\n const dx = e.offsetX - x_on_start;\n const dy = e.offsetY - y_on_start;\n\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n $bar.finaldx = this.get_snap_position(dx);\n this.hide_popup();\n if (is_resizing_left) {\n if (parent_bar_id === bar.task.id) {\n bar.update_bar_position({\n x: $bar.ox + $bar.finaldx,\n width: $bar.owidth - $bar.finaldx,\n });\n } else {\n bar.update_bar_position({\n x: $bar.ox + $bar.finaldx,\n });\n }\n } else if (is_resizing_right) {\n if (parent_bar_id === bar.task.id) {\n bar.update_bar_position({\n width: $bar.owidth + $bar.finaldx,\n });\n }\n } else if (is_dragging && !this.options.readonly) {\n bar.update_bar_position({ x: $bar.ox + $bar.finaldx });\n }\n });\n });\n\n document.addEventListener('mouseup', (e) => {\n is_dragging = false;\n is_resizing_left = false;\n is_resizing_right = false;\n });\n\n $.on(this.$svg, 'mouseup', (e) => {\n this.bar_being_dragged = null;\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n if (!$bar.finaldx) return;\n bar.date_changed();\n bar.set_action_completed();\n });\n });\n\n this.bind_bar_progress();\n }\n\n bind_bar_progress() {\n let x_on_start = 0;\n let y_on_start = 0;\n let is_resizing = null;\n let bar = null;\n let $bar_progress = null;\n let $bar = null;\n\n $.on(this.$svg, 'mousedown', '.handle.progress', (e, handle) => {\n is_resizing = true;\n x_on_start = e.offsetX;\n y_on_start = e.offsetY;\n\n const $bar_wrapper = $.closest('.bar-wrapper', handle);\n const id = $bar_wrapper.getAttribute('data-id');\n bar = this.get_bar(id);\n\n $bar_progress = bar.$bar_progress;\n $bar = bar.$bar;\n\n $bar_progress.finaldx = 0;\n $bar_progress.owidth = $bar_progress.getWidth();\n $bar_progress.min_dx = -$bar_progress.getWidth();\n $bar_progress.max_dx = $bar.getWidth() - $bar_progress.getWidth();\n });\n\n $.on(this.$svg, 'mousemove', (e) => {\n if (!is_resizing) return;\n let dx = e.offsetX - x_on_start;\n let dy = e.offsetY - y_on_start;\n\n if (dx > $bar_progress.max_dx) {\n dx = $bar_progress.max_dx;\n }\n if (dx < $bar_progress.min_dx) {\n dx = $bar_progress.min_dx;\n }\n\n const $handle = bar.$handle_progress;\n $.attr($bar_progress, 'width', $bar_progress.owidth + dx);\n $.attr($handle, 'points', bar.get_progress_polygon_points());\n $bar_progress.finaldx = dx;\n });\n\n $.on(this.$svg, 'mouseup', () => {\n is_resizing = false;\n if (!($bar_progress && $bar_progress.finaldx)) return;\n\n $bar_progress.finaldx = 0;\n bar.progress_changed();\n bar.set_action_completed();\n bar = null;\n $bar_progress = null;\n $bar = null;\n });\n }\n\n get_all_dependent_tasks(task_id) {\n let out = [];\n let to_process = [task_id];\n while (to_process.length) {\n const deps = to_process.reduce((acc, curr) => {\n acc = acc.concat(this.dependency_map[curr]);\n return acc;\n }, []);\n\n out = out.concat(deps);\n to_process = deps.filter((d) => !to_process.includes(d));\n }\n\n return out.filter(Boolean);\n }\n\n get_snap_position(dx) {\n let odx = dx,\n rem,\n position;\n\n if (this.view_is(VIEW_MODE.WEEK)) {\n rem = dx % (this.options.column_width / 7);\n position =\n odx -\n rem +\n (rem < this.options.column_width / 14\n ? 0\n : this.options.column_width / 7);\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n rem = dx % (this.options.column_width / 30);\n position =\n odx -\n rem +\n (rem < this.options.column_width / 60\n ? 0\n : this.options.column_width / 30);\n } else {\n rem = dx % this.options.column_width;\n position =\n odx -\n rem +\n (rem < this.options.column_width / 2\n ? 0\n : this.options.column_width);\n }\n return position;\n }\n\n unselect_all() {\n [...this.$svg.querySelectorAll('.bar-wrapper')].forEach((el) => {\n el.classList.remove('active');\n });\n this.popup.parent.classList.remove('hidden');\n }\n\n view_is(modes) {\n if (typeof modes === 'string') {\n return this.options.view_mode === modes;\n }\n\n if (Array.isArray(modes)) {\n return modes.some((mode) => this.options.view_mode === mode);\n }\n\n return false;\n }\n\n get_task(id) {\n return this.tasks.find((task) => {\n return task.id === id;\n });\n }\n\n get_bar(id) {\n return this.bars.find((bar) => {\n return bar.task.id === id;\n });\n }\n\n show_popup(options) {\n if (this.options.popup === false) return;\n if (!this.popup) {\n this.popup = new Popup(this.$popup_wrapper, this.options.popup);\n }\n this.popup.show(options);\n }\n\n hide_popup() {\n this.popup && this.popup.hide();\n }\n\n trigger_event(event, args) {\n if (this.options['on_' + event]) {\n this.options['on_' + event].apply(null, args);\n }\n }\n\n /**\n * Gets the oldest starting date from the list of tasks\n *\n * @returns Date\n * @memberof Gantt\n */\n get_oldest_starting_date() {\n if (!this.tasks.length) return new Date();\n return this.tasks\n .map((task) => task._start)\n .reduce((prev_date, cur_date) =>\n cur_date <= prev_date ? cur_date : prev_date,\n );\n }\n\n /**\n * Clear all elements from the parent svg element\n *\n * @memberof Gantt\n */\n clear() {\n this.$svg.innerHTML = '';\n this.$header?.remove?.();\n this.$current_highlight?.remove?.();\n this.popup?.hide?.();\n }\n}\n\nGantt.VIEW_MODE = VIEW_MODE;\n\nfunction generate_id(task) {\n return task.name + '_' + Math.random().toString(36).slice(2, 12);\n}\n"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/dist/frappe-gantt.min.css b/dist/frappe-gantt.min.css deleted file mode 100644 index 3462f83..0000000 --- a/dist/frappe-gantt.min.css +++ /dev/null @@ -1 +0,0 @@ -.dark>.gantt-container .gantt .grid-header{fill:#252525;stroke:#616161}.dark>.gantt-container .gantt .grid-row{fill:#252525}.dark>.gantt-container .gantt .grid-row:nth-child(even){fill:#3e3e3e}.dark>.gantt-container .gantt .row-line{stroke:#3e3e3e}.dark>.gantt-container .gantt .tick{stroke:#616161}.dark>.gantt-container .gantt .today-highlight{opacity:.2}.dark>.gantt-container .gantt .arrow{stroke:#eee}.dark>.gantt-container .gantt .bar{fill:#616161;stroke:none}.dark>.gantt-container .gantt .bar-progress{fill:#8a8aff}.dark>.gantt-container .gantt .bar-invalid{fill:rgba(0,0,0,0);stroke:#c6ccd2}.dark>.gantt-container .gantt .bar-invalid~.bar-label{fill:#ececec}.dark>.gantt-container .gantt .bar-label.big{fill:#ececec}.dark>.gantt-container .gantt .bar-wrapper:hover .bar{fill:#6e6e6e}.dark>.gantt-container .gantt .bar-wrapper:hover .bar-progress{fill:#a4a4ff}.dark>.gantt-container .gantt .bar-wrapper.active .bar{fill:#6e6e6e}.dark>.gantt-container .gantt .bar-wrapper.active .bar-progress{fill:#a4a4ff}.dark>.gantt-container .gantt .upper-text{fill:#a2a2a2}.dark>.gantt-container .gantt .lower-text{fill:#f7f7f7}.dark>.gantt-container .popup-wrapper{background-color:#333}.dark>.gantt-container .popup-wrapper .title{border-color:#a4a4ff}.dark>.gantt-container .popup-wrapper .pointer{border-top-color:#333}.gantt-container{line-height:14.5px}.gantt-container .grid-header{background-color:#fff;position:sticky;top:0;left:0;z-index:10}.gantt-container .lower-text,.gantt-container .upper-text{text-anchor:middle;color:#111}.gantt-container .upper-header{height:40px}.gantt-container .lower-header{height:30px}.gantt-container .lower-text{font-size:14px;position:absolute;width:fit-content}.gantt-container .upper-text{position:absolute;width:fit-content;font-weight:500;font-size:16px}.gantt-container .current-upper{position:fixed}.gantt-container .side-header{position:fixed;padding:0 10px;margin-right:10px;background:#fff;line-height:20px;font-weight:400}.gantt-container .today-button,.gantt-container .viewmode-select{background:#f4f5f6;text-align:-webkit-center;text-align:center;height:25px;border-radius:8px;border:none;color:#111;padding:4px 10px;border-radius:8px;height:25px}.gantt-container .viewmode-select{outline:none !important;padding:4px 8px;margin-right:4px;-webkit-appearance:none;-moz-appearance:none;text-indent:1px;text-overflow:""}.gantt-container .date-highlight{background-color:#ebeef0;border-radius:12px;position:absolute;display:none}.gantt-container .current-highlight{position:absolute;background:#2c94ec;width:1px}.gantt-container .current-date-highlight{background:#2c94ec;color:#fff;padding:4px 8px;border-radius:200px}.gantt{user-select:none;-webkit-user-select:none;position:absolute}.gantt .grid-background{fill:none}.gantt .grid-row{fill:#fff}.gantt .row-line{stroke:#ebeff2}.gantt .tick{stroke:#ebeef0;stroke-width:.4}.gantt .tick.thick{stroke:#e0e0e0;stroke-width:.7}.gantt .holiday-highlight{fill:#f9fafa}.gantt .arrow{fill:none;stroke:#9fa9b1;stroke-width:1}.gantt .bar-wrapper .bar{fill:#fff;stroke:#fff;stroke-width:0;transition:stroke-width .3s ease}.gantt .bar-progress{fill:#ebeef0}.gantt .bar-expected-progress{fill:#c4c4e9}.gantt .bar-invalid{fill:rgba(0,0,0,0);stroke:#fff;stroke-width:1;stroke-dasharray:5}.gantt .bar-invalid~.bar-label{fill:#fff}.gantt .bar-label{fill:#111;dominant-baseline:central;font-family:Helvetica;font-size:13px;font-weight:400}.gantt .bar-label.big{fill:#111;text-anchor:start}.gantt .bar-wrapper.important .bar{fill:#94c4f4}.gantt .bar-wrapper.important .bar-progress{fill:#2c94ec}.gantt .bar-wrapper.important .bar-label{fill:#fff}.gantt .bar-wrapper.important .handle{fill:#94c4f4}.gantt .bar-wrapper.important .handle.progress{fill:#fff}.gantt .handle{fill:#dcdce4;cursor:ew-resize;opacity:0;visibility:hidden;transition:opacity .3s ease}.gantt .handle.progress{fill:#666}.gantt .bar-wrapper{cursor:pointer;outline:none}.gantt .bar-wrapper.active .handle{visibility:visible;opacity:1}.gantt .bar-wrapper .bar{-webkit-filter:drop-shadow(3px 3px 2px rgba(0, 0, 0, 0.7));filter:drop-shadow(0 0 2px rgba(17, 43, 66, 0.16));border-radius:3px}.gantt .bar-wrapper:hover .bar{transition:transform .3s ease}.gantt .bar-wrapper:hover .date-highlight{display:block}.gantt .hide{display:none}.gantt-container{position:relative;overflow:auto;font-size:12px;height:500px}.gantt-container .popup-wrapper{position:absolute;top:0;left:0;background:#171b1f;padding:10px;border-radius:5px;width:max-content}.gantt-container .popup-wrapper.hidden{opacity:0 !important}.gantt-container .popup-wrapper .title{margin-bottom:5px;text-align:-webkit-center;text-align:center;color:#fff}.gantt-container .popup-wrapper .subtitle{color:#98a1a9}.gantt-container .popup-wrapper .pointer{position:absolute;height:5px;margin:0 0 0 -5px;border:5px solid rgba(0,0,0,0);border-bottom-color:rgba(0,0,0,.8)} \ No newline at end of file diff --git a/dist/frappe-gantt.min.js b/dist/frappe-gantt.min.js deleted file mode 100644 index f628634..0000000 --- a/dist/frappe-gantt.min.js +++ /dev/null @@ -1,2 +0,0 @@ -var Gantt=function(){"use strict";const t="year",e="month",s="day",i="hour",o="minute",a="second",n="millisecond",r={January:"Jan",February:"Feb",March:"Mar",April:"Apr",May:"May",June:"Jun",July:"Jul",August:"Aug",September:"Sep",October:"Oct",November:"Nov",December:"Dec"};var h={parse_duration(t){const e=/([0-9])+(y|m|d|h|min|s|ms)/gm.exec(t);if(null!==e){if("y"===e[2])return{duration:parseInt(e[1]),scale:"year"};if("m"===e[2])return{duration:parseInt(e[1]),scale:"month"};if("d"===e[2])return{duration:parseInt(e[1]),scale:"day"};if("h"===e[2])return{duration:parseInt(e[1]),scale:"hour"};if("min"===e[2])return{duration:parseInt(e[1]),scale:"minute"};if("s"===e[2])return{duration:parseInt(e[1]),scale:"second"};if("ms"===e[2])return{duration:parseInt(e[1]),scale:"millisecond"}}},parse(t,e="-",s=/[.:]/){if(t instanceof Date)return t;if("string"==typeof t){let i,o;const a=t.split(" ");i=a[0].split(e).map((t=>parseInt(t,10))),o=a[1]&&a[1].split(s),i[1]=i[1]?i[1]-1:0;let n=i;return o&&o.length&&(4===o.length&&(o[3]="0."+o[3],o[3]=1e3*parseFloat(o[3])),n=n.concat(o)),new Date(...n)}},to_string(t,e=!1){if(!(t instanceof Date))throw new TypeError("Invalid argument type");const s=this.get_date_values(t).map(((t,e)=>(1===e&&(t+=1),d(t+"",6===e?3:2,"0")))),i=`${s[0]}-${s[1]}-${s[2]}`,o=`${s[3]}:${s[4]}:${s[5]}.${s[6]}`;return i+(e?" "+o:"")},format(t,e="YYYY-MM-DD HH:mm:ss.SSS",s="en"){const i=new Intl.DateTimeFormat(s,{month:"long"}).format(t),o=i.charAt(0).toUpperCase()+i.slice(1),a=this.get_date_values(t).map((t=>d(t,2,0))),n={YYYY:a[0],MM:d(+a[1]+1,2,0),DD:a[2],HH:a[3],mm:a[4],ss:a[5],SSS:a[6],D:a[2],MMMM:o,MMM:r[o]};let h=e;const p=[];return Object.keys(n).sort(((t,e)=>e.length-t.length)).forEach((t=>{h.includes(t)&&(h=h.replaceAll(t,`$${p.length}`),p.push(n[t]))})),p.forEach(((t,e)=>{h=h.replaceAll(`$${e}`,t)})),h},diff(t,e,i=s){let o,a,n,r,h,d,p;return o=t-e,a=o/1e3,r=a/60,n=r/60,h=n/24,d=h/30,p=d/12,i.endsWith("s")||(i+="s"),Math.floor({milliseconds:o,seconds:a,minutes:r,hours:n,days:h,months:d,years:p}[i])},today(){const t=this.get_date_values(new Date).slice(0,3);return new Date(...t)},now:()=>new Date,add(r,h,d){h=parseInt(h,10);const p=[r.getFullYear()+(d===t?h:0),r.getMonth()+(d===e?h:0),r.getDate()+(d===s?h:0),r.getHours()+(d===i?h:0),r.getMinutes()+(d===o?h:0),r.getSeconds()+(d===a?h:0),r.getMilliseconds()+(d===n?h:0)];return new Date(...p)},start_of(r,h){const d={[t]:6,[e]:5,[s]:4,[i]:3,[o]:2,[a]:1,[n]:0};function p(t){return d[t]<=d[h]}const l=[r.getFullYear(),p(t)?0:r.getMonth(),p(e)?1:r.getDate(),p(s)?0:r.getHours(),p(i)?0:r.getMinutes(),p(o)?0:r.getSeconds(),p(a)?0:r.getMilliseconds()];return new Date(...l)},clone(t){return new Date(...this.get_date_values(t))},get_date_values:t=>[t.getFullYear(),t.getMonth(),t.getDate(),t.getHours(),t.getMinutes(),t.getSeconds(),t.getMilliseconds()],get_days_in_month(t){const e=[31,28,31,30,31,30,31,31,30,31,30,31],s=t.getMonth();if(1!==s)return e[s];const i=t.getFullYear();return i%4==0&&i%100!=0||i%400==0?29:28}};function d(t,e,s){return t+="",e>>=0,s=String(void 0!==s?s:" "),t.length>e?String(t):((e-=t.length)>s.length&&(s+=s.repeat(e/s.length)),s.slice(0,e)+String(t))}function p(t,e){return"string"==typeof t?(e||document).querySelector(t):t||null}function l(t,e){const s=document.createElementNS("http://www.w3.org/2000/svg",t);for(let t in e)if("append_to"===t){e.append_to.appendChild(s)}else"innerHTML"===t?s.innerHTML=e.innerHTML:"clipPath"===t?s.setAttribute("clip-path","url(#"+e[t]+")"):s.setAttribute(t,e[t]);return s}function _(t,e,s,i){const o=function(t,e,s,i,o="0.4s",a="0.1s"){const n=t.querySelector("animate");if(n)return p.attr(n,{attributeName:e,from:s,to:i,dur:o,begin:"click + "+a}),t;const r=l("animate",{attributeName:e,from:s,to:i,dur:o,begin:a,calcMode:"spline",values:s+";"+i,keyTimes:"0; 1",keySplines:g("ease-out")});return t.appendChild(r),t}(t,e,s,i);if(o===t){const t=document.createEvent("HTMLEvents");t.initEvent("click",!0,!0),t.eventName="click",o.dispatchEvent(t)}}function g(t){return{ease:".25 .1 .25 1",linear:"0 0 1 1","ease-in":".42 0 1 1","ease-out":"0 0 .58 1","ease-in-out":".42 0 .58 1"}[t]}p.on=(t,e,s,i)=>{i?p.delegate(t,e,s,i):(i=s,p.bind(t,e,i))},p.off=(t,e,s)=>{t.removeEventListener(e,s)},p.bind=(t,e,s)=>{e.split(/\s+/).forEach((function(e){t.addEventListener(e,s)}))},p.delegate=(t,e,s,i)=>{t.addEventListener(e,(function(t){const e=t.target.closest(s);e&&(t.delegatedTarget=e,i.call(this,t,e))}))},p.closest=(t,e)=>e?e.matches(t)?e:p.closest(t,e.parentNode):null,p.attr=(t,e,s)=>{if(!s&&"string"==typeof e)return t.getAttribute(e);if("object"!=typeof e)t.setAttribute(e,s);else for(let s in e)p.attr(t,s,e[s])};class u{constructor(t,e){this.set_defaults(t,e),this.prepare(),this.draw(),this.bind()}set_defaults(t,e){this.action_completed=!1,this.gantt=t,this.task=e}prepare(){this.prepare_values(),this.prepare_helpers()}prepare_values(){this.invalid=this.task.invalid,this.height=this.gantt.options.bar_height,this.image_size=this.height-5,this.compute_x(),this.compute_y(),this.compute_duration(),this.corner_radius=this.gantt.options.bar_corner_radius,this.width=this.gantt.options.column_width*this.duration,this.progress_width=this.gantt.options.column_width*this.duration*(this.task.progress/100)||0,this.group=l("g",{class:"bar-wrapper"+(this.task.custom_class?" "+this.task.custom_class:"")+(this.task.important?" important":""),"data-id":this.task.id}),this.bar_group=l("g",{class:"bar-group",append_to:this.group}),this.handle_group=l("g",{class:"handle-group",append_to:this.group})}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()}draw_bar(){this.$bar=l("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.$bar,"width",0,this.width),this.invalid&&this.$bar.classList.add("bar-invalid")}draw_expected_progress_bar(){this.invalid||(this.$expected_bar_progress=l("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}),_(this.$expected_bar_progress,"width",0,this.expected_progress_width))}draw_progress_bar(){if(this.invalid)return;this.$bar_progress=l("rect",{x:this.x,y:this.y,width:this.progress_width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar-progress",append_to:this.bar_group});const t=h.diff(this.task._start,this.gantt.gantt_start,"hour")/this.gantt.options.step*this.gantt.options.column_width;let e=document.createElement("div");e.id=`${this.task.id}-highlight`,e.classList.add("date-highlight"),e.style.height=.8*this.height+"px",e.style.width=this.width+"px",e.style.top=this.gantt.options.header_height-25+"px",e.style.left=t+"px",this.$date_highlight=e,this.gantt.$lower_header.prepend(e),_(this.$bar_progress,"width",0,this.progress_width)}draw_label(){let t=this.x+this.$bar.getWidth()/2;this.task.thumbnail&&(t=this.x+this.image_size+5),l("text",{x:t,y:this.y+this.height/2,innerHTML:this.task.name,class:"bar-label",append_to:this.bar_group}),requestAnimationFrame((()=>this.update_label_position()))}draw_thumbnail(){let t,e;t=l("defs",{append_to:this.bar_group}),l("rect",{id:"rect_"+this.task.id,x:this.x+10,y:this.y+2,width:this.image_size,height:this.image_size,rx:"15",class:"img_mask",append_to:t}),e=l("clipPath",{id:"clip_"+this.task.id,append_to:t}),l("use",{href:"#rect_"+this.task.id,append_to:e}),l("image",{x:this.x+10,y:this.y+2,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_resize_handles(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar;l("rect",{x:t.getX()+t.getWidth()+8-4,y:t.getY()+1,width:8,height:this.height-2,rx:this.corner_radius,ry:this.corner_radius,class:"handle right",append_to:this.handle_group}),l("rect",{x:t.getX()-8-4,y:t.getY()+1,width:8,height:this.height-2,rx:this.corner_radius,ry:this.corner_radius,class:"handle left",append_to:this.handle_group}),this.$handle_progress=l("polygon",{points:this.get_progress_polygon_points().join(","),class:"handle progress",append_to:this.handle_group})}get_progress_polygon_points(){const t=this.$bar_progress;return[t.getEndX()-5,t.getY()+t.getHeight()/2,t.getEndX(),t.getY()+t.getHeight()/2-7.5,t.getEndX()+5,t.getY()+t.getHeight()/2,t.getEndX(),t.getY()+t.getHeight()/2+7.5,t.getEndX()-5,t.getY()+t.getHeight()/2]}bind(){this.invalid||this.setup_click_event()}setup_click_event(){let t,e=this.task.id;p.on(this.group,"mouseover",(t=>{this.gantt.trigger_event("hover",[this.task,t.screenX,t.screenY,t])})),p.on(this.group,"mouseenter",(s=>t=setTimeout((()=>{this.show_popup(s.offsetX),document.querySelector(`#${e}-highlight`).style.display="block"}),200))),p.on(this.group,"mouseleave",(()=>{clearTimeout(t),this.gantt.popup?.hide?.(),document.querySelector(`#${e}-highlight`).style.display="none"})),p.on(this.group,this.gantt.options.popup_trigger,(()=>{this.gantt.trigger_event("click",[this.task])})),p.on(this.group,"dblclick",(t=>{this.action_completed||this.gantt.trigger_event("double_click",[this.task])}))}show_popup(t){if(this.gantt.bar_being_dragged)return;const e=`${h.format(this.task._start,"MMM D",this.gantt.options.language)} - ${h.format(h.add(this.task._end,-1,"second"),"MMM D",this.gantt.options.language)}
Progress: ${this.task.progress}`;this.gantt.show_popup({x:t,target_element:this.$bar,title:this.task.name,subtitle:e,task:this.task})}update_bar_position({x:t=null,width:e=null}){const s=this.$bar;if(t){if(!this.task.dependencies.map((t=>this.gantt.get_bar(t).$bar.getX())).reduce(((e,s)=>t>=s),t))return void(e=null);this.update_attr(s,"x",t),this.$date_highlight.style.left=t+"px"}e&&(this.update_attr(s,"width",e),this.$date_highlight.style.width=e+"px"),this.update_label_position(),this.update_handle_position(),this.gantt.options.show_expected_progress&&(this.date_changed(),this.compute_duration(),this.update_expected_progressbar_position()),this.update_progressbar_position(),this.update_arrow_position()}update_label_position_on_horizontal_scroll({x:t,sx:e}){const s=document.querySelector(".gantt-container"),i=this.group.querySelector(".bar-label"),o=this.group.querySelector(".bar-img")||"",a=this.bar_group.querySelector(".img_mask")||"";let n=this.$bar.getX()+this.$bar.getWidth(),r=i.getX()+t,h=o&&o.getX()+t||0,d=o&&o.getBBox().width+7||7,p=r+i.getBBox().width+7,l=e+s.clientWidth/2;i.classList.contains("big")||(p0&&pthis.$bar.getX()&&t<0&&p>l)&&(i.setAttribute("x",r),o&&(o.setAttribute("x",h),a.setAttribute("x",h)))}date_changed(){let t=!1;const{new_start_date:e,new_end_date:s}=this.compute_start_end_date();Number(this.task._start)!==Number(e)&&(t=!0,this.task._start=e),Number(this.task._end)!==Number(s)&&(t=!0,this.task._end=s),t&&this.gantt.trigger_event("date_change",[this.task,e,h.add(s,-1,"second")])}progress_changed(){const t=this.compute_progress();this.task.progress=t,this.gantt.trigger_event("progress_change",[this.task,t])}set_action_completed(){this.action_completed=!0,setTimeout((()=>this.action_completed=!1),1e3)}compute_start_end_date(){const t=this.$bar,e=t.getX()/this.gantt.options.column_width,s=h.add(this.gantt.gantt_start,e*this.gantt.options.step,"hour"),i=t.getWidth()/this.gantt.options.column_width;return{new_start_date:s,new_end_date:h.add(s,i*this.gantt.options.step,"hour")}}compute_progress(){const t=this.$bar_progress.getWidth()/this.$bar.getWidth()*100;return parseInt(t,10)}compute_expected_progress(){this.expected_progress=h.diff(h.today(),this.task._start,"hour")/this.gantt.options.step,this.expected_progress=100*(this.expected_progressn?(s.classList.add("big"),i?(i.setAttribute("x",e.getX()+e.getWidth()+5),t.setAttribute("x",e.getX()+e.getWidth()+5),s.setAttribute("x",e.getX()+e.getWidth()+o)):s.setAttribute("x",e.getX()+e.getWidth()+5)):(s.classList.remove("big"),i?(i.setAttribute("x",e.getX()+5),t.setAttribute("x",e.getX()+5),s.setAttribute("x",e.getX()+n/2+o)):s.setAttribute("x",e.getX()+n/2-a/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()-12),this.handle_group.querySelector(".handle.right").setAttribute("x",t.getEndX()+4);const e=this.group.querySelector(".handle.progress");e&&e.setAttribute("points",this.get_progress_polygon_points())}update_arrow_position(){this.arrows=this.arrows||[];for(let t of this.arrows)t.update()}}class c{constructor(t,e,s){this.gantt=t,this.from_task=e,this.to_task=s,this.calculate_path(),this.draw()}calculate_path(){let t=this.from_task.$bar.getX()+this.from_task.$bar.getWidth()/2;const e=()=>this.to_task.$bar.getX()this.from_task.$bar.getX()+this.gantt.options.padding;for(;e();)t-=10;const s=this.gantt.options.header_height+this.gantt.options.bar_height+(this.gantt.options.padding+this.gantt.options.bar_height)*this.from_task.task._index+this.gantt.options.padding,i=this.to_task.$bar.getX()-this.gantt.options.padding/2-7,o=this.gantt.options.header_height+this.gantt.options.bar_height/2+(this.gantt.options.padding+this.gantt.options.bar_height)*this.to_task.task._index+this.gantt.options.padding,a=this.from_task.task._index>this.to_task.task._index,n=this.gantt.options.arrow_curve,r=a?1:0,h=a?-n:n,d=a?o+this.gantt.options.arrow_curve:o-this.gantt.options.arrow_curve;if(this.path=`\n M ${t} ${s}\n V ${d}\n a ${n} ${n} 0 0 ${r} ${n} ${h}\n L ${i} ${o}\n m -5 -5\n l 5 5\n l -5 5`,this.to_task.$bar.getX()\n
\n
\n ',this.hide(),this.title=this.parent.querySelector(".title"),this.subtitle=this.parent.querySelector(".subtitle"),this.pointer=this.parent.querySelector(".pointer")}show(t){if(!t.target_element)throw new Error("target_element is required to show popup");const e=t.target_element;if(this.custom_html){let e=this.custom_html(t.task);e+='
',this.parent.innerHTML=e,this.pointer=this.parent.querySelector(".pointer")}else this.title.innerHTML=t.title,this.subtitle.innerHTML=t.subtitle;let s;e instanceof HTMLElement?s=e.getBoundingClientRect():e instanceof SVGElement&&(s=t.target_element.getBBox()),this.parent.style.left=t.x-this.parent.clientWidth/2+"px",this.parent.style.top=s.y+s.height+10+"px",this.pointer.style.left=this.parent.clientWidth/2+"px",this.pointer.style.top="-15px",this.parent.style.opacity=1}hide(){this.parent.style.opacity=0,this.parent.style.left=0}}const w={HOUR:"Hour",QUARTER_DAY:"Quarter Day",HALF_DAY:"Half Day",DAY:"Day",WEEK:"Week",MONTH:"Month",YEAR:"Year"},f={HOUR:["7d","7d"],QUARTER_DAY:["7d","7d"],HALF_DAY:["7d","7d"],DAY:["1m","1m"],WEEK:["1m","1m"],MONTH:["1m","1m"],YEAR:["2y","2y"]},b={header_height:65,column_width:30,step:24,view_modes:[...Object.values(w)],bar_height:30,bar_corner_radius:3,arrow_curve:5,padding:18,view_mode:"Day",date_format:"YYYY-MM-DD",popup_trigger:"click",show_expected_progress:!1,popup:null,language:"en",readonly:!1,highlight_weekend:!0,scroll_to:"start",lines:"both",auto_move_label:!0,today_button:!0,view_mode_select:!1};class y{constructor(t,e,s){this.setup_wrapper(t),this.setup_options(s),this.setup_tasks(e),this.change_view_mode(),this.bind_events()}setup_wrapper(t){let e,s;if("string"==typeof t&&(t=document.querySelector(t)),t instanceof HTMLElement)s=t,e=t.querySelector("svg");else{if(!(t instanceof SVGElement))throw new TypeError("Frappé Gantt only supports usage of a string CSS selector, HTML DOM element or SVG DOM element for the 'element' parameter");e=t}e?(this.$svg=e,this.$svg.classList.add("gantt")):this.$svg=l("svg",{append_to:s,class:"gantt"}),this.$container=document.createElement("div"),this.$container.classList.add("gantt-container");this.$svg.parentElement.appendChild(this.$container),this.$container.appendChild(this.$svg),this.$popup_wrapper=document.createElement("div"),this.$popup_wrapper.classList.add("popup-wrapper"),this.$container.appendChild(this.$popup_wrapper)}setup_options(t){this.options={...b,...t},t.view_mode_padding||(t.view_mode_padding={});for(let[e,s]of Object.entries(t.view_mode_padding))"string"==typeof s&&(t.view_mode_padding[e]=[s,s]);this.options.view_mode_padding={...f,...t.view_mode_padding}}setup_tasks(t){this.tasks=t.map(((t,e)=>{if(t._start=h.parse(t.start),void 0===t.end&&void 0!==t.duration){t.end=t._start,t.duration.split(" ").forEach((e=>{let{duration:s,scale:i}=h.parse_duration(e);t.end=h.add(t.end,s,i)}))}if(t._end=h.parse(t.end),h.diff(t._end,t._start,"year")<0)throw Error("start of task can't be after end of task: in task #, "+(e+1));if(h.diff(t._end,t._start,"year")>10&&(t.end=null),t._index=e,!t.start&&!t.end){const e=h.today();t._start=e,t._end=h.add(e,2,"day")}!t.start&&t.end&&(t._start=h.add(t._end,-2,"day")),t.start&&!t.end&&(t._end=h.add(t._start,2,"day"));if(h.get_date_values(t._end).slice(3).every((t=>0===t))&&(t._end=h.add(t._end,24,"hour")),t.start&&t.end||(t.invalid=!0),"string"==typeof t.dependencies||!t.dependencies){let e=[];t.dependencies&&(e=t.dependencies.split(",").map((t=>t.trim().replaceAll(" ","_"))).filter((t=>t))),t.dependencies=e}return t.id?"string"==typeof t.id?t.id=t.id.replaceAll(" ","_"):t.id=`${t.id}`:t.id=function(t){return t.name+"_"+Math.random().toString(36).slice(2,12)}(t),t})),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()}change_view_mode(t=this.options.view_mode){this.update_view_scale(t),this.setup_dates(),this.render(),this.trigger_event("view_change",[t])}update_view_scale(t){this.options.view_mode=t,t===w.HOUR?(this.options.step=1,this.options.column_width=38):t===w.DAY?(this.options.step=24,this.options.column_width=38):t===w.HALF_DAY?(this.options.step=12,this.options.column_width=38):t===w.QUARTER_DAY?(this.options.step=6,this.options.column_width=38):t===w.WEEK?(this.options.step=168,this.options.column_width=140):t===w.MONTH?(this.options.step=720,this.options.column_width=120):t===w.YEAR&&(this.options.step=8760,this.options.column_width=120)}setup_dates(){this.setup_gantt_dates(),this.setup_date_values()}setup_gantt_dates(){this.gantt_start=this.gantt_end=null;for(let t of this.tasks)(!this.gantt_start||t._startthis.gantt_end)&&(this.gantt_end=t._end);let t,e,s;t=this.gantt_start?h.start_of(this.gantt_start,"day"):new Date,e=this.gantt_end?h.start_of(this.gantt_end,"day"):new Date;for(let[t,e]of Object.entries(w))e===this.options.view_mode&&(s=t);const[i,o]=this.options.view_mode_padding[s].map(h.parse_duration);let a;t=h.add(t,-i.duration,i.scale),a=this.view_is(w.YEAR)?"YYYY":this.view_is(w.MONTH)?"YYYY-MM":this.view_is(w.DAY)?"YYYY-MM-DD":"YYYY-MM-DD HH",this.gantt_start=h.parse(h.format(t,a)),this.gantt_start.setHours(0,0,0,0),this.gantt_end=h.add(e,o.duration,o.scale)}setup_date_values(){this.dates=[];let t=null;for(;null===t||t=1&&i.getDate()<8&&(o+=" thick"),this.view_is(w.MONTH)&&i.getMonth()%3==0&&(o+=" thick"),l("path",{d:`M ${t} ${e} v ${s}`,class:o,append_to:this.layers.grid}),this.view_is(w.MONTH)?t+=h.get_days_in_month(i)*this.options.column_width/30:t+=this.options.column_width}}highlightWeekends(){if(this.view_is("Day")||this.view_is("Half Day"))for(let t=new Date(this.gantt_start);t<=this.gantt_end;t.setDate(t.getDate()+1))if(0===t.getDay()||6===t.getDay()){const e=h.diff(t,this.gantt_start,"hour")/this.options.step*this.options.column_width,s=(this.options.bar_height+this.options.padding)*this.tasks.length;l("rect",{x:e,y:this.options.header_height+this.options.padding/2,width:(this.view_is("Day")?1:2)*this.options.column_width,height:s,class:"holiday-highlight",append_to:this.layers.grid})}}computeGridHighlightDimensions(t){let e=this.options.column_width/2;if(this.view_is(w.DAY)){let t=h.today();return{x:e+h.diff(t,this.gantt_start,"hour")/this.options.step*this.options.column_width,date:t}}for(let s of this.dates){const i=new Date,o=new Date(s),a=new Date(s);switch(t){case w.WEEK:a.setDate(s.getDate()+7);break;case w.MONTH:a.setMonth(s.getMonth()+1);break;case w.YEAR:a.setFullYear(s.getFullYear()+1)}if(i>=o&&i<=a)return{x:e,date:o};e+=this.options.column_width}}make_grid_highlights(){if(this.options.highlight_weekend&&this.highlightWeekends(),this.view_is(w.DAY)||this.view_is(w.WEEK)||this.view_is(w.MONTH)||this.view_is(w.YEAR)){const{x:t,date:e}=this.computeGridHighlightDimensions(this.options.view_mode),s=this.options.header_height+this.options.padding/2,i=(this.options.bar_height+this.options.padding)*this.tasks.length;this.$current_highlight=this.create_el({top:s,left:t,height:i,classes:"current-highlight",append_to:this.$container});let o=document.getElementById(h.format(e).replaceAll(" ","_"));o.classList.add("current-date-highlight"),o.style.top=+o.style.top.slice(0,-2)-4+"px",o.style.left=+o.style.left.slice(0,-2)-8+"px"}}create_el({left:t,top:e,width:s,height:i,id:o,classes:a,append_to:n}){let r=document.createElement("div");return r.classList.add(a),r.style.top=e+"px",r.style.left=t+"px",o&&(r.id=o),s&&(r.style.width=i+"px"),i&&(r.style.height=i+"px"),n.appendChild(r),r}make_dates(){this.upper_texts_x={},this.get_dates_to_draw().forEach(((t,e)=>{let s=this.create_el({left:t.lower_x,top:t.lower_y,id:t.formatted_date,classes:"lower-text",append_to:this.$lower_header});if(s.innerText=t.lower_text,s.style.left=+s.style.left.slice(0,-2)-s.clientWidth/2+"px",t.upper_text){this.upper_texts_x[t.upper_text]=t.upper_x;let e=document.createElement("div");e.classList.add("upper-text"),e.style.left=t.upper_x+"px",e.style.top=t.upper_y+"px",e.innerText=t.upper_text,this.$upper_header.appendChild(e),t.upper_x>this.layers.grid.getBBox().width&&e.remove()}}))}get_dates_to_draw(){let t=null;return this.dates.map(((e,s)=>{const i=this.get_date_info(e,t,s);return t=i,i}))}get_date_info(t,e){let s=e?e.date:h.add(t,1,"day");const i={Hour_lower:h.format(t,"HH",this.options.language),"Quarter Day_lower":h.format(t,"HH",this.options.language),"Half Day_lower":h.format(t,"HH",this.options.language),Day_lower:t.getDate()!==s.getDate()?h.format(t,"D",this.options.language):"",Week_lower:t.getMonth()!==s.getMonth()?h.format(t,"D MMM",this.options.language):h.format(t,"D",this.options.language),Month_lower:h.format(t,"MMMM",this.options.language),Year_lower:h.format(t,"YYYY",this.options.language),Hour_upper:t.getDate()!==s.getDate()?h.format(t,"D MMMM",this.options.language):"","Quarter Day_upper":t.getDate()!==s.getDate()?h.format(t,"D MMM",this.options.language):"","Half Day_upper":t.getDate()!==s.getDate()?t.getMonth()!==s.getMonth()?h.format(t,"D MMM",this.options.language):h.format(t,"D",this.options.language):"",Day_upper:t.getMonth()===s.getMonth()&&e?"":h.format(t,"MMMM",this.options.language),Week_upper:t.getMonth()!==s.getMonth()?h.format(t,"MMMM",this.options.language):"",Month_upper:t.getFullYear()!==s.getFullYear()?h.format(t,"YYYY",this.options.language):"",Year_upper:t.getFullYear()!==s.getFullYear()?h.format(t,"YYYY",this.options.language):""};let o=this.view_is(w.MONTH)?h.get_days_in_month(t)*this.options.column_width/30:this.options.column_width;const a={x:e?e.base_pos_x+e.column_width:0,lower_y:this.options.header_height-20,upper_y:this.options.header_height-50},n={Hour_lower:o/2,Hour_upper:12*o,"Quarter Day_lower":o/2,"Quarter Day_upper":2*o,"Half Day_lower":o/2,"Half Day_upper":o,Day_lower:o/2,Day_upper:o/2,Week_lower:o/2,Week_upper:4*o/2,Month_lower:o/2,Month_upper:o/2,Year_lower:o/2,Year_upper:30*o/2};return{date:t,formatted_date:h.format(t).replaceAll(" ","_"),column_width:o,base_pos_x:a.x,upper_text:this.options.lower_text?this.options.upper_text(t,this.options.view_mode,i[`${this.options.view_mode}_upper`]):i[`${this.options.view_mode}_upper`],lower_text:this.options.lower_text?this.options.lower_text(t,this.options.view_mode,i[`${this.options.view_mode}_lower`]):i[`${this.options.view_mode}_lower`],upper_x:a.x+n[`${this.options.view_mode}_upper`],upper_y:a.upper_y,lower_x:a.x+n[`${this.options.view_mode}_lower`],lower_y:a.lower_y}}make_bars(){this.bars=this.tasks.map((t=>{const e=new u(this,t);return this.layers.bar.appendChild(e.group),e}))}make_arrows(){this.arrows=[];for(let t of this.tasks){let e=[];e=t.dependencies.map((e=>{const s=this.get_task(e);if(!s)return;const i=new c(this,this.bars[s._index],this.bars[t._index]);return this.layers.arrow.appendChild(i.element),i})).filter(Boolean),this.arrows=this.arrows.concat(e)}}map_arrows_on_bars(){for(let t of this.bars)t.arrows=this.arrows.filter((e=>e.from_task.task.id===t.task.id||e.to_task.task.id===t.task.id))}set_width(){const t=this.$svg.getBoundingClientRect().width,e=this.$svg.querySelector(".grid .grid-row")?this.$svg.querySelector(".grid .grid-row").getAttribute("width"):0;t{this.unselect_all(),this.hide_popup()}))}bind_bar_events(){let t=!1,e=0,s=0,i=0,o=!1,a=!1,n=null,r=[];this.bar_being_dragged=null,p.on(this.$svg,"mousedown",".bar-wrapper, .handle",((s,h)=>{const d=p.closest(".bar-wrapper",h);r.forEach((t=>t.group.classList.remove("active"))),h.classList.contains("left")?o=!0:h.classList.contains("right")?a=!0:h.classList.contains("bar-wrapper")&&(t=!0),d.classList.add("active"),this.popup.parent.classList.add("hidden"),e=s.offsetX,i=s.offsetY,n=d.getAttribute("data-id");const l=[n,...this.get_all_dependent_tasks(n)];r=l.map((t=>this.get_bar(t))),this.bar_being_dragged=n,r.forEach((t=>{const e=t.$bar;e.ox=e.getX(),e.oy=e.getY(),e.owidth=e.getWidth(),e.finaldx=0}))})),p.on(this.$container,"scroll",(t=>{let e=document.querySelectorAll(".bar-wrapper"),i=[];const o=[];let a;s&&(a=t.currentTarget.scrollLeft-s);const n=t.currentTarget.scrollLeft/this.options.column_width*this.options.step/24;let r="D MMM";["Year","Month"].includes(this.options.view_mode)?r="YYYY":["Day","Week"].includes(this.options.view_mode)?r="MMMM":this.view_is("Half Day")?r="D":this.view_is("Hour")&&(r="D MMMM");let d=h.format(h.add(this.gantt_start,n,"day"),r);const p=Array.from(document.querySelectorAll(".upper-text")).find((t=>t.textContent===d));if(p&&!p.classList.contains("current-upper")){const t=document.querySelector(".current-upper");t&&(t.classList.remove("current-upper"),t.style.left=this.upper_texts_x[t.textContent]+"px",t.style.top=this.options.header_height-50+"px"),p.classList.add("current-upper");let e=this.$svg.getBoundingClientRect();p.style.left=e.x+this.$container.scrollLeft+10+"px",p.style.top=e.y+this.options.header_height-50+"px"}Array.prototype.forEach.call(e,(function(t,e){o.push(t.getAttribute("data-id"))})),a&&(i=o.map((t=>this.get_bar(t))),this.options.auto_move_label&&i.forEach((e=>{e.update_label_position_on_horizontal_scroll({x:a,sx:t.currentTarget.scrollLeft})}))),s=t.currentTarget.scrollLeft})),p.on(this.$svg,"mousemove",(s=>{if(!(t||o||a))return;const i=s.offsetX-e;s.offsetY,r.forEach((e=>{const s=e.$bar;s.finaldx=this.get_snap_position(i),this.hide_popup(),o?n===e.task.id?e.update_bar_position({x:s.ox+s.finaldx,width:s.owidth-s.finaldx}):e.update_bar_position({x:s.ox+s.finaldx}):a?n===e.task.id&&e.update_bar_position({width:s.owidth+s.finaldx}):t&&!this.options.readonly&&e.update_bar_position({x:s.ox+s.finaldx})}))})),document.addEventListener("mouseup",(e=>{t=!1,o=!1,a=!1})),p.on(this.$svg,"mouseup",(t=>{this.bar_being_dragged=null,r.forEach((t=>{t.$bar.finaldx&&(t.date_changed(),t.set_action_completed())}))})),this.bind_bar_progress()}bind_bar_progress(){let t=0,e=0,s=null,i=null,o=null,a=null;p.on(this.$svg,"mousedown",".handle.progress",((n,r)=>{s=!0,t=n.offsetX,e=n.offsetY;const h=p.closest(".bar-wrapper",r).getAttribute("data-id");i=this.get_bar(h),o=i.$bar_progress,a=i.$bar,o.finaldx=0,o.owidth=o.getWidth(),o.min_dx=-o.getWidth(),o.max_dx=a.getWidth()-o.getWidth()})),p.on(this.$svg,"mousemove",(e=>{if(!s)return;let a=e.offsetX-t;e.offsetY,a>o.max_dx&&(a=o.max_dx),a{s=!1,o&&o.finaldx&&(o.finaldx=0,i.progress_changed(),i.set_action_completed(),i=null,o=null,a=null)}))}get_all_dependent_tasks(t){let e=[],s=[t];for(;s.length;){const t=s.reduce(((t,e)=>t=t.concat(this.dependency_map[e])),[]);e=e.concat(t),s=t.filter((t=>!s.includes(t)))}return e.filter(Boolean)}get_snap_position(t){let e,s,i=t;return this.view_is(w.WEEK)?(e=t%(this.options.column_width/7),s=i-e+(e{t.classList.remove("active")})),this.popup.parent.classList.remove("hidden")}view_is(t){return"string"==typeof t?this.options.view_mode===t:!!Array.isArray(t)&&t.some((t=>this.options.view_mode===t))}get_task(t){return this.tasks.find((e=>e.id===t))}get_bar(t){return this.bars.find((e=>e.task.id===t))}show_popup(t){!1!==this.options.popup&&(this.popup||(this.popup=new m(this.$popup_wrapper,this.options.popup)),this.popup.show(t))}hide_popup(){this.popup&&this.popup.hide()}trigger_event(t,e){this.options["on_"+t]&&this.options["on_"+t].apply(null,e)}get_oldest_starting_date(){return this.tasks.length?this.tasks.map((t=>t._start)).reduce(((t,e)=>e<=t?e:t)):new Date}clear(){this.$svg.innerHTML="",this.$header?.remove?.(),this.$current_highlight?.remove?.(),this.popup?.hide?.()}}return y.VIEW_MODE=w,y}(); -//# sourceMappingURL=frappe-gantt.min.js.map diff --git a/dist/frappe-gantt.min.js.map b/dist/frappe-gantt.min.js.map deleted file mode 100644 index 38b6df5..0000000 --- a/dist/frappe-gantt.min.js.map +++ /dev/null @@ -1 +0,0 @@ -{"version":3,"file":"frappe-gantt.min.js","sources":["../src/date_utils.js","../src/svg_utils.js","../src/bar.js","../src/arrow.js","../src/popup.js","../src/index.js"],"sourcesContent":["const YEAR = 'year';\nconst MONTH = 'month';\nconst DAY = 'day';\nconst HOUR = 'hour';\nconst MINUTE = 'minute';\nconst SECOND = 'second';\nconst MILLISECOND = 'millisecond';\n\nconst SHORTENED = {\n January: 'Jan',\n February: 'Feb',\n March: 'Mar',\n April: 'Apr',\n May: 'May',\n June: 'Jun',\n July: 'Jul',\n August: 'Aug',\n September: 'Sep',\n October: 'Oct',\n November: 'Nov',\n December: 'Dec',\n};\n\nexport default {\n parse_duration(duration) {\n const regex = /([0-9])+(y|m|d|h|min|s|ms)/gm;\n const matches = regex.exec(duration);\n\n if (matches !== null) {\n if (matches[2] === 'y') {\n return { duration: parseInt(matches[1]), scale: `year` };\n } else if (matches[2] === 'm') {\n return { duration: parseInt(matches[1]), scale: `month` };\n } else if (matches[2] === 'd') {\n return { duration: parseInt(matches[1]), scale: `day` };\n } else if (matches[2] === 'h') {\n return { duration: parseInt(matches[1]), scale: `hour` };\n } else if (matches[2] === 'min') {\n return { duration: parseInt(matches[1]), scale: `minute` };\n } else if (matches[2] === 's') {\n return { duration: parseInt(matches[1]), scale: `second` };\n } else if (matches[2] === 'ms') {\n return { duration: parseInt(matches[1]), scale: `millisecond` };\n }\n }\n },\n parse(date, date_separator = '-', time_separator = /[.:]/) {\n if (date instanceof Date) {\n return date;\n }\n if (typeof date === 'string') {\n let date_parts, time_parts;\n const parts = date.split(' ');\n date_parts = parts[0]\n .split(date_separator)\n .map((val) => parseInt(val, 10));\n time_parts = parts[1] && parts[1].split(time_separator);\n\n // month is 0 indexed\n date_parts[1] = date_parts[1] ? date_parts[1] - 1 : 0;\n\n let vals = date_parts;\n\n if (time_parts && time_parts.length) {\n if (time_parts.length === 4) {\n time_parts[3] = '0.' + time_parts[3];\n time_parts[3] = parseFloat(time_parts[3]) * 1000;\n }\n vals = vals.concat(time_parts);\n }\n return new Date(...vals);\n }\n },\n\n to_string(date, with_time = false) {\n if (!(date instanceof Date)) {\n throw new TypeError('Invalid argument type');\n }\n const vals = this.get_date_values(date).map((val, i) => {\n if (i === 1) {\n // add 1 for month\n val = val + 1;\n }\n\n if (i === 6) {\n return padStart(val + '', 3, '0');\n }\n\n return padStart(val + '', 2, '0');\n });\n const date_string = `${vals[0]}-${vals[1]}-${vals[2]}`;\n const time_string = `${vals[3]}:${vals[4]}:${vals[5]}.${vals[6]}`;\n\n return date_string + (with_time ? ' ' + time_string : '');\n },\n\n format(date, format_string = 'YYYY-MM-DD HH:mm:ss.SSS', lang = 'en') {\n const dateTimeFormat = new Intl.DateTimeFormat(lang, {\n month: 'long',\n });\n const month_name = dateTimeFormat.format(date);\n const month_name_capitalized =\n month_name.charAt(0).toUpperCase() + month_name.slice(1);\n\n const values = this.get_date_values(date).map((d) => padStart(d, 2, 0));\n const format_map = {\n YYYY: values[0],\n MM: padStart(+values[1] + 1, 2, 0),\n DD: values[2],\n HH: values[3],\n mm: values[4],\n ss: values[5],\n SSS: values[6],\n D: values[2],\n MMMM: month_name_capitalized,\n MMM: SHORTENED[month_name_capitalized],\n };\n\n let str = format_string;\n const formatted_values = [];\n\n Object.keys(format_map)\n .sort((a, b) => b.length - a.length) // big string first\n .forEach((key) => {\n if (str.includes(key)) {\n str = str.replaceAll(key, `$${formatted_values.length}`);\n formatted_values.push(format_map[key]);\n }\n });\n\n formatted_values.forEach((value, i) => {\n str = str.replaceAll(`$${i}`, value);\n });\n\n return str;\n },\n\n diff(date_a, date_b, scale = DAY) {\n let milliseconds, seconds, hours, minutes, days, months, years;\n\n milliseconds = date_a - date_b;\n seconds = milliseconds / 1000;\n minutes = seconds / 60;\n hours = minutes / 60;\n days = hours / 24;\n months = days / 30;\n years = months / 12;\n\n if (!scale.endsWith('s')) {\n scale += 's';\n }\n\n return Math.floor(\n {\n milliseconds,\n seconds,\n minutes,\n hours,\n days,\n months,\n years,\n }[scale],\n );\n },\n\n today() {\n const vals = this.get_date_values(new Date()).slice(0, 3);\n return new Date(...vals);\n },\n\n now() {\n return new Date();\n },\n\n add(date, qty, scale) {\n qty = parseInt(qty, 10);\n const vals = [\n date.getFullYear() + (scale === YEAR ? qty : 0),\n date.getMonth() + (scale === MONTH ? qty : 0),\n date.getDate() + (scale === DAY ? qty : 0),\n date.getHours() + (scale === HOUR ? qty : 0),\n date.getMinutes() + (scale === MINUTE ? qty : 0),\n date.getSeconds() + (scale === SECOND ? qty : 0),\n date.getMilliseconds() + (scale === MILLISECOND ? qty : 0),\n ];\n return new Date(...vals);\n },\n\n start_of(date, scale) {\n const scores = {\n [YEAR]: 6,\n [MONTH]: 5,\n [DAY]: 4,\n [HOUR]: 3,\n [MINUTE]: 2,\n [SECOND]: 1,\n [MILLISECOND]: 0,\n };\n\n function should_reset(_scale) {\n const max_score = scores[scale];\n return scores[_scale] <= max_score;\n }\n\n const vals = [\n date.getFullYear(),\n should_reset(YEAR) ? 0 : date.getMonth(),\n should_reset(MONTH) ? 1 : date.getDate(),\n should_reset(DAY) ? 0 : date.getHours(),\n should_reset(HOUR) ? 0 : date.getMinutes(),\n should_reset(MINUTE) ? 0 : date.getSeconds(),\n should_reset(SECOND) ? 0 : date.getMilliseconds(),\n ];\n\n return new Date(...vals);\n },\n\n clone(date) {\n return new Date(...this.get_date_values(date));\n },\n\n get_date_values(date) {\n return [\n date.getFullYear(),\n date.getMonth(),\n date.getDate(),\n date.getHours(),\n date.getMinutes(),\n date.getSeconds(),\n date.getMilliseconds(),\n ];\n },\n\n get_days_in_month(date) {\n const no_of_days = [31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31];\n\n const month = date.getMonth();\n\n if (month !== 1) {\n return no_of_days[month];\n }\n\n // Feb\n const year = date.getFullYear();\n if ((year % 4 === 0 && year % 100 != 0) || year % 400 === 0) {\n return 29;\n }\n return 28;\n },\n};\n\n// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/String/padStart\nfunction padStart(str, targetLength, padString) {\n str = str + '';\n targetLength = targetLength >> 0;\n padString = String(typeof padString !== 'undefined' ? padString : ' ');\n if (str.length > targetLength) {\n return String(str);\n } else {\n targetLength = targetLength - str.length;\n if (targetLength > padString.length) {\n padString += padString.repeat(targetLength / padString.length);\n }\n return padString.slice(0, targetLength) + String(str);\n }\n}\n","export function $(expr, con) {\n return typeof expr === \"string\"\n ? (con || document).querySelector(expr)\n : expr || null;\n}\n\nexport function createSVG(tag, attrs) {\n const elem = document.createElementNS(\"http://www.w3.org/2000/svg\", tag);\n for (let attr in attrs) {\n if (attr === \"append_to\") {\n const parent = attrs.append_to;\n parent.appendChild(elem);\n } else if (attr === \"innerHTML\") {\n elem.innerHTML = attrs.innerHTML;\n } else if (attr === 'clipPath') {\n elem.setAttribute('clip-path', 'url(#' + attrs[attr] + ')');\n } else {\n elem.setAttribute(attr, attrs[attr]);\n }\n }\n return elem;\n}\n\nexport function animateSVG(svgElement, attr, from, to) {\n const animatedSvgElement = getAnimationElement(svgElement, attr, from, to);\n\n if (animatedSvgElement === svgElement) {\n // triggered 2nd time programmatically\n // trigger artificial click event\n const event = document.createEvent(\"HTMLEvents\");\n event.initEvent(\"click\", true, true);\n event.eventName = \"click\";\n animatedSvgElement.dispatchEvent(event);\n }\n}\n\nfunction getAnimationElement(\n svgElement,\n attr,\n from,\n to,\n dur = \"0.4s\",\n begin = \"0.1s\",\n) {\n const animEl = svgElement.querySelector(\"animate\");\n if (animEl) {\n $.attr(animEl, {\n attributeName: attr,\n from,\n to,\n dur,\n begin: \"click + \" + begin, // artificial click\n });\n return svgElement;\n }\n\n const animateElement = createSVG(\"animate\", {\n attributeName: attr,\n from,\n to,\n dur,\n begin,\n calcMode: \"spline\",\n values: from + \";\" + to,\n keyTimes: \"0; 1\",\n keySplines: cubic_bezier(\"ease-out\"),\n });\n svgElement.appendChild(animateElement);\n\n return svgElement;\n}\n\nfunction cubic_bezier(name) {\n return {\n ease: \".25 .1 .25 1\",\n linear: \"0 0 1 1\",\n \"ease-in\": \".42 0 1 1\",\n \"ease-out\": \"0 0 .58 1\",\n \"ease-in-out\": \".42 0 .58 1\",\n }[name];\n}\n\n$.on = (element, event, selector, callback) => {\n if (!callback) {\n callback = selector;\n $.bind(element, event, callback);\n } else {\n $.delegate(element, event, selector, callback);\n }\n};\n\n$.off = (element, event, handler) => {\n element.removeEventListener(event, handler);\n};\n\n$.bind = (element, event, callback) => {\n event.split(/\\s+/).forEach(function (event) {\n element.addEventListener(event, callback);\n });\n};\n\n$.delegate = (element, event, selector, callback) => {\n element.addEventListener(event, function (e) {\n const delegatedTarget = e.target.closest(selector);\n if (delegatedTarget) {\n e.delegatedTarget = delegatedTarget;\n callback.call(this, e, delegatedTarget);\n }\n });\n};\n\n$.closest = (selector, element) => {\n if (!element) return null;\n\n if (element.matches(selector)) {\n return element;\n }\n\n return $.closest(selector, element.parentNode);\n};\n\n$.attr = (element, attr, value) => {\n if (!value && typeof attr === \"string\") {\n return element.getAttribute(attr);\n }\n\n if (typeof attr === \"object\") {\n for (let key in attr) {\n $.attr(element, key, attr[key]);\n }\n return;\n }\n\n element.setAttribute(attr, value);\n};\n","import date_utils from './date_utils';\nimport { $, createSVG, animateSVG } from './svg_utils';\n\nexport default class Bar {\n constructor(gantt, task) {\n this.set_defaults(gantt, task);\n this.prepare();\n this.draw();\n this.bind();\n }\n\n set_defaults(gantt, task) {\n this.action_completed = false;\n this.gantt = gantt;\n this.task = task;\n }\n\n prepare() {\n this.prepare_values();\n this.prepare_helpers();\n }\n\n prepare_values() {\n this.invalid = this.task.invalid;\n this.height = this.gantt.options.bar_height;\n this.image_size = this.height - 5;\n this.compute_x();\n this.compute_y();\n this.compute_duration();\n this.corner_radius = this.gantt.options.bar_corner_radius;\n this.width = this.gantt.options.column_width * this.duration;\n this.progress_width =\n this.gantt.options.column_width *\n this.duration *\n (this.task.progress / 100) || 0;\n this.group = createSVG('g', {\n class:\n 'bar-wrapper' +\n (this.task.custom_class ? ' ' + this.task.custom_class : '') +\n (this.task.important ? ' important' : ''),\n 'data-id': this.task.id,\n });\n this.bar_group = createSVG('g', {\n class: 'bar-group',\n append_to: this.group,\n });\n this.handle_group = createSVG('g', {\n class: 'handle-group',\n append_to: this.group,\n });\n }\n\n prepare_helpers() {\n SVGElement.prototype.getX = function () {\n return +this.getAttribute('x');\n };\n SVGElement.prototype.getY = function () {\n return +this.getAttribute('y');\n };\n SVGElement.prototype.getWidth = function () {\n return +this.getAttribute('width');\n };\n SVGElement.prototype.getHeight = function () {\n return +this.getAttribute('height');\n };\n SVGElement.prototype.getEndX = function () {\n return this.getX() + this.getWidth();\n };\n }\n\n prepare_expected_progress_values() {\n this.compute_expected_progress();\n this.expected_progress_width =\n this.gantt.options.column_width *\n this.duration *\n (this.expected_progress / 100) || 0;\n }\n\n draw() {\n this.draw_bar();\n this.draw_progress_bar();\n if (this.gantt.options.show_expected_progress) {\n this.prepare_expected_progress_values();\n this.draw_expected_progress_bar();\n }\n this.draw_label();\n this.draw_resize_handles();\n\n if (this.task.thumbnail) {\n this.draw_thumbnail();\n }\n }\n\n draw_bar() {\n this.$bar = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar',\n append_to: this.bar_group,\n });\n\n animateSVG(this.$bar, 'width', 0, this.width);\n\n if (this.invalid) {\n this.$bar.classList.add('bar-invalid');\n }\n }\n\n draw_expected_progress_bar() {\n if (this.invalid) return;\n this.$expected_bar_progress = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.expected_progress_width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar-expected-progress',\n append_to: this.bar_group,\n });\n\n animateSVG(\n this.$expected_bar_progress,\n 'width',\n 0,\n this.expected_progress_width,\n );\n }\n\n draw_progress_bar() {\n if (this.invalid) return;\n this.$bar_progress = createSVG('rect', {\n x: this.x,\n y: this.y,\n width: this.progress_width,\n height: this.height,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'bar-progress',\n append_to: this.bar_group,\n });\n const x =\n (date_utils.diff(this.task._start, this.gantt.gantt_start, 'hour') /\n this.gantt.options.step) *\n this.gantt.options.column_width;\n\n let $date_highlight = document.createElement('div');\n $date_highlight.id = `${this.task.id}-highlight`;\n $date_highlight.classList.add('date-highlight');\n $date_highlight.style.height = this.height * 0.8 + 'px';\n $date_highlight.style.width = this.width + 'px';\n $date_highlight.style.top =\n this.gantt.options.header_height - 25 + 'px';\n $date_highlight.style.left = x + 'px';\n this.$date_highlight = $date_highlight;\n this.gantt.$lower_header.prepend($date_highlight);\n\n animateSVG(this.$bar_progress, 'width', 0, this.progress_width);\n }\n\n draw_label() {\n let x_coord = this.x + this.$bar.getWidth() / 2;\n\n if (this.task.thumbnail) {\n x_coord = this.x + this.image_size + 5;\n }\n\n createSVG('text', {\n x: x_coord,\n y: this.y + this.height / 2,\n innerHTML: this.task.name,\n class: 'bar-label',\n append_to: this.bar_group,\n });\n // labels get BBox in the next tick\n requestAnimationFrame(() => this.update_label_position());\n }\n draw_thumbnail() {\n let x_offset = 10,\n y_offset = 2;\n let defs, clipPath;\n\n defs = createSVG('defs', {\n append_to: this.bar_group,\n });\n\n createSVG('rect', {\n id: 'rect_' + this.task.id,\n x: this.x + x_offset,\n y: this.y + y_offset,\n width: this.image_size,\n height: this.image_size,\n rx: '15',\n class: 'img_mask',\n append_to: defs,\n });\n\n clipPath = createSVG('clipPath', {\n id: 'clip_' + this.task.id,\n append_to: defs,\n });\n\n createSVG('use', {\n href: '#rect_' + this.task.id,\n append_to: clipPath,\n });\n\n createSVG('image', {\n x: this.x + x_offset,\n y: this.y + y_offset,\n width: this.image_size,\n height: this.image_size,\n class: 'bar-img',\n href: this.task.thumbnail,\n clipPath: 'clip_' + this.task.id,\n append_to: this.bar_group,\n });\n }\n\n draw_resize_handles() {\n if (this.invalid || this.gantt.options.readonly) return;\n\n const bar = this.$bar;\n const handle_width = 8;\n\n createSVG('rect', {\n x: bar.getX() + bar.getWidth() + handle_width - 4,\n y: bar.getY() + 1,\n width: handle_width,\n height: this.height - 2,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'handle right',\n append_to: this.handle_group,\n });\n\n createSVG('rect', {\n x: bar.getX() - handle_width - 4,\n y: bar.getY() + 1,\n width: handle_width,\n height: this.height - 2,\n rx: this.corner_radius,\n ry: this.corner_radius,\n class: 'handle left',\n append_to: this.handle_group,\n });\n\n this.$handle_progress = createSVG('polygon', {\n points: this.get_progress_polygon_points().join(','),\n class: 'handle progress',\n append_to: this.handle_group,\n });\n }\n\n get_progress_polygon_points() {\n const bar_progress = this.$bar_progress;\n let icon_width = 10;\n let icon_height = 15;\n\n return [\n bar_progress.getEndX() - icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n\n bar_progress.getEndX(),\n bar_progress.getY() +\n bar_progress.getHeight() / 2 -\n icon_height / 2,\n\n bar_progress.getEndX() + icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n\n bar_progress.getEndX(),\n bar_progress.getY() +\n bar_progress.getHeight() / 2 +\n icon_height / 2,\n\n bar_progress.getEndX() - icon_width / 2,\n bar_progress.getY() + bar_progress.getHeight() / 2,\n ];\n }\n\n bind() {\n if (this.invalid) return;\n this.setup_click_event();\n }\n\n setup_click_event() {\n let task_id = this.task.id;\n $.on(this.group, 'mouseover', (e) => {\n this.gantt.trigger_event('hover', [\n this.task,\n e.screenX,\n e.screenY,\n e,\n ]);\n });\n\n let timeout;\n $.on(\n this.group,\n 'mouseenter',\n (e) =>\n (timeout = setTimeout(() => {\n this.show_popup(e.offsetX);\n document.querySelector(\n `#${task_id}-highlight`,\n ).style.display = 'block';\n }, 200)),\n );\n\n $.on(this.group, 'mouseleave', () => {\n clearTimeout(timeout);\n this.gantt.popup?.hide?.();\n document.querySelector(`#${task_id}-highlight`).style.display =\n 'none';\n });\n\n $.on(this.group, this.gantt.options.popup_trigger, () => {\n this.gantt.trigger_event('click', [this.task]);\n });\n\n $.on(this.group, 'dblclick', (e) => {\n if (this.action_completed) {\n // just finished a move action, wait for a few seconds\n return;\n }\n\n this.gantt.trigger_event('double_click', [this.task]);\n });\n }\n\n show_popup(x) {\n if (this.gantt.bar_being_dragged) return;\n\n const start_date = date_utils.format(\n this.task._start,\n 'MMM D',\n this.gantt.options.language,\n );\n const end_date = date_utils.format(\n date_utils.add(this.task._end, -1, 'second'),\n 'MMM D',\n this.gantt.options.language,\n );\n const subtitle = `${start_date} - ${end_date}
Progress: ${this.task.progress}`;\n\n this.gantt.show_popup({\n x,\n target_element: this.$bar,\n title: this.task.name,\n subtitle: subtitle,\n task: this.task,\n });\n }\n\n update_bar_position({ x = null, width = null }) {\n const bar = this.$bar;\n if (x) {\n // get all x values of parent task\n const xs = this.task.dependencies.map((dep) => {\n return this.gantt.get_bar(dep).$bar.getX();\n });\n // child task must not go before parent\n const valid_x = xs.reduce((_, curr) => {\n return x >= curr;\n }, x);\n if (!valid_x) {\n width = null;\n return;\n }\n this.update_attr(bar, 'x', x);\n this.$date_highlight.style.left = x + 'px';\n }\n if (width) {\n this.update_attr(bar, 'width', width);\n this.$date_highlight.style.width = width + 'px';\n }\n this.update_label_position();\n this.update_handle_position();\n if (this.gantt.options.show_expected_progress) {\n this.date_changed();\n this.compute_duration();\n this.update_expected_progressbar_position();\n }\n this.update_progressbar_position();\n this.update_arrow_position();\n }\n\n update_label_position_on_horizontal_scroll({ x, sx }) {\n const container = document.querySelector('.gantt-container');\n const label = this.group.querySelector('.bar-label');\n const img = this.group.querySelector('.bar-img') || '';\n const img_mask = this.bar_group.querySelector('.img_mask') || '';\n\n let barWidthLimit = this.$bar.getX() + this.$bar.getWidth();\n let newLabelX = label.getX() + x;\n let newImgX = (img && img.getX() + x) || 0;\n let imgWidth = (img && img.getBBox().width + 7) || 7;\n let labelEndX = newLabelX + label.getBBox().width + 7;\n let viewportCentral = sx + container.clientWidth / 2;\n\n if (label.classList.contains('big')) return;\n\n if (labelEndX < barWidthLimit && x > 0 && labelEndX < viewportCentral) {\n label.setAttribute('x', newLabelX);\n if (img) {\n img.setAttribute('x', newImgX);\n img_mask.setAttribute('x', newImgX);\n }\n } else if (\n newLabelX - imgWidth > this.$bar.getX() &&\n x < 0 &&\n labelEndX > viewportCentral\n ) {\n label.setAttribute('x', newLabelX);\n if (img) {\n img.setAttribute('x', newImgX);\n img_mask.setAttribute('x', newImgX);\n }\n }\n }\n\n date_changed() {\n let changed = false;\n const { new_start_date, new_end_date } = this.compute_start_end_date();\n\n if (Number(this.task._start) !== Number(new_start_date)) {\n changed = true;\n this.task._start = new_start_date;\n }\n\n if (Number(this.task._end) !== Number(new_end_date)) {\n changed = true;\n this.task._end = new_end_date;\n }\n\n if (!changed) return;\n\n this.gantt.trigger_event('date_change', [\n this.task,\n new_start_date,\n date_utils.add(new_end_date, -1, 'second'),\n ]);\n }\n\n progress_changed() {\n const new_progress = this.compute_progress();\n this.task.progress = new_progress;\n this.gantt.trigger_event('progress_change', [this.task, new_progress]);\n }\n\n set_action_completed() {\n this.action_completed = true;\n setTimeout(() => (this.action_completed = false), 1000);\n }\n\n compute_start_end_date() {\n const bar = this.$bar;\n const x_in_units = bar.getX() / this.gantt.options.column_width;\n const new_start_date = date_utils.add(\n this.gantt.gantt_start,\n x_in_units * this.gantt.options.step,\n 'hour',\n );\n const width_in_units = bar.getWidth() / this.gantt.options.column_width;\n const new_end_date = date_utils.add(\n new_start_date,\n width_in_units * this.gantt.options.step,\n 'hour',\n );\n\n return { new_start_date, new_end_date };\n }\n\n compute_progress() {\n const progress =\n (this.$bar_progress.getWidth() / this.$bar.getWidth()) * 100;\n return parseInt(progress, 10);\n }\n\n compute_expected_progress() {\n this.expected_progress =\n date_utils.diff(date_utils.today(), this.task._start, 'hour') /\n this.gantt.options.step;\n this.expected_progress =\n ((this.expected_progress < this.duration\n ? this.expected_progress\n : this.duration) *\n 100) /\n this.duration;\n }\n\n compute_x() {\n const { step, column_width } = this.gantt.options;\n const task_start = this.task._start;\n const gantt_start = this.gantt.gantt_start;\n\n const diff = date_utils.diff(task_start, gantt_start, 'hour');\n let x = (diff / step) * column_width;\n\n if (this.gantt.view_is('Month')) {\n const diff = date_utils.diff(task_start, gantt_start, 'day');\n x = (diff * column_width) / 30;\n }\n this.x = x;\n }\n\n compute_y() {\n this.y =\n this.gantt.options.header_height +\n this.gantt.options.padding +\n this.task._index * (this.height + this.gantt.options.padding);\n }\n\n compute_duration() {\n this.duration =\n date_utils.diff(this.task._end, this.task._start, 'hour') /\n this.gantt.options.step;\n }\n\n get_snap_position(dx) {\n let odx = dx,\n rem,\n position;\n\n if (this.gantt.view_is('Week')) {\n rem = dx % (this.gantt.options.column_width / 7);\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 14\n ? 0\n : this.gantt.options.column_width / 7);\n } else if (this.gantt.view_is('Month')) {\n rem = dx % (this.gantt.options.column_width / 30);\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 60\n ? 0\n : this.gantt.options.column_width / 30);\n } else {\n rem = dx % this.gantt.options.column_width;\n position =\n odx -\n rem +\n (rem < this.gantt.options.column_width / 2\n ? 0\n : this.gantt.options.column_width);\n }\n return position;\n }\n\n update_attr(element, attr, value) {\n value = +value;\n if (!isNaN(value)) {\n element.setAttribute(attr, value);\n }\n return element;\n }\n\n update_expected_progressbar_position() {\n if (this.invalid) return;\n this.$expected_bar_progress.setAttribute('x', this.$bar.getX());\n this.compute_expected_progress();\n this.$expected_bar_progress.setAttribute(\n 'width',\n this.gantt.options.column_width *\n this.duration *\n (this.expected_progress / 100) || 0,\n );\n }\n\n update_progressbar_position() {\n if (this.invalid || this.gantt.options.readonly) return;\n this.$bar_progress.setAttribute('x', this.$bar.getX());\n this.$bar_progress.setAttribute(\n 'width',\n this.$bar.getWidth() * (this.task.progress / 100),\n );\n }\n\n update_label_position() {\n const img_mask = this.bar_group.querySelector('.img_mask') || '';\n const bar = this.$bar,\n label = this.group.querySelector('.bar-label'),\n img = this.group.querySelector('.bar-img');\n\n let padding = 5;\n let x_offset_label_img = this.image_size + 10;\n const labelWidth = label.getBBox().width;\n const barWidth = bar.getWidth();\n if (labelWidth > barWidth) {\n label.classList.add('big');\n if (img) {\n img.setAttribute('x', bar.getX() + bar.getWidth() + padding);\n img_mask.setAttribute(\n 'x',\n bar.getX() + bar.getWidth() + padding,\n );\n label.setAttribute(\n 'x',\n bar.getX() + bar.getWidth() + x_offset_label_img,\n );\n } else {\n label.setAttribute('x', bar.getX() + bar.getWidth() + padding);\n }\n } else {\n label.classList.remove('big');\n if (img) {\n img.setAttribute('x', bar.getX() + padding);\n img_mask.setAttribute('x', bar.getX() + padding);\n label.setAttribute(\n 'x',\n bar.getX() + barWidth / 2 + x_offset_label_img,\n );\n } else {\n label.setAttribute(\n 'x',\n bar.getX() + barWidth / 2 - labelWidth / 2,\n );\n }\n }\n }\n\n update_handle_position() {\n if (this.invalid || this.gantt.options.readonly) return;\n const bar = this.$bar;\n this.handle_group\n .querySelector('.handle.left')\n .setAttribute('x', bar.getX() - 12);\n this.handle_group\n .querySelector('.handle.right')\n .setAttribute('x', bar.getEndX() + 4);\n const handle = this.group.querySelector('.handle.progress');\n handle &&\n handle.setAttribute('points', this.get_progress_polygon_points());\n }\n\n update_arrow_position() {\n this.arrows = this.arrows || [];\n for (let arrow of this.arrows) {\n arrow.update();\n }\n }\n}\n\nfunction isFunction(functionToCheck) {\n let getType = {};\n return (\n functionToCheck &&\n getType.toString.call(functionToCheck) === '[object Function]'\n );\n}\n","import { createSVG } from './svg_utils';\n\nexport default class Arrow {\n constructor(gantt, from_task, to_task) {\n this.gantt = gantt;\n this.from_task = from_task;\n this.to_task = to_task;\n\n this.calculate_path();\n this.draw();\n }\n\n calculate_path() {\n let start_x =\n this.from_task.$bar.getX() + this.from_task.$bar.getWidth() / 2;\n\n const condition = () =>\n this.to_task.$bar.getX() < start_x + this.gantt.options.padding &&\n start_x > this.from_task.$bar.getX() + this.gantt.options.padding;\n\n while (condition()) {\n start_x -= 10;\n }\n\n const start_y =\n this.gantt.options.header_height +\n this.gantt.options.bar_height +\n (this.gantt.options.padding + this.gantt.options.bar_height) *\n this.from_task.task._index +\n this.gantt.options.padding;\n\n const end_x =\n this.to_task.$bar.getX() - this.gantt.options.padding / 2 - 7;\n const end_y =\n this.gantt.options.header_height +\n this.gantt.options.bar_height / 2 +\n (this.gantt.options.padding + this.gantt.options.bar_height) *\n this.to_task.task._index +\n this.gantt.options.padding;\n\n const from_is_below_to =\n this.from_task.task._index > this.to_task.task._index;\n const curve = this.gantt.options.arrow_curve;\n const clockwise = from_is_below_to ? 1 : 0;\n const curve_y = from_is_below_to ? -curve : curve;\n const offset = from_is_below_to\n ? end_y + this.gantt.options.arrow_curve\n : end_y - this.gantt.options.arrow_curve;\n\n this.path = `\n M ${start_x} ${start_y}\n V ${offset}\n a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n L ${end_x} ${end_y}\n m -5 -5\n l 5 5\n l -5 5`;\n\n if (\n this.to_task.$bar.getX() <\n this.from_task.$bar.getX() + this.gantt.options.padding\n ) {\n const down_1 = this.gantt.options.padding / 2 - curve;\n const down_2 =\n this.to_task.$bar.getY() +\n this.to_task.$bar.getHeight() / 2 -\n curve_y;\n const left = this.to_task.$bar.getX() - this.gantt.options.padding;\n\n this.path = `\n M ${start_x} ${start_y}\n v ${down_1}\n a ${curve} ${curve} 0 0 1 -${curve} ${curve}\n H ${left}\n a ${curve} ${curve} 0 0 ${clockwise} -${curve} ${curve_y}\n V ${down_2}\n a ${curve} ${curve} 0 0 ${clockwise} ${curve} ${curve_y}\n L ${end_x} ${end_y}\n m -5 -5\n l 5 5\n l -5 5`;\n }\n }\n\n draw() {\n this.element = createSVG('path', {\n d: this.path,\n 'data-from': this.from_task.task.id,\n 'data-to': this.to_task.task.id,\n });\n }\n\n update() {\n this.calculate_path();\n this.element.setAttribute('d', this.path);\n }\n}\n","export default class Popup {\n constructor(parent, custom_html) {\n this.parent = parent;\n this.custom_html = custom_html;\n this.make();\n }\n\n make() {\n this.parent.innerHTML = `\n
\n
\n
\n `;\n\n this.hide();\n\n this.title = this.parent.querySelector(\".title\");\n this.subtitle = this.parent.querySelector(\".subtitle\");\n this.pointer = this.parent.querySelector(\".pointer\");\n }\n\n show(options) {\n if (!options.target_element) {\n throw new Error(\"target_element is required to show popup\");\n }\n const target_element = options.target_element;\n\n if (this.custom_html) {\n let html = this.custom_html(options.task);\n html += '
';\n this.parent.innerHTML = html;\n this.pointer = this.parent.querySelector(\".pointer\");\n } else {\n // set data\n this.title.innerHTML = options.title;\n this.subtitle.innerHTML = options.subtitle;\n }\n\n // set position\n let position_meta;\n if (target_element instanceof HTMLElement) {\n position_meta = target_element.getBoundingClientRect();\n } else if (target_element instanceof SVGElement) {\n position_meta = options.target_element.getBBox();\n }\n\n this.parent.style.left = options.x - this.parent.clientWidth / 2 + \"px\";\n this.parent.style.top = position_meta.y + position_meta.height + 10 + \"px\";\n\n this.pointer.style.left = this.parent.clientWidth / 2 + \"px\";\n this.pointer.style.top = \"-15px\";\n\n // show\n this.parent.style.opacity = 1;\n }\n\n hide() {\n this.parent.style.opacity = 0;\n this.parent.style.left = 0;\n }\n}\n","import date_utils from \"./date_utils\";\nimport { $, createSVG } from \"./svg_utils\";\nimport Bar from \"./bar\";\nimport Arrow from \"./arrow\";\nimport Popup from \"./popup\";\n\nimport \"./gantt.scss\";\n\nconst VIEW_MODE = {\n HOUR: \"Hour\",\n QUARTER_DAY: \"Quarter Day\",\n HALF_DAY: \"Half Day\",\n DAY: \"Day\",\n WEEK: \"Week\",\n MONTH: \"Month\",\n YEAR: \"Year\",\n};\n\nconst VIEW_MODE_PADDING = {\n HOUR: [\"7d\", \"7d\"],\n QUARTER_DAY: [\"7d\", \"7d\"],\n HALF_DAY: [\"7d\", \"7d\"],\n DAY: [\"1m\", \"1m\"],\n WEEK: [\"1m\", \"1m\"],\n MONTH: [\"1m\", \"1m\"],\n YEAR: [\"2y\", \"2y\"],\n};\n\nconst DEFAULT_OPTIONS = {\n header_height: 65,\n column_width: 30,\n step: 24,\n view_modes: [...Object.values(VIEW_MODE)],\n bar_height: 30,\n bar_corner_radius: 3,\n arrow_curve: 5,\n padding: 18,\n view_mode: \"Day\",\n date_format: \"YYYY-MM-DD\",\n popup_trigger: \"click\",\n show_expected_progress: false,\n popup: null,\n language: \"en\",\n readonly: false,\n highlight_weekend: true,\n scroll_to: 'start',\n lines: 'both',\n auto_move_label: true,\n today_button: true,\n view_mode_select: false,\n};\n\nexport default class Gantt {\n constructor(wrapper, tasks, options) {\n this.setup_wrapper(wrapper);\n this.setup_options(options);\n this.setup_tasks(tasks);\n // initialize with default view mode\n this.change_view_mode();\n this.bind_events();\n }\n\n setup_wrapper(element) {\n let svg_element, wrapper_element;\n\n // CSS Selector is passed\n if (typeof element === \"string\") {\n element = document.querySelector(element);\n }\n\n // get the SVGElement\n if (element instanceof HTMLElement) {\n wrapper_element = element;\n svg_element = element.querySelector(\"svg\");\n } else if (element instanceof SVGElement) {\n svg_element = element;\n } else {\n throw new TypeError(\n \"Frappé Gantt only supports usage of a string CSS selector,\" +\n \" HTML DOM element or SVG DOM element for the 'element' parameter\",\n );\n }\n\n // svg element\n if (!svg_element) {\n // create it\n this.$svg = createSVG(\"svg\", {\n append_to: wrapper_element,\n class: \"gantt\",\n });\n } else {\n this.$svg = svg_element;\n this.$svg.classList.add(\"gantt\");\n }\n\n // wrapper element\n this.$container = document.createElement(\"div\");\n this.$container.classList.add(\"gantt-container\");\n\n const parent_element = this.$svg.parentElement;\n parent_element.appendChild(this.$container);\n this.$container.appendChild(this.$svg);\n\n // popup wrapper\n this.$popup_wrapper = document.createElement(\"div\");\n this.$popup_wrapper.classList.add(\"popup-wrapper\");\n this.$container.appendChild(this.$popup_wrapper);\n }\n\n setup_options(options) {\n this.options = { ...DEFAULT_OPTIONS, ...options }\n if (!options.view_mode_padding) options.view_mode_padding = {}\n for (let [key, value] of Object.entries(options.view_mode_padding)) {\n if (typeof value === \"string\") {\n // Configure for single value given\n options.view_mode_padding[key] = [value, value];\n }\n }\n\n this.options.view_mode_padding = {\n ...VIEW_MODE_PADDING,\n ...options.view_mode_padding,\n };\n }\n\n setup_tasks(tasks) {\n // prepare tasks\n this.tasks = tasks.map((task, i) => {\n // convert to Date objects\n task._start = date_utils.parse(task.start);\n if (task.end === undefined && task.duration !== undefined) {\n task.end = task._start;\n let durations = task.duration.split(\" \");\n\n durations.forEach((tmpDuration) => {\n let { duration, scale } = date_utils.parse_duration(tmpDuration);\n task.end = date_utils.add(task.end, duration, scale);\n });\n }\n task._end = date_utils.parse(task.end);\n let diff = date_utils.diff(task._end, task._start, \"year\");\n if (diff < 0) {\n throw Error(\"start of task can't be after end of task: in task #, \" + (i + 1))\n }\n // make task invalid if duration too large\n if (date_utils.diff(task._end, task._start, \"year\") > 10) {\n task.end = null;\n }\n\n\n // cache index\n task._index = i;\n\n // invalid dates\n if (!task.start && !task.end) {\n const today = date_utils.today();\n task._start = today;\n task._end = date_utils.add(today, 2, \"day\");\n }\n\n if (!task.start && task.end) {\n task._start = date_utils.add(task._end, -2, \"day\");\n }\n\n if (task.start && !task.end) {\n task._end = date_utils.add(task._start, 2, \"day\");\n }\n\n // if hours is not set, assume the last day is full day\n // e.g: 2018-09-09 becomes 2018-09-09 23:59:59\n const task_end_values = date_utils.get_date_values(task._end);\n if (task_end_values.slice(3).every((d) => d === 0)) {\n task._end = date_utils.add(task._end, 24, \"hour\");\n }\n\n // invalid flag\n if (!task.start || !task.end) {\n task.invalid = true;\n }\n\n // dependencies\n if (typeof task.dependencies === \"string\" || !task.dependencies) {\n let deps = [];\n if (task.dependencies) {\n deps = task.dependencies\n .split(\",\")\n .map((d) => d.trim().replaceAll(' ', '_'))\n .filter((d) => d);\n }\n task.dependencies = deps;\n }\n\n // uids\n if (!task.id) {\n task.id = generate_id(task);\n } else if (typeof task.id === 'string') {\n task.id = task.id.replaceAll(' ', '_')\n } else {\n task.id = `${task.id}`\n }\n\n return task;\n });\n\n this.setup_dependencies();\n }\n\n setup_dependencies() {\n this.dependency_map = {};\n for (let t of this.tasks) {\n for (let d of t.dependencies) {\n this.dependency_map[d] = this.dependency_map[d] || [];\n this.dependency_map[d].push(t.id);\n }\n }\n }\n\n refresh(tasks) {\n this.setup_tasks(tasks);\n this.change_view_mode();\n }\n\n change_view_mode(mode = this.options.view_mode) {\n this.update_view_scale(mode);\n this.setup_dates();\n this.render();\n // fire viewmode_change event\n this.trigger_event(\"view_change\", [mode]);\n }\n\n update_view_scale(view_mode) {\n this.options.view_mode = view_mode;\n if (view_mode === VIEW_MODE.HOUR) {\n this.options.step = 24 / 24;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.DAY) {\n this.options.step = 24;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.HALF_DAY) {\n this.options.step = 24 / 2;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.QUARTER_DAY) {\n this.options.step = 24 / 4;\n this.options.column_width = 38;\n } else if (view_mode === VIEW_MODE.WEEK) {\n this.options.step = 24 * 7;\n this.options.column_width = 140;\n } else if (view_mode === VIEW_MODE.MONTH) {\n this.options.step = 24 * 30;\n this.options.column_width = 120;\n } else if (view_mode === VIEW_MODE.YEAR) {\n this.options.step = 24 * 365;\n this.options.column_width = 120;\n }\n }\n\n setup_dates() {\n this.setup_gantt_dates();\n this.setup_date_values();\n }\n\n setup_gantt_dates() {\n this.gantt_start = this.gantt_end = null;\n\n for (let task of this.tasks) {\n // set global start and end date\n if (!this.gantt_start || task._start < this.gantt_start) {\n this.gantt_start = task._start;\n }\n if (!this.gantt_end || task._end > this.gantt_end) {\n this.gantt_end = task._end;\n }\n }\n let gantt_start, gantt_end;\n if (!this.gantt_start) gantt_start = new Date();\n else gantt_start = date_utils.start_of(this.gantt_start, \"day\");\n if (!this.gantt_end) gantt_end = new Date();\n else gantt_end = date_utils.start_of(this.gantt_end, \"day\");\n\n // add date padding on both sides\n let viewKey;\n for (let [key, value] of Object.entries(VIEW_MODE)) {\n if (value === this.options.view_mode) {\n viewKey = key;\n }\n }\n const [padding_start, padding_end] = this.options.view_mode_padding[\n viewKey\n ].map(date_utils.parse_duration);\n gantt_start = date_utils.add(\n gantt_start,\n -padding_start.duration,\n padding_start.scale,\n );\n\n let format_string;\n if (this.view_is(VIEW_MODE.YEAR)) {\n format_string = \"YYYY\"\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n format_string = \"YYYY-MM\"\n } else if (this.view_is(VIEW_MODE.DAY)) {\n format_string = \"YYYY-MM-DD\"\n } else {\n format_string = \"YYYY-MM-DD HH\"\n }\n this.gantt_start = date_utils.parse(date_utils.format(gantt_start, format_string));\n this.gantt_start.setHours(0, 0, 0, 0)\n this.gantt_end = date_utils.add(\n gantt_end,\n padding_end.duration,\n padding_end.scale,\n );\n }\n\n setup_date_values() {\n this.dates = [];\n let cur_date = null;\n\n while (cur_date === null || cur_date < this.gantt_end) {\n if (!cur_date) {\n cur_date = date_utils.clone(this.gantt_start);\n } else {\n if (this.view_is(VIEW_MODE.YEAR)) {\n cur_date = date_utils.add(cur_date, 1, \"year\");\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n cur_date = date_utils.add(cur_date, 1, \"month\");\n } else {\n cur_date = date_utils.add(cur_date, this.options.step, \"hour\");\n }\n }\n this.dates.push(cur_date);\n }\n }\n\n bind_events() {\n if (this.options.readonly) return\n this.bind_grid_click();\n this.bind_bar_events();\n }\n\n render() {\n this.clear();\n this.setup_layers();\n this.make_grid();\n this.make_dates();\n this.make_bars();\n this.make_grid_extras();\n this.make_arrows();\n this.map_arrows_on_bars();\n this.set_width();\n this.set_scroll_position(this.options.scroll_to);\n }\n\n setup_layers() {\n this.layers = {};\n const layers = [\"grid\", \"arrow\", \"progress\", \"bar\", \"details\"];\n // make group layers\n for (let layer of layers) {\n this.layers[layer] = createSVG(\"g\", {\n class: layer,\n append_to: this.$svg,\n });\n }\n }\n\n make_grid() {\n this.make_grid_background();\n this.make_grid_rows();\n this.make_grid_header();\n }\n\n make_grid_extras() {\n this.make_grid_highlights();\n this.make_grid_ticks();\n }\n\n make_grid_background() {\n const grid_width = this.dates.length * this.options.column_width;\n const grid_height =\n this.options.header_height +\n this.options.padding +\n (this.options.bar_height + this.options.padding) * this.tasks.length;\n\n createSVG(\"rect\", {\n x: 0,\n y: 0,\n width: grid_width,\n height: grid_height,\n class: \"grid-background\",\n append_to: this.$svg,\n });\n\n $.attr(this.$svg, {\n height: grid_height + this.options.padding + 100,\n width: \"100%\",\n });\n }\n\n make_grid_rows() {\n const rows_layer = createSVG(\"g\", { append_to: this.layers.grid });\n\n const row_width = this.dates.length * this.options.column_width;\n const row_height = this.options.bar_height + this.options.padding;\n\n let row_y = this.options.header_height + this.options.padding / 2;\n\n for (let _ of this.tasks) {\n createSVG(\"rect\", {\n x: 0,\n y: row_y,\n width: row_width,\n height: row_height,\n class: \"grid-row\",\n append_to: rows_layer,\n });\n if (this.options.lines === 'both' || this.options.lines === 'horizontal') {\n\n }\n\n row_y += this.options.bar_height + this.options.padding;\n }\n }\n\n make_grid_header() {\n const curHeader = document.querySelector('.grid-header')\n\n let $header = document.createElement(\"div\");\n $header.style.height = this.options.header_height + 10 + \"px\";\n $header.style.width = this.dates.length * this.options.column_width + \"px\";\n $header.classList.add('grid-header')\n this.$header = $header\n this.$container.appendChild($header)\n\n let $upper_header = document.createElement(\"div\");\n $upper_header.classList.add('upper-header')\n this.$upper_header = $upper_header\n this.$header.appendChild($upper_header)\n\n let $lower_header = document.createElement(\"div\");\n $lower_header.classList.add('lower-header')\n this.$lower_header = $lower_header\n this.$header.appendChild($lower_header)\n\n this.make_side_header()\n }\n\n make_side_header() {\n let $side_header = document.createElement('div')\n $side_header.classList.add('side-header')\n\n // Create view mode change select\n if (this.options.view_mode_select) {\n\n const $select = document.createElement(\"select\");\n $select.classList.add('viewmode-select')\n\n const $el = document.createElement(\"option\");\n $el.selected = true\n $el.disabled = true\n $el.textContent = 'Mode'\n $select.appendChild($el)\n\n for (const key in VIEW_MODE) {\n const $option = document.createElement(\"option\");\n $option.value = VIEW_MODE[key];\n $option.textContent = VIEW_MODE[key];\n $select.appendChild($option);\n }\n // $select.value = this.options.view_mode\n $select.addEventListener(\"change\", (function () {\n this.change_view_mode($select.value)\n }).bind(this));\n $side_header.appendChild($select)\n }\n\n // Create today button\n if (this.options.today_button) {\n let $today_button = document.createElement('button')\n $today_button.classList.add('today-button')\n $today_button.textContent = 'Today'\n $today_button.onclick = this.scroll_today.bind(this)\n $side_header.appendChild($today_button)\n }\n\n this.$header.appendChild($side_header)\n const { left, y } = this.$header.getBoundingClientRect();\n const width = Math.min(this.$header.clientWidth, this.$container.clientWidth)\n $side_header.style.left = left + this.$container.scrollLeft + width - $side_header.clientWidth + 'px';\n $side_header.style.top = y + 10 + 'px';\n }\n\n make_grid_ticks() {\n if (!['both', 'vertical', 'horizontal'].includes(this.options.lines)) return\n let tick_x = 0;\n let tick_y = this.options.header_height + this.options.padding / 2;\n let tick_height =\n (this.options.bar_height + this.options.padding) * this.tasks.length;\n\n let $lines_layer = createSVG(\"g\", { class: 'lines_layer', append_to: this.layers.grid });\n\n\n let row_y = this.options.header_height + this.options.padding / 2;\n\n const row_width = this.dates.length * this.options.column_width;\n const row_height = this.options.bar_height + this.options.padding;\n if (this.options.lines !== 'vertical') {\n for (let _ of this.tasks) {\n createSVG(\"line\", {\n x1: 0,\n y1: row_y + row_height,\n x2: row_width,\n y2: row_y + row_height,\n class: \"row-line\",\n append_to: $lines_layer,\n });\n row_y += row_height;\n }\n }\n if (this.options.lines === 'horizontal') return;\n for (let date of this.dates) {\n let tick_class = \"tick\";\n // thick tick for monday\n if (this.view_is(VIEW_MODE.DAY) && date.getDate() === 1) {\n tick_class += \" thick\";\n }\n // thick tick for first week\n if (\n this.view_is(VIEW_MODE.WEEK) &&\n date.getDate() >= 1 &&\n date.getDate() < 8\n ) {\n tick_class += \" thick\";\n }\n // thick ticks for quarters\n if (this.view_is(VIEW_MODE.MONTH) && date.getMonth() % 3 === 0) {\n tick_class += \" thick\";\n }\n\n createSVG(\"path\", {\n d: `M ${tick_x} ${tick_y} v ${tick_height}`,\n class: tick_class,\n append_to: this.layers.grid,\n });\n\n if (this.view_is(VIEW_MODE.MONTH)) {\n tick_x +=\n (date_utils.get_days_in_month(date) * this.options.column_width) / 30;\n } else {\n tick_x += this.options.column_width;\n }\n }\n }\n\n highlightWeekends() {\n if (!this.view_is('Day') && !this.view_is('Half Day')) return\n for (let d = new Date(this.gantt_start); d <= this.gantt_end; d.setDate(d.getDate() + 1)) {\n if (d.getDay() === 0 || d.getDay() === 6) {\n const x = (date_utils.diff(d, this.gantt_start, 'hour') /\n this.options.step) *\n this.options.column_width;\n const height = (this.options.bar_height + this.options.padding) * this.tasks.length;\n createSVG('rect', {\n x,\n y: this.options.header_height + this.options.padding / 2,\n width: (this.view_is('Day') ? 1 : 2) * this.options.column_width,\n height,\n class: 'holiday-highlight',\n append_to: this.layers.grid,\n });\n }\n }\n }\n\n //compute the horizontal x distance\n computeGridHighlightDimensions(view_mode) {\n let x = this.options.column_width / 2;\n\n if (this.view_is(VIEW_MODE.DAY)) {\n let today = date_utils.today()\n return {\n x: x +\n (date_utils.diff(today, this.gantt_start, \"hour\") / this.options.step) *\n this.options.column_width,\n date: today\n }\n }\n\n for (let date of this.dates) {\n const todayDate = new Date();\n const startDate = new Date(date);\n const endDate = new Date(date);\n switch (view_mode) {\n case VIEW_MODE.WEEK:\n endDate.setDate(date.getDate() + 7);\n break;\n case VIEW_MODE.MONTH:\n endDate.setMonth(date.getMonth() + 1);\n break;\n case VIEW_MODE.YEAR:\n endDate.setFullYear(date.getFullYear() + 1);\n break;\n }\n if (todayDate >= startDate && todayDate <= endDate) {\n return { x, date: startDate }\n } else {\n x += this.options.column_width;\n }\n }\n }\n\n make_grid_highlights() {\n if (this.options.highlight_weekend) this.highlightWeekends()\n // highlight today's | week's | month's | year's\n if (\n this.view_is(VIEW_MODE.DAY) ||\n this.view_is(VIEW_MODE.WEEK) ||\n this.view_is(VIEW_MODE.MONTH) ||\n this.view_is(VIEW_MODE.YEAR)\n ) {\n // Used as we must find the _end_ of session if view is not Day\n const { x: left, date } = this.computeGridHighlightDimensions(this.options.view_mode)\n const top = this.options.header_height + this.options.padding / 2;\n const height = (this.options.bar_height + this.options.padding) * this.tasks.length;\n this.$current_highlight = this.create_el({ top, left, height, classes: 'current-highlight', append_to: this.$container })\n let $today = document.getElementById(date_utils.format(date).replaceAll(' ', '_'))\n\n $today.classList.add('current-date-highlight')\n $today.style.top = +$today.style.top.slice(0, -2) - 4 + 'px'\n $today.style.left = +$today.style.left.slice(0, -2) - 8 + 'px'\n }\n }\n\n create_el({ left, top, width, height, id, classes, append_to }) {\n let $el = document.createElement(\"div\");\n $el.classList.add(classes)\n $el.style.top = top + 'px'\n $el.style.left = left + 'px'\n if (id) $el.id = id\n if (width) $el.style.width = height + 'px'\n if (height) $el.style.height = height + 'px'\n append_to.appendChild($el)\n return $el\n }\n\n make_dates() {\n this.upper_texts_x = {}\n this.get_dates_to_draw().forEach((date, i) => {\n let $lower_text = this.create_el({\n left: date.lower_x,\n top: date.lower_y,\n id: date.formatted_date,\n classes: 'lower-text',\n append_to: this.$lower_header\n })\n $lower_text.innerText = date.lower_text\n $lower_text.style.left = +$lower_text.style.left.slice(0, -2) - $lower_text.clientWidth / 2 + 'px'\n\n if (date.upper_text) {\n this.upper_texts_x[date.upper_text] = date.upper_x\n let $upper_text = document.createElement('div');\n $upper_text.classList.add('upper-text')\n $upper_text.style.left = date.upper_x + 'px'\n $upper_text.style.top = date.upper_y + 'px'\n $upper_text.innerText = date.upper_text\n this.$upper_header.appendChild($upper_text)\n\n // remove out-of-bound dates\n if (date.upper_x > this.layers.grid.getBBox().width) {\n $upper_text.remove();\n }\n }\n })\n }\n\n get_dates_to_draw() {\n let last_date = null;\n const dates = this.dates.map((date, i) => {\n const d = this.get_date_info(date, last_date, i);\n last_date = d;\n return d;\n });\n return dates;\n }\n\n get_date_info(date, last_date_info) {\n let last_date = last_date_info ? last_date_info.date : date_utils.add(date, 1, \"day\")\n const date_text = {\n Hour_lower: date_utils.format(date, \"HH\", this.options.language),\n \"Quarter Day_lower\": date_utils.format(date, \"HH\", this.options.language),\n \"Half Day_lower\": date_utils.format(date, \"HH\", this.options.language),\n Day_lower:\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, \"D\", this.options.language)\n : \"\",\n Week_lower:\n date.getMonth() !== last_date.getMonth()\n ? date_utils.format(date, \"D MMM\", this.options.language)\n : date_utils.format(date, \"D\", this.options.language),\n Month_lower: date_utils.format(date, \"MMMM\", this.options.language),\n Year_lower: date_utils.format(date, \"YYYY\", this.options.language),\n Hour_upper:\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, \"D MMMM\", this.options.language)\n : \"\",\n \"Quarter Day_upper\":\n date.getDate() !== last_date.getDate()\n ? date_utils.format(date, \"D MMM\", this.options.language)\n : \"\",\n \"Half Day_upper\":\n date.getDate() !== last_date.getDate()\n ? date.getMonth() !== last_date.getMonth()\n ? date_utils.format(date, \"D MMM\", this.options.language)\n : date_utils.format(date, \"D\", this.options.language)\n : \"\",\n Day_upper:\n date.getMonth() !== last_date.getMonth() || !last_date_info\n ? date_utils.format(date, \"MMMM\", this.options.language)\n : \"\",\n Week_upper:\n date.getMonth() !== last_date.getMonth()\n ? date_utils.format(date, \"MMMM\", this.options.language)\n : \"\",\n Month_upper:\n date.getFullYear() !== last_date.getFullYear()\n ? date_utils.format(date, \"YYYY\", this.options.language)\n : \"\",\n Year_upper:\n date.getFullYear() !== last_date.getFullYear()\n ? date_utils.format(date, \"YYYY\", this.options.language)\n : \"\",\n };\n let column_width = this.view_is(VIEW_MODE.MONTH) ? (date_utils.get_days_in_month(date) * this.options.column_width) / 30 : this.options.column_width;\n const base_pos = {\n x: last_date_info\n ? last_date_info.base_pos_x + last_date_info.column_width\n : 0,\n lower_y: this.options.header_height - 20,\n upper_y: this.options.header_height - 50,\n };\n const x_pos = {\n Hour_lower: column_width / 2,\n Hour_upper: column_width * 12,\n \"Quarter Day_lower\": column_width / 2,\n \"Quarter Day_upper\": column_width * 2,\n \"Half Day_lower\": column_width / 2,\n \"Half Day_upper\": column_width,\n Day_lower: column_width / 2,\n Day_upper: column_width / 2,\n Week_lower: column_width / 2,\n Week_upper: (column_width * 4) / 2,\n Month_lower: column_width / 2,\n Month_upper: column_width / 2,\n Year_lower: column_width / 2,\n Year_upper: (column_width * 30) / 2,\n };\n return {\n date,\n formatted_date: date_utils.format(date).replaceAll(' ', '_'),\n column_width,\n base_pos_x: base_pos.x,\n upper_text: this.options.lower_text ? this.options.upper_text(date, this.options.view_mode, date_text[`${this.options.view_mode}_upper`]) : date_text[`${this.options.view_mode}_upper`],\n lower_text: this.options.lower_text ? this.options.lower_text(date, this.options.view_mode, date_text[`${this.options.view_mode}_lower`]) : date_text[`${this.options.view_mode}_lower`],\n upper_x: base_pos.x + x_pos[`${this.options.view_mode}_upper`],\n upper_y: base_pos.upper_y,\n lower_x: base_pos.x + x_pos[`${this.options.view_mode}_lower`],\n lower_y: base_pos.lower_y,\n };\n }\n\n make_bars() {\n this.bars = this.tasks.map((task) => {\n const bar = new Bar(this, task);\n this.layers.bar.appendChild(bar.group);\n return bar;\n });\n }\n\n make_arrows() {\n this.arrows = [];\n for (let task of this.tasks) {\n let arrows = [];\n arrows = task.dependencies\n .map((task_id) => {\n const dependency = this.get_task(task_id);\n if (!dependency) return;\n const arrow = new Arrow(\n this,\n this.bars[dependency._index], // from_task\n this.bars[task._index], // to_task\n );\n this.layers.arrow.appendChild(arrow.element);\n return arrow;\n })\n .filter(Boolean); // filter falsy values\n this.arrows = this.arrows.concat(arrows);\n }\n }\n\n map_arrows_on_bars() {\n for (let bar of this.bars) {\n bar.arrows = this.arrows.filter((arrow) => {\n return (\n arrow.from_task.task.id === bar.task.id ||\n arrow.to_task.task.id === bar.task.id\n );\n });\n }\n }\n\n set_width() {\n const cur_width = this.$svg.getBoundingClientRect().width;\n const actual_width = this.$svg.querySelector('.grid .grid-row') ? this.$svg\n .querySelector('.grid .grid-row')\n .getAttribute('width') : 0;\n if (cur_width < actual_width) {\n this.$svg.setAttribute(\"width\", actual_width);\n }\n }\n\n set_scroll_position(date) {\n if (!date || date === 'start') {\n date = this.gantt_start\n } else if (date === 'today') {\n return this.scroll_today()\n } else if (typeof date === 'string') {\n date = date_utils.parse(date)\n }\n\n const parent_element = this.$svg.parentElement;\n if (!parent_element) return;\n\n const hours_before_first_task = date_utils.diff(\n date,\n this.gantt_start,\n \"hour\",\n ) + 24;\n\n const scroll_pos =\n (hours_before_first_task / this.options.step) *\n this.options.column_width -\n this.options.column_width;\n parent_element.scrollTo({ left: scroll_pos, behavior: 'smooth' })\n }\n\n scroll_today() {\n this.set_scroll_position(new Date())\n }\n\n bind_grid_click() {\n $.on(\n this.$svg,\n this.options.popup_trigger,\n \".grid-row, .grid-header\",\n () => {\n this.unselect_all();\n this.hide_popup();\n },\n );\n }\n\n bind_bar_events() {\n let is_dragging = false;\n let x_on_start = 0;\n let x_on_scroll_start = 0;\n let y_on_start = 0;\n let is_resizing_left = false;\n let is_resizing_right = false;\n let parent_bar_id = null;\n let bars = []; // instanceof Bar\n this.bar_being_dragged = null;\n\n function action_in_progress() {\n return is_dragging || is_resizing_left || is_resizing_right;\n }\n\n $.on(this.$svg, \"mousedown\", \".bar-wrapper, .handle\", (e, element) => {\n const bar_wrapper = $.closest(\".bar-wrapper\", element);\n bars.forEach((bar) => bar.group.classList.remove(\"active\"));\n\n if (element.classList.contains(\"left\")) {\n is_resizing_left = true;\n } else if (element.classList.contains(\"right\")) {\n is_resizing_right = true;\n } else if (element.classList.contains(\"bar-wrapper\")) {\n is_dragging = true;\n }\n\n bar_wrapper.classList.add(\"active\");\n this.popup.parent.classList.add('hidden')\n\n x_on_start = e.offsetX;\n y_on_start = e.offsetY;\n\n parent_bar_id = bar_wrapper.getAttribute(\"data-id\");\n const ids = [\n parent_bar_id,\n ...this.get_all_dependent_tasks(parent_bar_id),\n ];\n bars = ids.map((id) => this.get_bar(id));\n\n this.bar_being_dragged = parent_bar_id;\n\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n $bar.ox = $bar.getX();\n $bar.oy = $bar.getY();\n $bar.owidth = $bar.getWidth();\n $bar.finaldx = 0;\n });\n });\n $.on(this.$container, 'scroll', e => {\n let elements = document.querySelectorAll('.bar-wrapper');\n let localBars = [];\n const ids = [];\n let dx;\n if (x_on_scroll_start) {\n dx = e.currentTarget.scrollLeft - x_on_scroll_start;\n }\n\n const daysSinceStart = e.currentTarget.scrollLeft / this.options.column_width * this.options.step / 24;\n let format_str = \"D MMM\"\n if ([\"Year\", \"Month\"].includes(this.options.view_mode)) format_str = 'YYYY'\n else if ([\"Day\", \"Week\"].includes(this.options.view_mode)) format_str = 'MMMM'\n else if (this.view_is('Half Day')) format_str = 'D'\n else if (this.view_is('Hour')) format_str = \"D MMMM\"\n\n\n let currentUpper = date_utils.format(\n date_utils.add(this.gantt_start, daysSinceStart, 'day'),\n format_str\n );\n const upperTexts = Array.from(document.querySelectorAll('.upper-text'));\n const $el = upperTexts.find(el => el.textContent === currentUpper)\n if ($el && !$el.classList.contains('current-upper')) {\n const $current = document.querySelector('.current-upper')\n if ($current) {\n $current.classList.remove('current-upper')\n $current.style.left = this.upper_texts_x[$current.textContent] + 'px';\n $current.style.top = this.options.header_height - 50 + 'px';\n }\n\n $el.classList.add('current-upper')\n let dimensions = this.$svg.getBoundingClientRect()\n $el.style.left = dimensions.x + this.$container.scrollLeft + 10 + 'px';\n $el.style.top = dimensions.y + this.options.header_height - 50 + 'px';\n }\n\n Array.prototype.forEach.call(elements, function (el, i) {\n ids.push(el.getAttribute('data-id'));\n });\n\n if (dx) {\n localBars = ids.map(id => this.get_bar(id));\n if (this.options.auto_move_label) {\n localBars.forEach(bar => {\n bar.update_label_position_on_horizontal_scroll({ x: dx, sx: e.currentTarget.scrollLeft });\n });\n }\n }\n\n x_on_scroll_start = e.currentTarget.scrollLeft;\n });\n\n $.on(this.$svg, \"mousemove\", (e) => {\n if (!action_in_progress()) return;\n const dx = e.offsetX - x_on_start;\n const dy = e.offsetY - y_on_start;\n\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n $bar.finaldx = this.get_snap_position(dx);\n this.hide_popup();\n if (is_resizing_left) {\n if (parent_bar_id === bar.task.id) {\n bar.update_bar_position({\n x: $bar.ox + $bar.finaldx,\n width: $bar.owidth - $bar.finaldx,\n });\n } else {\n bar.update_bar_position({\n x: $bar.ox + $bar.finaldx,\n });\n }\n } else if (is_resizing_right) {\n if (parent_bar_id === bar.task.id) {\n bar.update_bar_position({\n width: $bar.owidth + $bar.finaldx,\n });\n }\n } else if (is_dragging && !this.options.readonly) {\n bar.update_bar_position({ x: $bar.ox + $bar.finaldx });\n }\n });\n });\n\n document.addEventListener(\"mouseup\", (e) => {\n\n is_dragging = false;\n is_resizing_left = false;\n is_resizing_right = false;\n });\n\n $.on(this.$svg, \"mouseup\", (e) => {\n this.bar_being_dragged = null;\n bars.forEach((bar) => {\n const $bar = bar.$bar;\n if (!$bar.finaldx) return;\n bar.date_changed();\n bar.set_action_completed();\n });\n });\n\n this.bind_bar_progress();\n }\n\n bind_bar_progress() {\n let x_on_start = 0;\n let y_on_start = 0;\n let is_resizing = null;\n let bar = null;\n let $bar_progress = null;\n let $bar = null;\n\n $.on(this.$svg, \"mousedown\", \".handle.progress\", (e, handle) => {\n is_resizing = true;\n x_on_start = e.offsetX;\n y_on_start = e.offsetY;\n\n const $bar_wrapper = $.closest(\".bar-wrapper\", handle);\n const id = $bar_wrapper.getAttribute(\"data-id\");\n bar = this.get_bar(id);\n\n $bar_progress = bar.$bar_progress;\n $bar = bar.$bar;\n\n $bar_progress.finaldx = 0;\n $bar_progress.owidth = $bar_progress.getWidth();\n $bar_progress.min_dx = -$bar_progress.getWidth();\n $bar_progress.max_dx = $bar.getWidth() - $bar_progress.getWidth();\n });\n\n $.on(this.$svg, \"mousemove\", (e) => {\n if (!is_resizing) return;\n let dx = e.offsetX - x_on_start;\n let dy = e.offsetY - y_on_start;\n\n if (dx > $bar_progress.max_dx) {\n dx = $bar_progress.max_dx;\n }\n if (dx < $bar_progress.min_dx) {\n dx = $bar_progress.min_dx;\n }\n\n const $handle = bar.$handle_progress;\n $.attr($bar_progress, \"width\", $bar_progress.owidth + dx);\n $.attr($handle, \"points\", bar.get_progress_polygon_points());\n $bar_progress.finaldx = dx;\n });\n\n $.on(this.$svg, \"mouseup\", () => {\n is_resizing = false;\n if (!($bar_progress && $bar_progress.finaldx)) return;\n\n $bar_progress.finaldx = 0;\n bar.progress_changed();\n bar.set_action_completed();\n bar = null;\n $bar_progress = null;\n $bar = null;\n });\n }\n\n get_all_dependent_tasks(task_id) {\n let out = [];\n let to_process = [task_id];\n while (to_process.length) {\n const deps = to_process.reduce((acc, curr) => {\n acc = acc.concat(this.dependency_map[curr]);\n return acc;\n }, []);\n\n out = out.concat(deps);\n to_process = deps.filter((d) => !to_process.includes(d));\n }\n\n return out.filter(Boolean);\n }\n\n get_snap_position(dx) {\n let odx = dx,\n rem,\n position;\n\n if (this.view_is(VIEW_MODE.WEEK)) {\n rem = dx % (this.options.column_width / 7);\n position =\n odx -\n rem +\n (rem < this.options.column_width / 14\n ? 0\n : this.options.column_width / 7);\n } else if (this.view_is(VIEW_MODE.MONTH)) {\n rem = dx % (this.options.column_width / 30);\n position =\n odx -\n rem +\n (rem < this.options.column_width / 60\n ? 0\n : this.options.column_width / 30);\n } else {\n rem = dx % this.options.column_width;\n position =\n odx -\n rem +\n (rem < this.options.column_width / 2 ? 0 : this.options.column_width);\n }\n return position;\n }\n\n unselect_all() {\n [...this.$svg.querySelectorAll(\".bar-wrapper\")].forEach((el) => {\n el.classList.remove(\"active\");\n });\n this.popup.parent.classList.remove('hidden')\n }\n\n view_is(modes) {\n if (typeof modes === \"string\") {\n return this.options.view_mode === modes;\n }\n\n if (Array.isArray(modes)) {\n return modes.some((mode) => this.options.view_mode === mode);\n }\n\n return false;\n }\n\n get_task(id) {\n return this.tasks.find((task) => {\n return task.id === id;\n });\n }\n\n get_bar(id) {\n return this.bars.find((bar) => {\n return bar.task.id === id;\n });\n }\n\n show_popup(options) {\n if (this.options.popup === false) return\n if (!this.popup) {\n this.popup = new Popup(\n this.$popup_wrapper,\n this.options.popup,\n );\n }\n this.popup.show(options);\n }\n\n hide_popup() {\n this.popup && this.popup.hide();\n }\n\n trigger_event(event, args) {\n if (this.options[\"on_\" + event]) {\n this.options[\"on_\" + event].apply(null, args);\n }\n }\n\n /**\n * Gets the oldest starting date from the list of tasks\n *\n * @returns Date\n * @memberof Gantt\n */\n get_oldest_starting_date() {\n if (!this.tasks.length) return new Date()\n return this.tasks\n .map((task) => task._start)\n .reduce((prev_date, cur_date) =>\n cur_date <= prev_date ? cur_date : prev_date,\n );\n }\n\n /**\n * Clear all elements from the parent svg element\n *\n * @memberof Gantt\n */\n clear() {\n this.$svg.innerHTML = \"\";\n this.$header?.remove?.()\n this.$current_highlight?.remove?.()\n this.popup?.hide?.()\n }\n}\n\nGantt.VIEW_MODE = VIEW_MODE;\n\nfunction generate_id(task) {\n return task.name + \"_\" + Math.random().toString(36).slice(2, 12);\n}\n"],"names":["YEAR","MONTH","DAY","HOUR","MINUTE","SECOND","MILLISECOND","SHORTENED","January","February","March","April","May","June","July","August","September","October","November","December","date_utils","parse_duration","duration","matches","exec","parseInt","scale","parse","date","date_separator","time_separator","Date","date_parts","time_parts","parts","split","map","val","vals","length","parseFloat","concat","to_string","with_time","TypeError","this","get_date_values","i","padStart","date_string","time_string","format","format_string","lang","month_name","Intl","DateTimeFormat","month","month_name_capitalized","charAt","toUpperCase","slice","values","d","format_map","YYYY","MM","DD","HH","mm","ss","SSS","D","MMMM","MMM","str","formatted_values","Object","keys","sort","a","b","forEach","key","includes","replaceAll","push","value","diff","date_a","date_b","milliseconds","seconds","hours","minutes","days","months","years","endsWith","Math","floor","today","now","add","qty","getFullYear","getMonth","getDate","getHours","getMinutes","getSeconds","getMilliseconds","start_of","scores","should_reset","_scale","clone","get_days_in_month","no_of_days","year","targetLength","padString","String","repeat","$","expr","con","document","querySelector","createSVG","tag","attrs","elem","createElementNS","attr","append_to","appendChild","innerHTML","setAttribute","animateSVG","svgElement","from","to","animatedSvgElement","dur","begin","animEl","attributeName","animateElement","calcMode","keyTimes","keySplines","cubic_bezier","getAnimationElement","event","createEvent","initEvent","eventName","dispatchEvent","name","ease","linear","on","element","selector","callback","delegate","bind","off","handler","removeEventListener","addEventListener","e","delegatedTarget","target","closest","call","parentNode","getAttribute","Bar","constructor","gantt","task","set_defaults","prepare","draw","action_completed","prepare_values","prepare_helpers","invalid","height","options","bar_height","image_size","compute_x","compute_y","compute_duration","corner_radius","bar_corner_radius","width","column_width","progress_width","progress","group","class","custom_class","important","id","bar_group","handle_group","SVGElement","prototype","getX","getY","getWidth","getHeight","getEndX","prepare_expected_progress_values","compute_expected_progress","expected_progress_width","expected_progress","draw_bar","draw_progress_bar","show_expected_progress","draw_expected_progress_bar","draw_label","draw_resize_handles","thumbnail","draw_thumbnail","$bar","x","y","rx","ry","classList","$expected_bar_progress","$bar_progress","_start","gantt_start","step","$date_highlight","createElement","style","top","header_height","left","$lower_header","prepend","x_coord","requestAnimationFrame","update_label_position","defs","clipPath","href","readonly","bar","$handle_progress","points","get_progress_polygon_points","join","bar_progress","icon_width","icon_height","setup_click_event","timeout","task_id","trigger_event","screenX","screenY","setTimeout","show_popup","offsetX","display","clearTimeout","popup","hide","popup_trigger","bar_being_dragged","subtitle","language","_end","target_element","title","update_bar_position","dependencies","dep","get_bar","reduce","_","curr","update_attr","update_handle_position","date_changed","update_expected_progressbar_position","update_progressbar_position","update_arrow_position","update_label_position_on_horizontal_scroll","sx","container","label","img","img_mask","barWidthLimit","newLabelX","newImgX","imgWidth","getBBox","labelEndX","viewportCentral","clientWidth","contains","changed","new_start_date","new_end_date","compute_start_end_date","Number","progress_changed","new_progress","compute_progress","set_action_completed","x_in_units","width_in_units","task_start","view_is","padding","_index","get_snap_position","dx","rem","position","odx","isNaN","x_offset_label_img","labelWidth","barWidth","remove","handle","arrows","arrow","update","Arrow","from_task","to_task","calculate_path","start_x","condition","start_y","end_x","end_y","from_is_below_to","curve","arrow_curve","clockwise","curve_y","offset","path","down_1","down_2","Popup","parent","custom_html","make","pointer","show","Error","html","position_meta","HTMLElement","getBoundingClientRect","opacity","VIEW_MODE","QUARTER_DAY","HALF_DAY","WEEK","VIEW_MODE_PADDING","DEFAULT_OPTIONS","view_modes","view_mode","date_format","highlight_weekend","scroll_to","lines","auto_move_label","today_button","view_mode_select","Gantt","wrapper","tasks","setup_wrapper","setup_options","setup_tasks","change_view_mode","bind_events","svg_element","wrapper_element","$svg","$container","parentElement","$popup_wrapper","view_mode_padding","entries","start","undefined","end","tmpDuration","every","deps","trim","filter","random","toString","generate_id","setup_dependencies","dependency_map","t","refresh","mode","update_view_scale","setup_dates","render","setup_gantt_dates","setup_date_values","gantt_end","viewKey","padding_start","padding_end","setHours","dates","cur_date","bind_grid_click","bind_bar_events","clear","setup_layers","make_grid","make_dates","make_bars","make_grid_extras","make_arrows","map_arrows_on_bars","set_width","set_scroll_position","layers","layer","make_grid_background","make_grid_rows","make_grid_header","make_grid_highlights","make_grid_ticks","grid_width","grid_height","rows_layer","grid","row_width","row_height","row_y","$header","$upper_header","make_side_header","$side_header","$select","$el","selected","disabled","textContent","$option","$today_button","onclick","scroll_today","min","scrollLeft","tick_x","tick_y","tick_height","$lines_layer","x1","y1","x2","y2","tick_class","highlightWeekends","setDate","getDay","computeGridHighlightDimensions","todayDate","startDate","endDate","setMonth","setFullYear","$current_highlight","create_el","classes","$today","getElementById","upper_texts_x","get_dates_to_draw","$lower_text","lower_x","lower_y","formatted_date","innerText","lower_text","upper_text","upper_x","$upper_text","upper_y","last_date","get_date_info","last_date_info","date_text","Hour_lower","Day_lower","Week_lower","Month_lower","Year_lower","Hour_upper","Day_upper","Week_upper","Month_upper","Year_upper","base_pos","base_pos_x","x_pos","bars","dependency","get_task","Boolean","cur_width","actual_width","parent_element","scroll_pos","scrollTo","behavior","unselect_all","hide_popup","is_dragging","x_on_start","x_on_scroll_start","y_on_start","is_resizing_left","is_resizing_right","parent_bar_id","bar_wrapper","offsetY","ids","get_all_dependent_tasks","ox","oy","owidth","finaldx","elements","querySelectorAll","localBars","currentTarget","daysSinceStart","format_str","currentUpper","Array","find","el","$current","dimensions","bind_bar_progress","is_resizing","min_dx","max_dx","$handle","out","to_process","acc","modes","isArray","some","args","apply","get_oldest_starting_date","prev_date"],"mappings":"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"} \ No newline at end of file diff --git a/dist/frappe-gantt.umd.cjs b/dist/frappe-gantt.umd.cjs new file mode 100644 index 0000000..1a6ed4f --- /dev/null +++ b/dist/frappe-gantt.umd.cjs @@ -0,0 +1,23 @@ +(function(x,v){typeof exports=="object"&&typeof module<"u"?module.exports=v():typeof define=="function"&&define.amd?define(v):(x=typeof globalThis<"u"?globalThis:x||self,x["frappe-gantt"]=v())})(this,function(){"use strict";const x="year",v="month",k="day",Y="hour",E="minute",A="second",L="millisecond",W={January:"Jan",February:"Feb",March:"Mar",April:"Apr",May:"May",June:"Jun",July:"Jul",August:"Aug",September:"Sep",October:"Oct",November:"Nov",December:"Dec"},h={parse_duration(o){const e=/([0-9])+(y|m|d|h|min|s|ms)/gm.exec(o);if(e!==null){if(e[2]==="y")return{duration:parseInt(e[1]),scale:"year"};if(e[2]==="m")return{duration:parseInt(e[1]),scale:"month"};if(e[2]==="d")return{duration:parseInt(e[1]),scale:"day"};if(e[2]==="h")return{duration:parseInt(e[1]),scale:"hour"};if(e[2]==="min")return{duration:parseInt(e[1]),scale:"minute"};if(e[2]==="s")return{duration:parseInt(e[1]),scale:"second"};if(e[2]==="ms")return{duration:parseInt(e[1]),scale:"millisecond"}}},parse(o,t="-",e=/[.:]/){if(o instanceof Date)return o;if(typeof o=="string"){let s,r;const i=o.split(" ");s=i[0].split(t).map(a=>parseInt(a,10)),r=i[1]&&i[1].split(e),s[1]=s[1]?s[1]-1:0;let n=s;return r&&r.length&&(r.length===4&&(r[3]="0."+r[3],r[3]=parseFloat(r[3])*1e3),n=n.concat(r)),new Date(...n)}},to_string(o,t=!1){if(!(o instanceof Date))throw new TypeError("Invalid argument type");const e=this.get_date_values(o).map((i,n)=>(n===1&&(i=i+1),n===6?D(i+"",3,"0"):D(i+"",2,"0"))),s=`${e[0]}-${e[1]}-${e[2]}`,r=`${e[3]}:${e[4]}:${e[5]}.${e[6]}`;return s+(t?" "+r:"")},format(o,t="YYYY-MM-DD HH:mm:ss.SSS",e="en"){const r=new Intl.DateTimeFormat(e,{month:"long"}).format(o),i=r.charAt(0).toUpperCase()+r.slice(1),n=this.get_date_values(o).map(g=>D(g,2,0)),a={YYYY:n[0],MM:D(+n[1]+1,2,0),DD:n[2],HH:n[3],mm:n[4],ss:n[5],SSS:n[6],D:n[2],MMMM:i,MMM:W[i]};let p=t;const _=[];return Object.keys(a).sort((g,c)=>c.length-g.length).forEach(g=>{p.includes(g)&&(p=p.replaceAll(g,`$${_.length}`),_.push(a[g]))}),_.forEach((g,c)=>{p=p.replaceAll(`$${c}`,g)}),p},diff(o,t,e=k){let s,r,i,n,a,p,_;return s=o-t,r=s/1e3,n=r/60,i=n/60,a=i/24,p=a/30,_=p/12,e.endsWith("s")||(e+="s"),Math.floor({milliseconds:s,seconds:r,minutes:n,hours:i,days:a,months:p,years:_}[e])},today(){const o=this.get_date_values(new Date).slice(0,3);return new Date(...o)},now(){return new Date},add(o,t,e){t=parseInt(t,10);const s=[o.getFullYear()+(e===x?t:0),o.getMonth()+(e===v?t:0),o.getDate()+(e===k?t:0),o.getHours()+(e===Y?t:0),o.getMinutes()+(e===E?t:0),o.getSeconds()+(e===A?t:0),o.getMilliseconds()+(e===L?t:0)];return new Date(...s)},start_of(o,t){const e={[x]:6,[v]:5,[k]:4,[Y]:3,[E]:2,[A]:1,[L]:0};function s(i){const n=e[t];return e[i]<=n}const r=[o.getFullYear(),s(x)?0:o.getMonth(),s(v)?1:o.getDate(),s(k)?0:o.getHours(),s(Y)?0:o.getMinutes(),s(E)?0:o.getSeconds(),s(A)?0:o.getMilliseconds()];return new Date(...r)},clone(o){return new Date(...this.get_date_values(o))},get_date_values(o){return[o.getFullYear(),o.getMonth(),o.getDate(),o.getHours(),o.getMinutes(),o.getSeconds(),o.getMilliseconds()]},get_days_in_month(o){const t=[31,28,31,30,31,30,31,31,30,31,30,31],e=o.getMonth();if(e!==1)return t[e];const s=o.getFullYear();return s%4===0&&s%100!=0||s%400===0?29:28}};function D(o,t,e){return o=o+"",t=t>>0,e=String(typeof e<"u"?e:" "),o.length>t?String(o):(t=t-o.length,t>e.length&&(e+=e.repeat(t/e.length)),e.slice(0,t)+String(o))}function l(o,t){return typeof o=="string"?(t||document).querySelector(o):o||null}function u(o,t){const e=document.createElementNS("http://www.w3.org/2000/svg",o);for(let s in t)s==="append_to"?t.append_to.appendChild(e):s==="innerHTML"?e.innerHTML=t.innerHTML:s==="clipPath"?e.setAttribute("clip-path","url(#"+t[s]+")"):e.setAttribute(s,t[s]);return e}function H(o,t,e,s){const r=X(o,t,e,s);if(r===o){const i=document.createEvent("HTMLEvents");i.initEvent("click",!0,!0),i.eventName="click",r.dispatchEvent(i)}}function X(o,t,e,s,r="0.4s",i="0.1s"){const n=o.querySelector("animate");if(n)return l.attr(n,{attributeName:t,from:e,to:s,dur:r,begin:"click + "+i}),o;const a=u("animate",{attributeName:t,from:e,to:s,dur:r,begin:i,calcMode:"spline",values:e+";"+s,keyTimes:"0; 1",keySplines:O("ease-out")});return o.appendChild(a),o}function O(o){return{ease:".25 .1 .25 1",linear:"0 0 1 1","ease-in":".42 0 1 1","ease-out":"0 0 .58 1","ease-in-out":".42 0 .58 1"}[o]}l.on=(o,t,e,s)=>{s?l.delegate(o,t,e,s):(s=e,l.bind(o,t,s))},l.off=(o,t,e)=>{o.removeEventListener(t,e)},l.bind=(o,t,e)=>{t.split(/\s+/).forEach(function(s){o.addEventListener(s,e)})},l.delegate=(o,t,e,s)=>{o.addEventListener(t,function(r){const i=r.target.closest(e);i&&(r.delegatedTarget=i,s.call(this,r,i))})},l.closest=(o,t)=>t?t.matches(o)?t:l.closest(o,t.parentNode):null,l.attr=(o,t,e)=>{if(!e&&typeof t=="string")return o.getAttribute(t);if(typeof t=="object"){for(let s in t)l.attr(o,s,t[s]);return}o.setAttribute(t,e)};class C{constructor(t,e){this.set_defaults(t,e),this.prepare(),this.draw(),this.bind()}set_defaults(t,e){this.action_completed=!1,this.gantt=t,this.task=e}prepare(){this.prepare_values(),this.prepare_helpers()}prepare_values(){this.invalid=this.task.invalid,this.height=this.gantt.options.bar_height,this.image_size=this.height-5,this.compute_x(),this.compute_y(),this.compute_duration(),this.corner_radius=this.gantt.options.bar_corner_radius,this.width=this.gantt.options.column_width*this.duration,this.progress_width=this.gantt.options.column_width*this.duration*(this.task.progress/100)||0,this.group=u("g",{class:"bar-wrapper"+(this.task.custom_class?" "+this.task.custom_class:"")+(this.task.important?" important":""),"data-id":this.task.id}),this.bar_group=u("g",{class:"bar-group",append_to:this.group}),this.handle_group=u("g",{class:"handle-group",append_to:this.group})}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()}draw_bar(){this.$bar=u("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}),H(this.$bar,"width",0,this.width),this.invalid&&this.$bar.classList.add("bar-invalid")}draw_expected_progress_bar(){this.invalid||(this.$expected_bar_progress=u("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}),H(this.$expected_bar_progress,"width",0,this.expected_progress_width))}draw_progress_bar(){if(this.invalid)return;this.$bar_progress=u("rect",{x:this.x,y:this.y,width:this.progress_width,height:this.height,rx:this.corner_radius,ry:this.corner_radius,class:"bar-progress",append_to:this.bar_group});const t=h.diff(this.task._start,this.gantt.gantt_start,"hour")/this.gantt.options.step*this.gantt.options.column_width;let e=document.createElement("div");e.id=`${this.task.id}-highlight`,e.classList.add("date-highlight"),e.style.height=this.height*.8+"px",e.style.width=this.width+"px",e.style.top=this.gantt.options.header_height-25+"px",e.style.left=t+"px",this.$date_highlight=e,this.gantt.$lower_header.prepend(e),H(this.$bar_progress,"width",0,this.progress_width)}draw_label(){let t=this.x+this.$bar.getWidth()/2;this.task.thumbnail&&(t=this.x+this.image_size+5),u("text",{x:t,y:this.y+this.height/2,innerHTML:this.task.name,class:"bar-label",append_to:this.bar_group}),requestAnimationFrame(()=>this.update_label_position())}draw_thumbnail(){let t=10,e=2,s,r;s=u("defs",{append_to:this.bar_group}),u("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:s}),r=u("clipPath",{id:"clip_"+this.task.id,append_to:s}),u("use",{href:"#rect_"+this.task.id,append_to:r}),u("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_resize_handles(){if(this.invalid||this.gantt.options.readonly)return;const t=this.$bar,e=8;u("rect",{x:t.getX()+t.getWidth()+e-4,y:t.getY()+1,width:e,height:this.height-2,rx:this.corner_radius,ry:this.corner_radius,class:"handle right",append_to:this.handle_group}),u("rect",{x:t.getX()-e-4,y:t.getY()+1,width:e,height:this.height-2,rx:this.corner_radius,ry:this.corner_radius,class:"handle left",append_to:this.handle_group}),this.$handle_progress=u("polygon",{points:this.get_progress_polygon_points().join(","),class:"handle progress",append_to:this.handle_group})}get_progress_polygon_points(){const t=this.$bar_progress;let e=10,s=15;return[t.getEndX()-e/2,t.getY()+t.getHeight()/2,t.getEndX(),t.getY()+t.getHeight()/2-s/2,t.getEndX()+e/2,t.getY()+t.getHeight()/2,t.getEndX(),t.getY()+t.getHeight()/2+s/2,t.getEndX()-e/2,t.getY()+t.getHeight()/2]}bind(){this.invalid||this.setup_click_event()}setup_click_event(){let t=this.task.id;l.on(this.group,"mouseover",s=>{this.gantt.trigger_event("hover",[this.task,s.screenX,s.screenY,s])});let e;l.on(this.group,"mouseenter",s=>e=setTimeout(()=>{this.show_popup(s.offsetX),document.querySelector(`#${t}-highlight`).style.display="block"},200)),l.on(this.group,"mouseleave",()=>{var s,r;clearTimeout(e),(r=(s=this.gantt.popup)==null?void 0:s.hide)==null||r.call(s),document.querySelector(`#${t}-highlight`).style.display="none"}),l.on(this.group,this.gantt.options.popup_trigger,()=>{this.gantt.trigger_event("click",[this.task])}),l.on(this.group,"dblclick",s=>{this.action_completed||this.gantt.trigger_event("double_click",[this.task])})}show_popup(t){if(this.gantt.bar_being_dragged)return;const e=h.format(this.task._start,"MMM D",this.gantt.options.language),s=h.format(h.add(this.task._end,-1,"second"),"MMM D",this.gantt.options.language),r=`${e} - ${s}
Progress: ${this.task.progress}`;this.gantt.show_popup({x:t,target_element:this.$bar,title:this.task.name,subtitle:r,task:this.task})}update_bar_position({x:t=null,width:e=null}){const s=this.$bar;if(t){if(!this.task.dependencies.map(n=>this.gantt.get_bar(n).$bar.getX()).reduce((n,a)=>t>=a,t)){e=null;return}this.update_attr(s,"x",t),this.$date_highlight.style.left=t+"px"}e&&(this.update_attr(s,"width",e),this.$date_highlight.style.width=e+"px"),this.update_label_position(),this.update_handle_position(),this.gantt.options.show_expected_progress&&(this.date_changed(),this.compute_duration(),this.update_expected_progressbar_position()),this.update_progressbar_position(),this.update_arrow_position()}update_label_position_on_horizontal_scroll({x:t,sx:e}){const s=document.querySelector(".gantt-container"),r=this.group.querySelector(".bar-label"),i=this.group.querySelector(".bar-img")||"",n=this.bar_group.querySelector(".img_mask")||"";let a=this.$bar.getX()+this.$bar.getWidth(),p=r.getX()+t,_=i&&i.getX()+t||0,g=i&&i.getBBox().width+7||7,c=p+r.getBBox().width+7,f=e+s.clientWidth/2;r.classList.contains("big")||(c0&&cthis.$bar.getX()&&t<0&&c>f)&&(r.setAttribute("x",p),i&&(i.setAttribute("x",_),n.setAttribute("x",_)))}date_changed(){let t=!1;const{new_start_date:e,new_end_date:s}=this.compute_start_end_date();Number(this.task._start)!==Number(e)&&(t=!0,this.task._start=e),Number(this.task._end)!==Number(s)&&(t=!0,this.task._end=s),t&&this.gantt.trigger_event("date_change",[this.task,e,h.add(s,-1,"second")])}progress_changed(){const t=this.compute_progress();this.task.progress=t,this.gantt.trigger_event("progress_change",[this.task,t])}set_action_completed(){this.action_completed=!0,setTimeout(()=>this.action_completed=!1,1e3)}compute_start_end_date(){const t=this.$bar,e=t.getX()/this.gantt.options.column_width,s=h.add(this.gantt.gantt_start,e*this.gantt.options.step,"hour"),r=t.getWidth()/this.gantt.options.column_width,i=h.add(s,r*this.gantt.options.step,"hour");return{new_start_date:s,new_end_date:i}}compute_progress(){const t=this.$bar_progress.getWidth()/this.$bar.getWidth()*100;return parseInt(t,10)}compute_expected_progress(){this.expected_progress=h.diff(h.today(),this.task._start,"hour")/this.gantt.options.step,this.expected_progress=(this.expected_progressp?(s.classList.add("big"),r?(r.setAttribute("x",e.getX()+e.getWidth()+i),t.setAttribute("x",e.getX()+e.getWidth()+i),s.setAttribute("x",e.getX()+e.getWidth()+n)):s.setAttribute("x",e.getX()+e.getWidth()+i)):(s.classList.remove("big"),r?(r.setAttribute("x",e.getX()+i),t.setAttribute("x",e.getX()+i),s.setAttribute("x",e.getX()+p/2+n)):s.setAttribute("x",e.getX()+p/2-a/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()-12),this.handle_group.querySelector(".handle.right").setAttribute("x",t.getEndX()+4);const e=this.group.querySelector(".handle.progress");e&&e.setAttribute("points",this.get_progress_polygon_points())}update_arrow_position(){this.arrows=this.arrows||[];for(let t of this.arrows)t.update()}}class N{constructor(t,e,s){this.gantt=t,this.from_task=e,this.to_task=s,this.calculate_path(),this.draw()}calculate_path(){let t=this.from_task.$bar.getX()+this.from_task.$bar.getWidth()/2;const e=()=>this.to_task.$bar.getX()this.from_task.$bar.getX()+this.gantt.options.padding;for(;e();)t-=10;const s=this.gantt.options.header_height+this.gantt.options.bar_height+(this.gantt.options.padding+this.gantt.options.bar_height)*this.from_task.task._index+this.gantt.options.padding,r=this.to_task.$bar.getX()-this.gantt.options.padding/2-7,i=this.gantt.options.header_height+this.gantt.options.bar_height/2+(this.gantt.options.padding+this.gantt.options.bar_height)*this.to_task.task._index+this.gantt.options.padding,n=this.from_task.task._index>this.to_task.task._index,a=this.gantt.options.arrow_curve,p=n?1:0,_=n?-a:a,g=n?i+this.gantt.options.arrow_curve:i-this.gantt.options.arrow_curve;if(this.path=` + M ${t} ${s} + V ${g} + a ${a} ${a} 0 0 ${p} ${a} ${_} + L ${r} ${i} + m -5 -5 + l 5 5 + l -5 5`,this.to_task.$bar.getX() +
+
+ `,this.hide(),this.title=this.parent.querySelector(".title"),this.subtitle=this.parent.querySelector(".subtitle"),this.pointer=this.parent.querySelector(".pointer")}show(t){if(!t.target_element)throw new Error("target_element is required to show popup");const e=t.target_element;if(this.custom_html){let r=this.custom_html(t.task);r+='
',this.parent.innerHTML=r,this.pointer=this.parent.querySelector(".pointer")}else this.title.innerHTML=t.title,this.subtitle.innerHTML=t.subtitle;let s;e instanceof HTMLElement?s=e.getBoundingClientRect():e instanceof SVGElement&&(s=t.target_element.getBBox()),this.parent.style.left=t.x-this.parent.clientWidth/2+"px",this.parent.style.top=s.y+s.height+10+"px",this.pointer.style.left=this.parent.clientWidth/2+"px",this.pointer.style.top="-15px",this.parent.style.opacity=1}hide(){this.parent.style.opacity=0,this.parent.style.left=0}}const d={HOUR:"Hour",QUARTER_DAY:"Quarter Day",HALF_DAY:"Half Day",DAY:"Day",WEEK:"Week",MONTH:"Month",YEAR:"Year"},F={HOUR:["7d","7d"],QUARTER_DAY:["7d","7d"],HALF_DAY:["7d","7d"],DAY:["1m","1m"],WEEK:["1m","1m"],MONTH:["1m","1m"],YEAR:["2y","2y"]},I={header_height:65,column_width:30,step:24,view_modes:[...Object.values(d)],bar_height:30,bar_corner_radius:3,arrow_curve:5,padding:18,view_mode:"Day",date_format:"YYYY-MM-DD",popup_trigger:"click",show_expected_progress:!1,popup:null,language:"en",readonly:!1,highlight_weekend:!0,scroll_to:"start",lines:"both",auto_move_label:!0,today_button:!0,view_mode_select:!1};class T{constructor(t,e,s){this.setup_wrapper(t),this.setup_options(s),this.setup_tasks(e),this.change_view_mode(),this.bind_events()}setup_wrapper(t){let e,s;if(typeof t=="string"&&(t=document.querySelector(t)),t instanceof HTMLElement)s=t,e=t.querySelector("svg");else if(t instanceof SVGElement)e=t;else throw new TypeError("Frappé 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=u("svg",{append_to:s,class:"gantt"}),this.$container=document.createElement("div"),this.$container.classList.add("gantt-container"),this.$svg.parentElement.appendChild(this.$container),this.$container.appendChild(this.$svg),this.$popup_wrapper=document.createElement("div"),this.$popup_wrapper.classList.add("popup-wrapper"),this.$container.appendChild(this.$popup_wrapper)}setup_options(t){this.options={...I,...t},t.view_mode_padding||(t.view_mode_padding={});for(let[e,s]of Object.entries(t.view_mode_padding))typeof s=="string"&&(t.view_mode_padding[e]=[s,s]);this.options.view_mode_padding={...F,...t.view_mode_padding}}setup_tasks(t){this.tasks=t.map((e,s)=>{if(e._start=h.parse(e.start),e.end===void 0&&e.duration!==void 0&&(e.end=e._start,e.duration.split(" ").forEach(a=>{let{duration:p,scale:_}=h.parse_duration(a);e.end=h.add(e.end,p,_)})),e._end=h.parse(e.end),h.diff(e._end,e._start,"year")<0)throw Error("start of task can't be after end of task: in task #, "+(s+1));if(h.diff(e._end,e._start,"year")>10&&(e.end=null),e._index=s,!e.start&&!e.end){const n=h.today();e._start=n,e._end=h.add(n,2,"day")}if(!e.start&&e.end&&(e._start=h.add(e._end,-2,"day")),e.start&&!e.end&&(e._end=h.add(e._start,2,"day")),h.get_date_values(e._end).slice(3).every(n=>n===0)&&(e._end=h.add(e._end,24,"hour")),(!e.start||!e.end)&&(e.invalid=!0),typeof e.dependencies=="string"||!e.dependencies){let n=[];e.dependencies&&(n=e.dependencies.split(",").map(a=>a.trim().replaceAll(" ","_")).filter(a=>a)),e.dependencies=n}return e.id?typeof e.id=="string"?e.id=e.id.replaceAll(" ","_"):e.id=`${e.id}`:e.id=q(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()}change_view_mode(t=this.options.view_mode){this.update_view_scale(t),this.setup_dates(),this.render(),this.trigger_event("view_change",[t])}update_view_scale(t){this.options.view_mode=t,t===d.HOUR?(this.options.step=24/24,this.options.column_width=38):t===d.DAY?(this.options.step=24,this.options.column_width=38):t===d.HALF_DAY?(this.options.step=24/2,this.options.column_width=38):t===d.QUARTER_DAY?(this.options.step=24/4,this.options.column_width=38):t===d.WEEK?(this.options.step=24*7,this.options.column_width=140):t===d.MONTH?(this.options.step=24*30,this.options.column_width=120):t===d.YEAR&&(this.options.step=24*365,this.options.column_width=120)}setup_dates(){this.setup_gantt_dates(),this.setup_date_values()}setup_gantt_dates(){this.gantt_start=this.gantt_end=null;for(let a of this.tasks)(!this.gantt_start||a._startthis.gantt_end)&&(this.gantt_end=a._end);let t,e;this.gantt_start?t=h.start_of(this.gantt_start,"day"):t=new Date,this.gantt_end?e=h.start_of(this.gantt_end,"day"):e=new Date;let s;for(let[a,p]of Object.entries(d))p===this.options.view_mode&&(s=a);const[r,i]=this.options.view_mode_padding[s].map(h.parse_duration);t=h.add(t,-r.duration,r.scale);let n;this.view_is(d.YEAR)?n="YYYY":this.view_is(d.MONTH)?n="YYYY-MM":this.view_is(d.DAY)?n="YYYY-MM-DD":n="YYYY-MM-DD HH",this.gantt_start=h.parse(h.format(t,n)),this.gantt_start.setHours(0,0,0,0),this.gantt_end=h.add(e,i.duration,i.scale)}setup_date_values(){this.dates=[];let t=null;for(;t===null||t=1&&p.getDate()<8&&(_+=" thick"),this.view_is(d.MONTH)&&p.getMonth()%3===0&&(_+=" thick"),u("path",{d:`M ${t} ${e} v ${s}`,class:_,append_to:this.layers.grid}),this.view_is(d.MONTH)?t+=h.get_days_in_month(p)*this.options.column_width/30:t+=this.options.column_width}}highlightWeekends(){if(!(!this.view_is("Day")&&!this.view_is("Half Day"))){for(let t=new Date(this.gantt_start);t<=this.gantt_end;t.setDate(t.getDate()+1))if(t.getDay()===0||t.getDay()===6){const e=h.diff(t,this.gantt_start,"hour")/this.options.step*this.options.column_width,s=(this.options.bar_height+this.options.padding)*this.tasks.length;u("rect",{x:e,y:this.options.header_height+this.options.padding/2,width:(this.view_is("Day")?1:2)*this.options.column_width,height:s,class:"holiday-highlight",append_to:this.layers.grid})}}}computeGridHighlightDimensions(t){let e=this.options.column_width/2;if(this.view_is(d.DAY)){let s=h.today();return{x:e+h.diff(s,this.gantt_start,"hour")/this.options.step*this.options.column_width,date:s}}for(let s of this.dates){const r=new Date,i=new Date(s),n=new Date(s);switch(t){case d.WEEK:n.setDate(s.getDate()+7);break;case d.MONTH:n.setMonth(s.getMonth()+1);break;case d.YEAR:n.setFullYear(s.getFullYear()+1);break}if(r>=i&&r<=n)return{x:e,date:i};e+=this.options.column_width}}make_grid_highlights(){if(this.options.highlight_weekend&&this.highlightWeekends(),this.view_is(d.DAY)||this.view_is(d.WEEK)||this.view_is(d.MONTH)||this.view_is(d.YEAR)){const{x:t,date:e}=this.computeGridHighlightDimensions(this.options.view_mode),s=this.options.header_height+this.options.padding/2,r=(this.options.bar_height+this.options.padding)*this.tasks.length;this.$current_highlight=this.create_el({top:s,left:t,height:r,classes:"current-highlight",append_to:this.$container});let i=document.getElementById(h.format(e).replaceAll(" ","_"));i.classList.add("current-date-highlight"),i.style.top=+i.style.top.slice(0,-2)-4+"px",i.style.left=+i.style.left.slice(0,-2)-8+"px"}}create_el({left:t,top:e,width:s,height:r,id:i,classes:n,append_to:a}){let p=document.createElement("div");return p.classList.add(n),p.style.top=e+"px",p.style.left=t+"px",i&&(p.id=i),s&&(p.style.width=r+"px"),r&&(p.style.height=r+"px"),a.appendChild(p),p}make_dates(){this.upper_texts_x={},this.get_dates_to_draw().forEach((t,e)=>{let s=this.create_el({left:t.lower_x,top:t.lower_y,id:t.formatted_date,classes:"lower-text",append_to:this.$lower_header});if(s.innerText=t.lower_text,s.style.left=+s.style.left.slice(0,-2)-s.clientWidth/2+"px",t.upper_text){this.upper_texts_x[t.upper_text]=t.upper_x;let r=document.createElement("div");r.classList.add("upper-text"),r.style.left=t.upper_x+"px",r.style.top=t.upper_y+"px",r.innerText=t.upper_text,this.$upper_header.appendChild(r),t.upper_x>this.layers.grid.getBBox().width&&r.remove()}})}get_dates_to_draw(){let t=null;return this.dates.map((s,r)=>{const i=this.get_date_info(s,t,r);return t=i,i})}get_date_info(t,e){let s=e?e.date:h.add(t,1,"day");const r={Hour_lower:h.format(t,"HH",this.options.language),"Quarter Day_lower":h.format(t,"HH",this.options.language),"Half Day_lower":h.format(t,"HH",this.options.language),Day_lower:t.getDate()!==s.getDate()?h.format(t,"D",this.options.language):"",Week_lower:t.getMonth()!==s.getMonth()?h.format(t,"D MMM",this.options.language):h.format(t,"D",this.options.language),Month_lower:h.format(t,"MMMM",this.options.language),Year_lower:h.format(t,"YYYY",this.options.language),Hour_upper:t.getDate()!==s.getDate()?h.format(t,"D MMMM",this.options.language):"","Quarter Day_upper":t.getDate()!==s.getDate()?h.format(t,"D MMM",this.options.language):"","Half Day_upper":t.getDate()!==s.getDate()?t.getMonth()!==s.getMonth()?h.format(t,"D MMM",this.options.language):h.format(t,"D",this.options.language):"",Day_upper:t.getMonth()!==s.getMonth()||!e?h.format(t,"MMMM",this.options.language):"",Week_upper:t.getMonth()!==s.getMonth()?h.format(t,"MMMM",this.options.language):"",Month_upper:t.getFullYear()!==s.getFullYear()?h.format(t,"YYYY",this.options.language):"",Year_upper:t.getFullYear()!==s.getFullYear()?h.format(t,"YYYY",this.options.language):""};let i=this.view_is(d.MONTH)?h.get_days_in_month(t)*this.options.column_width/30:this.options.column_width;const n={x:e?e.base_pos_x+e.column_width:0,lower_y:this.options.header_height-20,upper_y:this.options.header_height-50},a={Hour_lower:i/2,Hour_upper:i*12,"Quarter Day_lower":i/2,"Quarter Day_upper":i*2,"Half Day_lower":i/2,"Half Day_upper":i,Day_lower:i/2,Day_upper:i/2,Week_lower:i/2,Week_upper:i*4/2,Month_lower:i/2,Month_upper:i/2,Year_lower:i/2,Year_upper:i*30/2};return{date:t,formatted_date:h.format(t).replaceAll(" ","_"),column_width:i,base_pos_x:n.x,upper_text:this.options.lower_text?this.options.upper_text(t,this.options.view_mode,r[`${this.options.view_mode}_upper`]):r[`${this.options.view_mode}_upper`],lower_text:this.options.lower_text?this.options.lower_text(t,this.options.view_mode,r[`${this.options.view_mode}_lower`]):r[`${this.options.view_mode}_lower`],upper_x:n.x+a[`${this.options.view_mode}_upper`],upper_y:n.upper_y,lower_x:n.x+a[`${this.options.view_mode}_lower`],lower_y:n.lower_y}}make_bars(){this.bars=this.tasks.map(t=>{const e=new C(this,t);return this.layers.bar.appendChild(e.group),e})}make_arrows(){this.arrows=[];for(let t of this.tasks){let e=[];e=t.dependencies.map(s=>{const r=this.get_task(s);if(!r)return;const i=new N(this,this.bars[r._index],this.bars[t._index]);return this.layers.arrow.appendChild(i.element),i}).filter(Boolean),this.arrows=this.arrows.concat(e)}}map_arrows_on_bars(){for(let t of this.bars)t.arrows=this.arrows.filter(e=>e.from_task.task.id===t.task.id||e.to_task.task.id===t.task.id)}set_width(){const t=this.$svg.getBoundingClientRect().width,e=this.$svg.querySelector(".grid .grid-row")?this.$svg.querySelector(".grid .grid-row").getAttribute("width"):0;t{this.unselect_all(),this.hide_popup()})}bind_bar_events(){let t=!1,e=0,s=0,r=0,i=!1,n=!1,a=null,p=[];this.bar_being_dragged=null;function _(){return t||i||n}l.on(this.$svg,"mousedown",".bar-wrapper, .handle",(g,c)=>{const f=l.closest(".bar-wrapper",c);p.forEach(b=>b.group.classList.remove("active")),c.classList.contains("left")?i=!0:c.classList.contains("right")?n=!0:c.classList.contains("bar-wrapper")&&(t=!0),f.classList.add("active"),this.popup&&this.popup.parent.classList.add("hidden"),e=g.offsetX,r=g.offsetY,a=f.getAttribute("data-id"),p=[a,...this.get_all_dependent_tasks(a)].map(b=>this.get_bar(b)),this.bar_being_dragged=a,p.forEach(b=>{const y=b.$bar;y.ox=y.getX(),y.oy=y.getY(),y.owidth=y.getWidth(),y.finaldx=0})}),l.on(this.$container,"scroll",g=>{let c=document.querySelectorAll(".bar-wrapper"),f=[];const m=[];let b;s&&(b=g.currentTarget.scrollLeft-s);const y=g.currentTarget.scrollLeft/this.options.column_width*this.options.step/24;let $="D MMM";["Year","Month"].includes(this.options.view_mode)?$="YYYY":["Day","Week"].includes(this.options.view_mode)?$="MMMM":this.view_is("Half Day")?$="D":this.view_is("Hour")&&($="D MMMM");let z=h.format(h.add(this.gantt_start,y,"day"),$);const M=Array.from(document.querySelectorAll(".upper-text")).find(w=>w.textContent===z);if(M&&!M.classList.contains("current-upper")){const w=document.querySelector(".current-upper");w&&(w.classList.remove("current-upper"),w.style.left=this.upper_texts_x[w.textContent]+"px",w.style.top=this.options.header_height-50+"px"),M.classList.add("current-upper");let S=this.$svg.getBoundingClientRect();M.style.left=S.x+this.$container.scrollLeft+10+"px",M.style.top=S.y+this.options.header_height-50+"px"}Array.prototype.forEach.call(c,function(w,S){m.push(w.getAttribute("data-id"))}),b&&(f=m.map(w=>this.get_bar(w)),this.options.auto_move_label&&f.forEach(w=>{w.update_label_position_on_horizontal_scroll({x:b,sx:g.currentTarget.scrollLeft})})),s=g.currentTarget.scrollLeft}),l.on(this.$svg,"mousemove",g=>{if(!_())return;const c=g.offsetX-e;g.offsetY-r,p.forEach(f=>{const m=f.$bar;m.finaldx=this.get_snap_position(c),this.hide_popup(),i?a===f.task.id?f.update_bar_position({x:m.ox+m.finaldx,width:m.owidth-m.finaldx}):f.update_bar_position({x:m.ox+m.finaldx}):n?a===f.task.id&&f.update_bar_position({width:m.owidth+m.finaldx}):t&&!this.options.readonly&&f.update_bar_position({x:m.ox+m.finaldx})})}),document.addEventListener("mouseup",g=>{t=!1,i=!1,n=!1}),l.on(this.$svg,"mouseup",g=>{this.bar_being_dragged=null,p.forEach(c=>{c.$bar.finaldx&&(c.date_changed(),c.set_action_completed())})}),this.bind_bar_progress()}bind_bar_progress(){let t=0,e=0,s=null,r=null,i=null,n=null;l.on(this.$svg,"mousedown",".handle.progress",(a,p)=>{s=!0,t=a.offsetX,e=a.offsetY;const g=l.closest(".bar-wrapper",p).getAttribute("data-id");r=this.get_bar(g),i=r.$bar_progress,n=r.$bar,i.finaldx=0,i.owidth=i.getWidth(),i.min_dx=-i.getWidth(),i.max_dx=n.getWidth()-i.getWidth()}),l.on(this.$svg,"mousemove",a=>{if(!s)return;let p=a.offsetX-t;a.offsetY-e,p>i.max_dx&&(p=i.max_dx),p{s=!1,i&&i.finaldx&&(i.finaldx=0,r.progress_changed(),r.set_action_completed(),r=null,i=null,n=null)})}get_all_dependent_tasks(t){let e=[],s=[t];for(;s.length;){const r=s.reduce((i,n)=>(i=i.concat(this.dependency_map[n]),i),[]);e=e.concat(r),s=r.filter(i=>!s.includes(i))}return e.filter(Boolean)}get_snap_position(t){let e=t,s,r;return this.view_is(d.WEEK)?(s=t%(this.options.column_width/7),r=e-s+(s{t.classList.remove("active")}),this.popup&&this.popup.parent.classList.remove("hidden")}view_is(t){return typeof t=="string"?this.options.view_mode===t:Array.isArray(t)?t.some(e=>this.options.view_mode===e):!1}get_task(t){return this.tasks.find(e=>e.id===t)}get_bar(t){return this.bars.find(e=>e.task.id===t)}show_popup(t){this.options.popup!==!1&&(this.popup||(this.popup=new R(this.$popup_wrapper,this.options.popup)),this.popup.show(t))}hide_popup(){this.popup&&this.popup.hide()}trigger_event(t,e){this.options["on_"+t]&&this.options["on_"+t].apply(null,e)}get_oldest_starting_date(){return this.tasks.length?this.tasks.map(t=>t._start).reduce((t,e)=>e<=t?e:t):new Date}clear(){var t,e,s,r,i,n;this.$svg.innerHTML="",(e=(t=this.$header)==null?void 0:t.remove)==null||e.call(t),(r=(s=this.$current_highlight)==null?void 0:s.remove)==null||r.call(s),(n=(i=this.popup)==null?void 0:i.hide)==null||n.call(i)}}T.VIEW_MODE=d;function q(o){return o.name+"_"+Math.random().toString(36).slice(2,12)}return T}); diff --git a/dist/style.css b/dist/style.css new file mode 100644 index 0000000..4ea27cc --- /dev/null +++ b/dist/style.css @@ -0,0 +1 @@ +:root{--bar-color-dark: #616161;--bar-stroke-dark: #c6ccd2;--border-color-dark: #616161;--light-bg-dark: #3e3e3e;--light-border-color-dark: #3e3e3e;--text-muted-dark: #eee;--text-light-dark: #ececec;--text-color-dark: #f7f7f7;--blue-dark: #8a8aff}.dark>.gantt-container .gantt .grid-row{fill:#252525}.dark>.gantt-container .gantt .row-line{stroke:var(--light-border-color-dark)}.dark>.gantt-container .gantt .tick{stroke:var(--border-color-dark)}.dark>.gantt-container .gantt .holiday-highlight{fill:var(--light-bg-dark)}.dark>.gantt-container .gantt .arrow{stroke:var(--text-muted-dark)}.dark>.gantt-container .gantt .bar{fill:var(--bar-color-dark);stroke:none}.dark>.gantt-container .gantt .bar-progress{fill:var(--blue-dark)}.dark>.gantt-container .gantt .bar-invalid{fill:transparent;stroke:var(--bar-stroke-dark)}:is(.dark>.gantt-container .gantt .bar-invalid)~.bar-label{fill:var(--text-light-dark)}.dark>.gantt-container .gantt .bar-label.big{fill:var(--text-light-dark)}.dark>.gantt-container .gantt .bar-wrapper:hover .bar{fill:lighten(var(--bar-color-dark, 5))}.dark>.gantt-container .gantt .bar-wrapper:hover .bar-progress{fill:lighten(var(--blue-dark, 5))}.dark>.gantt-container .gantt .bar-wrapper.active .bar{fill:lighten(var(--bar-color-dark, 5))}.dark>.gantt-container .gantt .bar-wrapper.active .bar-progress{fill:lighten(var(--blue-dark, 5))}.dark>.gantt-container .grid-header{background-color:#252525}.dark>.gantt-container .popup-wrapper{background-color:#333}.dark>.gantt-container .popup-wrapper .title{border-color:lighten(var(--blue-dark, 5))}.dark>.gantt-container .popup-wrapper .pointer{border-top-color:#333}:root{--bar-color: #fff;--bar-color-important: #94c4f4;--bar-stroke: #fff;--dark-stroke-color: #e0e0e0;--stroke-color: #ebeef0;--light-bg: #f5f5f5;--light-border-color: #ebeff2;--light-yellow: #f6e796;--holiday-color: #f9fafa;--text-muted: #666;--text-grey: #98a1a9;--text-light: #fff;--text-dark: #111;--progress: #ebeef0;--handle-color: #dcdce4;--handle-color-important: #94c4f4;--light-blue: #c4c4e9;--middle-blue: #62b2f9;--dark-blue: #2c94ec}.gantt-container{line-height:14.5px;position:relative;overflow:auto;font-size:12px;height:500px}.gantt-container .popup-wrapper{position:absolute;top:0;left:0;background:#171b1f;padding:10px;border-radius:5px;width:max-content}.gantt-container .popup-wrapper.hidden{opacity:0!important}.gantt-container .popup-wrapper .title{margin-bottom:5px;text-align:-webkit-center;text-align:center;color:var(--text-light)}.gantt-container .popup-wrapper .subtitle{color:var(--text-grey)}.gantt-container .popup-wrapper .pointer{position:absolute;height:5px;margin:0 0 0 -5px;border:5px solid transparent;border-bottom-color:#000c}.gantt-container .grid-header{background-color:#fff;position:sticky;top:0;left:0;z-index:10}.gantt-container .lower-text,.gantt-container .upper-text{text-anchor:middle;color:var(--text-dark)}.gantt-container .upper-header{height:40px}.gantt-container .lower-header{height:30px}.gantt-container .lower-text{font-size:14px;position:absolute;width:fit-content}.gantt-container .upper-text{position:absolute;width:fit-content;font-weight:500;font-size:16px}.gantt-container .current-upper{position:fixed}.gantt-container .side-header{position:fixed;padding:0 10px;margin-right:10px;background:#fff;line-height:20px;font-weight:400}.gantt-container .today-button,.gantt-container .viewmode-select{background:#f4f5f6;text-align:-webkit-center;text-align:center;border:none;color:var(--text-dark);padding:4px 10px;border-radius:8px;height:25px}.gantt-container .viewmode-select{outline:none!important;padding:4px 8px;margin-right:4px;text-indent:1px;text-overflow:""}.gantt-container .date-highlight{background-color:var(--progress);border-radius:12px;position:absolute;display:none}.gantt-container .current-highlight{position:absolute;background:var(--dark-blue);width:1px}.gantt-container .current-date-highlight{background:var(--dark-blue);color:var(--text-light);padding:4px 8px;border-radius:200px}.gantt{user-select:none;-webkit-user-select:none;position:absolute}.gantt .grid-background{fill:none}.gantt .grid-row{fill:#fff}.gantt .row-line{stroke:var(--light-border-color)}.gantt .tick{stroke:var(--stroke-color);stroke-width:.4}.gantt .tick.thick{stroke:var(--dark-stroke-color);stroke-width:.7}.gantt .holiday-highlight{fill:var(--holiday-color)}.gantt .arrow{fill:none;stroke:#9fa9b1;stroke-width:1}.gantt .bar-wrapper .bar{fill:var(--bar-color);stroke:var(--bar-stroke);stroke-width:0;transition:stroke-width .3s ease}.gantt .bar-progress{fill:var(--progress)}.gantt .bar-expected-progress{fill:var(--light-blue)}.gantt .bar-invalid{fill:transparent;stroke:var(--bar-stroke);stroke-width:1;stroke-dasharray:5}:is(.gantt .bar-invalid)~.bar-label{fill:var(--text-light)}.gantt .bar-label{fill:var(--text-dark);dominant-baseline:central;font-family:Helvetica;font-size:13px;font-weight:400}.gantt .bar-label.big{fill:var(--text-dark);text-anchor:start}.gantt .bar-wrapper.important .bar{fill:var(--bar-color-important)}.gantt .bar-wrapper.important .bar-progress{fill:var(--dark-blue)}.gantt .bar-wrapper.important .bar-label{fill:var(--text-light)}.gantt .bar-wrapper.important .handle{fill:var(--handle-color-important)}.gantt .bar-wrapper.important .handle.progress{fill:var(--text-light)}.gantt .handle{fill:var(--handle-color);cursor:ew-resize;opacity:0;visibility:hidden;transition:opacity .3s ease}.gantt .handle.progress{fill:var(--text-muted)}.gantt .bar-wrapper{cursor:pointer;outline:none}.gantt .bar-wrapper.active .handle{visibility:visible;opacity:1}.gantt .bar-wrapper .bar{-webkit-filter:drop-shadow(3px 3px 2px rgba(0,0,0,.7));filter:drop-shadow(0 0 2px rgba(17,43,66,.16));border-radius:3px}.gantt .bar-wrapper:hover .bar{transition:transform .3s ease}.gantt .bar-wrapper:hover .date-highlight{display:block}.gantt .hide{display:none} diff --git a/index.html b/index.html index 62bdef3..75879eb 100644 --- a/index.html +++ b/index.html @@ -23,17 +23,18 @@ background-color: #252525; } - - + +

Interactive Gantt Chart entirely made in SVG!

-
+
-