makula-schedule 2.2.6 → 2.3.0

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.
@@ -62,9 +62,6 @@ var DnDContext = exports["default"] = /*#__PURE__*/_createClass(function DnDCont
62
62
  if (cellUnit !== _default.CellUnit.Hour) {
63
63
  endTime = localeDayjs(new Date(resourceEvents.headerItems[leftIndex].start)).hour(23).minute(59).second(59).format(_default.DATETIME_FORMAT);
64
64
  }
65
- if (component && component.clearShadowState) {
66
- component.clearShadowState();
67
- }
68
65
  return {
69
66
  slotId: resourceEvents.slotId,
70
67
  slotName: resourceEvents.slotName,
@@ -130,30 +127,43 @@ var DnDContext = exports["default"] = /*#__PURE__*/_createClass(function DnDCont
130
127
  movingEvent(schedulerData, slotId, slotName, newStart, newEnd, action, type, item);
131
128
  }
132
129
 
133
- // Compute and set drop shadow position
134
- if (config.snapToGrid && component && component.setShadowState) {
135
- var shadowStartDayjs = localeDayjs(newStart);
136
- var shadowEndDayjs = localeDayjs(newEnd);
137
- var shadowLeftIndex = -1;
138
- var shadowSpan = 0;
139
- resourceEvents.headerItems.forEach(function (header, idx) {
140
- var headerStart = new Date(header.start);
141
- var headerEnd = new Date(header.end);
142
- if (headerEnd > shadowStartDayjs.toDate() && headerStart < shadowEndDayjs.toDate()) {
143
- if (shadowLeftIndex === -1) shadowLeftIndex = idx;
144
- shadowSpan += 1;
130
+ // Store preview data for drop indicator on the dragged item
131
+ if (config.dropPreviewEnabled !== false) {
132
+ // Find the header index that matches the adjusted newStart
133
+ var newStartDayjs = localeDayjs(newStart);
134
+ var previewLeftIndex = -1;
135
+ for (var i = 0; i < resourceEvents.headerItems.length; i++) {
136
+ var hStart = localeDayjs(resourceEvents.headerItems[i].start);
137
+ var hEnd = localeDayjs(resourceEvents.headerItems[i].end);
138
+ if (newStartDayjs >= hStart && newStartDayjs < hEnd) {
139
+ previewLeftIndex = i;
140
+ break;
145
141
  }
146
- });
147
- if (shadowLeftIndex >= 0 && shadowSpan > 0) {
148
- var shadowLeft = shadowLeftIndex * cellWidth + (shadowLeftIndex > 0 ? 2 : 3);
149
- var shadowWidth = shadowSpan * cellWidth - (shadowLeftIndex > 0 ? 5 : 6) > 0 ? shadowSpan * cellWidth - (shadowLeftIndex > 0 ? 5 : 6) : 0;
150
- component.setShadowState({
151
- left: shadowLeft,
152
- width: shadowWidth,
153
- top: 1,
154
- bgColor: isEvent ? item.bgColor : config.defaultEventBgColor
155
- });
156
142
  }
143
+ // Fallback: if newStart is before all headers, use first cell
144
+ if (previewLeftIndex < 0) previewLeftIndex = 0;
145
+ var durationMs = localeDayjs(newEnd).diff(newStartDayjs, 'ms');
146
+ var cellDurationMs;
147
+ if (cellUnit === _default.CellUnit.Hour) {
148
+ cellDurationMs = config.minuteStep * 60 * 1000;
149
+ } else {
150
+ cellDurationMs = 24 * 60 * 60 * 1000;
151
+ }
152
+ var cellSpan = Math.max(1, Math.ceil(durationMs / cellDurationMs));
153
+ var bgColor = isEvent ? item.bgColor || config.defaultEventBgColor : config.defaultEventBgColor;
154
+ var title = isEvent ? schedulerData.behaviors.getEventTextFunc(schedulerData, item) : '';
155
+
156
+ // Store on dragged item so collect can read it reliably
157
+ item._dropPreview = {
158
+ slotId: resourceEvents.slotId,
159
+ leftIndex: previewLeftIndex,
160
+ cellSpan: cellSpan,
161
+ bgColor: bgColor,
162
+ title: title,
163
+ eventItemHeight: config.eventItemHeight,
164
+ newStart: newStart,
165
+ newEnd: newEnd
166
+ };
157
167
  }
158
168
  },
159
169
  canDrop: function canDrop(props, monitor) {
@@ -182,9 +192,21 @@ var DnDContext = exports["default"] = /*#__PURE__*/_createClass(function DnDCont
182
192
  return spec.canDrop(props, monitor);
183
193
  },
184
194
  collect: function collect(monitor) {
195
+ var isOver = monitor.isOver();
196
+ var canDrop = monitor.canDrop();
197
+ var dropPreview = null;
198
+ if (isOver && canDrop) {
199
+ // Reading getClientOffset subscribes collect to offset changes during drag
200
+ monitor.getClientOffset();
201
+ var item = monitor.getItem();
202
+ if (item && item._dropPreview && item._dropPreview.slotId === props.resourceEvents.slotId) {
203
+ dropPreview = item._dropPreview;
204
+ }
205
+ }
185
206
  return {
186
- isOver: monitor.isOver(),
187
- canDrop: monitor.canDrop()
207
+ isOver: isOver,
208
+ canDrop: canDrop,
209
+ dropPreview: dropPreview
188
210
  };
189
211
  }
190
212
  };
@@ -252,16 +252,6 @@ var ResourceEvents = /*#__PURE__*/function (_Component) {
252
252
  }
253
253
  }
254
254
  });
255
- _defineProperty(_this, "setShadowState", function (shadow) {
256
- _this.setState({
257
- shadowState: shadow
258
- });
259
- });
260
- _defineProperty(_this, "clearShadowState", function () {
261
- _this.setState({
262
- shadowState: null
263
- });
264
- });
265
255
  _defineProperty(_this, "eventContainerRef", function (element) {
266
256
  _this.eventContainer = element;
267
257
  // Also set the drop ref if it exists
@@ -273,8 +263,7 @@ var ResourceEvents = /*#__PURE__*/function (_Component) {
273
263
  _this.state = {
274
264
  isSelecting: false,
275
265
  left: 0,
276
- width: 0,
277
- shadowState: null
266
+ width: 0
278
267
  };
279
268
  _this.supportTouch = false; // 'ontouchstart' in window;
280
269
  return _this;
@@ -317,8 +306,7 @@ var ResourceEvents = /*#__PURE__*/function (_Component) {
317
306
  var _this$state2 = this.state,
318
307
  isSelecting = _this$state2.isSelecting,
319
308
  left = _this$state2.left,
320
- width = _this$state2.width,
321
- shadowState = _this$state2.shadowState;
309
+ width = _this$state2.width;
322
310
  var cellWidth = schedulerData.getContentCellWidth();
323
311
  var cellMaxEvents = schedulerData.getCellMaxEvents();
324
312
  var rowWidth = schedulerData.getContentTableWidth();
@@ -441,23 +429,65 @@ var ResourceEvents = /*#__PURE__*/function (_Component) {
441
429
  }
442
430
  }
443
431
  });
444
- var dropShadow = shadowState && config.snapToGrid ? /*#__PURE__*/_react["default"].createElement("div", {
445
- className: "event-drop-shadow",
446
- style: {
447
- left: shadowState.left,
448
- width: shadowState.width,
449
- top: shadowState.top,
450
- height: config.eventItemHeight,
451
- backgroundColor: shadowState.bgColor || config.defaultEventBgColor
432
+ var dropPreview = this.props.dropPreview;
433
+ var dropPreviewElement = null;
434
+ if (dropPreview && config.dropPreviewEnabled !== false) {
435
+ var idx = dropPreview.leftIndex;
436
+ var previewLeft = idx * cellWidth + (idx > 0 ? 2 : 3);
437
+ var previewWidth = dropPreview.cellSpan * cellWidth - (idx > 0 ? 5 : 6);
438
+ if (cellUnit === _default2.CellUnit.Day) {
439
+ var previewStart = localeDayjs(dropPreview.newStart);
440
+ var previewEnd = localeDayjs(dropPreview.newEnd);
441
+ var dayStart = localeDayjs(resourceEvents.headerItems[idx].start).startOf('day');
442
+ var dayDurationMinutes = 1440;
443
+ var baseCellWidth = cellWidth - (idx > 0 ? 5 : 6);
444
+ if (dropPreview.cellSpan === 1) {
445
+ var startOffsetMinutes = previewStart.diff(dayStart, 'minute');
446
+ var eventDurationMinutes = previewEnd.diff(previewStart, 'minute');
447
+ var startPercentage = startOffsetMinutes / dayDurationMinutes;
448
+ var durationPercentage = eventDurationMinutes / dayDurationMinutes;
449
+ previewLeft = idx * cellWidth + (idx > 0 ? 2 : 3) + baseCellWidth * startPercentage;
450
+ previewWidth = Math.max(1, baseCellWidth * durationPercentage);
451
+ } else {
452
+ var eventStartDayStart = previewStart.startOf('day');
453
+ var eventEndDayEnd = previewEnd.endOf('day');
454
+ var totalSpanMinutes = eventEndDayEnd.diff(eventStartDayStart, 'minute');
455
+ var _startOffsetMinutes = previewStart.diff(eventStartDayStart, 'minute');
456
+ var _eventDurationMinutes2 = previewEnd.diff(previewStart, 'minute');
457
+ var _startPercentage2 = _startOffsetMinutes / dayDurationMinutes;
458
+ var _durationPercentage2 = totalSpanMinutes > 0 ? _eventDurationMinutes2 / totalSpanMinutes : 1;
459
+ var totalWidth = dropPreview.cellSpan * cellWidth - (idx > 0 ? 5 : 6);
460
+ previewLeft = idx * cellWidth + (idx > 0 ? 2 : 3) + cellWidth * _startPercentage2;
461
+ previewWidth = Math.max(1, totalWidth * _durationPercentage2);
462
+ }
452
463
  }
453
- }) : null;
464
+ dropPreviewElement = /*#__PURE__*/_react["default"].createElement("a", {
465
+ className: "timeline-event drop-preview",
466
+ style: {
467
+ left: previewLeft,
468
+ width: Math.max(0, previewWidth),
469
+ top: 1
470
+ }
471
+ }, /*#__PURE__*/_react["default"].createElement("div", {
472
+ className: "round-all event-item",
473
+ style: {
474
+ height: dropPreview.eventItemHeight,
475
+ backgroundColor: dropPreview.bgColor
476
+ }
477
+ }, /*#__PURE__*/_react["default"].createElement("span", {
478
+ style: {
479
+ marginLeft: '10px',
480
+ lineHeight: "".concat(dropPreview.eventItemHeight, "px")
481
+ }
482
+ }, dropPreview.title)));
483
+ }
454
484
  var eventContainer = /*#__PURE__*/_react["default"].createElement("div", {
455
485
  ref: this.eventContainerRef,
456
486
  className: "event-container",
457
487
  style: {
458
488
  height: resourceEvents.rowHeight
459
489
  }
460
- }, selectedArea, dropShadow, eventList);
490
+ }, selectedArea, dropPreviewElement, eventList);
461
491
  return /*#__PURE__*/_react["default"].createElement("tr", null, /*#__PURE__*/_react["default"].createElement("td", {
462
492
  style: {
463
493
  width: rowWidth
@@ -489,7 +519,7 @@ var ResourceEventsWithDnD = function ResourceEventsWithDnD(props) {
489
519
  var schedulerData = props.schedulerData,
490
520
  dndContext = props.dndContext;
491
521
  var config = schedulerData.config;
492
- var componentRef = (0, _react.useRef)(null);
522
+ var componentRef = _react["default"].useRef(null);
493
523
 
494
524
  // Always call useDrop unconditionally (Rules of Hooks)
495
525
  // Disable functionality when drag and drop is not enabled
@@ -501,7 +531,8 @@ var ResourceEventsWithDnD = function ResourceEventsWithDnD(props) {
501
531
  collect: function collect() {
502
532
  return {
503
533
  isOver: false,
504
- canDrop: false
534
+ canDrop: false,
535
+ dropPreview: null
505
536
  };
506
537
  }
507
538
  };
@@ -519,9 +550,21 @@ var ResourceEventsWithDnD = function ResourceEventsWithDnD(props) {
519
550
  return spec.canDrop(props, monitor);
520
551
  },
521
552
  collect: function collect(monitor) {
553
+ var over = monitor.isOver();
554
+ var drop = monitor.canDrop();
555
+ var preview = null;
556
+ if (over && drop) {
557
+ // Reading getClientOffset subscribes collect to offset changes during drag
558
+ monitor.getClientOffset();
559
+ var item = monitor.getItem();
560
+ if (item && item._dropPreview && item._dropPreview.slotId === props.resourceEvents.slotId) {
561
+ preview = item._dropPreview;
562
+ }
563
+ }
522
564
  return {
523
- isOver: monitor.isOver(),
524
- canDrop: monitor.canDrop()
565
+ isOver: over,
566
+ canDrop: drop,
567
+ dropPreview: preview
525
568
  };
526
569
  }
527
570
  };
@@ -530,18 +573,15 @@ var ResourceEventsWithDnD = function ResourceEventsWithDnD(props) {
530
573
  _useDrop2$ = _useDrop2[0],
531
574
  isOver = _useDrop2$.isOver,
532
575
  canDrop = _useDrop2$.canDrop,
576
+ dropPreview = _useDrop2$.dropPreview,
533
577
  dropRef = _useDrop2[1];
534
- (0, _react.useEffect)(function () {
535
- if (!isOver && componentRef.current) {
536
- componentRef.current.clearShadowState();
537
- }
538
- }, [isOver]);
539
578
  return /*#__PURE__*/_react["default"].createElement(ResourceEvents, _extends({
540
579
  ref: componentRef
541
580
  }, props, {
542
581
  dropRef: dropRef,
543
582
  isOver: isOver,
544
- canDrop: canDrop
583
+ canDrop: canDrop,
584
+ dropPreview: dropPreview
545
585
  }));
546
586
  };
547
587
  ResourceEventsWithDnD.displayName = 'ResourceEventsWithDnD';
@@ -80,8 +80,7 @@ var _default = exports["default"] = {
80
80
  relativeMove: true,
81
81
  defaultExpanded: true,
82
82
  dragAndDropEnabled: true,
83
- overflowArrowsEnabled: true,
84
- snapToGrid: false,
83
+ dropPreviewEnabled: true,
85
84
  schedulerHeaderEventsFuncsTimeoutMs: 100,
86
85
  resourceName: 'Resource Name',
87
86
  taskName: 'Task Name',
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "makula-schedule",
3
- "version": "2.2.6",
3
+ "version": "2.3.0",
4
4
  "description": "React Big Schedule is a powerful and intuitive scheduler and resource planning solution built with React. Seamlessly integrate this modern browser-compatible component into your applications to effectively manage time, appointments, and resources. With drag-and-drop functionality, interactive UI, and granular views, react-big-schedule empowers users to effortlessly schedule and allocate resources with precision. Enhance productivity and streamline your workflow with this React-based solution, designed to optimize time management and simplify calendar-based operations. Perfect for applications requiring advanced scheduling capabilities, react-big-schedule offers a seamless and intuitive experience for managing appointments, resource allocation, and time slots. Unlock the potential of your React projects with react-big-schedule and revolutionize the way you handle scheduling and resource planning. It is the updated version of react-big-scheduler",
5
5
  "keywords": [
6
6
  "react-big-schedule",