akfatimeline 1.0.6 → 1.2.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.
- package/CHANGELOG.md +98 -35
- package/dist/Timeline.js +4309 -1677
- package/dist/components/Timeline/AutocompleteSelect.js +150 -0
- package/dist/components/Timeline/ContextMenu.js +149 -0
- package/dist/components/Timeline/DailyView.js +255 -0
- package/dist/components/Timeline/DatePickerComponent.js +13 -0
- package/{public/dist/dist → dist}/components/Timeline/DragAndDropHandler.js +34 -34
- package/dist/components/Timeline/EventBadge.js +26 -0
- package/dist/components/Timeline/EventDetailModal.js +138 -0
- package/dist/components/Timeline/EventIcon.js +47 -0
- package/dist/{dist/components → components}/Timeline/EventTooltip.js +206 -206
- package/dist/components/Timeline/FilterPanel.js +179 -0
- package/dist/{dist/components → components}/Timeline/Indicator.js +26 -26
- package/dist/components/Timeline/LoadingSpinner.js +48 -0
- package/dist/{dist/components → components}/Timeline/MasterHeader.js +104 -68
- package/{public/dist/dist → dist}/components/Timeline/Resources.js +53 -53
- package/dist/{dist/components → components}/Timeline/ResourcesHeader.js +14 -14
- package/dist/components/Timeline/Timeline.css +2491 -0
- package/dist/components/Timeline/Timeline.js +607 -0
- package/dist/{dist/components → components}/Timeline/TimelineCell.js +8 -8
- package/dist/components/Timeline/TimelineContent.js +838 -0
- package/{public/dist/dist → dist}/components/Timeline/TimelineEvents.js +114 -114
- package/dist/components/Timeline/TimelineHeader.js +54 -0
- package/{public/dist/dist → dist}/components/Timeline/TimelineMonthContainer.js +29 -29
- package/{public/dist/dist → dist}/components/Timeline/TimelineResources.js +16 -16
- package/{public/dist/dist → dist}/hooks/useDragAndDrop.js +80 -80
- package/dist/{dist/hooks → hooks}/useEventDragDrop.js +126 -126
- package/dist/hooks/useEventManagement.js +173 -0
- package/dist/hooks/useEventSelection.js +82 -0
- package/{public/dist/dist → dist}/hooks/useExtendEvent.js +28 -28
- package/dist/hooks/useKeyboardShortcuts.js +158 -0
- package/dist/hooks/useTouchGestures.js +90 -0
- package/dist/utils/conflictUtils.js +105 -0
- package/dist/{dist/utils → utils}/dateUtils.js +36 -36
- package/dist/{dist/utils → utils}/filterTimelineData.js +20 -20
- package/dist/utils/filterUtils.js +106 -0
- package/dist/utils/timeUtils.js +179 -0
- package/dist/{dist/utils → utils}/timelineUtils.js +39 -39
- package/dist/utils/viewModeUtils.js +54 -0
- package/package.json +89 -19
- package/src/App.js +300 -19
- package/src/components/Timeline/AutocompleteSelect.js +150 -0
- package/src/components/Timeline/ContextMenu.js +149 -0
- package/src/components/Timeline/DailyView.js +255 -0
- package/src/components/Timeline/DatePickerComponent.js +13 -17
- package/src/components/Timeline/DragAndDropHandler.js +34 -34
- package/src/components/Timeline/EventBadge.js +26 -0
- package/src/components/Timeline/EventDetailModal.js +138 -0
- package/src/components/Timeline/EventIcon.js +47 -0
- package/src/components/Timeline/EventTooltip.js +206 -206
- package/src/components/Timeline/FilterPanel.js +179 -0
- package/src/components/Timeline/Indicator.js +26 -26
- package/src/components/Timeline/LoadingSpinner.js +48 -0
- package/src/components/Timeline/MasterHeader.js +104 -68
- package/src/components/Timeline/Resources.js +53 -53
- package/src/components/Timeline/ResourcesHeader.js +14 -14
- package/src/components/Timeline/Timeline.css +2491 -616
- package/src/components/Timeline/Timeline.js +607 -309
- package/src/components/Timeline/TimelineCell.js +8 -8
- package/src/components/Timeline/TimelineContent.js +838 -446
- package/src/components/Timeline/TimelineEvents.js +114 -114
- package/src/components/Timeline/TimelineHeader.js +54 -43
- package/src/components/Timeline/TimelineMonthContainer.js +29 -29
- package/src/components/Timeline/TimelineResources.js +16 -16
- package/src/demo.css +4 -0
- package/src/hooks/useDragAndDrop.js +80 -80
- package/src/hooks/useEventDragDrop.js +126 -126
- package/src/hooks/useEventManagement.js +173 -0
- package/src/hooks/useEventSelection.js +82 -0
- package/src/hooks/useExtendEvent.js +28 -28
- package/src/hooks/useKeyboardShortcuts.js +158 -0
- package/src/hooks/useTouchGestures.js +90 -0
- package/src/index.js +1 -7
- package/src/library.js +26 -0
- package/src/utils/conflictUtils.js +105 -0
- package/src/utils/dateUtils.js +36 -36
- package/src/utils/filterTimelineData.js +20 -20
- package/src/utils/filterUtils.js +106 -0
- package/src/utils/timeUtils.js +179 -0
- package/src/utils/timelineUtils.js +39 -39
- package/src/utils/viewModeUtils.js +54 -0
- package/.babelrc +0 -6
- package/babel.config.json +0 -4
- package/dist/dist/components/Timeline/DatePickerComponent.js +0 -17
- package/dist/dist/components/Timeline/DragAndDropHandler.js +0 -35
- package/dist/dist/components/Timeline/Resources.js +0 -53
- package/dist/dist/components/Timeline/Timeline.css +0 -616
- package/dist/dist/components/Timeline/Timeline.js +0 -309
- package/dist/dist/components/Timeline/TimelineContent.js +0 -446
- package/dist/dist/components/Timeline/TimelineEvents.js +0 -114
- package/dist/dist/components/Timeline/TimelineHeader.js +0 -43
- package/dist/dist/components/Timeline/TimelineMonthContainer.js +0 -29
- package/dist/dist/components/Timeline/TimelineResources.js +0 -16
- package/dist/dist/hooks/useDragAndDrop.js +0 -80
- package/dist/dist/hooks/useExtendEvent.js +0 -28
- package/public/dist/Timeline.js +0 -3277
- package/public/dist/dist/components/Timeline/DatePickerComponent.js +0 -17
- package/public/dist/dist/components/Timeline/EventTooltip.js +0 -206
- package/public/dist/dist/components/Timeline/Indicator.js +0 -29
- package/public/dist/dist/components/Timeline/MasterHeader.js +0 -68
- package/public/dist/dist/components/Timeline/ResourcesHeader.js +0 -14
- package/public/dist/dist/components/Timeline/Timeline.css +0 -616
- package/public/dist/dist/components/Timeline/Timeline.js +0 -304
- package/public/dist/dist/components/Timeline/TimelineCell.js +0 -8
- package/public/dist/dist/components/Timeline/TimelineContent.js +0 -447
- package/public/dist/dist/components/Timeline/TimelineHeader.js +0 -43
- package/public/dist/dist/hooks/useEventDragDrop.js +0 -126
- package/public/dist/dist/utils/HorizontalVirtualScroll.js +0 -0
- package/public/dist/dist/utils/dateUtils.js +0 -36
- package/public/dist/dist/utils/filterTimelineData.js +0 -21
- package/public/dist/dist/utils/timelineUtils.js +0 -40
- package/public/favicon.ico +0 -0
- package/public/index kutuphane /304/261c/304/261n.html" +0 -43
- package/public/index tasarim icin.html +0 -20
- package/public/index.html +0 -43
- package/public/logo192.png +0 -0
- package/public/logo512.png +0 -0
- package/public/manifest.json +0 -25
- package/public/robots.txt +0 -3
- package/src/App.css +0 -38
- package/src/App.test.js +0 -8
- package/src/dist/Timeline.js +0 -277
- package/src/index.css +0 -13
- package/src/logo.svg +0 -1
- package/src/reportWebVitals.js +0 -13
- package/src/setupTests.js +0 -5
- package/webpack.config.js +0 -49
- /package/dist/{dist/utils → utils}/HorizontalVirtualScroll.js +0 -0
|
@@ -1,447 +0,0 @@
|
|
|
1
|
-
import React, { useState, useRef, useEffect } from "react";
|
|
2
|
-
import { parseDate } from "../../utils/dateUtils";
|
|
3
|
-
import useDragAndDrop from "../../hooks/useDragAndDrop";
|
|
4
|
-
import useEventDragDrop from "../../hooks/useEventDragDrop";
|
|
5
|
-
import Indicator from "./Indicator";
|
|
6
|
-
import useExtendEvent from "../../hooks/useExtendEvent";
|
|
7
|
-
// import "./Timeline.css"; // varsayalım "Timeline.css" globalde import ediliyor
|
|
8
|
-
|
|
9
|
-
const TimelineContent = ({
|
|
10
|
-
groupedResources,
|
|
11
|
-
dates,
|
|
12
|
-
collapsedGroups,
|
|
13
|
-
events,
|
|
14
|
-
setEvents,
|
|
15
|
-
onEventClick,
|
|
16
|
-
todayIndex,
|
|
17
|
-
indicatorOn,
|
|
18
|
-
resourceSettings,
|
|
19
|
-
setDropInfo,
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
eventsDragOn = true,
|
|
23
|
-
eventsExtendOn = true,
|
|
24
|
-
createNewEventOn = true,
|
|
25
|
-
|
|
26
|
-
onExtendInfo,
|
|
27
|
-
onCreateEventInfo,
|
|
28
|
-
onEventRightClick,
|
|
29
|
-
|
|
30
|
-
eventTooltipOn = true,
|
|
31
|
-
tooltipComponent: TooltipComponent,
|
|
32
|
-
tempEventStyle = {},
|
|
33
|
-
|
|
34
|
-
eventStyleResolver = () => ({}),
|
|
35
|
-
}) => {
|
|
36
|
-
// ------------------- HOOKS & STATE -------------------
|
|
37
|
-
const containerRef = useRef(null);
|
|
38
|
-
|
|
39
|
-
// Drag
|
|
40
|
-
const { isDragging, dragStart, dragEnd } = useDragAndDrop(events, setEvents);
|
|
41
|
-
const { handleDragStart, handleDragOver, handleDrop, handleDragEnd } = useEventDragDrop(
|
|
42
|
-
events,
|
|
43
|
-
setEvents,
|
|
44
|
-
setDropInfo // Doğrudan setDropInfo'yu geçiriyoruz
|
|
45
|
-
);
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
// Extend
|
|
52
|
-
const { extendEvent } = useExtendEvent(events, setEvents);
|
|
53
|
-
const [mode, setMode] = useState(null); // null | "extend"
|
|
54
|
-
const [extendingEvent, setExtendingEvent] = useState(null);
|
|
55
|
-
const [originalEndDate, setOriginalEndDate] = useState(null);
|
|
56
|
-
const [startMouseX, setStartMouseX] = useState(null);
|
|
57
|
-
|
|
58
|
-
// Create new event
|
|
59
|
-
const [isCreating, setIsCreating] = useState(false);
|
|
60
|
-
const [tempEvent, setTempEvent] = useState(null);
|
|
61
|
-
|
|
62
|
-
// Tooltip
|
|
63
|
-
const [selectedEvent, setSelectedEvent] = useState(null);
|
|
64
|
-
const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });
|
|
65
|
-
|
|
66
|
-
const totalDays = dates.length;
|
|
67
|
-
|
|
68
|
-
// ------------------- Tooltip Logic -------------------
|
|
69
|
-
const handleEventClickInternal = (event, e) => {
|
|
70
|
-
e.stopPropagation();
|
|
71
|
-
// Eğer mod "extend" ise tooltip'i açma
|
|
72
|
-
if (mode === "extend") {
|
|
73
|
-
return;
|
|
74
|
-
}
|
|
75
|
-
|
|
76
|
-
// Harici callback
|
|
77
|
-
if (onEventClick) onEventClick(event, e);
|
|
78
|
-
|
|
79
|
-
// Tooltip göstermek
|
|
80
|
-
const eventElement = e.currentTarget;
|
|
81
|
-
if (eventElement) {
|
|
82
|
-
const rect = eventElement.getBoundingClientRect();
|
|
83
|
-
setTooltipPosition({
|
|
84
|
-
top: rect.top + window.scrollY,
|
|
85
|
-
left: rect.left + rect.width / 2 + window.scrollX,
|
|
86
|
-
});
|
|
87
|
-
setSelectedEvent(event);
|
|
88
|
-
}
|
|
89
|
-
};
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
const handleCloseTooltip = () => {
|
|
93
|
-
setSelectedEvent(null);
|
|
94
|
-
};
|
|
95
|
-
|
|
96
|
-
// ------------------- Create New Event -------------------
|
|
97
|
-
const handleCellClick = (resourceId, date) => {
|
|
98
|
-
if (!createNewEventOn) return; // create devrede değilse
|
|
99
|
-
|
|
100
|
-
const startDate = parseDate(date.fullDate);
|
|
101
|
-
const newEvent = {
|
|
102
|
-
id: Date.now(),
|
|
103
|
-
title: "1 Gece",
|
|
104
|
-
startDate,
|
|
105
|
-
endDate: new Date(startDate.getTime() + 24 * 60 * 60 * 1000),
|
|
106
|
-
resourceId,
|
|
107
|
-
// color => var(--timeline-new-event-background-color) => => Sonra inline style yerine className
|
|
108
|
-
color: "", // Bunu .css’te "var(--timeline-new-event-background-color)" atayabilirsin
|
|
109
|
-
};
|
|
110
|
-
setTempEvent(newEvent);
|
|
111
|
-
setIsCreating(true);
|
|
112
|
-
};
|
|
113
|
-
|
|
114
|
-
useEffect(() => {
|
|
115
|
-
if (!createNewEventOn) return;
|
|
116
|
-
if (!isCreating) return;
|
|
117
|
-
if (mode === "extend") {
|
|
118
|
-
console.log(">>> 'extend' mode, skip new event creation");
|
|
119
|
-
return;
|
|
120
|
-
}
|
|
121
|
-
|
|
122
|
-
const handleMouseMove = (e) => {
|
|
123
|
-
if (!isCreating || !tempEvent) return;
|
|
124
|
-
const cell = document.elementFromPoint(e.clientX, e.clientY);
|
|
125
|
-
const cellW = cell?.offsetWidth || 30;
|
|
126
|
-
|
|
127
|
-
const startX = tempEvent.startX || e.clientX;
|
|
128
|
-
const deltaX = e.clientX - startX;
|
|
129
|
-
const daysToAdd = Math.max(1, Math.floor(deltaX / cellW));
|
|
130
|
-
|
|
131
|
-
const newEndDate = new Date(tempEvent.startDate.getTime());
|
|
132
|
-
newEndDate.setDate(newEndDate.getDate() + daysToAdd);
|
|
133
|
-
|
|
134
|
-
setTempEvent({
|
|
135
|
-
...tempEvent,
|
|
136
|
-
endDate: newEndDate,
|
|
137
|
-
startX: startX,
|
|
138
|
-
title: `${daysToAdd} Gece`,
|
|
139
|
-
});
|
|
140
|
-
};
|
|
141
|
-
|
|
142
|
-
const handleMouseUp = () => {
|
|
143
|
-
if (isCreating && tempEvent) {
|
|
144
|
-
setEvents([...events, tempEvent]);
|
|
145
|
-
if (onCreateEventInfo) {
|
|
146
|
-
onCreateEventInfo(tempEvent);
|
|
147
|
-
}
|
|
148
|
-
}
|
|
149
|
-
setTempEvent(null);
|
|
150
|
-
setIsCreating(false);
|
|
151
|
-
};
|
|
152
|
-
|
|
153
|
-
window.addEventListener("mousemove", handleMouseMove);
|
|
154
|
-
window.addEventListener("mouseup", handleMouseUp);
|
|
155
|
-
|
|
156
|
-
return () => {
|
|
157
|
-
window.removeEventListener("mousemove", handleMouseMove);
|
|
158
|
-
window.removeEventListener("mouseup", handleMouseUp);
|
|
159
|
-
};
|
|
160
|
-
}, [createNewEventOn, isCreating, mode, tempEvent, events, onCreateEventInfo, setEvents]);
|
|
161
|
-
|
|
162
|
-
// ------------------- Drag Logic -------------------
|
|
163
|
-
const handleDragStartSafe = (e, eventId) => {
|
|
164
|
-
if (!eventsDragOn) {
|
|
165
|
-
e.preventDefault();
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
handleDragStart(e, eventId);
|
|
169
|
-
};
|
|
170
|
-
const handleDragEndSafe = (e) => {
|
|
171
|
-
if (!eventsDragOn) {
|
|
172
|
-
e.preventDefault();
|
|
173
|
-
return;
|
|
174
|
-
}
|
|
175
|
-
handleDragEnd();
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
};
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
// ------------------- Extend Logic -------------------
|
|
183
|
-
const handleMouseDownExtend = (mouseEvent, event) => {
|
|
184
|
-
if (!eventsExtendOn) return;
|
|
185
|
-
mouseEvent.stopPropagation();
|
|
186
|
-
console.log(">>> Extend start ID:", event.id);
|
|
187
|
-
setMode("extend");
|
|
188
|
-
setExtendingEvent(event);
|
|
189
|
-
setOriginalEndDate(event.endDate);
|
|
190
|
-
setStartMouseX(mouseEvent.clientX);
|
|
191
|
-
};
|
|
192
|
-
|
|
193
|
-
const handleMouseMoveExtend = (e) => {
|
|
194
|
-
if (mode !== "extend" || !extendingEvent) return;
|
|
195
|
-
if (!eventsExtendOn) return;
|
|
196
|
-
|
|
197
|
-
const currentMouseX = e.clientX;
|
|
198
|
-
const deltaX = currentMouseX - (startMouseX ?? 0);
|
|
199
|
-
const cellW = 30;
|
|
200
|
-
const daysToAdd = Math.floor(deltaX / cellW);
|
|
201
|
-
|
|
202
|
-
const newEndDate = new Date((originalEndDate ?? new Date()).getTime());
|
|
203
|
-
newEndDate.setDate(newEndDate.getDate() + daysToAdd);
|
|
204
|
-
|
|
205
|
-
console.log(">>> Extending ID:", extendingEvent.id, "=>", newEndDate);
|
|
206
|
-
|
|
207
|
-
setEvents((prev) =>
|
|
208
|
-
prev.map((evt) => (evt.id === extendingEvent.id ? { ...evt, endDate: newEndDate } : evt))
|
|
209
|
-
);
|
|
210
|
-
};
|
|
211
|
-
|
|
212
|
-
const handleMouseUpExtend = () => {
|
|
213
|
-
console.log(">>> Extend finished ID:", extendingEvent?.id);
|
|
214
|
-
if (onExtendInfo && extendingEvent) {
|
|
215
|
-
// callback
|
|
216
|
-
const updatedEvent = events.find((ev) => ev.id === extendingEvent.id);
|
|
217
|
-
if (updatedEvent) {
|
|
218
|
-
onExtendInfo({
|
|
219
|
-
eventId: extendingEvent.id,
|
|
220
|
-
newEndDate: updatedEvent.endDate,
|
|
221
|
-
});
|
|
222
|
-
}
|
|
223
|
-
}
|
|
224
|
-
|
|
225
|
-
// Tooltip açılmasını engellemek için modun null olmasını geciktiriyoruz
|
|
226
|
-
setTimeout(() => {
|
|
227
|
-
setMode(null);
|
|
228
|
-
}, 100); // 100ms gecikme
|
|
229
|
-
setExtendingEvent(null);
|
|
230
|
-
setOriginalEndDate(null);
|
|
231
|
-
setStartMouseX(null);
|
|
232
|
-
};
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
useEffect(() => {
|
|
236
|
-
if (mode === "extend") {
|
|
237
|
-
const onMove = (e) => handleMouseMoveExtend(e);
|
|
238
|
-
const onUp = () => handleMouseUpExtend();
|
|
239
|
-
document.addEventListener("mousemove", onMove);
|
|
240
|
-
document.addEventListener("mouseup", onUp);
|
|
241
|
-
return () => {
|
|
242
|
-
document.removeEventListener("mousemove", onMove);
|
|
243
|
-
document.removeEventListener("mouseup", onUp);
|
|
244
|
-
};
|
|
245
|
-
}
|
|
246
|
-
}, [mode, extendingEvent, eventsExtendOn, originalEndDate, startMouseX]);
|
|
247
|
-
|
|
248
|
-
// ------------------- Right Click (context) -------------------
|
|
249
|
-
const handleRightClickEvent = (evt, reactEvent) => {
|
|
250
|
-
reactEvent.preventDefault();
|
|
251
|
-
if (onEventRightClick) onEventRightClick(evt, reactEvent);
|
|
252
|
-
};
|
|
253
|
-
|
|
254
|
-
// ------------------- Helper isCellSelected -------------------
|
|
255
|
-
const isCellSelected = (resourceId, date) => {
|
|
256
|
-
if (!dragStart || !dragEnd) return false;
|
|
257
|
-
if (resourceId !== dragStart.resourceId) return false;
|
|
258
|
-
|
|
259
|
-
const startIndex = dates.findIndex((d) => parseDate(d.fullDate).getTime() === parseDate(dragStart.date).getTime());
|
|
260
|
-
const endIndex = dates.findIndex((d) => parseDate(d.fullDate).getTime() === parseDate(dragEnd.date).getTime());
|
|
261
|
-
const currentIndex = dates.findIndex((d) => parseDate(d.fullDate).getTime() === parseDate(date.fullDate).getTime());
|
|
262
|
-
|
|
263
|
-
if (startIndex === -1 || endIndex === -1 || currentIndex === -1) return false;
|
|
264
|
-
|
|
265
|
-
return currentIndex >= Math.min(startIndex, endIndex) && currentIndex <= Math.max(startIndex, endIndex);
|
|
266
|
-
};
|
|
267
|
-
|
|
268
|
-
// ------------------- calculatePosition -------------------
|
|
269
|
-
const calculatePosition = (ev, dateArr) => {
|
|
270
|
-
const startDate = parseDate(ev.startDate);
|
|
271
|
-
const endDate = parseDate(ev.endDate);
|
|
272
|
-
|
|
273
|
-
const startIndex = dateArr.findIndex((d) => parseDate(d.fullDate).toDateString() === startDate.toDateString());
|
|
274
|
-
const endIndex = dateArr.findIndex((d) => parseDate(d.fullDate).toDateString() === endDate.toDateString());
|
|
275
|
-
|
|
276
|
-
const totalDays = dateArr.length;
|
|
277
|
-
if (startIndex < 0 && endIndex < 0) {
|
|
278
|
-
return { isVisible: false, left: 0, width: 0, isPartialStart: false, isPartialEnd: false };
|
|
279
|
-
}
|
|
280
|
-
if (startIndex >= totalDays && endIndex >= totalDays) {
|
|
281
|
-
return { isVisible: false, left: 0, width: 0, isPartialStart: false, isPartialEnd: false };
|
|
282
|
-
}
|
|
283
|
-
|
|
284
|
-
const effectiveStartIndex = Math.max(startIndex, 0);
|
|
285
|
-
const effectiveEndIndex = Math.min(endIndex, totalDays - 1);
|
|
286
|
-
|
|
287
|
-
const isPartialStart = startIndex < 0;
|
|
288
|
-
const isPartialEnd = endIndex >= totalDays;
|
|
289
|
-
|
|
290
|
-
const leftPercentage = ((effectiveStartIndex + (isPartialStart ? 0 : 0.5)) / totalDays) * 100;
|
|
291
|
-
const rightPercentage = ((effectiveEndIndex + (isPartialEnd ? 1 : 0.5)) / totalDays) * 100;
|
|
292
|
-
const widthPercentage = rightPercentage - leftPercentage;
|
|
293
|
-
|
|
294
|
-
return {
|
|
295
|
-
isVisible: true,
|
|
296
|
-
left: `${leftPercentage}%`,
|
|
297
|
-
width: `${widthPercentage}%`,
|
|
298
|
-
isPartialStart,
|
|
299
|
-
isPartialEnd,
|
|
300
|
-
};
|
|
301
|
-
};
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
// ------------------- RENDER -------------------
|
|
309
|
-
return (
|
|
310
|
-
<div
|
|
311
|
-
ref={containerRef}
|
|
312
|
-
className="timeline-content-container" // Yeni class, stilini timeline.css'e ekleyebilirsin
|
|
313
|
-
>
|
|
314
|
-
{indicatorOn && (
|
|
315
|
-
<Indicator todayIndex={todayIndex} totalDays={totalDays} />
|
|
316
|
-
)}
|
|
317
|
-
|
|
318
|
-
{groupedResources.map((group, groupIndex) => (
|
|
319
|
-
<div key={groupIndex} className="timeline-group-container">
|
|
320
|
-
{/* Grup Başlığı */}
|
|
321
|
-
{resourceSettings.isGrouped && (
|
|
322
|
-
<div className="timeline-group-header-row">
|
|
323
|
-
{dates.map((dateObj, colIndex) => (
|
|
324
|
-
<div
|
|
325
|
-
key={`group-header-${groupIndex}-${colIndex}`}
|
|
326
|
-
className="timeline-group-header-cell"
|
|
327
|
-
></div>
|
|
328
|
-
))}
|
|
329
|
-
</div>
|
|
330
|
-
)}
|
|
331
|
-
|
|
332
|
-
{/* Kaynaklar */}
|
|
333
|
-
{!collapsedGroups[group.groupName] &&
|
|
334
|
-
group.resources.map((resource, rowIndex) => {
|
|
335
|
-
const resourceEvents = events.filter((ev) => ev.resourceId === resource.id);
|
|
336
|
-
|
|
337
|
-
return (
|
|
338
|
-
<div key={resource.id} className="timeline-resource-row">
|
|
339
|
-
{/* Her resource row'u */}
|
|
340
|
-
{resourceEvents.map((event) => {
|
|
341
|
-
const { isVisible, left, width, isPartialStart, isPartialEnd } =
|
|
342
|
-
calculatePosition(event, dates);
|
|
343
|
-
if (!isVisible) return null;
|
|
344
|
-
|
|
345
|
-
// Kullanıcıdan gelen stil
|
|
346
|
-
const eventStyle = eventStyleResolver ? eventStyleResolver(event) : {};
|
|
347
|
-
|
|
348
|
-
return (
|
|
349
|
-
<div
|
|
350
|
-
key={event.id}
|
|
351
|
-
className="timeline-event"
|
|
352
|
-
draggable={mode !== "extend" && eventsDragOn}
|
|
353
|
-
onDragStart={(e) => {
|
|
354
|
-
if (mode === "extend") {
|
|
355
|
-
e.preventDefault();
|
|
356
|
-
return;
|
|
357
|
-
}
|
|
358
|
-
handleDragStartSafe(e, event.id);
|
|
359
|
-
}}
|
|
360
|
-
onDragEnd={(e) => {
|
|
361
|
-
if (mode === "extend") {
|
|
362
|
-
e.preventDefault();
|
|
363
|
-
return;
|
|
364
|
-
}
|
|
365
|
-
handleDragEndSafe(e);
|
|
366
|
-
}}
|
|
367
|
-
onContextMenu={(reactEvent) => handleRightClickEvent(event, reactEvent)}
|
|
368
|
-
onClick={(ev) => handleEventClickInternal(event, ev)}
|
|
369
|
-
style={{
|
|
370
|
-
left,
|
|
371
|
-
width,
|
|
372
|
-
top: "5px",
|
|
373
|
-
borderTopLeftRadius: isPartialStart ? "0px" : "20px",
|
|
374
|
-
borderBottomLeftRadius: isPartialStart ? "0px" : "20px",
|
|
375
|
-
borderTopRightRadius: isPartialEnd ? "0px" : "20px",
|
|
376
|
-
borderBottomRightRadius: isPartialEnd ? "0px" : "20px",
|
|
377
|
-
cursor: mode === "extend" ? "col-resize" : "grab",
|
|
378
|
-
...eventStyle, // Kullanıcı tarafından tanımlanan stiller
|
|
379
|
-
}}
|
|
380
|
-
>
|
|
381
|
-
{event.title}
|
|
382
|
-
{eventsExtendOn && (
|
|
383
|
-
<div
|
|
384
|
-
className="timeline-event-extend-handle"
|
|
385
|
-
onMouseDown={(mouseEvent) => {
|
|
386
|
-
mouseEvent.stopPropagation();
|
|
387
|
-
handleMouseDownExtend(mouseEvent, event);
|
|
388
|
-
}}
|
|
389
|
-
></div>
|
|
390
|
-
)}
|
|
391
|
-
</div>
|
|
392
|
-
);
|
|
393
|
-
})}
|
|
394
|
-
|
|
395
|
-
{/* Geçici (yeni) event */}
|
|
396
|
-
{tempEvent && tempEvent.resourceId === resource.id && (
|
|
397
|
-
<div
|
|
398
|
-
className="timeline-temp-event"
|
|
399
|
-
style={{
|
|
400
|
-
...calculatePosition(tempEvent, dates),
|
|
401
|
-
...tempEventStyle, // Kullanıcının geçtiği stiller
|
|
402
|
-
}}
|
|
403
|
-
>
|
|
404
|
-
{tempEvent.title}
|
|
405
|
-
</div>
|
|
406
|
-
)}
|
|
407
|
-
|
|
408
|
-
{/* Tarih Hücreleri */}
|
|
409
|
-
{dates.map((dateObj, colIndex) => (
|
|
410
|
-
<div
|
|
411
|
-
key={`cell-${groupIndex}-${rowIndex}-${colIndex}`}
|
|
412
|
-
className={`timeline-cell ${
|
|
413
|
-
isCellSelected(resource.id, dateObj) ? "selected" : ""
|
|
414
|
-
}`}
|
|
415
|
-
data-date={JSON.stringify(dateObj)}
|
|
416
|
-
data-resource-id={resource.id}
|
|
417
|
-
onMouseDown={() => handleCellClick(resource.id, dateObj)}
|
|
418
|
-
onDragOver={(e) => handleDragOver(e)}
|
|
419
|
-
onDrop={(e) =>
|
|
420
|
-
handleDrop(e, resource.id, parseDate(dateObj.fullDate))
|
|
421
|
-
}
|
|
422
|
-
></div>
|
|
423
|
-
))}
|
|
424
|
-
</div>
|
|
425
|
-
);
|
|
426
|
-
})}
|
|
427
|
-
</div>
|
|
428
|
-
))}
|
|
429
|
-
|
|
430
|
-
|
|
431
|
-
{/* Tooltip vb. */}
|
|
432
|
-
{eventTooltipOn && selectedEvent && TooltipComponent && mode !== "extend" && (
|
|
433
|
-
<TooltipComponent
|
|
434
|
-
event={selectedEvent}
|
|
435
|
-
position={tooltipPosition}
|
|
436
|
-
onClose={handleCloseTooltip}
|
|
437
|
-
/>
|
|
438
|
-
)}
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
</div>
|
|
444
|
-
);
|
|
445
|
-
};
|
|
446
|
-
|
|
447
|
-
export default TimelineContent;
|
|
@@ -1,43 +0,0 @@
|
|
|
1
|
-
import React from "react";
|
|
2
|
-
import "./Timeline.css"; // CSS dosyasını import etmeyi unutma
|
|
3
|
-
|
|
4
|
-
const TimelineHeader = ({ dates, monthHeaders }) => {
|
|
5
|
-
return (
|
|
6
|
-
<div className="timeline-header-container">
|
|
7
|
-
{/* Ay ve Yıl Başlıkları */}
|
|
8
|
-
<div className="timeline-header-month-row">
|
|
9
|
-
{monthHeaders.map((monthHeader, index) => (
|
|
10
|
-
<div
|
|
11
|
-
key={index}
|
|
12
|
-
className="timeline-header-month-cell"
|
|
13
|
-
style={{
|
|
14
|
-
flex: monthHeader.endIndex - monthHeader.startIndex + 1,
|
|
15
|
-
borderRight:
|
|
16
|
-
index < monthHeaders.length - 1 ? "1px solid var(--border-color)" : "none",
|
|
17
|
-
}}
|
|
18
|
-
>
|
|
19
|
-
{monthHeader.monthName} {monthHeader.year}
|
|
20
|
-
</div>
|
|
21
|
-
))}
|
|
22
|
-
</div>
|
|
23
|
-
|
|
24
|
-
{/* Günlük Hücreler */}
|
|
25
|
-
<div className="timeline-header-day-row">
|
|
26
|
-
{dates.map((date, index) => (
|
|
27
|
-
<div
|
|
28
|
-
key={index}
|
|
29
|
-
className="timeline-header-day-cell"
|
|
30
|
-
style={{
|
|
31
|
-
flex: 1,
|
|
32
|
-
borderRight: index < dates.length - 1 ? "1px solid var(--border-color)" : "none",
|
|
33
|
-
}}
|
|
34
|
-
>
|
|
35
|
-
{date.display}
|
|
36
|
-
</div>
|
|
37
|
-
))}
|
|
38
|
-
</div>
|
|
39
|
-
</div>
|
|
40
|
-
);
|
|
41
|
-
};
|
|
42
|
-
|
|
43
|
-
export default TimelineHeader;
|
|
@@ -1,126 +0,0 @@
|
|
|
1
|
-
import { useState } from "react";
|
|
2
|
-
|
|
3
|
-
const useEventDragDrop = (events, setEvents, setDropInfo) => {
|
|
4
|
-
const [draggingEvent, setDraggingEvent] = useState(null);
|
|
5
|
-
const [dragOffset, setDragOffset] = useState(0);
|
|
6
|
-
const [mode, setMode] = useState(null); // "drag" veya "extend"
|
|
7
|
-
|
|
8
|
-
const handleDragStart = (event, eventId) => {
|
|
9
|
-
if (mode === "extend") return; // Uzatma modundaysa taşıma işlemini başlatma
|
|
10
|
-
|
|
11
|
-
event.stopPropagation();
|
|
12
|
-
|
|
13
|
-
const eventElement = event.target;
|
|
14
|
-
const eventRect = eventElement.getBoundingClientRect();
|
|
15
|
-
const offset = event.clientX - eventRect.left;
|
|
16
|
-
|
|
17
|
-
setDraggingEvent(eventId);
|
|
18
|
-
setDragOffset(offset);
|
|
19
|
-
setMode("drag"); // Modu taşıma olarak ayarla
|
|
20
|
-
|
|
21
|
-
const draggedEvent = events.find((evt) => evt.id === eventId);
|
|
22
|
-
if (draggedEvent) {
|
|
23
|
-
console.log("Dragging Event Start:", draggedEvent.startDate);
|
|
24
|
-
console.log("Dragging Event End:", draggedEvent.endDate);
|
|
25
|
-
}
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
const handleExtendStart = (event, eventId) => {
|
|
29
|
-
event.stopPropagation();
|
|
30
|
-
|
|
31
|
-
setDraggingEvent(eventId);
|
|
32
|
-
setMode("extend"); // Modu uzatma olarak ayarla
|
|
33
|
-
};
|
|
34
|
-
|
|
35
|
-
const handleDragOver = (event) => {
|
|
36
|
-
event.preventDefault();
|
|
37
|
-
};
|
|
38
|
-
|
|
39
|
-
const handleDrop = (event, resourceId, targetDate) => {
|
|
40
|
-
event.preventDefault();
|
|
41
|
-
|
|
42
|
-
if (mode === "drag" && draggingEvent) {
|
|
43
|
-
const draggedEvent = events.find((evt) => evt.id === draggingEvent);
|
|
44
|
-
|
|
45
|
-
if (draggedEvent) {
|
|
46
|
-
const duration = draggedEvent.endDate - draggedEvent.startDate;
|
|
47
|
-
const cellWidth = event.target.offsetWidth || 30;
|
|
48
|
-
const offsetDays = Math.floor(dragOffset / cellWidth);
|
|
49
|
-
const newStartDate = new Date(targetDate.getTime() - offsetDays * 24 * 60 * 60 * 1000);
|
|
50
|
-
const newEndDate = new Date(newStartDate.getTime() + duration);
|
|
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
|
|
69
|
-
setEvents((prevEvents) =>
|
|
70
|
-
prevEvents.map((evt) =>
|
|
71
|
-
evt.id === draggingEvent
|
|
72
|
-
? {
|
|
73
|
-
...evt,
|
|
74
|
-
resourceId,
|
|
75
|
-
startDate: newStartDate,
|
|
76
|
-
endDate: newEndDate,
|
|
77
|
-
}
|
|
78
|
-
: evt
|
|
79
|
-
)
|
|
80
|
-
);
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
|
|
84
|
-
setDraggingEvent(null);
|
|
85
|
-
setDragOffset(0);
|
|
86
|
-
setMode(null);
|
|
87
|
-
};
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
const handleExtend = (event, eventId, newEndDate) => {
|
|
91
|
-
if (mode !== "extend" || draggingEvent !== eventId) return;
|
|
92
|
-
|
|
93
|
-
setEvents((prevEvents) =>
|
|
94
|
-
prevEvents.map((evt) =>
|
|
95
|
-
evt.id === eventId
|
|
96
|
-
? {
|
|
97
|
-
...evt,
|
|
98
|
-
endDate: newEndDate,
|
|
99
|
-
}
|
|
100
|
-
: evt
|
|
101
|
-
)
|
|
102
|
-
);
|
|
103
|
-
|
|
104
|
-
console.log("Extended Event ID:", eventId, "New End Date:", newEndDate);
|
|
105
|
-
|
|
106
|
-
setDraggingEvent(null);
|
|
107
|
-
setMode(null);
|
|
108
|
-
};
|
|
109
|
-
|
|
110
|
-
const handleDragEnd = () => {
|
|
111
|
-
setDraggingEvent(null);
|
|
112
|
-
setDragOffset(0);
|
|
113
|
-
setMode(null);
|
|
114
|
-
};
|
|
115
|
-
|
|
116
|
-
return {
|
|
117
|
-
handleDragStart,
|
|
118
|
-
handleExtendStart,
|
|
119
|
-
handleDragOver,
|
|
120
|
-
handleDrop,
|
|
121
|
-
handleExtend,
|
|
122
|
-
handleDragEnd,
|
|
123
|
-
};
|
|
124
|
-
};
|
|
125
|
-
|
|
126
|
-
export default useEventDragDrop;
|
|
File without changes
|
|
@@ -1,36 +0,0 @@
|
|
|
1
|
-
// src/utils/dateUtils.js
|
|
2
|
-
|
|
3
|
-
/**
|
|
4
|
-
* "dd/mm/yyyy" formatındaki bir tarih string'ini Date objesine dönüştürür.
|
|
5
|
-
* Eğer dateInput bir string değilse, direkt Date objesini döndürür.
|
|
6
|
-
* @param {string | Object | Date} dateInput - "dd/mm/yyyy" formatında tarih stringi veya {fullDate: Date, display: string} objesi veya Date objesi.
|
|
7
|
-
* @returns {Date} - Date objesi.
|
|
8
|
-
*/
|
|
9
|
-
export const parseDate = (dateInput) => {
|
|
10
|
-
if (dateInput instanceof Date) {
|
|
11
|
-
return dateInput;
|
|
12
|
-
}
|
|
13
|
-
if (typeof dateInput === 'string') {
|
|
14
|
-
const [day, month, year] = dateInput.split("/").map(Number);
|
|
15
|
-
return new Date(year, month - 1, day);
|
|
16
|
-
} else if (typeof dateInput === 'object' && dateInput.fullDate instanceof Date) {
|
|
17
|
-
return new Date(dateInput.fullDate.getTime() + dateInput.fullDate.getTimezoneOffset() * 60000);
|
|
18
|
-
} else {
|
|
19
|
-
console.error("parseDate received invalid input:", dateInput);
|
|
20
|
-
return new Date(); // veya hata fırlat
|
|
21
|
-
}
|
|
22
|
-
};
|
|
23
|
-
|
|
24
|
-
/**
|
|
25
|
-
* Bir tarihin belirli bir aralık içinde olup olmadığını kontrol eder.
|
|
26
|
-
* @param {string | Object | Date} date - "dd/mm/yyyy" formatında tarih stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
27
|
-
* @param {string | Object | Date} startDate - "dd/mm/yyyy" formatında başlangıç tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
28
|
-
* @param {string | Object | Date} endDate - "dd/mm/yyyy" formatında bitiş tarihi stringi, {fullDate: Date, display: string} objesi veya Date objesi.
|
|
29
|
-
* @returns {boolean} - Tarih aralık içinde ise true, değilse false.
|
|
30
|
-
*/
|
|
31
|
-
export const isDateInRange = (date, startDate, endDate) => {
|
|
32
|
-
const d = parseDate(date);
|
|
33
|
-
const start = parseDate(startDate);
|
|
34
|
-
const end = parseDate(endDate);
|
|
35
|
-
return d >= start && d <= end;
|
|
36
|
-
};
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
const filterTimelineData = (dates, startDate, dayCount) => {
|
|
2
|
-
const startIndex = dates.findIndex(
|
|
3
|
-
(date) => date.fullDate.toISOString().split("T")[0] === startDate
|
|
4
|
-
);
|
|
5
|
-
|
|
6
|
-
if (startIndex === -1) {
|
|
7
|
-
console.warn("Seçilen başlangıç tarihi bulunamadı.");
|
|
8
|
-
return { filteredDates: [] };
|
|
9
|
-
}
|
|
10
|
-
|
|
11
|
-
const filteredDates = dates.slice(startIndex, startIndex + dayCount);
|
|
12
|
-
|
|
13
|
-
return {
|
|
14
|
-
filteredDates,
|
|
15
|
-
startIndex,
|
|
16
|
-
endIndex: startIndex + dayCount - 1,
|
|
17
|
-
};
|
|
18
|
-
};
|
|
19
|
-
|
|
20
|
-
export default filterTimelineData;
|
|
21
|
-
|