dhtmlx-scheduler 7.2.10 → 7.2.12
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/bower.json +1 -1
- package/codebase/dhtmlxscheduler.css +1 -1
- package/codebase/dhtmlxscheduler.es.js +3988 -3906
- package/codebase/dhtmlxscheduler.es.js.map +1 -1
- package/codebase/dhtmlxscheduler.js +58 -58
- package/codebase/dhtmlxscheduler.js.map +1 -1
- package/codebase/sources/dhtmlxscheduler.css +1 -0
- package/codebase/sources/dhtmlxscheduler.es.js +389 -223
- package/codebase/sources/dhtmlxscheduler.es.js.map +1 -1
- package/codebase/sources/dhtmlxscheduler.js +389 -223
- package/codebase/sources/dhtmlxscheduler.js.map +1 -1
- package/codebase/sources/less/package.json +1 -1
- package/codebase/sources/less/src/quick_info.less +1 -0
- package/package.json +1 -1
- package/whatsnew.md +23 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
/** @license
|
|
2
2
|
|
|
3
|
-
dhtmlxScheduler v.7.2.
|
|
3
|
+
dhtmlxScheduler v.7.2.12 Standard
|
|
4
4
|
|
|
5
5
|
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
|
|
6
6
|
|
|
@@ -1297,7 +1297,7 @@ function createHandlers(scheduler2) {
|
|
|
1297
1297
|
if (scheduler2._dp && scheduler2._dp._in_progress[event2.id]) {
|
|
1298
1298
|
return;
|
|
1299
1299
|
}
|
|
1300
|
-
if (type === "add-event") {
|
|
1300
|
+
if (type === "add-event" && scheduler2._dp) {
|
|
1301
1301
|
for (const id in scheduler2._dp._in_progress) {
|
|
1302
1302
|
if (scheduler2._dp.getState(id) === "inserted") {
|
|
1303
1303
|
scheduler2._dp.attachEvent("onFullSync", function() {
|
|
@@ -1336,9 +1336,13 @@ function createHandlers(scheduler2) {
|
|
|
1336
1336
|
console.warn(`Event with ID ${eventData.id} already exists. Skipping add.`);
|
|
1337
1337
|
return;
|
|
1338
1338
|
}
|
|
1339
|
-
eventData.start_date
|
|
1340
|
-
|
|
1341
|
-
|
|
1339
|
+
if (typeof eventData.start_date === "string") {
|
|
1340
|
+
eventData.start_date = scheduler2.templates.parse_date(eventData.start_date);
|
|
1341
|
+
}
|
|
1342
|
+
if (typeof eventData.end_date === "string") {
|
|
1343
|
+
eventData.end_date = scheduler2.templates.parse_date(eventData.end_date);
|
|
1344
|
+
}
|
|
1345
|
+
if (eventData.original_start && typeof eventData.original_start === "string") {
|
|
1342
1346
|
eventData.original_start = scheduler2.templates.parse_date(eventData.original_start);
|
|
1343
1347
|
}
|
|
1344
1348
|
ignore(() => {
|
|
@@ -1358,9 +1362,13 @@ function createHandlers(scheduler2) {
|
|
|
1358
1362
|
existingEvent[key] = eventData[key];
|
|
1359
1363
|
}
|
|
1360
1364
|
}
|
|
1361
|
-
|
|
1362
|
-
|
|
1363
|
-
|
|
1365
|
+
if (typeof eventData.start_date === "string") {
|
|
1366
|
+
eventData.start_date = scheduler2.templates.parse_date(eventData.start_date);
|
|
1367
|
+
}
|
|
1368
|
+
if (typeof eventData.end_date === "string") {
|
|
1369
|
+
eventData.end_date = scheduler2.templates.parse_date(eventData.end_date);
|
|
1370
|
+
}
|
|
1371
|
+
if (eventData.original_start && typeof eventData.original_start === "string") {
|
|
1364
1372
|
eventData.original_start = scheduler2.templates.parse_date(eventData.original_start);
|
|
1365
1373
|
}
|
|
1366
1374
|
scheduler2.callEvent("onEventChanged", [sid, existingEvent]);
|
|
@@ -2091,18 +2099,21 @@ function extend$j(scheduler2) {
|
|
|
2091
2099
|
});
|
|
2092
2100
|
return views.concat(date).concat(nav);
|
|
2093
2101
|
}
|
|
2102
|
+
scheduler2._getInitialState = function(provided) {
|
|
2103
|
+
const initialDate = provided.date || this._currentDate();
|
|
2104
|
+
const initialView = provided.mode || "week";
|
|
2105
|
+
return { date: initialDate, mode: initialView };
|
|
2106
|
+
};
|
|
2094
2107
|
scheduler2.init = function(id, date, mode) {
|
|
2095
2108
|
if (this.$destroyed) {
|
|
2096
2109
|
return;
|
|
2097
2110
|
}
|
|
2098
|
-
date = date || scheduler2._currentDate();
|
|
2099
|
-
mode = mode || "week";
|
|
2100
|
-
if (this._obj) {
|
|
2101
|
-
this.unset_actions();
|
|
2102
|
-
}
|
|
2103
2111
|
this._obj = typeof id == "string" ? document.getElementById(id) : id;
|
|
2104
2112
|
this.$container = this._obj;
|
|
2105
2113
|
this.$root = this._obj;
|
|
2114
|
+
if (this._obj) {
|
|
2115
|
+
this.unset_actions();
|
|
2116
|
+
}
|
|
2106
2117
|
if (!this.$container.offsetHeight && this.$container.offsetWidth && this.$container.style.height === "100%") {
|
|
2107
2118
|
window.console.error(scheduler2._commonErrorMessages.collapsedContainer(), this.$container);
|
|
2108
2119
|
}
|
|
@@ -2140,9 +2151,12 @@ function extend$j(scheduler2) {
|
|
|
2140
2151
|
this._init_once();
|
|
2141
2152
|
this._init_touch_events();
|
|
2142
2153
|
this.set_sizes();
|
|
2154
|
+
const initialState = scheduler2._getInitialState({ date, mode });
|
|
2155
|
+
const initialDate = initialState.date;
|
|
2156
|
+
const initialMode = initialState.mode;
|
|
2143
2157
|
scheduler2.callEvent("onSchedulerReady", []);
|
|
2144
2158
|
scheduler2.$initialized = true;
|
|
2145
|
-
this.setCurrentView(
|
|
2159
|
+
this.setCurrentView(initialDate, initialMode);
|
|
2146
2160
|
};
|
|
2147
2161
|
scheduler2.xy = { min_event_height: 20, bar_height: 24, scale_width: 50, scroll_width: 18, scale_height: 20, month_scale_height: 20, menu_width: 25, margin_top: 0, margin_left: 0, editor_width: 140, month_head_height: 22, event_header_height: 14 };
|
|
2148
2162
|
scheduler2.keys = { edit_save: 13, edit_cancel: 27 };
|
|
@@ -2165,7 +2179,25 @@ function extend$j(scheduler2) {
|
|
|
2165
2179
|
this.$container.insertBefore(materialScalePlaceholder, this._els["dhx_cal_header"][0]);
|
|
2166
2180
|
}
|
|
2167
2181
|
materialScalePlaceholder.style.display = "block";
|
|
2168
|
-
|
|
2182
|
+
const navElement = scheduler2.$root.querySelector(".dhx_cal_navline");
|
|
2183
|
+
let navHeight = 0;
|
|
2184
|
+
if (navElement) {
|
|
2185
|
+
navHeight += navElement.offsetHeight;
|
|
2186
|
+
}
|
|
2187
|
+
const headerElement = scheduler2.$root.querySelector(".dhx_cal_header");
|
|
2188
|
+
let headerHeight = 0;
|
|
2189
|
+
if (headerElement) {
|
|
2190
|
+
headerHeight += headerElement.offsetHeight;
|
|
2191
|
+
}
|
|
2192
|
+
let offsetTop, offsetHeight;
|
|
2193
|
+
if (!headerHeight) {
|
|
2194
|
+
offsetTop = navHeight - 4;
|
|
2195
|
+
offsetHeight = 5;
|
|
2196
|
+
} else {
|
|
2197
|
+
offsetTop = navHeight + 1;
|
|
2198
|
+
offsetHeight = headerHeight;
|
|
2199
|
+
}
|
|
2200
|
+
this.set_xy(materialScalePlaceholder, w, offsetHeight, 0, offsetTop);
|
|
2169
2201
|
} else {
|
|
2170
2202
|
if (materialScalePlaceholder) {
|
|
2171
2203
|
materialScalePlaceholder.parentNode.removeChild(materialScalePlaceholder);
|
|
@@ -3057,11 +3089,8 @@ function extend$j(scheduler2) {
|
|
|
3057
3089
|
var container = this._obj;
|
|
3058
3090
|
var oldClass = "dhx_scheduler_" + this._mode;
|
|
3059
3091
|
var newClass = "dhx_scheduler_" + mode;
|
|
3060
|
-
|
|
3061
|
-
|
|
3062
|
-
} else {
|
|
3063
|
-
container.className = container.className.replace(oldClass, newClass);
|
|
3064
|
-
}
|
|
3092
|
+
container.classList.remove(oldClass);
|
|
3093
|
+
container.classList.add(newClass);
|
|
3065
3094
|
var dhx_multi_day = "dhx_multi_day";
|
|
3066
3095
|
var prev_scroll = this._mode == mode && this.config.preserve_scroll ? this._els[dhx_cal_data][0].scrollTop : false;
|
|
3067
3096
|
var multidayScroll;
|
|
@@ -4201,6 +4230,7 @@ function extend$g(scheduler2) {
|
|
|
4201
4230
|
this.clearAll();
|
|
4202
4231
|
if (this.$container) {
|
|
4203
4232
|
this.$container.innerHTML = "";
|
|
4233
|
+
this.$container.classList.remove(`dhx_scheduler_${this._mode}`);
|
|
4204
4234
|
}
|
|
4205
4235
|
if (this._eventRemoveAll) {
|
|
4206
4236
|
this._eventRemoveAll();
|
|
@@ -9237,7 +9267,7 @@ class DatePicker {
|
|
|
9237
9267
|
}
|
|
9238
9268
|
}
|
|
9239
9269
|
function factoryMethod(extensionManager) {
|
|
9240
|
-
const scheduler2 = { version: "7.2.
|
|
9270
|
+
const scheduler2 = { version: "7.2.12" };
|
|
9241
9271
|
scheduler2.$stateProvider = StateService();
|
|
9242
9272
|
scheduler2.getState = scheduler2.$stateProvider.getState;
|
|
9243
9273
|
extend$n(scheduler2);
|
|
@@ -9721,7 +9751,10 @@ function agenda_view(scheduler2) {
|
|
|
9721
9751
|
scheduler2._colsS = null;
|
|
9722
9752
|
scheduler2._table_view = true;
|
|
9723
9753
|
const dateHeader = scheduler2._getNavDateElement();
|
|
9724
|
-
|
|
9754
|
+
if (dateHeader) {
|
|
9755
|
+
dateHeader.innerHTML = scheduler2.templates.agenda_date(scheduler2._date);
|
|
9756
|
+
}
|
|
9757
|
+
scheduler2.set_sizes();
|
|
9725
9758
|
fill_agenda_tab();
|
|
9726
9759
|
} else {
|
|
9727
9760
|
scheduler2._table_view = false;
|
|
@@ -10286,74 +10319,95 @@ function container_autoresize(scheduler2) {
|
|
|
10286
10319
|
}
|
|
10287
10320
|
}
|
|
10288
10321
|
function cookie(scheduler2) {
|
|
10289
|
-
function
|
|
10290
|
-
|
|
10291
|
-
|
|
10292
|
-
|
|
10293
|
-
|
|
10294
|
-
|
|
10295
|
-
|
|
10296
|
-
|
|
10297
|
-
|
|
10298
|
-
|
|
10299
|
-
var end = document.cookie.indexOf(";", offset);
|
|
10300
|
-
if (end == -1)
|
|
10301
|
-
end = document.cookie.length;
|
|
10302
|
-
return document.cookie.substring(offset, end);
|
|
10303
|
-
}
|
|
10322
|
+
function getStorageKey() {
|
|
10323
|
+
return (scheduler2._obj.id || "scheduler") + "_settings";
|
|
10324
|
+
}
|
|
10325
|
+
const dateToString = scheduler2.date.date_to_str("%Y-%m-%d %H:%i");
|
|
10326
|
+
const stringToDate = scheduler2.date.str_to_date("%Y-%m-%d %H:%i");
|
|
10327
|
+
function safeLocalStorageGet(key) {
|
|
10328
|
+
try {
|
|
10329
|
+
return window.localStorage.getItem(key);
|
|
10330
|
+
} catch (e) {
|
|
10331
|
+
return null;
|
|
10304
10332
|
}
|
|
10305
|
-
return "";
|
|
10306
10333
|
}
|
|
10307
|
-
function
|
|
10308
|
-
|
|
10334
|
+
function safeLocalStorageSet(key, value) {
|
|
10335
|
+
try {
|
|
10336
|
+
window.localStorage.setItem(key, value);
|
|
10337
|
+
return true;
|
|
10338
|
+
} catch (e) {
|
|
10339
|
+
return false;
|
|
10340
|
+
}
|
|
10309
10341
|
}
|
|
10310
|
-
|
|
10311
|
-
|
|
10312
|
-
|
|
10313
|
-
|
|
10314
|
-
|
|
10315
|
-
|
|
10342
|
+
function readStoredState() {
|
|
10343
|
+
const storageKey = getStorageKey();
|
|
10344
|
+
const raw = safeLocalStorageGet(storageKey);
|
|
10345
|
+
if (!raw) {
|
|
10346
|
+
return { date: null, mode: null };
|
|
10347
|
+
}
|
|
10348
|
+
let parsed;
|
|
10349
|
+
try {
|
|
10350
|
+
parsed = JSON.parse(raw);
|
|
10351
|
+
} catch (e) {
|
|
10352
|
+
return { date: null, mode: null };
|
|
10353
|
+
}
|
|
10354
|
+
if (!parsed || typeof parsed !== "object") {
|
|
10355
|
+
return { date: null, mode: null };
|
|
10356
|
+
}
|
|
10357
|
+
let parsedDate = null;
|
|
10358
|
+
if (typeof parsed.date === "string" && parsed.date.length > 0) {
|
|
10359
|
+
try {
|
|
10360
|
+
parsedDate = stringToDate(parsed.date);
|
|
10361
|
+
if (isNaN(+parsedDate)) {
|
|
10362
|
+
parsedDate = null;
|
|
10363
|
+
}
|
|
10364
|
+
} catch (e) {
|
|
10365
|
+
parsedDate = null;
|
|
10316
10366
|
}
|
|
10317
10367
|
}
|
|
10318
|
-
|
|
10319
|
-
|
|
10320
|
-
|
|
10321
|
-
|
|
10322
|
-
|
|
10323
|
-
|
|
10324
|
-
|
|
10368
|
+
const parsedMode = typeof parsed.mode === "string" ? parsed.mode : null;
|
|
10369
|
+
return { date: parsedDate, mode: parsedMode };
|
|
10370
|
+
}
|
|
10371
|
+
function urlHasExplicitNavigation() {
|
|
10372
|
+
if (!scheduler2._get_url_nav) {
|
|
10373
|
+
return false;
|
|
10374
|
+
}
|
|
10375
|
+
const urlState = scheduler2._get_url_nav();
|
|
10376
|
+
if (!urlState) {
|
|
10377
|
+
return false;
|
|
10378
|
+
}
|
|
10379
|
+
if (urlState.date || urlState.mode || urlState.event) {
|
|
10380
|
+
return true;
|
|
10381
|
+
}
|
|
10382
|
+
return false;
|
|
10383
|
+
}
|
|
10384
|
+
const originalGetInitialState = scheduler2._getInitialState;
|
|
10385
|
+
scheduler2._getInitialState = function(provided) {
|
|
10386
|
+
const baseState = originalGetInitialState.call(this, provided);
|
|
10387
|
+
if (urlHasExplicitNavigation()) {
|
|
10388
|
+
return baseState;
|
|
10389
|
+
}
|
|
10390
|
+
const storedState = readStoredState();
|
|
10391
|
+
const nextState = { date: baseState.date, mode: baseState.mode };
|
|
10392
|
+
if (storedState.date) {
|
|
10393
|
+
nextState.date = storedState.date;
|
|
10394
|
+
}
|
|
10395
|
+
if (storedState.mode) {
|
|
10396
|
+
try {
|
|
10397
|
+
if (this.isViewExists(storedState.mode)) {
|
|
10398
|
+
nextState.mode = storedState.mode;
|
|
10325
10399
|
}
|
|
10326
|
-
|
|
10327
|
-
schedulerCookie[0] = this._helpers.parseDate(schedulerCookie[0]);
|
|
10328
|
-
var view = this.isViewExists(schedulerCookie[1]) ? schedulerCookie[1] : mode, date = !isNaN(+schedulerCookie[0]) ? schedulerCookie[0] : date;
|
|
10329
|
-
window.setTimeout(function() {
|
|
10330
|
-
if (scheduler2.$destroyed) {
|
|
10331
|
-
return;
|
|
10332
|
-
}
|
|
10333
|
-
scheduler2.setCurrentView(date, view);
|
|
10334
|
-
}, 1);
|
|
10335
|
-
return false;
|
|
10400
|
+
} catch (e) {
|
|
10336
10401
|
}
|
|
10337
10402
|
}
|
|
10338
|
-
return
|
|
10339
|
-
}
|
|
10403
|
+
return nextState;
|
|
10404
|
+
};
|
|
10340
10405
|
scheduler2.attachEvent("onViewChange", function(newMode, newDate) {
|
|
10341
|
-
|
|
10342
|
-
|
|
10343
|
-
|
|
10406
|
+
const storageKey = getStorageKey();
|
|
10407
|
+
const payload = { date: dateToString(newDate), mode: newMode };
|
|
10408
|
+
safeLocalStorageSet(storageKey, JSON.stringify(payload));
|
|
10409
|
+
return true;
|
|
10344
10410
|
});
|
|
10345
|
-
var old_load = scheduler2._load;
|
|
10346
|
-
scheduler2._load = function() {
|
|
10347
|
-
var args = arguments;
|
|
10348
|
-
if (!scheduler2._date) {
|
|
10349
|
-
var that = this;
|
|
10350
|
-
window.setTimeout(function() {
|
|
10351
|
-
old_load.apply(that, args);
|
|
10352
|
-
}, 1);
|
|
10353
|
-
} else {
|
|
10354
|
-
old_load.apply(this, args);
|
|
10355
|
-
}
|
|
10356
|
-
};
|
|
10357
10411
|
}
|
|
10358
10412
|
const notImplemented = { alert: (extension, assert2) => {
|
|
10359
10413
|
assert2(false, `The ${extension} extension is not included in this version of dhtmlxScheduler.<br>
|
|
@@ -15419,41 +15473,39 @@ function quick_info(scheduler2) {
|
|
|
15419
15473
|
scheduler2.hideQuickInfo();
|
|
15420
15474
|
};
|
|
15421
15475
|
scheduler2._init_quick_info = function() {
|
|
15422
|
-
|
|
15423
|
-
|
|
15424
|
-
|
|
15425
|
-
|
|
15426
|
-
|
|
15427
|
-
|
|
15428
|
-
|
|
15429
|
-
|
|
15430
|
-
|
|
15431
|
-
|
|
15432
|
-
<
|
|
15433
|
-
|
|
15476
|
+
let qi = this._quick_info_box = document.createElement("div");
|
|
15477
|
+
this._waiAria.quickInfoAttr(qi);
|
|
15478
|
+
qi.className = "dhx_cal_quick_info";
|
|
15479
|
+
if (scheduler2.$testmode)
|
|
15480
|
+
qi.className += " dhx_no_animate";
|
|
15481
|
+
if (scheduler2.config.rtl)
|
|
15482
|
+
qi.className += " dhx_quick_info_rtl";
|
|
15483
|
+
let ariaAttr = this._waiAria.quickInfoHeaderAttrString();
|
|
15484
|
+
let html = `
|
|
15485
|
+
<div class="dhx_cal_qi_tcontrols">
|
|
15486
|
+
<a class="dhx_cal_qi_close_btn scheduler_icon close"></a>
|
|
15487
|
+
</div>
|
|
15488
|
+
<div class="dhx_cal_qi_title" ${ariaAttr}>
|
|
15489
|
+
|
|
15490
|
+
<div class="dhx_cal_qi_tcontent"></div>
|
|
15491
|
+
<div class="dhx_cal_qi_tdate"></div>
|
|
15434
15492
|
</div>
|
|
15435
|
-
<div class="
|
|
15436
|
-
|
|
15437
|
-
|
|
15438
|
-
|
|
15439
|
-
|
|
15440
|
-
|
|
15441
|
-
|
|
15442
|
-
|
|
15443
|
-
|
|
15444
|
-
|
|
15445
|
-
|
|
15446
|
-
|
|
15447
|
-
|
|
15448
|
-
|
|
15449
|
-
|
|
15450
|
-
scheduler2.event(
|
|
15451
|
-
scheduler2._qi_button_click(ev.target || ev.srcElement);
|
|
15452
|
-
});
|
|
15453
|
-
if (scheduler2.config.quick_info_detached) {
|
|
15454
|
-
scheduler2._detachDomEvent(scheduler2._els["dhx_cal_data"][0], "scroll", scheduler2._quick_info_onscroll_handler);
|
|
15455
|
-
scheduler2.event(scheduler2._els["dhx_cal_data"][0], "scroll", scheduler2._quick_info_onscroll_handler);
|
|
15456
|
-
}
|
|
15493
|
+
<div class="dhx_cal_qi_content"></div>`;
|
|
15494
|
+
html += '<div class="dhx_cal_qi_controls">';
|
|
15495
|
+
let buttons = scheduler2.config.icons_select;
|
|
15496
|
+
for (let i = 0; i < buttons.length; i++) {
|
|
15497
|
+
let ariaAttr2 = this._waiAria.quickInfoButtonAttrString(this.locale.labels[buttons[i]]);
|
|
15498
|
+
html += `<div ${ariaAttr2} class="dhx_qi_big_icon ${buttons[i]}" title="${scheduler2.locale.labels[buttons[i]]}">
|
|
15499
|
+
<div class='dhx_menu_icon ${buttons[i]}'></div><div>${scheduler2.locale.labels[buttons[i]]}</div></div>`;
|
|
15500
|
+
}
|
|
15501
|
+
html += "</div>";
|
|
15502
|
+
qi.innerHTML = html;
|
|
15503
|
+
scheduler2.event(qi, "click", function(ev) {
|
|
15504
|
+
scheduler2._qi_button_click(ev.target || ev.srcElement);
|
|
15505
|
+
});
|
|
15506
|
+
if (scheduler2.config.quick_info_detached) {
|
|
15507
|
+
scheduler2._detachDomEvent(scheduler2._els["dhx_cal_data"][0], "scroll", scheduler2._quick_info_onscroll_handler);
|
|
15508
|
+
scheduler2.event(scheduler2._els["dhx_cal_data"][0], "scroll", scheduler2._quick_info_onscroll_handler);
|
|
15457
15509
|
}
|
|
15458
15510
|
return this._quick_info_box;
|
|
15459
15511
|
};
|
|
@@ -18187,6 +18239,73 @@ function rdatesToString(param, rdates, tzid) {
|
|
|
18187
18239
|
return "".concat(header).concat(dateString);
|
|
18188
18240
|
}
|
|
18189
18241
|
function recurring(scheduler2) {
|
|
18242
|
+
scheduler2.ext.recurring = { confirm: function(context) {
|
|
18243
|
+
}, confirmDefault: function showRecurringConfirmModal(context) {
|
|
18244
|
+
const labels = context.labels || {};
|
|
18245
|
+
const options = Array.isArray(context.options) ? context.options : [];
|
|
18246
|
+
if (options.length === 0) {
|
|
18247
|
+
return Promise.resolve(null);
|
|
18248
|
+
}
|
|
18249
|
+
if (options.length === 1) {
|
|
18250
|
+
return Promise.resolve(options[0]);
|
|
18251
|
+
}
|
|
18252
|
+
const modalOptions = options.map((decision, index) => ({ value: decision, label: labelForDecision(decision, labels), checked: index === 0 }));
|
|
18253
|
+
return new Promise((resolve) => {
|
|
18254
|
+
scheduler2.modalbox({ text: `<div class="dhx_edit_recurrence_options">
|
|
18255
|
+
${modalOptions.map((option) => `<label class="dhx_styled_radio">
|
|
18256
|
+
<input type="radio" value="${option.value}" name="option" ${option.checked ? "checked" : ""}>
|
|
18257
|
+
${option.label}
|
|
18258
|
+
</label>`).join("")}
|
|
18259
|
+
</div>`, type: "recurring_mode", title: labels.title || scheduler2.locale.labels.confirm_recurring, width: "auto", position: "middle", buttons: [{ label: labels.ok || scheduler2.locale.labels.message_ok, value: "ok", css: "rec_ok" }, { label: labels.cancel || scheduler2.locale.labels.message_cancel, value: "cancel" }], callback: function onModalClose(value, event2) {
|
|
18260
|
+
if (value === "cancel") {
|
|
18261
|
+
resolve(null);
|
|
18262
|
+
return;
|
|
18263
|
+
}
|
|
18264
|
+
const box = event2.target.closest(".scheduler_modal_box");
|
|
18265
|
+
const checked = box && box.querySelector("input[type='radio']:checked");
|
|
18266
|
+
const selected = checked ? checked.value : null;
|
|
18267
|
+
if (!selected) {
|
|
18268
|
+
resolve(null);
|
|
18269
|
+
return;
|
|
18270
|
+
}
|
|
18271
|
+
resolve(selected);
|
|
18272
|
+
} });
|
|
18273
|
+
});
|
|
18274
|
+
}, _getDecision: async function _getDecision(context) {
|
|
18275
|
+
const confirmHandler = scheduler2.ext.recurring.confirm;
|
|
18276
|
+
let decision;
|
|
18277
|
+
if (typeof confirmHandler === "function") {
|
|
18278
|
+
decision = await confirmHandler(context);
|
|
18279
|
+
} else {
|
|
18280
|
+
decision = void 0;
|
|
18281
|
+
}
|
|
18282
|
+
if (decision === void 0) {
|
|
18283
|
+
decision = await scheduler2.ext.recurring.confirmDefault(context);
|
|
18284
|
+
}
|
|
18285
|
+
if (decision === null) {
|
|
18286
|
+
return null;
|
|
18287
|
+
}
|
|
18288
|
+
if (context.options && context.options.length > 0) {
|
|
18289
|
+
if (context.options.indexOf(decision) === -1) {
|
|
18290
|
+
console.warning(`[recurring extension] - the custom confirm handler returned a value ("${decision}") which is not in the allowed options list. The allowed options are: [${context.options.join(", ")}]. The operation will be cancelled.`);
|
|
18291
|
+
return null;
|
|
18292
|
+
}
|
|
18293
|
+
}
|
|
18294
|
+
return decision;
|
|
18295
|
+
} };
|
|
18296
|
+
scheduler2.ext.recurring.confirm = scheduler2.ext.recurring.confirmDefault;
|
|
18297
|
+
function labelForDecision(decision, labels) {
|
|
18298
|
+
if (decision === "occurrence") {
|
|
18299
|
+
return labels.occurrence || scheduler2.locale.labels.button_edit_occurrence;
|
|
18300
|
+
}
|
|
18301
|
+
if (decision === "following") {
|
|
18302
|
+
return labels.following || scheduler2.locale.labels.button_edit_occurrence_and_following;
|
|
18303
|
+
}
|
|
18304
|
+
if (decision === "series") {
|
|
18305
|
+
return labels.series || scheduler2.locale.labels.button_edit_series;
|
|
18306
|
+
}
|
|
18307
|
+
return decision;
|
|
18308
|
+
}
|
|
18190
18309
|
function clearMilliseconds(date) {
|
|
18191
18310
|
return new Date(date.getFullYear(), date.getMonth(), date.getDate(), date.getHours(), date.getMinutes(), date.getSeconds(), 0);
|
|
18192
18311
|
}
|
|
@@ -18226,10 +18345,14 @@ function recurring(scheduler2) {
|
|
|
18226
18345
|
if (ev.rrule.includes(";UNTIL=")) {
|
|
18227
18346
|
ev.rrule = ev.rrule.split(";UNTIL=")[0];
|
|
18228
18347
|
}
|
|
18229
|
-
let parsedRRule
|
|
18230
|
-
|
|
18231
|
-
|
|
18232
|
-
|
|
18348
|
+
let parsedRRule;
|
|
18349
|
+
if (ev.rrule.includes(";COUNT=")) {
|
|
18350
|
+
parsedRRule = rrulestr(`RRULE:${ev.rrule};UNTIL=${toIcalString(setUTCPartsToDate(ev._shorten_end_date))}`, { dtstart: ev.start_date });
|
|
18351
|
+
delete parsedRRule.origOptions.count;
|
|
18352
|
+
} else {
|
|
18353
|
+
parsedRRule = rrulestr(`RRULE:${ev.rrule};UNTIL=${toIcalString(setUTCPartsToDate(ev._end_date || ev.end_date))}`, { dtstart: ev.start_date });
|
|
18354
|
+
}
|
|
18355
|
+
ev.rrule = new RRule(parsedRRule.origOptions).toString().replace("RRULE:", "").split("\n")[1];
|
|
18233
18356
|
}
|
|
18234
18357
|
function updateFollowingRRULE(id, ev) {
|
|
18235
18358
|
if (!ev) {
|
|
@@ -18237,6 +18360,7 @@ function recurring(scheduler2) {
|
|
|
18237
18360
|
}
|
|
18238
18361
|
let rruleStringparts = ev.rrule.split(";");
|
|
18239
18362
|
let updatedRRULE = [];
|
|
18363
|
+
let interval;
|
|
18240
18364
|
for (let i = 0; i < rruleStringparts.length; i++) {
|
|
18241
18365
|
let splited = rruleStringparts[i].split("=");
|
|
18242
18366
|
let code = splited[0];
|
|
@@ -18253,6 +18377,17 @@ function recurring(scheduler2) {
|
|
|
18253
18377
|
ev._end_date = ev.end_date;
|
|
18254
18378
|
}
|
|
18255
18379
|
}
|
|
18380
|
+
if (code === "INTERVAL") {
|
|
18381
|
+
interval = Number(name);
|
|
18382
|
+
}
|
|
18383
|
+
if (code === "COUNT") {
|
|
18384
|
+
if (ev._shorten_end_date) {
|
|
18385
|
+
const start = scheduler2.date.date_part(new Date(ev._start_date));
|
|
18386
|
+
const end = scheduler2.date.date_part(new Date(ev._shorten_end_date));
|
|
18387
|
+
const days = Math.floor((end - start) / (1e3 * 60 * 60 * 24 * interval)) + 1;
|
|
18388
|
+
name = name - days;
|
|
18389
|
+
}
|
|
18390
|
+
}
|
|
18256
18391
|
updatedRRULE.push(code);
|
|
18257
18392
|
updatedRRULE.push("=");
|
|
18258
18393
|
updatedRRULE.push(name);
|
|
@@ -18392,8 +18527,10 @@ function recurring(scheduler2) {
|
|
|
18392
18527
|
for (let i in scheduler2._events) {
|
|
18393
18528
|
let tev = scheduler2._events[i];
|
|
18394
18529
|
if (tev.recurring_event_id == id || scheduler2._is_virtual_event(tev.id) && tev.id.split("#")[0] == id) {
|
|
18395
|
-
tev.
|
|
18396
|
-
|
|
18530
|
+
if (tev.start_date.valueOf() >= data.start_date.valueOf()) {
|
|
18531
|
+
tev.text = data.text;
|
|
18532
|
+
scheduler2.updateEvent(tev.id);
|
|
18533
|
+
}
|
|
18397
18534
|
}
|
|
18398
18535
|
}
|
|
18399
18536
|
}
|
|
@@ -18511,7 +18648,7 @@ function recurring(scheduler2) {
|
|
|
18511
18648
|
scheduler2.attachEvent("onRecurringEventSave", function(id, data, is_new_event) {
|
|
18512
18649
|
let ev = this.getEvent(id);
|
|
18513
18650
|
let tempEvent = scheduler2._lame_clone(ev);
|
|
18514
|
-
let
|
|
18651
|
+
let tempData = scheduler2._lame_clone(data);
|
|
18515
18652
|
if (ev && isSeries(ev)) {
|
|
18516
18653
|
if (!is_new_event && this._isFollowing(id)) {
|
|
18517
18654
|
if (ev._removeFollowing) {
|
|
@@ -18567,10 +18704,8 @@ function recurring(scheduler2) {
|
|
|
18567
18704
|
ev._shorten = true;
|
|
18568
18705
|
updateFollowingRRULEOnSave(ev);
|
|
18569
18706
|
scheduler2.callEvent("onEventChanged", [ev.id, ev]);
|
|
18570
|
-
let followingEv = { ...
|
|
18571
|
-
followingEv.
|
|
18572
|
-
followingEv.duration = data.duration;
|
|
18573
|
-
followingEv.rrule = tempDataRRULE;
|
|
18707
|
+
let followingEv = { ...tempData };
|
|
18708
|
+
followingEv._end_date = tempEvent._end_date;
|
|
18574
18709
|
followingEv._start_date = null;
|
|
18575
18710
|
followingEv.id = scheduler2.uid();
|
|
18576
18711
|
scheduler2.addEvent(followingEv.start_date, followingEv.end_date, followingEv.text, followingEv.id, followingEv);
|
|
@@ -18738,43 +18873,28 @@ function recurring(scheduler2) {
|
|
|
18738
18873
|
return this.showLightbox_rec(id);
|
|
18739
18874
|
}
|
|
18740
18875
|
if (formSetting === "ask") {
|
|
18741
|
-
|
|
18742
|
-
showModalbox([{ value: "Occurrence", label: locale2.labels.button_edit_occurrence, checked: true, callback: () => showRequiredLightbox(id, "Occurrence") }, { value: "Following", label: locale2.labels.button_edit_occurrence_and_following, callback: () => showRequiredLightbox(id, "Following") }, { value: "AllEvents", label: locale2.labels.button_edit_series, callback: () => showRequiredLightbox(id, "AllEvents") }]);
|
|
18876
|
+
showRecurringScopeConfirmForLightbox(id, pid);
|
|
18743
18877
|
}
|
|
18744
|
-
|
|
18745
|
-
|
|
18746
|
-
|
|
18747
|
-
|
|
18748
|
-
|
|
18749
|
-
|
|
18750
|
-
|
|
18751
|
-
const callbacks = options.reduce((result, o) => {
|
|
18752
|
-
result[o.value] = o.callback;
|
|
18753
|
-
return result;
|
|
18754
|
-
}, {});
|
|
18755
|
-
scheduler2.modalbox({ text: `<div class="dhx_edit_recurrence_options">
|
|
18756
|
-
${options.map((option) => `<label class="dhx_styled_radio">
|
|
18757
|
-
<input type="radio" value="${option.value}" name="option" ${option.checked ? "checked" : ""}>
|
|
18758
|
-
${option.label}
|
|
18759
|
-
</label>`).join("")}
|
|
18760
|
-
</div>`, type: "recurring_mode", title: locale.labels.confirm_recurring, width: "auto", position: "middle", buttons: [{ label: locale.labels.message_ok, value: "ok", css: "rec_ok" }, { label: locale.labels.message_cancel, value: "cancel" }], callback: function(value, e) {
|
|
18761
|
-
if (callback) {
|
|
18762
|
-
callback(value, e);
|
|
18763
|
-
}
|
|
18764
|
-
if (value === "cancel") {
|
|
18878
|
+
async function showRecurringScopeConfirmForLightbox(id2, pid2) {
|
|
18879
|
+
const locale2 = scheduler2.locale;
|
|
18880
|
+
const occurrence = scheduler2.getEvent(id2);
|
|
18881
|
+
const seriesEvent = scheduler2.getEvent(pid2);
|
|
18882
|
+
const context = { origin: "lightbox", occurrence, series: seriesEvent, labels: { title: locale2.labels.confirm_recurring, ok: locale2.labels.message_ok, cancel: locale2.labels.message_cancel, occurrence: locale2.labels.button_edit_occurrence, following: locale2.labels.button_edit_occurrence_and_following, series: locale2.labels.button_edit_series }, options: ["occurrence", "following", "series"] };
|
|
18883
|
+
const decision = await scheduler2.ext.recurring._getDecision(context);
|
|
18884
|
+
if (decision === null) {
|
|
18765
18885
|
return;
|
|
18766
18886
|
}
|
|
18767
|
-
|
|
18768
|
-
|
|
18769
|
-
let selectedOption;
|
|
18770
|
-
if (checked) {
|
|
18771
|
-
selectedOption = checked.value;
|
|
18887
|
+
if (decision === "occurrence") {
|
|
18888
|
+
return showRequiredLightbox(id2, "Occurrence");
|
|
18772
18889
|
}
|
|
18773
|
-
if (
|
|
18774
|
-
|
|
18890
|
+
if (decision === "following") {
|
|
18891
|
+
return showRequiredLightbox(id2, "Following");
|
|
18775
18892
|
}
|
|
18776
|
-
|
|
18777
|
-
|
|
18893
|
+
if (decision === "series") {
|
|
18894
|
+
return showRequiredLightbox(id2, "AllEvents");
|
|
18895
|
+
}
|
|
18896
|
+
}
|
|
18897
|
+
};
|
|
18778
18898
|
scheduler2._showRequiredModalBox = function(id, type) {
|
|
18779
18899
|
let buttons;
|
|
18780
18900
|
const locale = scheduler2.locale;
|
|
@@ -18896,17 +19016,30 @@ function recurring(scheduler2) {
|
|
|
18896
19016
|
}
|
|
18897
19017
|
}
|
|
18898
19018
|
};
|
|
18899
|
-
const btnAll = { value: "AllEvents", label: locale.labels.button_edit_series, callback: () => handleAllEvents(occurrence) };
|
|
18900
|
-
const btnFollowing = { value: "Following", label: locale.labels.button_edit_occurrence_and_following, callback: () => handleFollowing(occurrence) };
|
|
18901
|
-
const btnOccurrence = { value: "Occurrence", label: locale.labels.button_edit_occurrence, callback: () => handleOccurrence(occurrence), checked: true };
|
|
18902
19019
|
if (type === "ask") {
|
|
18903
|
-
buttons = [
|
|
19020
|
+
buttons = ["occurrence", "following", "series"];
|
|
18904
19021
|
} else {
|
|
18905
|
-
buttons = [
|
|
19022
|
+
buttons = ["occurrence", "following"];
|
|
18906
19023
|
}
|
|
18907
|
-
|
|
18908
|
-
|
|
19024
|
+
const context = { origin: "dnd", occurrence, series: event2, labels: { title: locale.labels.confirm_recurring, ok: locale.labels.message_ok, cancel: locale.labels.message_cancel, occurrence: locale.labels.button_edit_occurrence, following: locale.labels.button_edit_occurrence_and_following, series: locale.labels.button_edit_series }, options: buttons };
|
|
19025
|
+
Promise.resolve(scheduler2.ext.recurring._getDecision(context)).then((decision) => {
|
|
19026
|
+
if (!decision) {
|
|
18909
19027
|
removeTempDraggedEvent();
|
|
19028
|
+
return;
|
|
19029
|
+
}
|
|
19030
|
+
switch (decision) {
|
|
19031
|
+
case "occurrence":
|
|
19032
|
+
handleOccurrence(occurrence);
|
|
19033
|
+
break;
|
|
19034
|
+
case "following":
|
|
19035
|
+
handleFollowing(occurrence);
|
|
19036
|
+
break;
|
|
19037
|
+
case "series":
|
|
19038
|
+
handleAllEvents(occurrence);
|
|
19039
|
+
break;
|
|
19040
|
+
default:
|
|
19041
|
+
removeTempDraggedEvent();
|
|
19042
|
+
return;
|
|
18910
19043
|
}
|
|
18911
19044
|
});
|
|
18912
19045
|
};
|
|
@@ -19017,7 +19150,7 @@ function recurring(scheduler2) {
|
|
|
19017
19150
|
copy2.start_date = date;
|
|
19018
19151
|
copy2.id = ev.id + "#" + Math.ceil(date.valueOf());
|
|
19019
19152
|
copy2.end_date = new Date(date.valueOf() + eventDuration * 1e3);
|
|
19020
|
-
if (copy2.end_date.valueOf()
|
|
19153
|
+
if (copy2.end_date.valueOf() <= scheduler2._min_date.valueOf()) {
|
|
19021
19154
|
continue;
|
|
19022
19155
|
}
|
|
19023
19156
|
copy2.end_date = scheduler2._fix_daylight_saving_date(copy2.start_date, copy2.end_date, ev, date, copy2.end_date);
|
|
@@ -20958,73 +21091,103 @@ function units_restricted(scheduler2) {
|
|
|
20958
21091
|
notImplemented.alert("Units", scheduler2.assert);
|
|
20959
21092
|
}
|
|
20960
21093
|
function url(scheduler2) {
|
|
20961
|
-
|
|
20962
|
-
|
|
20963
|
-
|
|
20964
|
-
|
|
20965
|
-
|
|
20966
|
-
|
|
20967
|
-
|
|
21094
|
+
function parseHashParameters() {
|
|
21095
|
+
const parameters = {};
|
|
21096
|
+
const raw = (document.location.hash || "").replace("#", "");
|
|
21097
|
+
if (!raw) {
|
|
21098
|
+
return parameters;
|
|
21099
|
+
}
|
|
21100
|
+
const pairs = raw.split(",");
|
|
21101
|
+
for (let i = 0; i < pairs.length; i++) {
|
|
21102
|
+
const parts = pairs[i].split("=");
|
|
21103
|
+
if (parts.length === 2) {
|
|
21104
|
+
parameters[parts[0]] = parts[1];
|
|
21105
|
+
}
|
|
20968
21106
|
}
|
|
20969
|
-
return
|
|
21107
|
+
return parameters;
|
|
21108
|
+
}
|
|
21109
|
+
scheduler2._get_url_nav = function() {
|
|
21110
|
+
return parseHashParameters();
|
|
20970
21111
|
};
|
|
20971
|
-
scheduler2.
|
|
20972
|
-
|
|
20973
|
-
|
|
20974
|
-
|
|
20975
|
-
|
|
20976
|
-
|
|
20977
|
-
|
|
20978
|
-
|
|
20979
|
-
}
|
|
20980
|
-
|
|
20981
|
-
|
|
20982
|
-
|
|
20983
|
-
|
|
20984
|
-
if (
|
|
20985
|
-
|
|
20986
|
-
if (scheduler2.getEvent(p.event)) {
|
|
20987
|
-
setTimeout(function() {
|
|
20988
|
-
showEvent(p.event);
|
|
20989
|
-
});
|
|
20990
|
-
return false;
|
|
20991
|
-
} else {
|
|
20992
|
-
var handler = scheduler2.attachEvent("onXLE", function() {
|
|
20993
|
-
setTimeout(function() {
|
|
20994
|
-
showEvent(p.event);
|
|
20995
|
-
});
|
|
20996
|
-
scheduler2.detachEvent(handler);
|
|
20997
|
-
});
|
|
20998
|
-
}
|
|
20999
|
-
} catch (e) {
|
|
21000
|
-
}
|
|
21001
|
-
}
|
|
21002
|
-
if (p.date || p.mode) {
|
|
21003
|
-
try {
|
|
21004
|
-
this.setCurrentView(p.date ? s2d(p.date) : null, p.mode || null);
|
|
21005
|
-
} catch (e) {
|
|
21006
|
-
this.setCurrentView(p.date ? s2d(p.date) : null, m);
|
|
21007
|
-
}
|
|
21008
|
-
return false;
|
|
21112
|
+
const dateToString = scheduler2.date.date_to_str("%Y-%m-%d");
|
|
21113
|
+
const originalGetInitialState = scheduler2._getInitialState;
|
|
21114
|
+
scheduler2._getInitialState = function(provided) {
|
|
21115
|
+
const baseState = originalGetInitialState.call(this, provided);
|
|
21116
|
+
const url2 = scheduler2._get_url_nav ? scheduler2._get_url_nav() : null;
|
|
21117
|
+
if (!url2) {
|
|
21118
|
+
return baseState;
|
|
21119
|
+
}
|
|
21120
|
+
const nextState = { date: baseState.date, mode: baseState.mode };
|
|
21121
|
+
if (url2.date) {
|
|
21122
|
+
const stringToDate = scheduler2.date.str_to_date("%Y-%m-%d");
|
|
21123
|
+
try {
|
|
21124
|
+
const parsed = stringToDate(url2.date);
|
|
21125
|
+
if (!isNaN(+parsed)) {
|
|
21126
|
+
nextState.date = parsed;
|
|
21009
21127
|
}
|
|
21128
|
+
} catch (e) {
|
|
21010
21129
|
}
|
|
21011
|
-
|
|
21012
|
-
|
|
21013
|
-
|
|
21130
|
+
}
|
|
21131
|
+
if (url2.mode) {
|
|
21132
|
+
try {
|
|
21133
|
+
if (this.isViewExists(url2.mode)) {
|
|
21134
|
+
nextState.mode = url2.mode;
|
|
21135
|
+
}
|
|
21136
|
+
} catch (e) {
|
|
21014
21137
|
}
|
|
21015
|
-
|
|
21016
|
-
|
|
21017
|
-
|
|
21018
|
-
|
|
21019
|
-
|
|
21138
|
+
}
|
|
21139
|
+
return nextState;
|
|
21140
|
+
};
|
|
21141
|
+
function updateHashFromState(optionalSelectedEventId) {
|
|
21142
|
+
const currentDate = scheduler2._date || scheduler2.getState().date;
|
|
21143
|
+
const currentMode = scheduler2.getState().mode;
|
|
21144
|
+
const values = ["date=" + dateToString(currentDate), "mode=" + currentMode];
|
|
21145
|
+
if (optionalSelectedEventId) {
|
|
21146
|
+
values.push("event=" + optionalSelectedEventId);
|
|
21147
|
+
}
|
|
21148
|
+
document.location.hash = "#" + values.join(",");
|
|
21149
|
+
}
|
|
21150
|
+
function showEventWhenPossible(eventId) {
|
|
21151
|
+
if (!eventId) {
|
|
21152
|
+
return;
|
|
21153
|
+
}
|
|
21154
|
+
const tryShowNow = function() {
|
|
21020
21155
|
if (scheduler2.$destroyed) {
|
|
21021
|
-
return
|
|
21156
|
+
return;
|
|
21022
21157
|
}
|
|
21023
|
-
|
|
21024
|
-
|
|
21025
|
-
|
|
21158
|
+
if (scheduler2.getEvent(eventId)) {
|
|
21159
|
+
scheduler2.showEvent(eventId);
|
|
21160
|
+
return true;
|
|
21026
21161
|
}
|
|
21162
|
+
return false;
|
|
21163
|
+
};
|
|
21164
|
+
if (tryShowNow()) {
|
|
21165
|
+
return;
|
|
21027
21166
|
}
|
|
21167
|
+
const onLoadedId = scheduler2.attachEvent("onParse", function() {
|
|
21168
|
+
tryShowNow();
|
|
21169
|
+
scheduler2.detachEvent(onLoadedId);
|
|
21170
|
+
return true;
|
|
21171
|
+
});
|
|
21172
|
+
}
|
|
21173
|
+
let pendingSelectedEventId = null;
|
|
21174
|
+
scheduler2.attachEvent("onSchedulerReady", function() {
|
|
21175
|
+
const initialState = scheduler2._get_url_nav();
|
|
21176
|
+
if (initialState.event) {
|
|
21177
|
+
pendingSelectedEventId = initialState.event;
|
|
21178
|
+
showEventWhenPossible(initialState.event);
|
|
21179
|
+
}
|
|
21180
|
+
updateHashFromState(pendingSelectedEventId);
|
|
21181
|
+
return true;
|
|
21182
|
+
});
|
|
21183
|
+
scheduler2.attachEvent("onAfterEventDisplay", function() {
|
|
21184
|
+
pendingSelectedEventId = null;
|
|
21185
|
+
updateHashFromState(null);
|
|
21186
|
+
return true;
|
|
21187
|
+
});
|
|
21188
|
+
scheduler2.attachEvent("onViewChange", function() {
|
|
21189
|
+
updateHashFromState(pendingSelectedEventId);
|
|
21190
|
+
return true;
|
|
21028
21191
|
});
|
|
21029
21192
|
}
|
|
21030
21193
|
function week_agenda_restricted(scheduler2) {
|
|
@@ -21281,6 +21444,9 @@ function year_view(scheduler2) {
|
|
|
21281
21444
|
var locateEvent = scheduler2._locate_event;
|
|
21282
21445
|
scheduler2._locate_event = function(node) {
|
|
21283
21446
|
var id = locateEvent.apply(scheduler2, arguments);
|
|
21447
|
+
if (!isYearMode()) {
|
|
21448
|
+
return id;
|
|
21449
|
+
}
|
|
21284
21450
|
if (!id) {
|
|
21285
21451
|
var date = getCellDate(node);
|
|
21286
21452
|
if (!date)
|