feat: highlight weekends, build dist

This commit is contained in:
Safwan Samsudeen 2024-04-08 03:20:28 +05:30
parent bbbf28819b
commit b8bad72109
8 changed files with 119 additions and 20 deletions

12
dist/frappe-gantt.css vendored
View File

@ -95,19 +95,23 @@
stroke-width: 0.4;
}
.gantt .today-highlight {
fill: #fcf8e3;
fill: #f6e796;
opacity: 0.5;
}
.gantt .week-highlight {
fill: #fcf8e3;
fill: #f6e796;
opacity: 0.5;
}
.gantt .holiday-highlight {
fill: #EEE;
opacity: 0.5;
}
.gantt .month-highlight {
fill: #fcf8e3;
fill: #f6e796;
opacity: 0.5;
}
.gantt .year-highlight {
fill: #fcf8e3;
fill: #f6e796;
opacity: 0.5;
}
.gantt .arrow {

69
dist/frappe-gantt.js vendored
View File

@ -540,7 +540,7 @@ var Gantt = (function () {
}
draw_resize_handles() {
if (this.invalid) return;
if (this.invalid || this.gantt.options.readonly) return;
const bar = this.$bar;
const handle_width = 8;
@ -1071,7 +1071,7 @@ var Gantt = (function () {
} 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",
" HTML DOM element or SVG DOM element for the 'element' parameter",
);
}
@ -1116,8 +1116,11 @@ var Gantt = (function () {
popup_trigger: "click",
custom_popup_html: null,
language: "en",
readonly: false,
highlight_weekend: true,
};
this.options = Object.assign({}, 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
@ -1125,7 +1128,6 @@ var Gantt = (function () {
}
}
console.log(options.view_mode_padding);
this.options.view_mode_padding = {
...VIEW_MODE_PADDING,
...options.view_mode_padding,
@ -1272,9 +1274,12 @@ var Gantt = (function () {
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");
let gantt_start = date_utils.start_of(this.gantt_start, "day");
let 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)) {
@ -1285,11 +1290,32 @@ var Gantt = (function () {
const [padding_start, padding_end] = this.options.view_mode_padding[
viewKey
].map(date_utils.parse_duration);
this.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 = new Date(
date_utils.format(
date_utils.add(gantt_start, -padding_end.duration, padding_end.scale),
format_string
)
);
this.gantt_start.setHours(0, 0, 0, 0);
this.gantt_end = date_utils.add(
gantt_end,
padding_end.duration,
@ -1318,6 +1344,7 @@ var Gantt = (function () {
}
bind_events() {
if (this.options.readonly) return
this.bind_grid_click();
this.bind_bar_events();
}
@ -1461,6 +1488,28 @@ var Gantt = (function () {
}
}
highlightWeekends() {
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 +
this.options.header_height +
this.options.padding / 2;
createSVG('rect', {
x,
y: 0,
width: this.options.column_width,
height,
class: 'holiday-highlight',
append_to: this.layers.grid,
});
}
}
}
//compute the horizontal x distance
computeGridHighlightDimensions(view_mode) {
let xDist = 0;
@ -1498,6 +1547,7 @@ var Gantt = (function () {
}
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) ||
@ -1701,9 +1751,9 @@ var Gantt = (function () {
set_width() {
const cur_width = this.$svg.getBoundingClientRect().width;
const actual_width = this.$svg
.querySelector(".grid .grid-row")
.getAttribute("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);
}
@ -1721,7 +1771,7 @@ var Gantt = (function () {
const scroll_pos =
(hours_before_first_task / this.options.step) *
this.options.column_width -
this.options.column_width -
this.options.column_width;
parent_element.scrollLeft = scroll_pos;
@ -1998,6 +2048,7 @@ var Gantt = (function () {
* @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) =>

File diff suppressed because one or more lines are too long

View File

@ -1 +1 @@
.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{user-select:none;-webkit-user-select:none}.gantt .grid-background{fill:none}.gantt .grid-header{fill:#fff;stroke:#e0e0e0;stroke-width:1.4}.gantt .grid-row{fill:#fff}.gantt .grid-row:nth-child(even){fill:#f5f5f5}.gantt .row-line{stroke:#ebeff2}.gantt .tick{stroke:#e0e0e0;stroke-width:.2}.gantt .tick.thick{stroke-width:.4}.gantt .today-highlight{fill:#fcf8e3;opacity:.5}.gantt .week-highlight{fill:#fcf8e3;opacity:.5}.gantt .month-highlight{fill:#fcf8e3;opacity:.5}.gantt .year-highlight{fill:#fcf8e3;opacity:.5}.gantt .arrow{fill:none;stroke:#666;stroke-width:1.4}.gantt .bar{fill:#b8c2cc;stroke:#8d99a6;stroke-width:0;transition:stroke-width .3s ease}.gantt .bar-progress{fill:#acacfa}.gantt .bar-expected-progress{fill:#c4c4e9}.gantt .bar-invalid{fill:rgba(0,0,0,0);stroke:#8d99a6;stroke-width:1;stroke-dasharray:5}.gantt .bar-invalid~.bar-label{fill:#555}.gantt .bar-label{fill:#fff;dominant-baseline:central;text-anchor:middle;font-size:12px;font-weight:lighter}.gantt .bar-label.big{fill:#555;text-anchor:start}.gantt .handle{fill:#ddd;cursor:ew-resize;opacity:0;visibility:hidden;transition:opacity .3s ease}.gantt .bar-wrapper{cursor:pointer;outline:none}.gantt .bar-wrapper:hover .bar{fill:#a9b5c1}.gantt .bar-wrapper:hover .bar-progress{fill:#9494f9}.gantt .bar-wrapper:hover .handle{visibility:visible;opacity:1}.gantt .bar-wrapper.active .bar{fill:#a9b5c1}.gantt .bar-wrapper.active .bar-progress{fill:#9494f9}.gantt .lower-text,.gantt .upper-text{font-size:12px;text-anchor:middle}.gantt .upper-text{fill:#555}.gantt .lower-text{fill:#333}.gantt .hide{display:none}.gantt-container{position:relative;overflow:auto;font-size:12px}.gantt-container .popup-wrapper{position:absolute;top:0;left:0;background:rgba(0,0,0,.8);padding:0;color:#959da5;border-radius:3px}.gantt-container .popup-wrapper .title{border-bottom:3px solid #acacfa;padding:10px}.gantt-container .popup-wrapper .subtitle{padding:10px;color:#dfe2e5}.gantt-container .popup-wrapper .pointer{position:absolute;height:5px;margin:0 0 0 -5px;border:5px solid rgba(0,0,0,0);border-top-color:rgba(0,0,0,.8)}
.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{user-select:none;-webkit-user-select:none}.gantt .grid-background{fill:none}.gantt .grid-header{fill:#fff;stroke:#e0e0e0;stroke-width:1.4}.gantt .grid-row{fill:#fff}.gantt .grid-row:nth-child(even){fill:#f5f5f5}.gantt .row-line{stroke:#ebeff2}.gantt .tick{stroke:#e0e0e0;stroke-width:.2}.gantt .tick.thick{stroke-width:.4}.gantt .today-highlight{fill:#f6e796;opacity:.5}.gantt .week-highlight{fill:#f6e796;opacity:.5}.gantt .holiday-highlight{fill:#eee;opacity:.5}.gantt .month-highlight{fill:#f6e796;opacity:.5}.gantt .year-highlight{fill:#f6e796;opacity:.5}.gantt .arrow{fill:none;stroke:#666;stroke-width:1.4}.gantt .bar{fill:#b8c2cc;stroke:#8d99a6;stroke-width:0;transition:stroke-width .3s ease}.gantt .bar-progress{fill:#acacfa}.gantt .bar-expected-progress{fill:#c4c4e9}.gantt .bar-invalid{fill:rgba(0,0,0,0);stroke:#8d99a6;stroke-width:1;stroke-dasharray:5}.gantt .bar-invalid~.bar-label{fill:#555}.gantt .bar-label{fill:#fff;dominant-baseline:central;text-anchor:middle;font-size:12px;font-weight:lighter}.gantt .bar-label.big{fill:#555;text-anchor:start}.gantt .handle{fill:#ddd;cursor:ew-resize;opacity:0;visibility:hidden;transition:opacity .3s ease}.gantt .bar-wrapper{cursor:pointer;outline:none}.gantt .bar-wrapper:hover .bar{fill:#a9b5c1}.gantt .bar-wrapper:hover .bar-progress{fill:#9494f9}.gantt .bar-wrapper:hover .handle{visibility:visible;opacity:1}.gantt .bar-wrapper.active .bar{fill:#a9b5c1}.gantt .bar-wrapper.active .bar-progress{fill:#9494f9}.gantt .lower-text,.gantt .upper-text{font-size:12px;text-anchor:middle}.gantt .upper-text{fill:#555}.gantt .lower-text{fill:#333}.gantt .hide{display:none}.gantt-container{position:relative;overflow:auto;font-size:12px}.gantt-container .popup-wrapper{position:absolute;top:0;left:0;background:rgba(0,0,0,.8);padding:0;color:#959da5;border-radius:3px}.gantt-container .popup-wrapper .title{border-bottom:3px solid #acacfa;padding:10px}.gantt-container .popup-wrapper .subtitle{padding:10px;color:#dfe2e5}.gantt-container .popup-wrapper .pointer{position:absolute;height:5px;margin:0 0 0 -5px;border:5px solid rgba(0,0,0,0);border-top-color:rgba(0,0,0,.8)}

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View File

@ -5,7 +5,8 @@ $bar-stroke: #8d99a6 !default;
$border-color: #e0e0e0 !default;
$light-bg: #f5f5f5 !default;
$light-border-color: #ebeff2 !default;
$light-yellow: #fcf8e3 !default;
$light-yellow: #f6e796 !default;
$holiday-color: #EEE !default;
$text-muted: #666 !default;
$text-light: #555 !default;
$text-color: #333 !default;
@ -20,27 +21,34 @@ $light-blue: #c4c4e9 !default;
.grid-background {
fill: none;
}
.grid-header {
fill: #ffffff;
stroke: $border-color;
stroke-width: 1.4;
}
.grid-row {
fill: #ffffff;
}
.grid-row:nth-child(even) {
fill: $light-bg;
}
.row-line {
stroke: $light-border-color;
}
.tick {
stroke: $border-color;
stroke-width: 0.2;
&.thick {
stroke-width: 0.4;
}
}
.today-highlight {
fill: $light-yellow;
opacity: 0.5;
@ -51,6 +59,11 @@ $light-blue: #c4c4e9 !default;
opacity: 0.5;
}
.holiday-highlight {
fill: $holiday-color;
opacity: 0.5;
}
.month-highlight {
fill: $light-yellow;
opacity: 0.5;
@ -73,22 +86,26 @@ $light-blue: #c4c4e9 !default;
stroke-width: 0;
transition: stroke-width 0.3s ease;
}
.bar-progress {
fill: $blue;
}
.bar-expected-progress {
fill: $light-blue;
}
.bar-invalid {
fill: transparent;
stroke: $bar-stroke;
stroke-width: 1;
stroke-dasharray: 5;
& ~ .bar-label {
&~.bar-label {
fill: $text-light;
}
}
.bar-label {
fill: #fff;
dominant-baseline: central;
@ -145,9 +162,11 @@ $light-blue: #c4c4e9 !default;
font-size: 12px;
text-anchor: middle;
}
.upper-text {
fill: $text-light;
}
.lower-text {
fill: $text-color;
}
@ -189,4 +208,4 @@ $light-blue: #c4c4e9 !default;
border-top-color: rgba(0, 0, 0, 0.8);
}
}
}
}

View File

@ -99,8 +99,10 @@ export default class Gantt {
custom_popup_html: null,
language: "en",
readonly: false,
highlight_weekend: true,
};
this.options = Object.assign({}, 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
@ -468,6 +470,28 @@ export default class Gantt {
}
}
highlightWeekends() {
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 +
this.options.header_height +
this.options.padding / 2;
createSVG('rect', {
x,
y: 0,
width: this.options.column_width,
height,
class: 'holiday-highlight',
append_to: this.layers.grid,
});
}
}
}
//compute the horizontal x distance
computeGridHighlightDimensions(view_mode) {
let xDist = 0;
@ -505,6 +529,7 @@ export default class Gantt {
}
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) ||