chore: upgrade calendar component to latest
feature parity for, - toolbar actions - show/hide weekend - navigate through calendar and click events
This commit is contained in:
parent
c7c3eee6d5
commit
3d29f90dbd
1 changed files with 65 additions and 62 deletions
|
|
@ -1,6 +1,12 @@
|
|||
// Copyright (c) 2018, Frappe Technologies Pvt. Ltd. and Contributors
|
||||
// MIT License. See license.txt
|
||||
|
||||
import { Calendar as FullCalendar } from "@fullcalendar/core";
|
||||
import dayGridPlugin from "@fullcalendar/daygrid";
|
||||
import listPlugin from "@fullcalendar/list";
|
||||
import timeGridPlugin from "@fullcalendar/timegrid";
|
||||
import interactionPlugin from "@fullcalendar/interaction";
|
||||
|
||||
frappe.provide("frappe.views.calendar");
|
||||
frappe.provide("frappe.views.calendars");
|
||||
|
||||
|
|
@ -99,18 +105,6 @@ frappe.views.CalendarView = class CalendarView extends frappe.views.ListView {
|
|||
}
|
||||
});
|
||||
}
|
||||
|
||||
get required_libs() {
|
||||
let assets = [
|
||||
"assets/frappe/js/lib/fullcalendar/fullcalendar.min.css",
|
||||
"assets/frappe/js/lib/fullcalendar/fullcalendar.min.js",
|
||||
];
|
||||
let user_language = frappe.boot.lang;
|
||||
if (user_language && user_language !== "en") {
|
||||
assets.push("assets/frappe/js/lib/fullcalendar/locale-all.js");
|
||||
}
|
||||
return assets;
|
||||
}
|
||||
};
|
||||
|
||||
frappe.views.Calendar = class Calendar {
|
||||
|
|
@ -133,10 +127,10 @@ frappe.views.Calendar = class Calendar {
|
|||
}
|
||||
get_default_options() {
|
||||
return new Promise((resolve) => {
|
||||
let defaultView = localStorage.getItem("cal_defaultView");
|
||||
let initialView = localStorage.getItem("cal_initialView");
|
||||
let weekends = localStorage.getItem("cal_weekends");
|
||||
let defaults = {
|
||||
defaultView: defaultView ? defaultView : "month",
|
||||
initialView: initialView ? initialView : "dayGridMonth",
|
||||
weekends: weekends ? weekends : true,
|
||||
};
|
||||
resolve(defaults);
|
||||
|
|
@ -162,13 +156,13 @@ frappe.views.Calendar = class Calendar {
|
|||
});
|
||||
|
||||
$(this.parent).on("show", function () {
|
||||
me.$cal.fullCalendar("refetchEvents");
|
||||
me.$cal.fullCalendar.refetchEvents();
|
||||
});
|
||||
}
|
||||
|
||||
make() {
|
||||
this.$wrapper = this.parent;
|
||||
this.$cal = $("<div>").appendTo(this.$wrapper);
|
||||
this.$cal = $("<div id='fc-calendar-wrapper'>").appendTo(this.$wrapper);
|
||||
this.footnote_area = frappe.utils.set_footnote(
|
||||
this.footnote_area,
|
||||
this.$wrapper,
|
||||
|
|
@ -176,7 +170,9 @@ frappe.views.Calendar = class Calendar {
|
|||
);
|
||||
this.footnote_area.css({ "border-top": "0px" });
|
||||
|
||||
this.$cal.fullCalendar(this.cal_options);
|
||||
this.fullCalendar = new FullCalendar(this.$cal[0], this.cal_options);
|
||||
this.fullCalendar.render();
|
||||
|
||||
this.set_css();
|
||||
}
|
||||
setup_view_mode_button(defaults) {
|
||||
|
|
@ -194,37 +190,42 @@ frappe.views.Calendar = class Calendar {
|
|||
const me = this;
|
||||
let btn_group = me.$wrapper.find(".fc-button-group");
|
||||
btn_group.on("click", ".btn", function () {
|
||||
let value = $(this).hasClass("fc-agendaWeek-button")
|
||||
? "agendaWeek"
|
||||
: $(this).hasClass("fc-agendaDay-button")
|
||||
? "agendaDay"
|
||||
: "month";
|
||||
me.set_localStorage_option("cal_defaultView", value);
|
||||
let value = $(this).hasClass("fc-dayGridWeek-button")
|
||||
? "dayGridWeek"
|
||||
: $(this).hasClass("fc-dayGridDay-button")
|
||||
? "dayGridDay"
|
||||
: "dayGridMonth";
|
||||
me.set_localStorage_option("cal_initialView", value);
|
||||
});
|
||||
|
||||
me.$wrapper.on("click", ".btn-weekend", function () {
|
||||
me.cal_options.weekends = !me.cal_options.weekends;
|
||||
me.$cal.fullCalendar("option", "weekends", me.cal_options.weekends);
|
||||
//me.fullCalendar("option", "weekends", );
|
||||
me.fullCalendar.setOption("weekends", me.cal_options.weekends);
|
||||
me.set_localStorage_option("cal_weekends", me.cal_options.weekends);
|
||||
me.set_css();
|
||||
me.setup_view_mode_button(me.cal_options);
|
||||
});
|
||||
}
|
||||
set_css() {
|
||||
// flatify buttons
|
||||
this.$wrapper
|
||||
.find("button.fc-state-default")
|
||||
.removeClass("fc-state-default")
|
||||
.find("button.fc-button")
|
||||
.removeClass("fc-button")
|
||||
.removeClass("fc-button-primary")
|
||||
.addClass("btn btn-default");
|
||||
|
||||
this.$wrapper
|
||||
.find(".fc-month-button, .fc-agendaWeek-button, .fc-agendaDay-button")
|
||||
.find(".fc-dayGridMonth-button, .fc-dayGridWeek-button, .fc-dayGridDay-button")
|
||||
.wrapAll('<div class="btn-group" />');
|
||||
|
||||
// add icons
|
||||
this.$wrapper
|
||||
.find(".fc-prev-button span")
|
||||
.attr("class", "")
|
||||
.html(frappe.utils.icon("left"));
|
||||
|
||||
this.$wrapper.find(".fc-prev-button").css("margin-right", 5 + "px");
|
||||
|
||||
this.$wrapper
|
||||
.find(".fc-next-button span")
|
||||
.attr("class", "")
|
||||
|
|
@ -235,7 +236,7 @@ frappe.views.Calendar = class Calendar {
|
|||
this.$wrapper.find(".fc-day-number").wrap('<div class="fc-day"></div>');
|
||||
|
||||
var btn_group = this.$wrapper.find(".fc-button-group");
|
||||
btn_group.find(".fc-state-active").addClass("active");
|
||||
btn_group.find(".fc-button-active").addClass("active");
|
||||
|
||||
btn_group.find(".btn").on("click", function () {
|
||||
btn_group.find(".btn").removeClass("active");
|
||||
|
|
@ -244,93 +245,95 @@ frappe.views.Calendar = class Calendar {
|
|||
}
|
||||
|
||||
get_system_datetime(date) {
|
||||
date._offset = moment(date).tz(frappe.sys_defaults.time_zone)._offset;
|
||||
return frappe.datetime.convert_to_system_tz(moment(date).locale("en"));
|
||||
return frappe.datetime.convert_to_system_tz(new Date(date));
|
||||
}
|
||||
setup_options(defaults) {
|
||||
var me = this;
|
||||
defaults.meridiem = "false";
|
||||
this.cal_options = {
|
||||
plugins: [dayGridPlugin, listPlugin, timeGridPlugin, interactionPlugin],
|
||||
initialView: defaults.initialView || "dayGridMonth",
|
||||
locale: frappe.boot.lang,
|
||||
header: {
|
||||
left: "prev, title, next",
|
||||
right: "today, month, agendaWeek, agendaDay",
|
||||
headerToolbar: {
|
||||
left: "prev,next",
|
||||
center: "title",
|
||||
right: "today,dayGridMonth,dayGridWeek,dayGridDay",
|
||||
},
|
||||
editable: true,
|
||||
droppable: true,
|
||||
selectable: true,
|
||||
selectHelper: true,
|
||||
selectMirror: true,
|
||||
forceEventDuration: true,
|
||||
displayEventTime: true,
|
||||
defaultView: defaults.defaultView,
|
||||
displayEventTime: false,
|
||||
weekends: defaults.weekends,
|
||||
nowIndicator: true,
|
||||
themeSystem: null,
|
||||
buttonText: {
|
||||
today: __("Today"),
|
||||
month: __("Month"),
|
||||
week: __("Week"),
|
||||
day: __("Day"),
|
||||
},
|
||||
events: function (start, end, timezone, callback) {
|
||||
events: function (info, successCallback, failureCallback) {
|
||||
return frappe.call({
|
||||
method: me.get_events_method || "frappe.desk.calendar.get_events",
|
||||
type: "GET",
|
||||
args: me.get_args(start, end),
|
||||
args: me.get_args(info.startStr, info.endStr),
|
||||
callback: function (r) {
|
||||
var events = r.message || [];
|
||||
events = me.prepare_events(events);
|
||||
callback(events);
|
||||
successCallback(events);
|
||||
},
|
||||
});
|
||||
},
|
||||
displayEventEnd: true,
|
||||
eventRender: function (event, element) {
|
||||
element.attr("title", event.tooltip);
|
||||
},
|
||||
eventClick: function (event) {
|
||||
eventClick: function (info) {
|
||||
// edit event description or delete
|
||||
var doctype = event.doctype || me.doctype;
|
||||
var doctype = info.doctype || me.doctype;
|
||||
if (frappe.model.can_read(doctype)) {
|
||||
frappe.set_route("Form", doctype, event.name);
|
||||
frappe.set_route("Form", doctype, info.event.id);
|
||||
}
|
||||
},
|
||||
eventDrop: function (event, delta, revertFunc) {
|
||||
me.update_event(event, revertFunc);
|
||||
eventDrop: function (info) {
|
||||
me.update_event(info.event, info.revert);
|
||||
},
|
||||
eventResize: function (event, delta, revertFunc) {
|
||||
me.update_event(event, revertFunc);
|
||||
eventResize: function (info) {
|
||||
me.update_event(info.event, info.revert);
|
||||
},
|
||||
select: function (startDate, endDate, jsEvent, view) {
|
||||
if (view.name === "month" && endDate - startDate === 86400000) {
|
||||
select: function (info) {
|
||||
if (info.view.type === "dayGridMonth" && info.end - info.start === 86400000) {
|
||||
// detect single day click in month view
|
||||
return;
|
||||
}
|
||||
|
||||
var event = frappe.model.get_new_doc(me.doctype);
|
||||
|
||||
event[me.field_map.start] = me.get_system_datetime(startDate);
|
||||
event[me.field_map.start] = me.get_system_datetime(info.startStr);
|
||||
|
||||
if (me.field_map.end) event[me.field_map.end] = me.get_system_datetime(endDate);
|
||||
if (me.field_map.end)
|
||||
event[me.field_map.end] = me.get_system_datetime(info.endStr);
|
||||
|
||||
if (me.field_map.allDay) {
|
||||
var all_day = startDate._ambigTime && endDate._ambigTime ? 1 : 0;
|
||||
var all_day = info.start._ambigTime && info.end._ambigTime ? 1 : 0;
|
||||
|
||||
event[me.field_map.allDay] = all_day;
|
||||
|
||||
if (all_day)
|
||||
event[me.field_map.end] = me.get_system_datetime(
|
||||
moment(endDate).subtract(1, "s")
|
||||
moment(info.endStr).subtract(1, "s")
|
||||
);
|
||||
}
|
||||
|
||||
frappe.set_route("Form", me.doctype, event.name);
|
||||
},
|
||||
dayClick: function (date, jsEvent, view) {
|
||||
if (view.name === "month") {
|
||||
const $date_cell = $("td[data-date=" + date.format("YYYY-MM-DD") + "]");
|
||||
dateClick: function (info) {
|
||||
if (info.view.type === "dayGridMonth") {
|
||||
const $date_cell = $(
|
||||
"td[data-date=" + info.date.toISOString().slice(0, 10) + "]"
|
||||
);
|
||||
|
||||
if ($date_cell.hasClass("date-clicked")) {
|
||||
me.$cal.fullCalendar("changeView", "agendaDay");
|
||||
me.$cal.fullCalendar("gotoDate", date);
|
||||
me.fullCalendar.changeView("timeGridDay", info.date);
|
||||
me.$wrapper.find(".date-clicked").removeClass("date-clicked");
|
||||
|
||||
// update "active view" btn
|
||||
|
|
@ -361,7 +364,7 @@ frappe.views.Calendar = class Calendar {
|
|||
return args;
|
||||
}
|
||||
refresh() {
|
||||
this.$cal.fullCalendar("refetchEvents");
|
||||
this.fullCalendar.refetchEvents();
|
||||
}
|
||||
prepare_events(events) {
|
||||
var me = this;
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue