Merge pull request #34532 from frappe/gantt-integration
feat: improve calendar and gantt view
This commit is contained in:
commit
b9e3296078
7 changed files with 74 additions and 36 deletions
|
|
@ -2,4 +2,9 @@
|
|||
// For license information, please see license.txt
|
||||
|
||||
frappe.views.calendar["{doctype}"] = {{
|
||||
// field_map: {{
|
||||
// start: "start_date",
|
||||
// end: "end_date",
|
||||
// }},
|
||||
// gantt: true
|
||||
}};
|
||||
|
|
@ -8,7 +8,6 @@ frappe.views.calendar["ToDo"] = {
|
|||
id: "name",
|
||||
title: "description",
|
||||
allDay: "allDay",
|
||||
progress: "progress",
|
||||
},
|
||||
gantt: true,
|
||||
filters: [
|
||||
|
|
|
|||
|
|
@ -75,7 +75,9 @@ frappe.views.ListViewSelect = class ListViewSelect {
|
|||
action: () => this.set_route("dashboard"),
|
||||
},
|
||||
Calendar: {
|
||||
condition: frappe.views.calendar[this.doctype],
|
||||
condition:
|
||||
frappe.views.calendar[this.doctype] ||
|
||||
frappe.get_meta(this.doctype).is_calendar_and_gantt,
|
||||
action: () => this.set_route("calendar", "default"),
|
||||
current_view_handler: () => {
|
||||
this.get_calendars().then((calendars) => {
|
||||
|
|
@ -84,7 +86,9 @@ frappe.views.ListViewSelect = class ListViewSelect {
|
|||
},
|
||||
},
|
||||
Gantt: {
|
||||
condition: frappe.views.calendar[this.doctype],
|
||||
condition:
|
||||
frappe.views.calendar[this.doctype] ||
|
||||
frappe.get_meta(this.doctype).is_calendar_and_gantt,
|
||||
action: () => this.set_route("gantt"),
|
||||
},
|
||||
Inbox: {
|
||||
|
|
|
|||
|
|
@ -1,5 +1,12 @@
|
|||
frappe.provide("frappe.views");
|
||||
|
||||
const DEFAULT_FIELD_MAP = {
|
||||
start: "start",
|
||||
end: "end",
|
||||
id: "name",
|
||||
progress: "progress",
|
||||
};
|
||||
|
||||
frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
||||
get view_name() {
|
||||
return "Gantt";
|
||||
|
|
@ -9,6 +16,10 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
return super.setup_defaults().then(() => {
|
||||
this.page_title = this.page_title + " " + __("Gantt");
|
||||
this.calendar_settings = frappe.views.calendar[this.doctype] || {};
|
||||
this.calendar_settings.field_map = {
|
||||
...DEFAULT_FIELD_MAP,
|
||||
...(this.calendar_settings.field_map || {}),
|
||||
};
|
||||
|
||||
if (typeof this.calendar_settings.gantt == "object") {
|
||||
Object.assign(this.calendar_settings, this.calendar_settings.gantt);
|
||||
|
|
@ -35,32 +46,44 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
prepare_tasks() {
|
||||
var me = this;
|
||||
var meta = this.meta;
|
||||
var field_map = this.calendar_settings.field_map;
|
||||
|
||||
let field_map = this.calendar_settings.field_map || DEFAULT_FIELD_MAP;
|
||||
if (!this.data[0]?.[field_map.progress]) {
|
||||
this.progress_disabled = true;
|
||||
}
|
||||
this.tasks = this.data.map(function (item) {
|
||||
// set progress
|
||||
var progress = 0;
|
||||
if (field_map.progress && $.isFunction(field_map.progress)) {
|
||||
if (typeof field_map.progress === "function") {
|
||||
progress = field_map.progress(item);
|
||||
} else if (field_map.progress) {
|
||||
progress = item[field_map.progress];
|
||||
}
|
||||
|
||||
// title
|
||||
var label;
|
||||
if (meta.title_field) {
|
||||
let label;
|
||||
if (field_map.title) {
|
||||
label = item[field_map.title];
|
||||
} else if (meta.title_field) {
|
||||
label = item.progress
|
||||
? __("{0} ({1}) - {2}%", [item[meta.title_field], item.name, item.progress])
|
||||
: __("{0} ({1})", [item[meta.title_field], item.name]);
|
||||
} else {
|
||||
label = item[field_map.title];
|
||||
label = item["name"];
|
||||
}
|
||||
|
||||
var r = {
|
||||
if (!item[field_map.start]) {
|
||||
frappe.msgprint({
|
||||
title: __("Incorrect configuration"),
|
||||
message: __(
|
||||
"Please configure the start field for this Doctype in the controller file."
|
||||
),
|
||||
indicator: "red",
|
||||
});
|
||||
}
|
||||
const r = {
|
||||
start: item[field_map.start],
|
||||
end: item[field_map.end],
|
||||
end: item[field_map.end] || item[field_map.start],
|
||||
name: label,
|
||||
id: item[field_map.id || "name"],
|
||||
id: item[field_map.id],
|
||||
doctype: me.doctype,
|
||||
progress: progress,
|
||||
dependencies: item.depends_on_tasks || "",
|
||||
|
|
@ -93,20 +116,22 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
const date_format = "YYYY-MM-DD";
|
||||
|
||||
this.$result.empty();
|
||||
this.$result.addClass("gantt-modern");
|
||||
|
||||
this.gantt = new Gantt(this.$result[0], this.tasks, {
|
||||
bar_height: 35,
|
||||
bar_corner_radius: 4,
|
||||
resize_handle_width: 8,
|
||||
resize_handle_height: 28,
|
||||
resize_handle_corner_radius: 3,
|
||||
resize_handle_offset: 4,
|
||||
hover_on_date: true,
|
||||
view_mode: gantt_view_mode,
|
||||
date_format: "YYYY-MM-DD",
|
||||
on_click: (task) => {
|
||||
readonly: !me.can_write,
|
||||
readonly_progress: this.progress_disabled,
|
||||
fixed_duration: field_map.start == field_map.end,
|
||||
on_double_click: (task) => {
|
||||
frappe.set_route("Form", task.doctype, task.id);
|
||||
},
|
||||
on_date_click: (date) => {
|
||||
console.log(date);
|
||||
if (date) frappe.new_doc("ToDo", { date: new Date(date) });
|
||||
},
|
||||
on_date_change: (task, start, end) => {
|
||||
if (!me.can_write) return;
|
||||
frappe.db.set_value(task.doctype, task.id, {
|
||||
|
|
@ -116,11 +141,11 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
},
|
||||
on_progress_change: (task, progress) => {
|
||||
if (!me.can_write) return;
|
||||
var progress_fieldname = "progress";
|
||||
let progress_fieldname;
|
||||
|
||||
if ($.isFunction(field_map.progress)) {
|
||||
if (typeof field_map.progress === "function") {
|
||||
progress_fieldname = null;
|
||||
} else if (field_map.progress) {
|
||||
} else if (field_map.progress && task[field_map.progress]) {
|
||||
progress_fieldname = field_map.progress;
|
||||
}
|
||||
|
||||
|
|
@ -133,14 +158,13 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
on_view_change: (mode) => {
|
||||
// save view mode
|
||||
me.save_view_user_settings({
|
||||
gantt_view_mode: mode,
|
||||
gantt_view_mode: mode.name,
|
||||
});
|
||||
},
|
||||
custom_popup_html: (task) => {
|
||||
popup: ({ task }) => {
|
||||
var item = me.get_item(task.id);
|
||||
|
||||
var html = `<div class="title">${task.name}</div>
|
||||
<div class="subtitle">${moment(task._start).format("MMM D")} - ${moment(task._end).format(
|
||||
<div class="subtitle">${moment(task.start).format("MMM D")} - ${moment(task.end).format(
|
||||
"MMM D"
|
||||
)}</div>`;
|
||||
|
||||
|
|
@ -170,9 +194,9 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
${view_modes
|
||||
.map(
|
||||
(value) => `<button type="button"
|
||||
class="btn btn-default btn-sm btn-view-mode ${active_class(value)}"
|
||||
data-value="${value}">
|
||||
${__(value)}
|
||||
class="btn btn-default btn-sm btn-view-mode ${active_class(value.name)}"
|
||||
data-value="${value.name}">
|
||||
${__(value.name)}
|
||||
</button>`
|
||||
)
|
||||
.join("")}
|
||||
|
|
@ -226,7 +250,7 @@ frappe.views.GanttView = class GanttView extends frappe.views.ListView {
|
|||
get required_libs() {
|
||||
return [
|
||||
"assets/frappe/node_modules/frappe-gantt/dist/frappe-gantt.css",
|
||||
"assets/frappe/node_modules/frappe-gantt/dist/frappe-gantt.min.js",
|
||||
"assets/frappe/node_modules/frappe-gantt/dist/frappe-gantt.umd.js",
|
||||
];
|
||||
}
|
||||
};
|
||||
|
|
|
|||
|
|
@ -1,3 +1,9 @@
|
|||
.gantt {
|
||||
.grid-column:hover {
|
||||
cursor: copy;
|
||||
}
|
||||
}
|
||||
|
||||
.gantt-modern .gantt {
|
||||
.bar {
|
||||
fill: white;
|
||||
|
|
|
|||
|
|
@ -53,7 +53,7 @@
|
|||
"fast-glob": "^3.2.5",
|
||||
"frappe-charts": "2.0.0-rc27",
|
||||
"frappe-datatable": "1.19.0",
|
||||
"frappe-gantt": "^0.6.0",
|
||||
"frappe-gantt": "^1.1.0",
|
||||
"frappe-quill-image-resize": "^3.0.9",
|
||||
"gemoji": "^8.1.0",
|
||||
"highlight.js": "^10.4.1",
|
||||
|
|
|
|||
|
|
@ -1440,10 +1440,10 @@ frappe-datatable@1.19.0:
|
|||
lodash "^4.17.5"
|
||||
sortablejs "^1.7.0"
|
||||
|
||||
frappe-gantt@^0.6.0:
|
||||
version "0.6.1"
|
||||
resolved "https://registry.yarnpkg.com/frappe-gantt/-/frappe-gantt-0.6.1.tgz#57ae0b5f024101fc7cd5ba92f605de97dba9c9a1"
|
||||
integrity sha512-1cSU9vLbwypjzaxnCfnEE03Xr3HlAV2S8dRtjxw62o+amkx1A8bBIFd2jp84mcDdTCM77Ij4LzZBslAKZB8oMg==
|
||||
frappe-gantt@^1.1.0:
|
||||
version "1.1.0"
|
||||
resolved "https://registry.yarnpkg.com/frappe-gantt/-/frappe-gantt-1.1.0.tgz#b889053357a117606a74d934d288aad605df1b0d"
|
||||
integrity sha512-ex3QNuYU7nTNKtkC5MSoUhnW8YhZOCmNC1W+Xp4hSJTOyiZhC405JChkvDh66CkMSPlMHaASdaWQZ2nC0MhMFA==
|
||||
|
||||
frappe-quill-image-resize@^3.0.9:
|
||||
version "3.0.9"
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue