akfatimeline 1.0.4 → 1.0.6
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/dist/Timeline.js +1097 -112
- package/dist/dist/components/Timeline/DatePickerComponent.js +17 -0
- package/dist/dist/components/Timeline/EventTooltip.js +1 -1
- package/dist/dist/components/Timeline/Indicator.js +0 -4
- package/dist/dist/components/Timeline/MasterHeader.js +36 -23
- package/dist/dist/components/Timeline/Timeline.css +90 -8
- package/dist/dist/components/Timeline/Timeline.js +79 -47
- package/dist/dist/components/Timeline/TimelineContent.js +154 -130
- package/dist/dist/hooks/useEventDragDrop.js +22 -16
- package/package.json +1 -1
- package/public/dist/Timeline.js +3277 -0
- package/public/dist/dist/components/Timeline/DatePickerComponent.js +17 -0
- package/public/dist/dist/components/Timeline/DragAndDropHandler.js +35 -0
- package/public/dist/dist/components/Timeline/EventTooltip.js +206 -0
- package/public/dist/dist/components/Timeline/Indicator.js +29 -0
- package/public/dist/dist/components/Timeline/MasterHeader.js +68 -0
- package/public/dist/dist/components/Timeline/Resources.js +53 -0
- package/public/dist/dist/components/Timeline/ResourcesHeader.js +14 -0
- package/public/dist/dist/components/Timeline/Timeline.css +616 -0
- package/public/dist/dist/components/Timeline/Timeline.js +304 -0
- package/public/dist/dist/components/Timeline/TimelineCell.js +8 -0
- package/public/dist/dist/components/Timeline/TimelineContent.js +447 -0
- package/public/dist/dist/components/Timeline/TimelineEvents.js +114 -0
- package/public/dist/dist/components/Timeline/TimelineHeader.js +43 -0
- package/public/dist/dist/components/Timeline/TimelineMonthContainer.js +29 -0
- package/public/dist/dist/components/Timeline/TimelineResources.js +16 -0
- package/public/dist/dist/hooks/useDragAndDrop.js +80 -0
- package/public/dist/dist/hooks/useEventDragDrop.js +126 -0
- package/public/dist/dist/hooks/useExtendEvent.js +28 -0
- package/public/dist/dist/utils/HorizontalVirtualScroll.js +0 -0
- package/public/dist/dist/utils/dateUtils.js +36 -0
- package/public/dist/dist/utils/filterTimelineData.js +21 -0
- package/public/dist/dist/utils/timelineUtils.js +40 -0
- package/src/App.js +3 -1
- package/src/components/Timeline/Indicator.js +0 -3
- package/src/components/Timeline/Timeline.js +16 -11
- package/src/components/Timeline/TimelineContent.js +0 -1
|
@@ -18,22 +18,35 @@ const TimelineContent = ({
|
|
|
18
18
|
resourceSettings,
|
|
19
19
|
setDropInfo,
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
|
|
22
22
|
eventsDragOn = true,
|
|
23
23
|
eventsExtendOn = true,
|
|
24
24
|
createNewEventOn = true,
|
|
25
|
-
|
|
25
|
+
|
|
26
26
|
onExtendInfo,
|
|
27
27
|
onCreateEventInfo,
|
|
28
28
|
onEventRightClick,
|
|
29
|
+
|
|
30
|
+
eventTooltipOn = true,
|
|
31
|
+
tooltipComponent: TooltipComponent,
|
|
32
|
+
tempEventStyle = {},
|
|
33
|
+
|
|
34
|
+
eventStyleResolver = () => ({}),
|
|
29
35
|
}) => {
|
|
30
36
|
// ------------------- HOOKS & STATE -------------------
|
|
31
37
|
const containerRef = useRef(null);
|
|
32
38
|
|
|
33
39
|
// Drag
|
|
34
40
|
const { isDragging, dragStart, dragEnd } = useDragAndDrop(events, setEvents);
|
|
35
|
-
const { handleDragStart, handleDragOver, handleDrop, handleDragEnd } =
|
|
36
|
-
|
|
41
|
+
const { handleDragStart, handleDragOver, handleDrop, handleDragEnd } = useEventDragDrop(
|
|
42
|
+
events,
|
|
43
|
+
setEvents,
|
|
44
|
+
setDropInfo // Doğrudan setDropInfo'yu geçiriyoruz
|
|
45
|
+
);
|
|
46
|
+
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
|
|
37
50
|
|
|
38
51
|
// Extend
|
|
39
52
|
const { extendEvent } = useExtendEvent(events, setEvents);
|
|
@@ -55,9 +68,14 @@ const TimelineContent = ({
|
|
|
55
68
|
// ------------------- Tooltip Logic -------------------
|
|
56
69
|
const handleEventClickInternal = (event, e) => {
|
|
57
70
|
e.stopPropagation();
|
|
71
|
+
// Eğer mod "extend" ise tooltip'i açma
|
|
72
|
+
if (mode === "extend") {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
75
|
+
|
|
58
76
|
// Harici callback
|
|
59
77
|
if (onEventClick) onEventClick(event, e);
|
|
60
|
-
|
|
78
|
+
|
|
61
79
|
// Tooltip göstermek
|
|
62
80
|
const eventElement = e.currentTarget;
|
|
63
81
|
if (eventElement) {
|
|
@@ -69,6 +87,7 @@ const TimelineContent = ({
|
|
|
69
87
|
setSelectedEvent(event);
|
|
70
88
|
}
|
|
71
89
|
};
|
|
90
|
+
|
|
72
91
|
|
|
73
92
|
const handleCloseTooltip = () => {
|
|
74
93
|
setSelectedEvent(null);
|
|
@@ -154,8 +173,11 @@ const TimelineContent = ({
|
|
|
154
173
|
return;
|
|
155
174
|
}
|
|
156
175
|
handleDragEnd();
|
|
157
|
-
|
|
176
|
+
|
|
177
|
+
|
|
158
178
|
};
|
|
179
|
+
|
|
180
|
+
|
|
159
181
|
|
|
160
182
|
// ------------------- Extend Logic -------------------
|
|
161
183
|
const handleMouseDownExtend = (mouseEvent, event) => {
|
|
@@ -180,7 +202,6 @@ const TimelineContent = ({
|
|
|
180
202
|
const newEndDate = new Date((originalEndDate ?? new Date()).getTime());
|
|
181
203
|
newEndDate.setDate(newEndDate.getDate() + daysToAdd);
|
|
182
204
|
|
|
183
|
-
console.log(">>> Extending ID:", extendingEvent.id, "=>", newEndDate);
|
|
184
205
|
|
|
185
206
|
setEvents((prev) =>
|
|
186
207
|
prev.map((evt) => (evt.id === extendingEvent.id ? { ...evt, endDate: newEndDate } : evt))
|
|
@@ -199,11 +220,16 @@ const TimelineContent = ({
|
|
|
199
220
|
});
|
|
200
221
|
}
|
|
201
222
|
}
|
|
202
|
-
|
|
223
|
+
|
|
224
|
+
// Tooltip açılmasını engellemek için modun null olmasını geciktiriyoruz
|
|
225
|
+
setTimeout(() => {
|
|
226
|
+
setMode(null);
|
|
227
|
+
}, 100); // 100ms gecikme
|
|
203
228
|
setExtendingEvent(null);
|
|
204
229
|
setOriginalEndDate(null);
|
|
205
230
|
setStartMouseX(null);
|
|
206
231
|
};
|
|
232
|
+
|
|
207
233
|
|
|
208
234
|
useEffect(() => {
|
|
209
235
|
if (mode === "extend") {
|
|
@@ -273,6 +299,11 @@ const TimelineContent = ({
|
|
|
273
299
|
};
|
|
274
300
|
};
|
|
275
301
|
|
|
302
|
+
|
|
303
|
+
|
|
304
|
+
|
|
305
|
+
|
|
306
|
+
|
|
276
307
|
// ------------------- RENDER -------------------
|
|
277
308
|
return (
|
|
278
309
|
<div
|
|
@@ -283,138 +314,131 @@ const TimelineContent = ({
|
|
|
283
314
|
<Indicator todayIndex={todayIndex} totalDays={totalDays} />
|
|
284
315
|
)}
|
|
285
316
|
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
|
|
317
|
+
{groupedResources.map((group, groupIndex) => (
|
|
318
|
+
<div key={groupIndex} className="timeline-group-container">
|
|
319
|
+
{/* Grup Başlığı */}
|
|
320
|
+
{resourceSettings.isGrouped && (
|
|
321
|
+
<div className="timeline-group-header-row">
|
|
322
|
+
{dates.map((dateObj, colIndex) => (
|
|
323
|
+
<div
|
|
324
|
+
key={`group-header-${groupIndex}-${colIndex}`}
|
|
325
|
+
className="timeline-group-header-cell"
|
|
326
|
+
></div>
|
|
327
|
+
))}
|
|
328
|
+
</div>
|
|
329
|
+
)}
|
|
330
|
+
|
|
331
|
+
{/* Kaynaklar */}
|
|
332
|
+
{!collapsedGroups[group.groupName] &&
|
|
333
|
+
group.resources.map((resource, rowIndex) => {
|
|
334
|
+
const resourceEvents = events.filter((ev) => ev.resourceId === resource.id);
|
|
335
|
+
|
|
336
|
+
return (
|
|
337
|
+
<div key={resource.id} className="timeline-resource-row">
|
|
338
|
+
{/* Her resource row'u */}
|
|
339
|
+
{resourceEvents.map((event) => {
|
|
340
|
+
const { isVisible, left, width, isPartialStart, isPartialEnd } =
|
|
341
|
+
calculatePosition(event, dates);
|
|
342
|
+
if (!isVisible) return null;
|
|
343
|
+
|
|
344
|
+
// Kullanıcıdan gelen stil
|
|
345
|
+
const eventStyle = eventStyleResolver ? eventStyleResolver(event) : {};
|
|
304
346
|
|
|
305
347
|
return (
|
|
306
|
-
<div
|
|
307
|
-
{
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
if (
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
borderTopLeftRadius: isPartialStart ? "0px" : "20px",
|
|
341
|
-
borderBottomLeftRadius: isPartialStart ? "0px" : "20px",
|
|
342
|
-
borderTopRightRadius: isPartialEnd ? "0px" : "20px",
|
|
343
|
-
borderBottomRightRadius: isPartialEnd ? "0px" : "20px",
|
|
344
|
-
cursor: mode === "extend" ? "col-resize" : "grab",
|
|
345
|
-
}}
|
|
346
|
-
>
|
|
347
|
-
{event.title}
|
|
348
|
-
{eventsExtendOn && (
|
|
349
|
-
<div
|
|
350
|
-
className="timeline-event-extend-handle"
|
|
351
|
-
onMouseDown={(mouseEvent) => {
|
|
352
|
-
mouseEvent.stopPropagation();
|
|
353
|
-
handleMouseDownExtend(mouseEvent, event);
|
|
354
|
-
}}
|
|
355
|
-
></div>
|
|
356
|
-
)}
|
|
357
|
-
</div>
|
|
358
|
-
);
|
|
359
|
-
})}
|
|
360
|
-
|
|
361
|
-
{/* Geçici (yeni) event */}
|
|
362
|
-
{tempEvent && tempEvent.resourceId === resource.id && (
|
|
348
|
+
<div
|
|
349
|
+
key={event.id}
|
|
350
|
+
className="timeline-event"
|
|
351
|
+
draggable={mode !== "extend" && eventsDragOn}
|
|
352
|
+
onDragStart={(e) => {
|
|
353
|
+
if (mode === "extend") {
|
|
354
|
+
e.preventDefault();
|
|
355
|
+
return;
|
|
356
|
+
}
|
|
357
|
+
handleDragStartSafe(e, event.id);
|
|
358
|
+
}}
|
|
359
|
+
onDragEnd={(e) => {
|
|
360
|
+
if (mode === "extend") {
|
|
361
|
+
e.preventDefault();
|
|
362
|
+
return;
|
|
363
|
+
}
|
|
364
|
+
handleDragEndSafe(e);
|
|
365
|
+
}}
|
|
366
|
+
onContextMenu={(reactEvent) => handleRightClickEvent(event, reactEvent)}
|
|
367
|
+
onClick={(ev) => handleEventClickInternal(event, ev)}
|
|
368
|
+
style={{
|
|
369
|
+
left,
|
|
370
|
+
width,
|
|
371
|
+
top: "5px",
|
|
372
|
+
borderTopLeftRadius: isPartialStart ? "0px" : "20px",
|
|
373
|
+
borderBottomLeftRadius: isPartialStart ? "0px" : "20px",
|
|
374
|
+
borderTopRightRadius: isPartialEnd ? "0px" : "20px",
|
|
375
|
+
borderBottomRightRadius: isPartialEnd ? "0px" : "20px",
|
|
376
|
+
cursor: mode === "extend" ? "col-resize" : "grab",
|
|
377
|
+
...eventStyle, // Kullanıcı tarafından tanımlanan stiller
|
|
378
|
+
}}
|
|
379
|
+
>
|
|
380
|
+
{event.title}
|
|
381
|
+
{eventsExtendOn && (
|
|
363
382
|
<div
|
|
364
|
-
className="timeline-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
383
|
+
className="timeline-event-extend-handle"
|
|
384
|
+
onMouseDown={(mouseEvent) => {
|
|
385
|
+
mouseEvent.stopPropagation();
|
|
386
|
+
handleMouseDownExtend(mouseEvent, event);
|
|
368
387
|
}}
|
|
369
|
-
>
|
|
370
|
-
{tempEvent.title}
|
|
371
|
-
</div>
|
|
372
|
-
)}
|
|
373
|
-
|
|
374
|
-
{/* Tarih Hücreleri */}
|
|
375
|
-
{dates.map((dateObj, colIndex) => (
|
|
376
|
-
<div
|
|
377
|
-
key={`cell-${groupIndex}-${rowIndex}-${colIndex}`}
|
|
378
|
-
className={`timeline-cell ${
|
|
379
|
-
isCellSelected(resource.id, dateObj) ? "selected" : ""
|
|
380
|
-
}`}
|
|
381
|
-
data-date={JSON.stringify(dateObj)}
|
|
382
|
-
data-resource-id={resource.id}
|
|
383
|
-
onMouseDown={() => handleCellClick(resource.id, dateObj)}
|
|
384
|
-
onDragOver={(e) => handleDragOver(e)}
|
|
385
|
-
onDrop={(e) =>
|
|
386
|
-
handleDrop(e, resource.id, parseDate(dateObj.fullDate))
|
|
387
|
-
}
|
|
388
388
|
></div>
|
|
389
|
-
)
|
|
389
|
+
)}
|
|
390
390
|
</div>
|
|
391
391
|
);
|
|
392
392
|
})}
|
|
393
|
-
|
|
394
|
-
|
|
393
|
+
|
|
394
|
+
{/* Geçici (yeni) event */}
|
|
395
|
+
{tempEvent && tempEvent.resourceId === resource.id && (
|
|
396
|
+
<div
|
|
397
|
+
className="timeline-temp-event"
|
|
398
|
+
style={{
|
|
399
|
+
...calculatePosition(tempEvent, dates),
|
|
400
|
+
...tempEventStyle, // Kullanıcının geçtiği stiller
|
|
401
|
+
}}
|
|
402
|
+
>
|
|
403
|
+
{tempEvent.title}
|
|
404
|
+
</div>
|
|
405
|
+
)}
|
|
406
|
+
|
|
407
|
+
{/* Tarih Hücreleri */}
|
|
408
|
+
{dates.map((dateObj, colIndex) => (
|
|
409
|
+
<div
|
|
410
|
+
key={`cell-${groupIndex}-${rowIndex}-${colIndex}`}
|
|
411
|
+
className={`timeline-cell ${
|
|
412
|
+
isCellSelected(resource.id, dateObj) ? "selected" : ""
|
|
413
|
+
}`}
|
|
414
|
+
data-date={JSON.stringify(dateObj)}
|
|
415
|
+
data-resource-id={resource.id}
|
|
416
|
+
onMouseDown={() => handleCellClick(resource.id, dateObj)}
|
|
417
|
+
onDragOver={(e) => handleDragOver(e)}
|
|
418
|
+
onDrop={(e) =>
|
|
419
|
+
handleDrop(e, resource.id, parseDate(dateObj.fullDate))
|
|
420
|
+
}
|
|
421
|
+
></div>
|
|
422
|
+
))}
|
|
423
|
+
</div>
|
|
424
|
+
);
|
|
425
|
+
})}
|
|
426
|
+
</div>
|
|
427
|
+
))}
|
|
428
|
+
|
|
395
429
|
|
|
396
430
|
{/* Tooltip vb. */}
|
|
397
|
-
{selectedEvent && (
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
padding: "5px",
|
|
409
|
-
borderRadius: "4px",
|
|
410
|
-
zIndex: 999,
|
|
411
|
-
}}
|
|
412
|
-
>
|
|
413
|
-
<button onClick={() => handleCloseTooltip()}>X</button>
|
|
414
|
-
{/* Content */}
|
|
415
|
-
{selectedEvent.title}
|
|
416
|
-
</div>
|
|
417
|
-
)}
|
|
431
|
+
{eventTooltipOn && selectedEvent && TooltipComponent && mode !== "extend" && (
|
|
432
|
+
<TooltipComponent
|
|
433
|
+
event={selectedEvent}
|
|
434
|
+
position={tooltipPosition}
|
|
435
|
+
onClose={handleCloseTooltip}
|
|
436
|
+
/>
|
|
437
|
+
)}
|
|
438
|
+
|
|
439
|
+
|
|
440
|
+
|
|
441
|
+
|
|
418
442
|
</div>
|
|
419
443
|
);
|
|
420
444
|
};
|
|
@@ -38,20 +38,34 @@ const useEventDragDrop = (events, setEvents, setDropInfo) => {
|
|
|
38
38
|
|
|
39
39
|
const handleDrop = (event, resourceId, targetDate) => {
|
|
40
40
|
event.preventDefault();
|
|
41
|
-
|
|
41
|
+
|
|
42
42
|
if (mode === "drag" && draggingEvent) {
|
|
43
43
|
const draggedEvent = events.find((evt) => evt.id === draggingEvent);
|
|
44
|
-
|
|
44
|
+
|
|
45
45
|
if (draggedEvent) {
|
|
46
46
|
const duration = draggedEvent.endDate - draggedEvent.startDate;
|
|
47
47
|
const cellWidth = event.target.offsetWidth || 30;
|
|
48
48
|
const offsetDays = Math.floor(dragOffset / cellWidth);
|
|
49
49
|
const newStartDate = new Date(targetDate.getTime() - offsetDays * 24 * 60 * 60 * 1000);
|
|
50
50
|
const newEndDate = new Date(newStartDate.getTime() + duration);
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
51
|
+
|
|
52
|
+
// Callback kontrolü ve loglama
|
|
53
|
+
if (setDropInfo) {
|
|
54
|
+
console.log("setDropInfo is being called with:", {
|
|
55
|
+
id: draggingEvent,
|
|
56
|
+
newResourceId: resourceId,
|
|
57
|
+
newStartDate,
|
|
58
|
+
newEndDate,
|
|
59
|
+
});
|
|
60
|
+
setDropInfo({
|
|
61
|
+
id: draggingEvent,
|
|
62
|
+
newResourceId: resourceId,
|
|
63
|
+
newStartDate,
|
|
64
|
+
newEndDate,
|
|
65
|
+
});
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
// Event güncellemesi
|
|
55
69
|
setEvents((prevEvents) =>
|
|
56
70
|
prevEvents.map((evt) =>
|
|
57
71
|
evt.id === draggingEvent
|
|
@@ -64,22 +78,14 @@ const useEventDragDrop = (events, setEvents, setDropInfo) => {
|
|
|
64
78
|
: evt
|
|
65
79
|
)
|
|
66
80
|
);
|
|
67
|
-
|
|
68
|
-
if (setDropInfo) {
|
|
69
|
-
setDropInfo({
|
|
70
|
-
id: draggingEvent,
|
|
71
|
-
newResourceId: resourceId,
|
|
72
|
-
newStartDate,
|
|
73
|
-
newEndDate,
|
|
74
|
-
});
|
|
75
|
-
}
|
|
76
81
|
}
|
|
77
82
|
}
|
|
78
|
-
|
|
83
|
+
|
|
79
84
|
setDraggingEvent(null);
|
|
80
85
|
setDragOffset(0);
|
|
81
86
|
setMode(null);
|
|
82
87
|
};
|
|
88
|
+
|
|
83
89
|
|
|
84
90
|
const handleExtend = (event, eventId, newEndDate) => {
|
|
85
91
|
if (mode !== "extend" || draggingEvent !== eventId) return;
|