dhtmlx-scheduler
Version:
JavaScript event calendar. Allows to manage events and appointments in different views
1,254 lines (1,249 loc) • 958 kB
JavaScript
(function(global2, factory) {
typeof exports === "object" && typeof module !== "undefined" ? factory(exports) : typeof define === "function" && define.amd ? define(["exports"], factory) : (global2 = typeof globalThis !== "undefined" ? globalThis : global2 || self, factory(global2.dhtmlxscheduler = {}));
})(this, function(exports2) {
"use strict";/** @license
dhtmlxScheduler v.7.2.5 Standard
To use dhtmlxScheduler in non-GPL projects (and get Pro version of the product), please obtain Commercial/Enterprise or Ultimate license on our site https://dhtmlx.com/docs/products/dhtmlxScheduler/#licensing or contact us at sales@dhtmlx.com
(c) XB Software Ltd.
*/
function dhtmlxHook() {
if (typeof dhtmlx != "undefined" && dhtmlx.attaches) {
dhtmlx.attaches.attachScheduler = function(day, mode, tabs, scheduler2) {
var tabs = tabs || '<div class="dhx_cal_tab" name="day_tab" data-tab="day" style="right:204px;"></div><div class="dhx_cal_tab" name="week_tab" data-tab="week" style="right:140px;"></div><div class="dhx_cal_tab" name="month_tab" data-tab="month" style="right:76px;"></div>';
var obj = document.createElement("DIV");
obj.id = "dhxSchedObj_" + this._genStr(12);
obj.innerHTML = '<div id="' + obj.id + '" class="dhx_cal_container" style="width:100%; height:100%;"><div class="dhx_cal_navline"><div class="dhx_cal_prev_button"></div><div class="dhx_cal_next_button"></div><div class="dhx_cal_today_button"></div><div class="dhx_cal_date"></div>' + tabs + '</div><div class="dhx_cal_header"></div><div class="dhx_cal_data"></div></div>';
document.body.appendChild(obj.firstChild);
this.attachObject(obj.id, false, true);
this.vs[this.av].sched = scheduler2;
this.vs[this.av].schedId = obj.id;
scheduler2.setSizes = scheduler2.updateView;
scheduler2.destructor = function() {
};
scheduler2.init(obj.id, day, mode);
return this.vs[this._viewRestore()].sched;
};
}
}
const theme = "";
var globalScope;
if (typeof window !== "undefined") {
globalScope = window;
} else {
globalScope = global;
}
const global$1 = globalScope;
function dragHighlightPos(scheduler2) {
let dndMarkers = [];
let dragStarted = false;
let eventNode = null;
let event2 = null;
function isEnabled2() {
return scheduler2.config.drag_highlight && scheduler2.markTimespan;
}
function checkViewName(viewName) {
const viewObj = scheduler2.getView(viewName);
if (viewObj) {
return viewObj.layout;
}
return viewName;
}
function checkSectionPropertyName(viewName) {
const viewObj = scheduler2.getView(viewName);
if (viewObj.y_property) {
return viewObj.y_property;
}
if (viewObj.map_to) {
return viewObj.map_to;
}
}
function setRequiredStylesToMarker(eventNode2, layout) {
switch (layout) {
case "month":
eventNode2.style.top = "";
eventNode2.style.left = "";
break;
case "timeline":
eventNode2.style.left = "";
eventNode2.style.marginLeft = "1px";
break;
default:
eventNode2.style.top = "";
break;
}
}
function createMarkerConfig(configSettings) {
const { event: event3, layout, viewName, sectionId, eventNode: eventNode2 } = configSettings;
setRequiredStylesToMarker(eventNode2, layout);
const sections = {};
let markerObject = { start_date: event3.start_date, end_date: event3.end_date, css: "dhx_scheduler_dnd_marker", html: eventNode2 };
if (layout == "timeline") {
const viewObj = scheduler2.getView(viewName);
if (viewObj.round_position) {
const index = scheduler2._get_date_index(viewObj, event3.start_date);
const rounded_date = viewObj._trace_x[index];
markerObject.start_date = rounded_date;
}
}
if (layout == "timeline" || layout == "month") {
markerObject = { ...markerObject, end_date: scheduler2.date.add(event3.start_date, 1, "minute") };
}
if (sectionId) {
sections[viewName] = sectionId;
markerObject.sections = sections;
}
return markerObject;
}
function createViewMarker(settings) {
const { layout } = settings;
let markerConfigs;
switch (layout) {
case "month":
markerConfigs = getMonthViewMarkers(settings);
break;
case "timeline":
case "units":
markerConfigs = getTimelineAndUnitsViewMarkers(settings);
break;
default:
markerConfigs = getColumnViewMarkers(settings);
break;
}
markerConfigs.forEach((cfg) => {
dndMarkers.push(scheduler2.markTimespan(cfg));
});
}
function getColumnViewMarkers(settings) {
const { event: event3, layout, viewName, sectionId } = settings;
let columnViewMarkersArray = [];
let eventNodes = scheduler2.$container.querySelectorAll(`[${scheduler2.config.event_attribute}='${event3.id}']:not(.dhx_cal_select_menu):not(.dhx_drag_marker)`);
if (eventNodes) {
for (let i = 0; i < eventNodes.length; i++) {
let eventNodeClone = eventNodes[i].cloneNode(true);
let startDate = /* @__PURE__ */ new Date(+eventNodeClone.getAttribute("data-bar-start"));
let endDate = /* @__PURE__ */ new Date(+eventNodeClone.getAttribute("data-bar-end"));
let dates = { start_date: startDate, end_date: endDate };
const configSettings = { event: dates, layout, viewName, sectionId, eventNode: eventNodeClone };
columnViewMarkersArray.push(createMarkerConfig(configSettings));
}
}
return columnViewMarkersArray;
}
function getMonthViewMarkers(settings) {
let monthViewMarkersArray = [];
const { event: event3, layout, viewName, sectionId } = settings;
const weekDates = [];
let currDate = new Date(event3.start_date);
while (currDate.valueOf() < event3.end_date.valueOf()) {
let obj = { start_date: currDate };
weekDates.push(obj);
currDate = scheduler2.date.week_start(scheduler2.date.add(currDate, 1, "week"));
}
let cells = scheduler2.$container.querySelectorAll(`[${scheduler2.config.event_attribute}='${event3.id}']`);
for (let i = 0; i < cells.length; i++) {
const configSettings = { event: weekDates[i], layout, viewName, sectionId, eventNode: cells[i].cloneNode(true) };
monthViewMarkersArray.push(createMarkerConfig(configSettings));
}
return monthViewMarkersArray;
}
function getTimelineAndUnitsViewMarkers(settings) {
let unitMarkersArray = [];
const { event: event3, layout, viewName, eventNode: eventNode2 } = settings;
let sectionPropertyName = checkSectionPropertyName(viewName);
if (sectionPropertyName) {
const sections = String(event3[sectionPropertyName]).split(scheduler2.config.section_delimiter);
const formatedSections = sections.map((element) => String(element));
const elems = [];
for (let i = 0; i < formatedSections.length; i++) {
elems[i] = eventNode2.cloneNode(true);
const configSettings = { event: event3, layout, viewName, sectionId: formatedSections[i], eventNode: elems[i] };
unitMarkersArray.push(createMarkerConfig(configSettings));
}
}
return unitMarkersArray;
}
scheduler2.attachEvent("onBeforeDrag", function(id2, mode, e) {
if (isEnabled2()) {
dragStarted = true;
event2 = scheduler2.getEvent(id2);
eventNode = e.target.closest(`[${scheduler2.config.event_attribute}]`);
const viewName = scheduler2.getState().mode;
const layout = checkViewName(viewName);
if (layout == "units" && scheduler2.config.cascade_event_display) {
scheduler2.unselect(id2);
eventNode = e.target.closest(`[${scheduler2.config.event_attribute}]`);
}
}
return true;
});
scheduler2.attachEvent("onEventDrag", function(id2, mode, e) {
if (dragStarted && isEnabled2()) {
dragStarted = false;
const viewName = scheduler2.getState().mode;
const layout = checkViewName(viewName);
const sectionId = scheduler2.getActionData(e).section;
if (event2) {
const settings = { event: event2, layout, viewName, sectionId, eventNode };
createViewMarker(settings);
}
}
});
scheduler2.attachEvent("onDragEnd", function(id2, mode, e) {
for (let i = 0; i < dndMarkers.length; i++) {
scheduler2.unmarkTimespan(dndMarkers[i]);
}
dndMarkers = [];
eventNode = null;
event2 = null;
});
}
function undoDelete(scheduler2) {
const undoableDeletes = {};
scheduler2.attachEvent("onConfirmedBeforeEventDelete", function(id2) {
undoableDeletes[id2] = true;
return true;
});
scheduler2.attachEvent("onEventDeleted", function(id2, ev) {
if (undoableDeletes[id2]) {
delete undoableDeletes[id2];
} else {
return;
}
let deletedEvent = scheduler2.copy(ev);
if (scheduler2.config.undo_deleted && !scheduler2.getState().new_event) {
scheduler2.message({ text: `<div class="dhx_info_message">
<span class="undo_popup_text">Event deleted</span>
<button class="undo_button" data-deleted-event-id="${ev.id}">Undo</button>
</div>`, expire: 1e4, type: "popup_after_delete", callback: function(e) {
let undoBtn = e.target.closest(`[data-deleted-event-id="${ev.id}"]`);
if (undoBtn) {
if (deletedEvent.rrule && deletedEvent.duration) {
deletedEvent.end_date = new Date(deletedEvent.start_date.valueOf() + deletedEvent.duration * 1e3);
scheduler2.addEvent(deletedEvent);
}
scheduler2.addEvent(deletedEvent);
scheduler2.render();
}
} });
}
});
}
function limitPlugin(scheduler2) {
scheduler2.config.mark_now = true;
scheduler2.config.display_marked_timespans = true;
scheduler2.config.overwrite_marked_timespans = true;
var dhx_time_block = "dhx_time_block";
var default_timespan_type = "default";
var fix_options = function(options, days, zones) {
if (days instanceof Date && zones instanceof Date) {
options.start_date = days;
options.end_date = zones;
} else {
options.days = days;
options.zones = zones;
}
return options;
};
var get_resulting_options = function(days, zones, sections) {
var options = typeof days == "object" ? days : { days };
options.type = dhx_time_block;
options.css = "";
if (zones) {
if (sections)
options.sections = sections;
options = fix_options(options, days, zones);
}
return options;
};
scheduler2.blockTime = function(days, zones, sections) {
var options = get_resulting_options(days, zones, sections);
return scheduler2.addMarkedTimespan(options);
};
scheduler2.unblockTime = function(days, zones, sections) {
zones = zones || "fullday";
var options = get_resulting_options(days, zones, sections);
return scheduler2.deleteMarkedTimespan(options);
};
scheduler2.checkInMarkedTimespan = function(ev, timespan_type, on_overlap) {
timespan_type = timespan_type || default_timespan_type;
var res = true;
var temp_start_date = new Date(ev.start_date.valueOf());
var temp_end_date = scheduler2.date.add(temp_start_date, 1, "day");
var timespans = scheduler2._marked_timespans;
for (; temp_start_date < ev.end_date; temp_start_date = scheduler2.date.date_part(temp_end_date), temp_end_date = scheduler2.date.add(temp_start_date, 1, "day")) {
var day_value = +scheduler2.date.date_part(new Date(temp_start_date));
var day_index = temp_start_date.getDay();
var zones = getZones(ev, timespans, day_index, day_value, timespan_type);
if (zones) {
for (var i = 0; i < zones.length; i += 2) {
var eventStart = scheduler2._get_zone_minutes(temp_start_date);
var eventEnd = ev.end_date > temp_end_date || ev.end_date.getDate() != temp_start_date.getDate() ? 1440 : scheduler2._get_zone_minutes(ev.end_date);
var markerStart = zones[i];
var markerEnd = zones[i + 1];
if (markerStart < eventEnd && markerEnd > eventStart) {
if (typeof on_overlap == "function") {
res = on_overlap(ev, eventStart, eventEnd, markerStart, markerEnd);
} else {
res = false;
}
if (!res)
break;
}
}
}
}
return !res;
};
scheduler2.checkLimitViolation = function(event2) {
if (!event2)
return true;
if (!scheduler2.config.check_limits)
return true;
var s = scheduler2;
var c = s.config;
var evs = [];
if (event2.rec_type && event2._end_date || event2.rrule) {
const seriesEnd = event2._end_date || event2.end_date;
if (c.limit_start && c.limit_end) {
var recEventInLimits = seriesEnd.valueOf() >= c.limit_start.valueOf() && event2.start_date.valueOf() <= c.limit_end.valueOf();
return recEventInLimits;
} else
return true;
} else {
evs = [event2];
}
var complete_res = true;
for (var p = 0; p < evs.length; p++) {
var res = true;
var ev = evs[p];
ev._timed = scheduler2.isOneDayEvent(ev);
res = c.limit_start && c.limit_end ? ev.start_date.valueOf() >= c.limit_start.valueOf() && ev.end_date.valueOf() <= c.limit_end.valueOf() : true;
if (res) {
res = !scheduler2.checkInMarkedTimespan(ev, dhx_time_block, function(event3, eventStart, eventEnd, markerStart, markerEnd) {
var allow = true;
if (eventStart <= markerEnd && eventStart >= markerStart) {
if (markerEnd == 24 * 60 || eventEnd <= markerEnd) {
allow = false;
}
if (event3._timed && s._drag_id && s._drag_mode == "new-size") {
event3.start_date.setHours(0);
event3.start_date.setMinutes(markerEnd);
} else {
allow = false;
}
}
if (eventEnd >= markerStart && eventEnd <= markerEnd || eventStart < markerStart && eventEnd > markerEnd) {
if (event3._timed && s._drag_id && s._drag_mode == "new-size") {
event3.end_date.setHours(0);
event3.end_date.setMinutes(markerStart);
} else {
allow = false;
}
}
return allow;
});
}
if (!res) {
res = s.checkEvent("onLimitViolation") ? s.callEvent("onLimitViolation", [ev.id, ev]) : res;
}
complete_res = complete_res && res;
}
if (!complete_res) {
s._drag_id = null;
s._drag_mode = null;
}
return complete_res;
};
scheduler2._get_blocked_zones = function(timespans, property, day_index, day_value, timespan_type) {
var zones = [];
if (timespans && timespans[property]) {
var timeline_zones = timespans[property];
var blocked_timeline_zones = this._get_relevant_blocked_zones(day_index, day_value, timeline_zones, timespan_type);
for (var i = 0; i < blocked_timeline_zones.length; i++) {
zones = this._add_timespan_zones(zones, blocked_timeline_zones[i].zones);
}
}
return zones;
};
scheduler2._get_relevant_blocked_zones = function(day_index, day_value, zones, timespan_type) {
var resultZones;
if (scheduler2.config.overwrite_marked_timespans) {
resultZones = zones[day_value] && zones[day_value][timespan_type] ? zones[day_value][timespan_type] : zones[day_index] && zones[day_index][timespan_type] ? zones[day_index][timespan_type] : [];
} else {
resultZones = [];
if (zones[day_value] && zones[day_value][timespan_type]) {
resultZones = resultZones.concat(zones[day_value][timespan_type]);
}
if (zones[day_index] && zones[day_index][timespan_type]) {
resultZones = resultZones.concat(zones[day_index][timespan_type]);
}
}
return resultZones;
};
function getZones(ev, timespans, day_index, day_value, timespan_type) {
var s = scheduler2;
var zones = [];
var containers = { _props: "map_to", matrix: "y_property" };
for (var container in containers) {
var property = containers[container];
if (s[container]) {
for (var view in s[container]) {
var view_config = s[container][view];
var linker = view_config[property];
if (!ev[linker])
continue;
zones = s._add_timespan_zones(zones, scheduler2._get_blocked_zones(timespans[view], ev[linker], day_index, day_value, timespan_type));
}
}
}
zones = s._add_timespan_zones(zones, scheduler2._get_blocked_zones(timespans, "global", day_index, day_value, timespan_type));
return zones;
}
scheduler2._mark_now = function(hide) {
var dhx_now_time = "dhx_now_time";
if (!this._els[dhx_now_time]) {
this._els[dhx_now_time] = [];
}
var now = scheduler2._currentDate();
var cfg = this.config;
scheduler2._remove_mark_now();
if (!hide && cfg.mark_now && now < this._max_date && now > this._min_date && now.getHours() >= cfg.first_hour && now.getHours() < cfg.last_hour) {
var day_index = this.locate_holder_day(now);
this._els[dhx_now_time] = scheduler2._append_mark_now(day_index, now);
}
};
scheduler2._append_mark_now = function(day_index, now) {
var dhx_now_time = "dhx_now_time";
var zone_start = scheduler2._get_zone_minutes(now);
var options = { zones: [zone_start, zone_start + 1], css: dhx_now_time, type: dhx_now_time };
if (!this._table_view) {
if (this._props && this._props[this._mode]) {
var start_index, end_index;
var view = this._props[this._mode];
var units_l = view.size || view.options.length;
if (view.days > 1) {
if (view.size && view.options.length) {
day_index = (view.position + day_index) / view.options.length * view.size;
}
start_index = day_index;
end_index = day_index + units_l;
} else {
start_index = 0;
end_index = start_index + units_l;
}
var r_divs = [];
for (var i = start_index; i < end_index; i++) {
var t_day = i;
options.days = t_day;
var t_div = scheduler2._render_marked_timespan(options, null, t_day)[0];
r_divs.push(t_div);
}
return r_divs;
} else {
options.days = day_index;
return scheduler2._render_marked_timespan(options, null, day_index);
}
} else {
if (this._mode == "month") {
options.days = +scheduler2.date.date_part(now);
return scheduler2._render_marked_timespan(options, null, null);
}
}
};
scheduler2._remove_mark_now = function() {
var dhx_now_time = "dhx_now_time";
var els = this._els[dhx_now_time];
for (var i = 0; i < els.length; i++) {
var div = els[i];
var parent = div.parentNode;
if (parent) {
parent.removeChild(div);
}
}
this._els[dhx_now_time] = [];
};
scheduler2._marked_timespans = { global: {} };
scheduler2._get_zone_minutes = function(date) {
return date.getHours() * 60 + date.getMinutes();
};
scheduler2._prepare_timespan_options = function(config) {
var r_configs = [];
var temp_configs = [];
if (config.days == "fullweek")
config.days = [0, 1, 2, 3, 4, 5, 6];
if (config.days instanceof Array) {
var t_days = config.days.slice();
for (var i = 0; i < t_days.length; i++) {
var cloned_config = scheduler2._lame_clone(config);
cloned_config.days = t_days[i];
r_configs.push.apply(r_configs, scheduler2._prepare_timespan_options(cloned_config));
}
return r_configs;
}
if (!config || !(config.start_date && config.end_date && config.end_date > config.start_date || config.days !== void 0 && config.zones) && !config.type)
return r_configs;
var min = 0;
var max = 24 * 60;
if (config.zones == "fullday")
config.zones = [min, max];
if (config.zones && config.invert_zones) {
config.zones = scheduler2.invertZones(config.zones);
}
config.id = scheduler2.uid();
config.css = config.css || "";
config.type = config.type || default_timespan_type;
var sections = config.sections;
if (sections) {
for (var view_key in sections) {
if (sections.hasOwnProperty(view_key)) {
var ids = sections[view_key];
if (!(ids instanceof Array))
ids = [ids];
for (var i = 0; i < ids.length; i++) {
var t_config = scheduler2._lame_copy({}, config);
t_config.sections = {};
t_config.sections[view_key] = ids[i];
temp_configs.push(t_config);
}
}
}
} else {
temp_configs.push(config);
}
for (var k = 0; k < temp_configs.length; k++) {
var c_config = temp_configs[k];
var start_date = c_config.start_date;
var end_date = c_config.end_date;
if (start_date && end_date) {
var t_sd = scheduler2.date.date_part(new Date(start_date));
var t_ed = scheduler2.date.add(t_sd, 1, "day");
while (t_sd < end_date) {
var t_config = scheduler2._lame_copy({}, c_config);
delete t_config.start_date;
delete t_config.end_date;
t_config.days = t_sd.valueOf();
var zone_start = start_date > t_sd ? scheduler2._get_zone_minutes(start_date) : min;
var zone_end = end_date > t_ed || end_date.getDate() != t_sd.getDate() ? max : scheduler2._get_zone_minutes(end_date);
t_config.zones = [zone_start, zone_end];
r_configs.push(t_config);
t_sd = t_ed;
t_ed = scheduler2.date.add(t_ed, 1, "day");
}
} else {
if (c_config.days instanceof Date)
c_config.days = scheduler2.date.date_part(c_config.days).valueOf();
c_config.zones = config.zones.slice();
r_configs.push(c_config);
}
}
return r_configs;
};
scheduler2._get_dates_by_index = function(index, start, end) {
var dates = [];
start = scheduler2.date.date_part(new Date(start || scheduler2._min_date));
end = new Date(end || scheduler2._max_date);
var start_day = start.getDay();
var delta = index - start_day >= 0 ? index - start_day : 7 - start.getDay() + index;
var t_date = scheduler2.date.add(start, delta, "day");
for (; t_date < end; t_date = scheduler2.date.add(t_date, 1, "week")) {
dates.push(t_date);
}
return dates;
};
scheduler2._get_css_classes_by_config = function(config) {
var css_classes = [];
if (config.type == dhx_time_block) {
css_classes.push(dhx_time_block);
if (config.css)
css_classes.push(dhx_time_block + "_reset");
}
css_classes.push("dhx_marked_timespan", config.css);
return css_classes.join(" ");
};
scheduler2._get_block_by_config = function(config) {
var block = document.createElement("div");
if (config.html) {
if (typeof config.html == "string")
block.innerHTML = config.html;
else
block.appendChild(config.html);
}
return block;
};
scheduler2._render_marked_timespan = function(options, area, day) {
var blocks = [];
var c = scheduler2.config;
var min_date = this._min_date;
var max_date = this._max_date;
var day_value = false;
if (!c.display_marked_timespans)
return blocks;
if (!day && day !== 0) {
if (options.days < 7)
day = options.days;
else {
var date_to_display = new Date(options.days);
day_value = +date_to_display;
if (!(+max_date > +date_to_display && +min_date <= +date_to_display))
return blocks;
day = date_to_display.getDay();
}
var min_day = min_date.getDay();
if (min_day > day) {
day = 7 - (min_day - day);
} else {
day = day - min_day;
}
}
var zones = options.zones;
var css_classes = scheduler2._get_css_classes_by_config(options);
if (scheduler2._table_view && scheduler2._mode == "month") {
var areas = [];
var days = [];
if (!area) {
days = day_value ? [day_value] : scheduler2._get_dates_by_index(day);
for (var i = 0; i < days.length; i++) {
areas.push(this._scales[days[i]]);
}
} else {
areas.push(area);
days.push(day);
}
for (var i = 0; i < areas.length; i++) {
area = areas[i];
day = days[i];
var sday = this.locate_holder_day(day, false) % this._cols.length;
if (this._ignores[sday])
continue;
var block_proto = scheduler2._get_block_by_config(options);
block_proto.className = css_classes;
block_proto.style.top = "0px";
block_proto.style.height = "100%";
for (var k = 0; k < zones.length; k += 2) {
var start = zones[i];
var end = zones[i + 1];
if (end <= start)
return [];
var block = block_proto.cloneNode(true);
block.style.left = "0px";
block.style.width = "100%";
area.appendChild(block);
blocks.push(block);
}
}
} else {
var index = day;
if (this._ignores[this.locate_holder_day(day, false)])
return blocks;
if (this._props && this._props[this._mode] && options.sections && options.sections[this._mode]) {
var view = this._props[this._mode];
index = view.order[options.sections[this._mode]];
var inner_index = view.order[options.sections[this._mode]];
if (!(view.days > 1)) {
index = inner_index;
if (view.size && index > view.position + view.size) {
index = 0;
}
} else {
var units_l = view.size || view.options.length;
index = index * units_l + inner_index;
}
}
area = area ? area : scheduler2.locate_holder(index);
for (var i = 0; i < zones.length; i += 2) {
var start = Math.max(zones[i], c.first_hour * 60);
var end = Math.min(zones[i + 1], c.last_hour * 60);
if (end <= start) {
if (i + 2 < zones.length)
continue;
else
return [];
}
var block = scheduler2._get_block_by_config(options);
block.className = css_classes;
var all_hours_height = this.config.hour_size_px * 24 + 1;
var hour_ms = 60 * 60 * 1e3;
block.style.top = Math.round((start * 60 * 1e3 - this.config.first_hour * hour_ms) * this.config.hour_size_px / hour_ms) % all_hours_height + "px";
block.style.height = Math.max(Math.round((end - start) * 60 * 1e3 * this.config.hour_size_px / hour_ms) % all_hours_height, 1) + "px";
area.appendChild(block);
blocks.push(block);
}
}
return blocks;
};
scheduler2._mark_timespans = function() {
var data = this._els["dhx_cal_data"][0];
var divs = [];
if (scheduler2._table_view && scheduler2._mode == "month") {
for (var day in this._scales) {
var date = /* @__PURE__ */ new Date(+day);
divs.push.apply(divs, scheduler2._on_scale_add_marker(this._scales[day], date));
}
} else {
var date = new Date(scheduler2._min_date);
for (var i = 0, len = data.childNodes.length; i < len; i++) {
var area = data.childNodes[i];
if (area.firstChild && scheduler2._getClassName(area.firstChild).indexOf("dhx_scale_hour") > -1) {
continue;
}
divs.push.apply(divs, scheduler2._on_scale_add_marker(area, date));
date = scheduler2.date.add(date, 1, "day");
}
}
return divs;
};
scheduler2.markTimespan = function(configuration) {
if (!this._els) {
throw new Error("`scheduler.markTimespan` can't be used before scheduler initialization. Place `scheduler.markTimespan` call after `scheduler.init`.");
}
var rebuild_els = false;
if (!this._els["dhx_cal_data"]) {
scheduler2.get_elements();
rebuild_els = true;
}
var timespans_ids = scheduler2._marked_timespans_ids, timespan_types = scheduler2._marked_timespans_types, timespans = scheduler2._marked_timespans;
scheduler2.deleteMarkedTimespan();
scheduler2.addMarkedTimespan(configuration);
var divs = scheduler2._mark_timespans();
if (rebuild_els)
scheduler2._els = [];
scheduler2._marked_timespans_ids = timespans_ids;
scheduler2._marked_timespans_types = timespan_types;
scheduler2._marked_timespans = timespans;
return divs;
};
scheduler2.unmarkTimespan = function(divs) {
if (!divs)
return;
for (var i = 0; i < divs.length; i++) {
var div = divs[i];
if (div.parentNode) {
div.parentNode.removeChild(div);
}
}
};
scheduler2._addMarkerTimespanConfig = function(config) {
var global2 = "global";
var timespans = scheduler2._marked_timespans;
var id2 = config.id;
var ids = scheduler2._marked_timespans_ids;
if (!ids[id2])
ids[id2] = [];
var day = config.days;
var sections = config.sections;
var type = config.type;
config.id = id2;
if (sections) {
for (var view_key in sections) {
if (sections.hasOwnProperty(view_key)) {
if (!timespans[view_key])
timespans[view_key] = {};
var unit_id = sections[view_key];
var timespans_view = timespans[view_key];
if (!timespans_view[unit_id])
timespans_view[unit_id] = {};
if (!timespans_view[unit_id][day])
timespans_view[unit_id][day] = {};
if (!timespans_view[unit_id][day][type]) {
timespans_view[unit_id][day][type] = [];
if (!scheduler2._marked_timespans_types)
scheduler2._marked_timespans_types = {};
if (!scheduler2._marked_timespans_types[type])
scheduler2._marked_timespans_types[type] = true;
}
var day_configs = timespans_view[unit_id][day][type];
config._array = day_configs;
day_configs.push(config);
ids[id2].push(config);
}
}
} else {
if (!timespans[global2][day])
timespans[global2][day] = {};
if (!timespans[global2][day][type])
timespans[global2][day][type] = [];
if (!scheduler2._marked_timespans_types)
scheduler2._marked_timespans_types = {};
if (!scheduler2._marked_timespans_types[type])
scheduler2._marked_timespans_types[type] = true;
var day_configs = timespans[global2][day][type];
config._array = day_configs;
day_configs.push(config);
ids[id2].push(config);
}
};
scheduler2._marked_timespans_ids = {};
scheduler2.addMarkedTimespan = function(configuration) {
var configs = scheduler2._prepare_timespan_options(configuration);
if (!configs.length)
return;
var id2 = configs[0].id;
for (var i = 0; i < configs.length; i++) {
scheduler2._addMarkerTimespanConfig(configs[i]);
}
return id2;
};
scheduler2._add_timespan_zones = function(current_zones, zones) {
var resulting_zones = current_zones.slice();
zones = zones.slice();
if (!resulting_zones.length)
return zones;
for (var i = 0; i < resulting_zones.length; i += 2) {
var c_zone_start = resulting_zones[i];
var c_zone_end = resulting_zones[i + 1];
var isLast = i + 2 == resulting_zones.length;
for (var k = 0; k < zones.length; k += 2) {
var zone_start = zones[k];
var zone_end = zones[k + 1];
if (zone_end > c_zone_end && zone_start <= c_zone_end || zone_start < c_zone_start && zone_end >= c_zone_start) {
resulting_zones[i] = Math.min(c_zone_start, zone_start);
resulting_zones[i + 1] = Math.max(c_zone_end, zone_end);
i -= 2;
} else {
if (!isLast)
continue;
var offset = c_zone_start > zone_start ? 0 : 2;
resulting_zones.splice(i + offset, 0, zone_start, zone_end);
}
zones.splice(k--, 2);
break;
}
}
return resulting_zones;
};
scheduler2._subtract_timespan_zones = function(current_zones, zones) {
var resulting_zones = current_zones.slice();
for (var i = 0; i < resulting_zones.length; i += 2) {
var c_zone_start = resulting_zones[i];
var c_zone_end = resulting_zones[i + 1];
for (var k = 0; k < zones.length; k += 2) {
var zone_start = zones[k];
var zone_end = zones[k + 1];
if (zone_end > c_zone_start && zone_start < c_zone_end) {
var is_modified = false;
if (c_zone_start >= zone_start && c_zone_end <= zone_end) {
resulting_zones.splice(i, 2);
}
if (c_zone_start < zone_start) {
resulting_zones.splice(i, 2, c_zone_start, zone_start);
is_modified = true;
}
if (c_zone_end > zone_end) {
resulting_zones.splice(is_modified ? i + 2 : i, is_modified ? 0 : 2, zone_end, c_zone_end);
}
i -= 2;
break;
} else {
continue;
}
}
}
return resulting_zones;
};
scheduler2.invertZones = function(zones) {
return scheduler2._subtract_timespan_zones([0, 1440], zones.slice());
};
scheduler2._delete_marked_timespan_by_id = function(id2) {
var configs = scheduler2._marked_timespans_ids[id2];
if (configs) {
for (var i = 0; i < configs.length; i++) {
var config = configs[i];
var parent_array = config._array;
for (var k = 0; k < parent_array.length; k++) {
if (parent_array[k] == config) {
parent_array.splice(k, 1);
break;
}
}
}
}
};
scheduler2._delete_marked_timespan_by_config = function(config) {
var timespans = scheduler2._marked_timespans;
var sections = config.sections;
var day = config.days;
var type = config.type || default_timespan_type;
var viewspans;
if (sections) {
for (var view_key in sections) {
if (sections.hasOwnProperty(view_key) && timespans[view_key]) {
var unit_id = sections[view_key];
if (timespans[view_key][unit_id]) {
viewspans = timespans[view_key][unit_id];
}
}
}
} else {
viewspans = timespans.global;
}
if (viewspans) {
if (day !== void 0) {
if (viewspans[day] && viewspans[day][type]) {
scheduler2._addMarkerTimespanConfig(config);
scheduler2._delete_marked_timespans_list(viewspans[day][type], config);
}
} else {
for (var d in viewspans) {
if (viewspans[d][type]) {
var dayConfig = scheduler2._lame_clone(config);
config.days = d;
scheduler2._addMarkerTimespanConfig(dayConfig);
scheduler2._delete_marked_timespans_list(viewspans[d][type], config);
}
}
}
}
};
scheduler2._delete_marked_timespans_list = function(day_timespans, config) {
for (var i = 0; i < day_timespans.length; i++) {
var d_t = day_timespans[i];
var zones = scheduler2._subtract_timespan_zones(d_t.zones, config.zones);
if (zones.length)
d_t.zones = zones;
else {
day_timespans.splice(i, 1);
i--;
var related_zones = scheduler2._marked_timespans_ids[d_t.id];
for (var k = 0; k < related_zones.length; k++) {
if (related_zones[k] == d_t) {
related_zones.splice(k, 1);
break;
}
}
}
}
};
scheduler2.deleteMarkedTimespan = function(configuration) {
if (!arguments.length) {
scheduler2._marked_timespans = { global: {} };
scheduler2._marked_timespans_ids = {};
scheduler2._marked_timespans_types = {};
}
if (typeof configuration != "object") {
scheduler2._delete_marked_timespan_by_id(configuration);
} else {
if (!(configuration.start_date && configuration.end_date)) {
if (configuration.days === void 0 && !configuration.type)
configuration.days = "fullweek";
if (!configuration.zones)
configuration.zones = "fullday";
}
var types = [];
if (!configuration.type) {
for (var type in scheduler2._marked_timespans_types) {
types.push(type);
}
} else {
types.push(configuration.type);
}
var configs = scheduler2._prepare_timespan_options(configuration);
for (var i = 0; i < configs.length; i++) {
var config = configs[i];
for (var t2 = 0; t2 < types.length; t2++) {
var typedConfig = scheduler2._lame_clone(config);
typedConfig.type = types[t2];
scheduler2._delete_marked_timespan_by_config(typedConfig);
}
}
}
};
scheduler2._get_types_to_render = function(common2, specific) {
var types_to_render = common2 ? scheduler2._lame_copy({}, common2) : {};
for (var type in specific || {}) {
if (specific.hasOwnProperty(type)) {
types_to_render[type] = specific[type];
}
}
return types_to_render;
};
scheduler2._get_configs_to_render = function(types) {
var configs = [];
for (var type in types) {
if (types.hasOwnProperty(type)) {
configs.push.apply(configs, types[type]);
}
}
return configs;
};
scheduler2._on_scale_add_marker = function(area, day) {
if (scheduler2._table_view && scheduler2._mode != "month")
return;
var day_index = day.getDay();
var day_value = day.valueOf();
var mode = this._mode;
var timespans = scheduler2._marked_timespans;
var r_configs = [];
var divs = [];
if (this._props && this._props[mode]) {
var view = this._props[mode];
var units = view.options;
var index = scheduler2._get_unit_index(view, day);
var unit = units[index];
if (!(view.days > 1)) {
day = scheduler2.date.date_part(new Date(this._date));
} else {
var dx = 24 * 60 * 60 * 1e3;
var day_ind = Math.round((day - scheduler2._min_date) / dx);
var unitsPerDay = view.size || units.length;
day = scheduler2.date.add(scheduler2._min_date, Math.floor(day_ind / unitsPerDay), "day");
day = scheduler2.date.date_part(day);
}
day_index = day.getDay();
day_value = day.valueOf();
if (timespans[mode] && timespans[mode][unit.key]) {
var unit_zones = timespans[mode][unit.key];
var unit_types = scheduler2._get_types_to_render(unit_zones[day_index], unit_zones[day_value]);
r_configs.push.apply(r_configs, scheduler2._get_configs_to_render(unit_types));
}
}
var global_data = timespans["global"];
if (scheduler2.config.overwrite_marked_timespans) {
var day_types = global_data[day_value] || global_data[day_index];
r_configs.push.apply(r_configs, scheduler2._get_configs_to_render(day_types));
} else {
if (global_data[day_value]) {
r_configs.push.apply(r_configs, scheduler2._get_configs_to_render(global_data[day_value]));
}
if (global_data[day_index]) {
r_configs.push.apply(r_configs, scheduler2._get_configs_to_render(global_data[day_index]));
}
}
for (var i = 0; i < r_configs.length; i++) {
divs.push.apply(divs, scheduler2._render_marked_timespan(r_configs[i], area, day));
}
return divs;
};
scheduler2.attachEvent("onScaleAdd", function() {
scheduler2._on_scale_add_marker.apply(scheduler2, arguments);
});
scheduler2.dblclick_dhx_marked_timespan = function(e, src) {
scheduler2.callEvent("onScaleDblClick", [scheduler2.getActionData(e).date, src, e]);
if (scheduler2.config.dblclick_create) {
scheduler2.addEventNow(scheduler2.getActionData(e).date, null, e);
}
};
}
function createMethod(scheduler2) {
var methods = {};
var isActive = false;
function disableMethod(methodName, dummyMethod) {
dummyMethod = typeof dummyMethod == "function" ? dummyMethod : function() {
};
if (!methods[methodName]) {
methods[methodName] = this[methodName];
this[methodName] = dummyMethod;
}
}
function restoreMethod(methodName) {
if (methods[methodName]) {
this[methodName] = methods[methodName];
methods[methodName] = null;
}
}
function disableMethods(methodsHash) {
for (var i in methodsHash) {
disableMethod.call(this, i, methodsHash[i]);
}
}
function restoreMethods() {
for (var i in methods) {
restoreMethod.call(this, i);
}
}
function batchUpdatePayload(callback) {
try {
callback();
} catch (e) {
window.console.error(e);
}
}
scheduler2.$stateProvider.registerProvider("batchUpdate", function() {
return { batch_update: isActive };
}, false);
return function batchUpdate2(callback, noRedraw) {
if (isActive) {
batchUpdatePayload(callback);
return;
}
var call_dp = this._dp && this._dp.updateMode != "off";
var dp_mode;
if (call_dp) {
dp_mode = this._dp.updateMode;
this._dp.setUpdateMode("off");
}
const calls = { setModeDate: { date: null, mode: null }, needRender: false, needUpdateView: false, repaintEvents: {} };
const rememberModeDate = (date, mode) => {
if (date) {
calls.setModeDate.date = date;
}
if (mode) {
calls.setModeDate.mode = mode;
}
};
var methods2 = { render: (date, mode) => {
calls.needRender = true;
rememberModeDate(date, mode);
}, setCurrentView: (date, mode) => {
calls.needRender = true;
rememberModeDate(date, mode);
}, updateView: (date, mode) => {
calls.needUpdateView = true;
rememberModeDate(date, mode);
}, render_data: () => calls.needRender = true, render_view_data: (evs) => {
if (evs && evs.length) {
evs.forEach((e) => calls.repaintEvents[e.id] = true);
} else {
calls.needRender = true;
}
} };
disableMethods.call(this, methods2);
isActive = true;
this.callEvent("onBeforeBatchUpdate", []);
batchUpdatePayload(callback);
this.callEvent("onAfterBatchUpdate", []);
restoreMethods.call(this);
isActive = false;
if (!noRedraw) {
if (calls.needRender) {
scheduler2.render(calls.setModeDate.date, calls.setModeDate.mode);
} else if (calls.needUpdateView) {
scheduler2.updateView(calls.setModeDate.date, calls.setModeDate.mode);
} else {
for (const i in calls.repaintEvents) {
scheduler2.updateEvent(i);
}
}
}
if (call_dp) {
this._dp.setUpdateMode(dp_mode);
this._dp.sendData();
}
};
}
function batchUpdate(scheduler2) {
scheduler2.batchUpdate = createMethod(scheduler2);
}
class t {
constructor(t2) {
const { url: e, token: s } = t2;
this._url = e, this._token = s, this._mode = 1, this._seed = 1, this._queue = [], this.data = {}, this.api = {}, this._events = {};
}
headers() {
return { Accept: "application/json", "Content-Type": "application/json", "Remote-Token": this._token };
}
fetch(t2, e) {
const s = { credentials: "include", headers: this.headers() };
return e && (s.method = "POST", s.body = e), fetch(t2, s).then((t3) => t3.json());
}
load(t2) {
return t2 && (this._url = t2), this.fetch(this._url).then((t3) => this.parse(t3));
}
parse(t2) {
const { key: e, websocket: s } = t2;
e && (this._token = t2.key);
for (const e2 in t2.data)
this.data[e2] = t2.data[e2];
for (const e2 in t2.api) {
const s2 = this.api[e2] = {}, i = t2.api[e2];
for (const t3 in i)
s2[t3] = this._wrapper(e2 + "." + t3);
}
return s && this.connect(), this;
}
connect() {
const t2 = this._socket;
t2 && (this._socket = null, t2.onclose = function() {
}, t2.close()), this._mode = 2, this._socket = function(t3, e, s, i) {
let n = e;
"/" === n[0] && (n = document.location.protocol + "//" + document.location.host + e);
n = n.replace(/^http(s|):/, "ws$1:");
const o = -1 != n.indexOf("?") ? "&" : "?";
n = `${n}${o}token=${s}&ws=1`;
const r = new WebSocket(n);
return r.onclose = () => setTimeout(() => t3.connect(), 2e3), r.onmessage = (e2) => {
const s2 = JSON.parse(e2.data);
switch (s2.action) {
case "result":
t3.result(s2.body, []);
break;
case "event":
t3.fire(s2.body.name, s2.body.value);
break;
case "start":
i();
break;
default:
t3.onError(s2.data);
}
}, r;
}(this, this._url, this._token, () => (this._mode = 3, this._send(), this._resubscribe(), this));
}
_wrapper(t2) {
return (function() {
const e = [].slice.call(arguments);
let s = null;
const i = new Promise((i2, n) => {
s = { data: { id: this._uid(), name: t2, args: e }, status: 1, resolve: i2, reject: n }, this._queue.push(s);
});
return this.onCall(s, i), 3 === this._mode ? this._send(s) : setTimeout(() => this._send(), 1), i;
}).bind(this);
}
_uid() {
return (this._seed++).toString();
}
_send(t2) {
if (2 == this._mode)
return void setTimeout(() => this._send(), 100);
const e = t2 ? [t2] : this._queue.filter((t3) => 1 === t3.status);
if (!e.length)
return;
const s = e.map((t3) => (t3.status = 2, t3.data));
3 !== this._mode ? this.fetch(this._url, JSON.stringify(s)).catch((t3) => this.onError(t3)).then((t3) => this.result(t3, s)) : this._socket.send(JSON.stringify({ action: "call", body: s }));
}
result(t2, e) {
const s = {};
if (t2)
for (let e2 = 0; e2 < t2.length; e2++)
s[t2[e2].id] = t2[e2];
else
for (let t3 = 0; t3 < e.length; t3++)
s[e[t3].id] = { id: e[t3].id, error: "Network Error", data: null };
for (let t3 = this._queue.length - 1; t3 >= 0; t3--) {
const e2 = this._queue[t3], i = s[e2.data.id];
i && (this.onResponse(e2, i), i.error ? e2.reject(i.error) : e2.resolve(i.data), this._queue.splice(t3, 1));
}
}
on(t2, e) {
const s = this._uid();
let i = this._events[t2];
const n = !!i;
return n || (i = this._events[t2] = []), i.push({ id: s, handler: e }), n || 3 != this._mode || this._socket.send(JSON.stringify({ action: "subscribe", name: t2 })), { name: t2, id: s };
}
_resubscribe() {
if (3 == this._mode)
for (const t2 in this._events)
this._socket.send(JSON.stringify({ action: "subscribe", name: t2 }));
}
detach(t2) {
if (!t2) {
if (3 == this._mode)
for (const t3 in this._events)
this._socket.send(JSON.stringify({ action: "unsubscribe", key: t3 }));
return void (this._events = {});
}
const { id: e, name: s } = t2, i = this._events[s];
if (i) {
const t3 = i.filter((t4) => t4.id != e);
t3.length ? this._events[s] = t3 : (delete this._events[s], 3 == this._mode && this._socket.send(JSON.stringify({ action: "unsubscribe", name: s })));
}
}
fire(t2, e) {
const s = this._events[t2];
if (s)
for (let t3 = 0; t3 < s.length; t3++)
s[t3].handler(e);
}
onError(t2) {
return null;
}
onCall(