Skip to content

Commit d4d5623

Browse files
Merge pull request #186 from linked-planet/dev
TimeTable - added onTimeSlotClick, fixed that the time slot of a date…
2 parents 1842a9e + ed8ef2d commit d4d5623

File tree

8 files changed

+320
-266
lines changed

8 files changed

+320
-266
lines changed

library/src/components/timetable/ItemWrapper.tsx

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Dayjs } from "dayjs"
1+
import type { Dayjs } from "dayjs/esm"
22
import { useEffect, useRef } from "react"
33
import utilStyles from "../../utils.module.css"
44
import type { TimeSlotBooking, TimeTableGroup } from "./TimeTable"
@@ -119,10 +119,10 @@ export default function ItemWrapper<
119119
style={{
120120
pointerEvents: multiSelectionMode ? "none" : "auto",
121121
}}
122-
onClick={(e) => {
122+
onClick={onTimeSlotItemClick ? (e) => {
123123
e.stopPropagation()
124124
if (onTimeSlotItemClick) onTimeSlotItemClick(group, item)
125-
}}
125+
} : undefined}
126126
onKeyUp={(e) => {
127127
if (e.key === "Enter") {
128128
e.stopPropagation()

library/src/components/timetable/TimeTable.tsx

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -102,6 +102,11 @@ export interface LPTimeTableProps<
102102

103103
onTimeSlotItemClick?: (group: G, item: I) => void
104104

105+
/**
106+
* This function gets called when a time slot is clicked.
107+
*/
108+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void
109+
105110
/* this function gets called when a selection was made, i.g. to create a booking. the return value states if the selection should be cleared or not */
106111
onTimeRangeSelected?: onTimeRangeSelectedType
107112

@@ -265,6 +270,7 @@ const LPTimeTableImpl = <G extends TimeTableGroup, I extends TimeSlotBooking>({
265270
placeHolderComponent = PlaceHolderItemPlaceHolder,
266271
onRenderedGroupsChanged,
267272
onTimeSlotItemClick,
273+
onTimeSlotClick,
268274
onGroupClick,
269275
onTimeRangeSelected,
270276
defaultSelectedTimeRange,
@@ -661,6 +667,7 @@ const LPTimeTableImpl = <G extends TimeTableGroup, I extends TimeSlotBooking>({
661667
onRenderedGroupsChanged={
662668
onRenderedGroupsChanged
663669
}
670+
onTimeSlotClick={onTimeSlotClick}
664671
/>
665672
</tbody>
666673
</table>

library/src/components/timetable/TimeTableRows.tsx

Lines changed: 39 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -121,6 +121,11 @@ interface TimeTableRowsProps<
121121
* Callback for when rendered groups change, return the group indices that were rendered (parameter is a set of group indices)
122122
*/
123123
onRenderedGroupsChanged: ((groups: Set<number>) => void) | undefined
124+
125+
/**
126+
* Callback for when a time slot is clicked.
127+
*/
128+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void
124129
}
125130

126131
const intersectionStackDelay = 1
@@ -147,6 +152,7 @@ function renderGroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>(
147152
viewType: TimeTableViewType,
148153
timeStepMinutesHoursView: number,
149154
onRenderedGroupsChanged: ((groups: Set<number>) => void) | undefined,
155+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void,
150156
) {
151157
if (g < 0) {
152158
throw new Error("TimeTable - group number is negative")
@@ -234,6 +240,7 @@ function renderGroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>(
234240
renderedGroupsRef={renderedGroupsRef}
235241
changedGroupRowsRef={changedGroupRowsRef}
236242
timeStepMinutesHoursView={timeStepMinutesHoursView}
243+
onTimeSlotClick={onTimeSlotClick}
237244
//
238245
/>
239246
)
@@ -260,6 +267,7 @@ export default function TimeTableRows<
260267
viewType,
261268
timeStepMinutesHoursView,
262269
onRenderedGroupsChanged,
270+
onTimeSlotClick,
263271
}: TimeTableRowsProps<G, I>): JSX.Element[] {
264272
const storeIdent = useTimeTableIdent()
265273
const { rowHeight, columnWidth, placeHolderHeight } =
@@ -674,6 +682,7 @@ export default function TimeTableRows<
674682
viewType,
675683
timeStepMinutesHoursView,
676684
onRenderedGroupsChanged,
685+
onTimeSlotClick,
677686
)
678687
counter++
679688
if (counter > timeTableGroupRenderBatchSize) {
@@ -711,6 +720,7 @@ export default function TimeTableRows<
711720
viewType,
712721
timeStepMinutesHoursView,
713722
onRenderedGroupsChanged,
723+
onTimeSlotClick,
714724
)
715725
counter++
716726
if (counter > timeTableGroupRenderBatchSize) {
@@ -744,6 +754,7 @@ export default function TimeTableRows<
744754
viewType,
745755
timeStepMinutesHoursView,
746756
onRenderedGroupsChanged,
757+
onTimeSlotClick,
747758
)
748759
++counter
749760
}
@@ -769,6 +780,7 @@ export default function TimeTableRows<
769780
onRenderedGroupsChanged,
770781
groupRowKeys,
771782
groupRows,
783+
onTimeSlotClick,
772784
])
773785

774786
// Ensure rendering is triggered - handle edge cases where renderGroupRangeRef might be [-1, -1]
@@ -851,6 +863,7 @@ function TableCell<G extends TimeTableGroup, I extends TimeSlotBooking>({
851863
viewType,
852864
timeStepMinutesHoursView,
853865
groupItemRows,
866+
onTimeSlotClick,
854867
}: {
855868
timeSlotNumber: number
856869
group: G
@@ -867,6 +880,7 @@ function TableCell<G extends TimeTableGroup, I extends TimeSlotBooking>({
867880
viewType: TimeTableViewType
868881
timeStepMinutesHoursView: number
869882
groupItemRows: ItemRowEntry<I>[][] | null
883+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void
870884
}) {
871885
const storeIdent = useTimeTableIdent()
872886
const disableWeekendInteractions =
@@ -912,6 +926,8 @@ function TableCell<G extends TimeTableGroup, I extends TimeSlotBooking>({
912926
disableWeekendInteractions,
913927
)
914928

929+
const timeSlotEnd = timeSlot.add(timeSlotMinutes, "minutes")
930+
915931
const handleKeyUp = useKeyboardHandlers(
916932
timeSlotNumber,
917933
group.id,
@@ -1087,6 +1103,11 @@ function TableCell<G extends TimeTableGroup, I extends TimeSlotBooking>({
10871103
<td
10881104
key={timeSlotNumber}
10891105
{...mouseHandlersUsed}
1106+
onClick={onTimeSlotClick ? () => {
1107+
onTimeSlotClick({ groupId: group.id, startDate: timeSlot, endDate: timeSlotEnd })
1108+
}
1109+
: undefined
1110+
}
10901111
onKeyUp={handleKeyUp}
10911112
onBlur={(e) => {
10921113
// Only handle blur for the first cell
@@ -1200,6 +1221,7 @@ function PlaceholderTableCell<
12001221
slotsArray,
12011222
selectedTimeSlots, // this will be only with value when the current time slot is selected
12021223
placeHolderHeight,
1224+
onTimeSlotClick,
12031225
}: {
12041226
group: G
12051227
groupNumber: number
@@ -1212,6 +1234,7 @@ function PlaceholderTableCell<
12121234
slotsArray: readonly Dayjs[]
12131235
selectedTimeSlots: readonly number[] | undefined
12141236
placeHolderHeight: number
1237+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void
12151238
}) {
12161239
const storeIdent = useTimeTableIdent()
12171240
const focusedCell = useFocusedCell(storeIdent)
@@ -1279,14 +1302,16 @@ function PlaceholderTableCell<
12791302
disableWeekendInteractions,
12801303
)
12811304

1305+
const timeSlotEnd = timeSlot.add(timeSlotMinutes, "minutes")
1306+
12821307
const handleKeyUp = useKeyboardHandlers(
12831308
timeSlotNumber,
12841309
group.id,
12851310
nextGroupId,
12861311
previousGroupId,
12871312
slotsArray,
12881313
storeIdent,
1289-
groupItemRows,
1314+
groupItemRows
12901315
)
12911316

12921317
const isFocused =
@@ -1340,6 +1365,14 @@ function PlaceholderTableCell<
13401365
}}
13411366
tabIndex={-1}
13421367
onKeyUp={handleKeyUp}
1368+
onKeyDown={onTimeSlotClick ? (e) => {
1369+
if (e.key === "Enter") {
1370+
onTimeSlotClick?.({ groupId: group.id, startDate: timeSlot, endDate: timeSlotEnd })
1371+
}
1372+
} : undefined}
1373+
onClick={() => {
1374+
onTimeSlotClick?.({ groupId: group.id, startDate: timeSlot, endDate: timeSlotEnd })
1375+
}}
13431376
>
13441377
{isFocused && (
13451378
<div
@@ -1382,6 +1415,7 @@ type GroupRowsProps<G extends TimeTableGroup, I extends TimeSlotBooking> = {
13821415
renderedGroupsRef: React.MutableRefObject<Set<number>>
13831416
changedGroupRowsRef: React.MutableRefObject<Set<number>>
13841417
timeStepMinutesHoursView: number
1418+
onTimeSlotClick?: (s: { groupId: string; startDate: Dayjs; endDate: Dayjs }) => void
13851419
}
13861420

13871421
function GroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>({
@@ -1406,6 +1440,7 @@ function GroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>({
14061440
renderedGroupsRef,
14071441
changedGroupRowsRef,
14081442
//
1443+
onTimeSlotClick,
14091444
}: GroupRowsProps<G, I>) {
14101445
// ugly SIDE EFFECTs for now to make sure the rendered groups are set
14111446
changedGroupRowsRef.current.delete(groupNumber)
@@ -1541,6 +1576,7 @@ function GroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>({
15411576
placeHolderHeight={placeHolderHeight}
15421577
timeSlotMinutes={timeSlotMinutes}
15431578
groupItemRows={groupItemRows}
1579+
onTimeSlotClick={onTimeSlotClick}
15441580
/>,
15451581
)
15461582
}
@@ -1600,6 +1636,7 @@ function GroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>({
16001636
timeFrameDay={timeFrameDay}
16011637
viewType={viewType}
16021638
timeStepMinutesHoursView={timeStepMinutesHoursView}
1639+
onTimeSlotClick={onTimeSlotClick}
16031640
/>,
16041641
)
16051642
}
@@ -1621,6 +1658,7 @@ function GroupRows<G extends TimeTableGroup, I extends TimeSlotBooking>({
16211658
timeStepMinutesHoursView,
16221659
nextGroupId,
16231660
previousGroupId,
1661+
onTimeSlotClick,
16241662
])
16251663

16261664
if (!renderCells) {

library/src/components/timetable/TimeTableSelectionStore.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -169,9 +169,11 @@ function setTimeSlotSelectionByDateRange(
169169
basicConfig.timeStepMinutesHoursView,
170170
)
171171

172-
slot = slot
173-
.add(basicConfig.timeFrameDay.startHour, "hours")
174-
.add(basicConfig.timeFrameDay.startMinute, "minutes")
172+
if (basicConfig.viewType !== "hours") {
173+
slot = slot
174+
.add(basicConfig.timeFrameDay.startHour, "hours")
175+
.add(basicConfig.timeFrameDay.startMinute, "minutes")
176+
}
175177

176178
const slotEnd = slot.add(timeSlotMinutes, "minutes")
177179

library/src/components/timetable/useKeyboardHandler.ts

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import type { Dayjs } from "dayjs"
1+
import type { Dayjs } from "dayjs/esm"
22
import { useCallback } from "react"
33
import type { TimeSlotBooking } from "./TimeTable"
44
import { setFocusedCell, useFocusedCell } from "./TimeTableFocusStore"
@@ -12,7 +12,7 @@ export function useKeyboardHandlers<I extends TimeSlotBooking>(
1212
previousGroupId: string | null,
1313
slotsArray: readonly Dayjs[] | undefined,
1414
storeIdent: string,
15-
groupItemRows: ItemRowEntry<I>[][] | null,
15+
groupItemRows: ItemRowEntry<I>[][] | null
1616
) {
1717
// find the item in the groupItemRows to focus
1818
const currentItemKey = useFocusedCell(storeIdent).itemKey
@@ -148,12 +148,6 @@ export function useKeyboardHandlers<I extends TimeSlotBooking>(
148148
e.stopPropagation()
149149
if (slotsArray && timeSlotNumber < slotsArray.length - 1) {
150150
const nextItemKey = nextItemFunc()
151-
console.log(
152-
"NEXT ITEM KEY",
153-
nextItemKey,
154-
e.target,
155-
timeSlotNumber,
156-
)
157151
setFocusedCell(
158152
storeIdent,
159153
groupId,

package.json

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -110,13 +110,13 @@
110110
"lowlight": "^3.3.0",
111111
"lucide-react": "^0.544.0",
112112
"mime-types": "^3.0.1",
113-
"motion": "^12.23.12",
113+
"motion": "^12.23.13",
114114
"postcss": "^8.5.6",
115115
"react-awesome-slider": "^4.1.0",
116-
"react-day-picker": "^9.9.0",
116+
"react-day-picker": "^9.10.0",
117117
"react-intl": "^7.1.11",
118118
"react-joyride": "^2.9.3",
119-
"react-router-dom": "^7.8.2",
119+
"react-router-dom": "^7.9.1",
120120
"react-select": "^5.10.2",
121121
"react-syntax-highlighter": "^15.6.6",
122122
"react-transition-group": "^4.4.5",
@@ -137,10 +137,10 @@
137137
"@hello-pangea/dnd": "^18.0.1",
138138
"@monaco-editor/react": "^4.7.0",
139139
"@tailwindcss/vite": "^4.1.13",
140-
"@tanstack/react-query": "^5.87.4",
140+
"@tanstack/react-query": "^5.89.0",
141141
"@testing-library/jest-dom": "^6.8.0",
142142
"@total-typescript/ts-reset": "^0.6.1",
143-
"@types/node": "^24.3.1",
143+
"@types/node": "^24.5.0",
144144
"@types/react": "^18.3.24",
145145
"@types/react-dom": "^18.3.7",
146146
"@types/react-transition-group": "^4.4.12",

0 commit comments

Comments
 (0)