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
|
@@ -0,0 +1,304 @@
|
|
|
1
|
+
import React, { useState, useEffect } from "react";
|
|
2
|
+
import MasterHeader from "./MasterHeader";
|
|
3
|
+
import ResourcesHeader from "./ResourcesHeader";
|
|
4
|
+
import Resources from "./Resources";
|
|
5
|
+
import TimelineHeader from "./TimelineHeader";
|
|
6
|
+
import TimelineContent from "./TimelineContent";
|
|
7
|
+
import "./Timeline.css";
|
|
8
|
+
import EventTooltip from "./EventTooltip";
|
|
9
|
+
import { generateTimelineData } from "../../utils/timelineUtils";
|
|
10
|
+
|
|
11
|
+
const Timeline = ({
|
|
12
|
+
resources,
|
|
13
|
+
programDate = null,
|
|
14
|
+
events = [],
|
|
15
|
+
resourceSettings = {
|
|
16
|
+
showIdAsName: false,
|
|
17
|
+
isGrouped: true,
|
|
18
|
+
isCollapsible: true,
|
|
19
|
+
},
|
|
20
|
+
indicatorOn = false,
|
|
21
|
+
dropInfo,
|
|
22
|
+
setDropInfo,
|
|
23
|
+
|
|
24
|
+
masterHeaderView = true,
|
|
25
|
+
resourceHeaderContent = "Akfa Timeline",
|
|
26
|
+
eventsDragOn = true,
|
|
27
|
+
eventsExtendOn = true,
|
|
28
|
+
createNewEventOn = true,
|
|
29
|
+
onDragInfo,
|
|
30
|
+
onExtendInfo,
|
|
31
|
+
onCreateEventInfo,
|
|
32
|
+
// İsteğe bağlı event tıklama callback'leri
|
|
33
|
+
onEventClick,
|
|
34
|
+
onEventRightClick,
|
|
35
|
+
|
|
36
|
+
// Yatay scroll özelliği aç/kapa
|
|
37
|
+
horizontalScrollOn = false, // Varsayılan false
|
|
38
|
+
|
|
39
|
+
dayRange = 30,
|
|
40
|
+
setDayRange,
|
|
41
|
+
themeType = "light", // Tema bilgisi varsayılan olarak light
|
|
42
|
+
|
|
43
|
+
eventTooltipOn = true,
|
|
44
|
+
tooltipComponent: TooltipComponent, // Özelleştirilebilir Tooltip bileşeni
|
|
45
|
+
tempEventStyle = {},
|
|
46
|
+
eventStyleResolver = () => ({}),
|
|
47
|
+
|
|
48
|
+
onToday,
|
|
49
|
+
onAdvance,
|
|
50
|
+
onRetreat,
|
|
51
|
+
onMonthAdvance,
|
|
52
|
+
onMonthRetreat,
|
|
53
|
+
}) => {
|
|
54
|
+
// ---------------------------------------------------------
|
|
55
|
+
// 1) timelineData oluştur (dates, monthHeaders vs.)
|
|
56
|
+
// ---------------------------------------------------------
|
|
57
|
+
const timelineData = generateTimelineData(2020, 2030); // 10 yıllık veri
|
|
58
|
+
const { dates, monthHeaders } = timelineData;
|
|
59
|
+
const [selectedDate, setSelectedDate] = useState(() => {
|
|
60
|
+
const date = programDate ? new Date(programDate) : new Date();
|
|
61
|
+
date.setDate(date.getDate() - 3); // Program tarihinden 3 gün öncesini al
|
|
62
|
+
return date;
|
|
63
|
+
});
|
|
64
|
+
|
|
65
|
+
// ---------------------------------------------------------
|
|
66
|
+
// 2) local state
|
|
67
|
+
// ---------------------------------------------------------
|
|
68
|
+
const [collapsedGroups, setCollapsedGroups] = useState({});
|
|
69
|
+
|
|
70
|
+
const [localEvents, setLocalEvents] = useState(events);
|
|
71
|
+
|
|
72
|
+
const [selectedEvent, setSelectedEvent] = useState(null);
|
|
73
|
+
const [tooltipPosition, setTooltipPosition] = useState({ top: 0, left: 0 });
|
|
74
|
+
|
|
75
|
+
// dayRange = ekranda göstermeyi istediğimiz gün/hücre sayısı (ör. 30 gün)
|
|
76
|
+
|
|
77
|
+
const [isDarkMode, setIsDarkMode] = useState(themeType === "dark");
|
|
78
|
+
|
|
79
|
+
useEffect(() => {
|
|
80
|
+
if (themeType !== undefined) {
|
|
81
|
+
setIsDarkMode(themeType === "dark");
|
|
82
|
+
}
|
|
83
|
+
}, [themeType]);
|
|
84
|
+
|
|
85
|
+
const toggleDarkMode = () => {
|
|
86
|
+
setIsDarkMode((prev) => !prev);
|
|
87
|
+
};
|
|
88
|
+
// ---------------------------------------------------------
|
|
89
|
+
// 3) Sabit hücre genişliği (örneğin 56.95 px)
|
|
90
|
+
// Container genişliği = dayRange * cellWidth
|
|
91
|
+
// ---------------------------------------------------------
|
|
92
|
+
const cellWidth = 56.95; // her gün/hücre ~57 piksel
|
|
93
|
+
const containerWidth = dayRange * cellWidth;
|
|
94
|
+
// örneğin dayRange=30 => containerWidth=30*56.95=1708.5 px
|
|
95
|
+
|
|
96
|
+
// ---------------------------------------------------------
|
|
97
|
+
// 4) Event Tooltip logic
|
|
98
|
+
// ---------------------------------------------------------
|
|
99
|
+
const handleEventClick = (event, e) => {
|
|
100
|
+
// Harici onEventClick callback'i varsa, önce onu tetikleyelim
|
|
101
|
+
if (onEventClick) {
|
|
102
|
+
onEventClick(event, e);
|
|
103
|
+
}
|
|
104
|
+
// Ardından tooltip göstermek istiyorsak:
|
|
105
|
+
const eventElement = e.currentTarget;
|
|
106
|
+
if (eventElement) {
|
|
107
|
+
const rect = eventElement.getBoundingClientRect();
|
|
108
|
+
setTooltipPosition({
|
|
109
|
+
top: rect.top + window.scrollY,
|
|
110
|
+
left: rect.left + rect.width / 2 + window.scrollX,
|
|
111
|
+
});
|
|
112
|
+
setSelectedEvent(event);
|
|
113
|
+
}
|
|
114
|
+
};
|
|
115
|
+
|
|
116
|
+
const handleCloseTooltip = () => {
|
|
117
|
+
setSelectedEvent(null);
|
|
118
|
+
};
|
|
119
|
+
|
|
120
|
+
// ---------------------------------------------------------
|
|
121
|
+
// 5) Tarih filtreleme => filteredDates
|
|
122
|
+
// ---------------------------------------------------------
|
|
123
|
+
const startIndex = dates.findIndex((d) => d.fullDate >= selectedDate);
|
|
124
|
+
const endIndex = startIndex + dayRange;
|
|
125
|
+
const filteredDates =
|
|
126
|
+
startIndex !== -1 ? dates.slice(startIndex, Math.min(endIndex, dates.length)) : [];
|
|
127
|
+
|
|
128
|
+
const today = programDate ? new Date(programDate) : new Date();
|
|
129
|
+
const todayIndex = filteredDates.findIndex(
|
|
130
|
+
(d) => new Date(d.fullDate).toDateString() === today.toDateString()
|
|
131
|
+
);
|
|
132
|
+
const totalDays = filteredDates.length;
|
|
133
|
+
|
|
134
|
+
// ---------------------------------------------------------
|
|
135
|
+
// 6) Grupları aç/kapa
|
|
136
|
+
// ---------------------------------------------------------
|
|
137
|
+
const toggleGroupCollapse = (groupName) => {
|
|
138
|
+
setCollapsedGroups((prev) => ({
|
|
139
|
+
...prev,
|
|
140
|
+
[groupName]: !prev[groupName],
|
|
141
|
+
}));
|
|
142
|
+
};
|
|
143
|
+
|
|
144
|
+
// ---------------------------------------------------------
|
|
145
|
+
// 7) Navigation fonksiyonları
|
|
146
|
+
// --------------------------------------------------------- const { dates, monthHeaders } = timelineData;
|
|
147
|
+
|
|
148
|
+
|
|
149
|
+
|
|
150
|
+
const handleDateChange = (newDate) => {
|
|
151
|
+
setSelectedDate(new Date(newDate));
|
|
152
|
+
};
|
|
153
|
+
|
|
154
|
+
const handleToday = () => {
|
|
155
|
+
const today = new Date();
|
|
156
|
+
today.setDate(today.getDate() - 3); // Bugünden 3 gün öncesini ayarla
|
|
157
|
+
setSelectedDate(today);
|
|
158
|
+
};
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
const handleAdvance = () => {
|
|
162
|
+
setSelectedDate((prev) => new Date(prev.getTime() + 5 * 24 * 60 * 60 * 1000));
|
|
163
|
+
};
|
|
164
|
+
|
|
165
|
+
const handleRetreat = () => {
|
|
166
|
+
setSelectedDate((prev) => new Date(prev.getTime() - 5 * 24 * 60 * 60 * 1000));
|
|
167
|
+
};
|
|
168
|
+
|
|
169
|
+
const handleMonthAdvance = () => {
|
|
170
|
+
setSelectedDate((prev) => {
|
|
171
|
+
const newDate = new Date(prev);
|
|
172
|
+
newDate.setMonth(newDate.getMonth() + 1);
|
|
173
|
+
return newDate;
|
|
174
|
+
});
|
|
175
|
+
};
|
|
176
|
+
|
|
177
|
+
const handleMonthRetreat = () => {
|
|
178
|
+
setSelectedDate((prev) => {
|
|
179
|
+
const newDate = new Date(prev);
|
|
180
|
+
newDate.setMonth(newDate.getMonth() - 1);
|
|
181
|
+
return newDate;
|
|
182
|
+
});
|
|
183
|
+
};
|
|
184
|
+
|
|
185
|
+
// ---------------------------------------------------------
|
|
186
|
+
// 8) Dark Mode
|
|
187
|
+
// ---------------------------------------------------------
|
|
188
|
+
|
|
189
|
+
|
|
190
|
+
// ---------------------------------------------------------
|
|
191
|
+
// 9) Ay başlıklarını filtrele
|
|
192
|
+
// ---------------------------------------------------------
|
|
193
|
+
const filteredMonthHeaders = monthHeaders
|
|
194
|
+
.map((header) => {
|
|
195
|
+
const adjustedStartIndex = Math.max(header.startIndex, startIndex);
|
|
196
|
+
const adjustedEndIndex = Math.min(header.endIndex, endIndex - 1);
|
|
197
|
+
return {
|
|
198
|
+
...header,
|
|
199
|
+
startIndex: adjustedStartIndex,
|
|
200
|
+
endIndex: adjustedEndIndex,
|
|
201
|
+
};
|
|
202
|
+
})
|
|
203
|
+
.filter((header) => header.startIndex <= header.endIndex);
|
|
204
|
+
|
|
205
|
+
// ---------------------------------------------------------
|
|
206
|
+
// 10) Return
|
|
207
|
+
// ---------------------------------------------------------
|
|
208
|
+
return (
|
|
209
|
+
<div className={`timeline-container ${isDarkMode ? "dark-mode" : ""}`}>
|
|
210
|
+
{/* Üst kısım: MasterHeader */}
|
|
211
|
+
{masterHeaderView && (
|
|
212
|
+
<div className="timeline-master-header">
|
|
213
|
+
<MasterHeader
|
|
214
|
+
selectedDate={selectedDate} // Seçili tarihi gönder
|
|
215
|
+
onDateSelect={handleDateChange}
|
|
216
|
+
onToday={handleToday}
|
|
217
|
+
onAdvance={handleAdvance}
|
|
218
|
+
onRetreat={handleRetreat}
|
|
219
|
+
onMonthAdvance={handleMonthAdvance}
|
|
220
|
+
onMonthRetreat={handleMonthRetreat}
|
|
221
|
+
dayRange={dayRange}
|
|
222
|
+
setDayRange={setDayRange}
|
|
223
|
+
/>
|
|
224
|
+
</div>
|
|
225
|
+
)}
|
|
226
|
+
{/* Body: Sol kısım => Resources, Sağ kısım => timeline */}
|
|
227
|
+
<div className="timeline-body">
|
|
228
|
+
<div className="timeline-resources-container"
|
|
229
|
+
style={{ overflow: "hidden"}}>
|
|
230
|
+
<ResourcesHeader content={resourceHeaderContent} />
|
|
231
|
+
<Resources
|
|
232
|
+
groupedResources={resources}
|
|
233
|
+
toggleGroupCollapse={toggleGroupCollapse}
|
|
234
|
+
collapsedGroups={collapsedGroups}
|
|
235
|
+
resourceSettings={resourceSettings}
|
|
236
|
+
/>
|
|
237
|
+
</div>
|
|
238
|
+
|
|
239
|
+
|
|
240
|
+
<div
|
|
241
|
+
className="timeline-scrollable-container"
|
|
242
|
+
style={{
|
|
243
|
+
overflowX: horizontalScrollOn ? "auto" : "hidden",
|
|
244
|
+
}}
|
|
245
|
+
>
|
|
246
|
+
|
|
247
|
+
<div
|
|
248
|
+
className="timeline-header-content-wrapper"
|
|
249
|
+
style={{
|
|
250
|
+
width: horizontalScrollOn ? `${containerWidth}px` : "100%",
|
|
251
|
+
}}
|
|
252
|
+
>
|
|
253
|
+
<TimelineHeader
|
|
254
|
+
dates={filteredDates}
|
|
255
|
+
monthHeaders={filteredMonthHeaders}
|
|
256
|
+
/>
|
|
257
|
+
|
|
258
|
+
<TimelineContent
|
|
259
|
+
groupedResources={resources}
|
|
260
|
+
dates={filteredDates}
|
|
261
|
+
collapsedGroups={collapsedGroups}
|
|
262
|
+
events={localEvents}
|
|
263
|
+
setEvents={setLocalEvents}
|
|
264
|
+
onEventClick={onEventClick}
|
|
265
|
+
todayIndex={filteredDates.findIndex(
|
|
266
|
+
(d) => new Date(d.fullDate).toDateString() === new Date().toDateString()
|
|
267
|
+
)}
|
|
268
|
+
indicatorOn={indicatorOn}
|
|
269
|
+
resourceSettings={resourceSettings}
|
|
270
|
+
toggleGroupCollapse={toggleGroupCollapse}
|
|
271
|
+
setDropInfo={setDropInfo}
|
|
272
|
+
eventsDragOn={eventsDragOn}
|
|
273
|
+
eventsExtendOn={eventsExtendOn}
|
|
274
|
+
createNewEventOn={createNewEventOn}
|
|
275
|
+
onDragInfo={onDragInfo}
|
|
276
|
+
onExtendInfo={onExtendInfo}
|
|
277
|
+
onCreateEventInfo={onCreateEventInfo}
|
|
278
|
+
onEventRightClick={onEventRightClick}
|
|
279
|
+
eventTooltipOn={eventTooltipOn} // Tooltip kontrolü
|
|
280
|
+
tooltipComponent={TooltipComponent} // Özelleştirilebilir Tooltip bileşeni
|
|
281
|
+
tempEventStyle = {tempEventStyle}
|
|
282
|
+
eventStyleResolver={eventStyleResolver}
|
|
283
|
+
|
|
284
|
+
/>
|
|
285
|
+
|
|
286
|
+
{/* Tooltip */}
|
|
287
|
+
{selectedEvent && (
|
|
288
|
+
<EventTooltip
|
|
289
|
+
event={selectedEvent}
|
|
290
|
+
position={tooltipPosition}
|
|
291
|
+
onClose={handleCloseTooltip}
|
|
292
|
+
onDelete={(eventId) =>
|
|
293
|
+
setLocalEvents((prev) => prev.filter((e) => e.id !== eventId))
|
|
294
|
+
}
|
|
295
|
+
/>
|
|
296
|
+
)}
|
|
297
|
+
</div>
|
|
298
|
+
</div>
|
|
299
|
+
</div>
|
|
300
|
+
</div>
|
|
301
|
+
);
|
|
302
|
+
};
|
|
303
|
+
|
|
304
|
+
export default Timeline;
|