@mantine/schedule 9.4.0 → 9.4.1
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/cjs/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.cjs +17 -3
- package/cjs/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.cjs.map +1 -1
- package/cjs/components/ResourcesSchedule/ResourcesSchedule.cjs +3 -0
- package/cjs/components/ResourcesSchedule/ResourcesSchedule.cjs.map +1 -1
- package/cjs/components/ResourcesWeekView/ResourcesWeekView.cjs +74 -8
- package/cjs/components/ResourcesWeekView/ResourcesWeekView.cjs.map +1 -1
- package/cjs/hooks/use-horizontal-event-resize.cjs +12 -4
- package/cjs/hooks/use-horizontal-event-resize.cjs.map +1 -1
- package/cjs/index.cjs +2 -0
- package/cjs/utils/get-day-relative-percent/get-day-relative-percent.cjs +18 -0
- package/cjs/utils/get-day-relative-percent/get-day-relative-percent.cjs.map +1 -0
- package/esm/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.mjs +17 -3
- package/esm/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.mjs.map +1 -1
- package/esm/components/ResourcesSchedule/ResourcesSchedule.mjs +3 -0
- package/esm/components/ResourcesSchedule/ResourcesSchedule.mjs.map +1 -1
- package/esm/components/ResourcesWeekView/ResourcesWeekView.mjs +75 -9
- package/esm/components/ResourcesWeekView/ResourcesWeekView.mjs.map +1 -1
- package/esm/hooks/use-horizontal-event-resize.mjs +12 -4
- package/esm/hooks/use-horizontal-event-resize.mjs.map +1 -1
- package/esm/index.mjs +2 -1
- package/esm/utils/get-day-relative-percent/get-day-relative-percent.mjs +18 -0
- package/esm/utils/get-day-relative-percent/get-day-relative-percent.mjs.map +1 -0
- package/lib/components/ResourcesWeekView/ResourcesWeekView.d.ts +11 -0
- package/lib/hooks/use-horizontal-event-resize.d.ts +3 -1
- package/lib/utils/get-day-relative-percent/get-day-relative-percent.d.ts +15 -0
- package/lib/utils/index.d.ts +1 -0
- package/package.json +4 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"use-horizontal-event-resize.cjs","names":["parseTimeString","clampIntervalMinutes"],"sources":["../../src/hooks/use-horizontal-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'start' | 'end';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n currentLeft: number;\n currentWidth: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n}\n\nexport interface UseHorizontalEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n}\n\nexport function useHorizontalEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n onEventResize,\n canResizeEvent,\n}: UseHorizontalEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n const minWidthPercent = (clampedInterval / totalMinutes) * 100;\n\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped = Math.round(minutes / clampedInterval) * clampedInterval;\n return Math.max(0, Math.min(literalRange, snapped));\n },\n [literalRange, clampedInterval]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapPercent = useCallback(\n (percent: number): number => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n return (snappedMinutes / totalMinutes) * 100;\n },\n [totalMinutes, clampAndSnap]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n eventDate,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n eventDate: string;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n currentLeft: originalLeft,\n currentWidth: originalWidth,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n const savedCursor = document.body.style.cursor;\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'ew-resize';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const relativeX = e.clientX - containerRect.left;\n const rawPercent = Math.max(0, Math.min(100, (relativeX / containerRect.width) * 100));\n const snappedPercent = snapPercent(rawPercent);\n\n let newLeft = state.originalLeft;\n let newWidth = state.originalWidth;\n\n if (state.edge === 'end') {\n newWidth = Math.max(minWidthPercent, snappedPercent - state.originalLeft);\n } else {\n const originalRight = state.originalLeft + state.originalWidth;\n newLeft = Math.min(snappedPercent, originalRight - minWidthPercent);\n newWidth = originalRight - newLeft;\n }\n\n resizeRef.current = { ...state, currentLeft: newLeft, currentWidth: newWidth };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentLeft !== state.originalLeft ||\n state.currentWidth !== state.originalWidth\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'start') {\n newStart = percentToDateTime(state.currentLeft, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentLeft + state.currentWidth, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.body.style.cursor = savedCursor;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n return { left: resizeState.currentLeft, width: resizeState.currentWidth };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static' || event.display === 'background') {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n resizingEdge: resizeState?.edge ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"use-horizontal-event-resize.cjs","names":["parseTimeString","clampIntervalMinutes","getDayRelativePercent"],"sources":["../../src/hooks/use-horizontal-event-resize.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport { useCallback, useEffect, useEffectEvent, useRef, useState } from 'react';\nimport { DateTimeStringValue, ScheduleEventData, ScheduleMode } from '../types';\nimport { clampIntervalMinutes } from '../utils/clamp-interval-minutes/clamp-interval-minutes';\nimport { getDayRelativePercent } from '../utils/get-day-relative-percent/get-day-relative-percent';\nimport { parseTimeString } from '../utils/parse-time-string/parse-time-string';\n\ntype ResizeEdge = 'start' | 'end';\n\ninterface ResizeState {\n eventId: string | number;\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n currentLeft: number;\n currentWidth: number;\n eventDate: string;\n originalStart: DateTimeStringValue;\n originalEnd: DateTimeStringValue;\n dayIndex: number;\n dayCount: number;\n}\n\nexport interface UseHorizontalEventResizeInput {\n enabled?: boolean;\n mode?: ScheduleMode;\n startTime: string;\n endTime: string;\n intervalMinutes: number;\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n}\n\nexport function useHorizontalEventResize({\n enabled = false,\n mode = 'default',\n startTime,\n endTime,\n intervalMinutes,\n onEventResize,\n canResizeEvent,\n}: UseHorizontalEventResizeInput) {\n const [resizeState, setResizeState] = useState<ResizeState | null>(null);\n const resizeRef = useRef<ResizeState | null>(null);\n const justResizedRef = useRef(false);\n const stableOnEventResize = useEffectEvent(onEventResize || (() => {}));\n\n const parsedStartTime = parseTimeString(startTime);\n const parsedEndTime = parseTimeString(endTime);\n const startMinutes = parsedStartTime.hours * 60 + parsedStartTime.minutes;\n const endMinutes = parsedEndTime.hours * 60 + parsedEndTime.minutes;\n const clampedInterval = clampIntervalMinutes(intervalMinutes);\n const literalRange = endMinutes - startMinutes;\n const totalMinutes = Math.ceil(literalRange / clampedInterval) * clampedInterval;\n const minWidthPercent = (clampedInterval / totalMinutes) * 100;\n\n const clampAndSnap = useCallback(\n (minutes: number): number => {\n const snapped = Math.round(minutes / clampedInterval) * clampedInterval;\n return Math.max(0, Math.min(literalRange, snapped));\n },\n [literalRange, clampedInterval]\n );\n\n const percentToDateTime = useCallback(\n (percent: number, eventDate: string): DateTimeStringValue => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n const totalMins = startMinutes + snappedMinutes;\n const hours = Math.floor(totalMins / 60);\n const mins = totalMins % 60;\n return `${eventDate} ${String(hours).padStart(2, '0')}:${String(mins).padStart(2, '0')}:00`;\n },\n [totalMinutes, startMinutes, clampAndSnap]\n );\n\n const snapPercent = useCallback(\n (percent: number): number => {\n const minutes = (percent / 100) * totalMinutes;\n const snappedMinutes = clampAndSnap(minutes);\n return (snappedMinutes / totalMinutes) * 100;\n },\n [totalMinutes, clampAndSnap]\n );\n\n const handleResizeStart = useCallback(\n ({\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n eventDate,\n dayIndex = 0,\n dayCount = 1,\n pointerEvent,\n }: {\n event: ScheduleEventData;\n edge: ResizeEdge;\n container: HTMLElement;\n originalLeft: number;\n originalWidth: number;\n eventDate: string;\n dayIndex?: number;\n dayCount?: number;\n pointerEvent: React.PointerEvent;\n }) => {\n if (!enabled || mode === 'static') {\n return;\n }\n\n pointerEvent.preventDefault();\n pointerEvent.stopPropagation();\n\n const state: ResizeState = {\n eventId: event.id,\n event,\n edge,\n container,\n originalLeft,\n originalWidth,\n currentLeft: originalLeft,\n currentWidth: originalWidth,\n eventDate,\n originalStart: dayjs(event.start).format('YYYY-MM-DD HH:mm:ss'),\n originalEnd: dayjs(event.end).format('YYYY-MM-DD HH:mm:ss'),\n dayIndex,\n dayCount,\n };\n\n resizeRef.current = state;\n setResizeState(state);\n },\n [enabled, mode]\n );\n\n const isResizing = resizeState !== null;\n\n useEffect(() => {\n if (!isResizing) {\n return undefined;\n }\n\n const savedUserSelect = document.body.style.userSelect;\n const savedCursor = document.body.style.cursor;\n document.body.style.userSelect = 'none';\n document.body.style.cursor = 'ew-resize';\n\n const handlePointerMove = (e: PointerEvent) => {\n const state = resizeRef.current;\n if (!state) {\n return;\n }\n\n const containerRect = state.container.getBoundingClientRect();\n const rawPercent = getDayRelativePercent({\n clientX: e.clientX,\n containerLeft: containerRect.left,\n containerWidth: containerRect.width,\n dayIndex: state.dayIndex,\n dayCount: state.dayCount,\n });\n const snappedPercent = snapPercent(rawPercent);\n\n let newLeft = state.originalLeft;\n let newWidth = state.originalWidth;\n\n if (state.edge === 'end') {\n newWidth = Math.max(minWidthPercent, snappedPercent - state.originalLeft);\n } else {\n const originalRight = state.originalLeft + state.originalWidth;\n newLeft = Math.min(snappedPercent, originalRight - minWidthPercent);\n newWidth = originalRight - newLeft;\n }\n\n resizeRef.current = { ...state, currentLeft: newLeft, currentWidth: newWidth };\n setResizeState(resizeRef.current);\n };\n\n const handlePointerUp = () => {\n const state = resizeRef.current;\n if (state) {\n if (\n state.currentLeft !== state.originalLeft ||\n state.currentWidth !== state.originalWidth\n ) {\n let newStart: DateTimeStringValue;\n let newEnd: DateTimeStringValue;\n\n if (state.edge === 'start') {\n newStart = percentToDateTime(state.currentLeft, state.eventDate);\n newEnd = state.originalEnd;\n } else {\n newStart = state.originalStart;\n newEnd = percentToDateTime(state.currentLeft + state.currentWidth, state.eventDate);\n }\n\n stableOnEventResize({\n eventId: state.eventId,\n newStart,\n newEnd,\n event: state.event,\n });\n }\n }\n resizeRef.current = null;\n setResizeState(null);\n justResizedRef.current = true;\n requestAnimationFrame(() => {\n justResizedRef.current = false;\n });\n };\n\n document.addEventListener('pointermove', handlePointerMove);\n document.addEventListener('pointerup', handlePointerUp);\n\n return () => {\n document.body.style.userSelect = savedUserSelect;\n document.body.style.cursor = savedCursor;\n document.removeEventListener('pointermove', handlePointerMove);\n document.removeEventListener('pointerup', handlePointerUp);\n };\n }, [isResizing]);\n\n const getResizePosition = useCallback(\n (eventId: string | number) => {\n if (!resizeState || resizeState.eventId !== eventId) {\n return null;\n }\n return { left: resizeState.currentLeft, width: resizeState.currentWidth };\n },\n [resizeState]\n );\n\n const isResizableEvent = useCallback(\n (event: ScheduleEventData) => {\n if (!enabled || mode === 'static' || event.display === 'background') {\n return false;\n }\n return canResizeEvent ? canResizeEvent(event) : true;\n },\n [enabled, mode, canResizeEvent]\n );\n\n const wasResizing = useCallback(() => justResizedRef.current, []);\n\n return {\n handleResizeStart,\n isResizing,\n resizingEventId: resizeState?.eventId ?? null,\n resizingEdge: resizeState?.edge ?? null,\n getResizePosition,\n isResizableEvent,\n wasResizing,\n };\n}\n"],"mappings":"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"}
|
package/cjs/index.cjs
CHANGED
|
@@ -40,6 +40,7 @@ const require_get_ordered_resources = require("./utils/get-ordered-resources/get
|
|
|
40
40
|
const require_handle_resources_grid_key_down = require("./utils/handle-resources-grid-key-down/handle-resources-grid-key-down.cjs");
|
|
41
41
|
const require_get_group_to_resource_id_map = require("./utils/get-group-to-resource-id-map/get-group-to-resource-id-map.cjs");
|
|
42
42
|
const require_get_index_from_drag_point = require("./utils/get-index-from-drag-point/get-index-from-drag-point.cjs");
|
|
43
|
+
const require_get_day_relative_percent = require("./utils/get-day-relative-percent/get-day-relative-percent.cjs");
|
|
43
44
|
const require_AgendaView = require("./components/AgendaView/AgendaView.cjs");
|
|
44
45
|
const require_CurrentTimeIndicator = require("./components/CurrentTimeIndicator/CurrentTimeIndicator.cjs");
|
|
45
46
|
const require_DragContext = require("./components/DragContext/DragContext.cjs");
|
|
@@ -81,6 +82,7 @@ exports.formatDate = require_format_date.formatDate;
|
|
|
81
82
|
exports.getBusinessHoursMod = require_get_business_hours_mod.getBusinessHoursMod;
|
|
82
83
|
exports.getCurrentTimePosition = require_get_current_time_position.getCurrentTimePosition;
|
|
83
84
|
exports.getDayPosition = require_get_day_position.getDayPosition;
|
|
85
|
+
exports.getDayRelativePercent = require_get_day_relative_percent.getDayRelativePercent;
|
|
84
86
|
exports.getDayTimeIntervals = require_get_day_time_intervals.getDayTimeIntervals;
|
|
85
87
|
exports.getEndOfWeek = require_get_end_of_week.getEndOfWeek;
|
|
86
88
|
exports.getGroupToResourceIdMap = require_get_group_to_resource_id_map.getGroupToResourceIdMap;
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
"use client";
|
|
2
|
+
//#region packages/@mantine/schedule/src/utils/get-day-relative-percent/get-day-relative-percent.ts
|
|
3
|
+
/**
|
|
4
|
+
* Maps a horizontal pointer position to a percent (0-100) within a single day's
|
|
5
|
+
* sub-region of a container that holds `dayCount` equal-width days side by side.
|
|
6
|
+
* `dayIndex === 0` and `dayCount === 1` make it equivalent to a plain percent
|
|
7
|
+
* across the whole container. The result is clamped to the `[0, 100]` range.
|
|
8
|
+
*/
|
|
9
|
+
function getDayRelativePercent({ clientX, containerLeft, containerWidth, dayIndex, dayCount }) {
|
|
10
|
+
const dayWidth = containerWidth / dayCount;
|
|
11
|
+
if (dayWidth <= 0) return 0;
|
|
12
|
+
const relativeX = clientX - (containerLeft + dayIndex * dayWidth);
|
|
13
|
+
return Math.max(0, Math.min(100, relativeX / dayWidth * 100));
|
|
14
|
+
}
|
|
15
|
+
//#endregion
|
|
16
|
+
exports.getDayRelativePercent = getDayRelativePercent;
|
|
17
|
+
|
|
18
|
+
//# sourceMappingURL=get-day-relative-percent.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"get-day-relative-percent.cjs","names":[],"sources":["../../../src/utils/get-day-relative-percent/get-day-relative-percent.ts"],"sourcesContent":["interface GetDayRelativePercentInput {\n clientX: number;\n containerLeft: number;\n containerWidth: number;\n dayIndex: number;\n dayCount: number;\n}\n\n/**\n * Maps a horizontal pointer position to a percent (0-100) within a single day's\n * sub-region of a container that holds `dayCount` equal-width days side by side.\n * `dayIndex === 0` and `dayCount === 1` make it equivalent to a plain percent\n * across the whole container. The result is clamped to the `[0, 100]` range.\n */\nexport function getDayRelativePercent({\n clientX,\n containerLeft,\n containerWidth,\n dayIndex,\n dayCount,\n}: GetDayRelativePercentInput): number {\n const dayWidth = containerWidth / dayCount;\n if (dayWidth <= 0) {\n return 0;\n }\n const dayLeft = containerLeft + dayIndex * dayWidth;\n const relativeX = clientX - dayLeft;\n return Math.max(0, Math.min(100, (relativeX / dayWidth) * 100));\n}\n"],"mappings":";;;;;;;;AAcA,SAAgB,sBAAsB,EACpC,SACA,eACA,gBACA,UACA,YACqC;CACrC,MAAM,WAAW,iBAAiB;CAClC,IAAI,YAAY,GACd,OAAO;CAGT,MAAM,YAAY,WADF,gBAAgB,WAAW;CAE3C,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,KAAM,YAAY,WAAY,GAAG,CAAC;AAChE"}
|
|
@@ -35,8 +35,8 @@ function getResourcesDayViewEvents({ events, resources, date, startTime, endTime
|
|
|
35
35
|
const eventStart = dayjs(event.start);
|
|
36
36
|
const eventEnd = dayjs(event.end);
|
|
37
37
|
const isOnDay = eventStart.isSame(dayStart, "day");
|
|
38
|
-
const
|
|
39
|
-
if (isOnDay ||
|
|
38
|
+
const overlapsDay = eventStart.isBefore(dayEnd) && eventEnd.isAfter(dayStart);
|
|
39
|
+
if (isOnDay || overlapsDay) {
|
|
40
40
|
if (isOnDay && !isEventInTimeRange({
|
|
41
41
|
event,
|
|
42
42
|
startTime,
|
|
@@ -46,7 +46,21 @@ function getResourcesDayViewEvents({ events, resources, date, startTime, endTime
|
|
|
46
46
|
if (!ids.has(event.id)) ids.add(event.id);
|
|
47
47
|
else throw new Error(`[@mantine/schedule] ResourcesDayView: Duplicated event ids found: ${event.id}`);
|
|
48
48
|
if (event.display === "background") backgroundByResource[event.resourceId].push(validated);
|
|
49
|
-
else eventsByResource[event.resourceId].push(validated);
|
|
49
|
+
else if (isOnDay) eventsByResource[event.resourceId].push(validated);
|
|
50
|
+
else {
|
|
51
|
+
const clippedStart = eventStart.isBefore(dayStart) ? dayStart : eventStart;
|
|
52
|
+
const clippedEnd = eventEnd.isAfter(dayEnd) ? dayEnd : eventEnd;
|
|
53
|
+
const clippedEvent = {
|
|
54
|
+
...validated,
|
|
55
|
+
start: clippedStart.format("YYYY-MM-DD HH:mm:ss"),
|
|
56
|
+
end: clippedEnd.format("YYYY-MM-DD HH:mm:ss")
|
|
57
|
+
};
|
|
58
|
+
if (isEventInTimeRange({
|
|
59
|
+
event: clippedEvent,
|
|
60
|
+
startTime,
|
|
61
|
+
endTime
|
|
62
|
+
})) eventsByResource[event.resourceId].push(clippedEvent);
|
|
63
|
+
}
|
|
50
64
|
}
|
|
51
65
|
}
|
|
52
66
|
for (const resource of resources) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"get-resources-day-view-events.mjs","names":[],"sources":["../../../../src/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport {\n AnyDateValue,\n DayPositionedEventData,\n ScheduleEventData,\n ScheduleResourceData,\n} from '../../../types';\nimport { getDayPosition, isAllDayEvent, isEventInTimeRange, validateEvent } from '../../../utils';\nimport { getDayPositionedEvents } from '../../DayView/get-day-view-events/get-day-positioned-events';\n\ninterface GetResourcesDayViewEventsInput {\n events: ScheduleEventData[] | undefined;\n resources: ScheduleResourceData[];\n date: AnyDateValue;\n startTime?: string;\n endTime?: string;\n}\n\nexport interface ResourcesDayViewEventsResult {\n regularEvents: Record<string | number, DayPositionedEventData[]>;\n allDayEvents: Record<string | number, DayPositionedEventData[]>;\n backgroundTimedEvents: Record<string | number, DayPositionedEventData[]>;\n backgroundAllDayEvents: Record<string | number, DayPositionedEventData[]>;\n}\n\nexport function getResourcesDayViewEvents({\n events,\n resources,\n date,\n startTime,\n endTime,\n}: GetResourcesDayViewEventsInput): ResourcesDayViewEventsResult {\n const result: ResourcesDayViewEventsResult = {\n regularEvents: {},\n allDayEvents: {},\n backgroundTimedEvents: {},\n backgroundAllDayEvents: {},\n };\n\n for (const resource of resources) {\n result.regularEvents[resource.id] = [];\n result.allDayEvents[resource.id] = [];\n result.backgroundTimedEvents[resource.id] = [];\n result.backgroundAllDayEvents[resource.id] = [];\n }\n\n if (events === undefined) {\n return result;\n }\n\n const dayStart = dayjs(date).startOf('day');\n const dayEnd = dayjs(date).endOf('day');\n\n const eventsByResource: Record<string | number, ScheduleEventData[]> = {};\n const backgroundByResource: Record<string | number, ScheduleEventData[]> = {};\n\n for (const resource of resources) {\n eventsByResource[resource.id] = [];\n backgroundByResource[resource.id] = [];\n }\n\n const ids = new Set<string | number>();\n\n for (const event of events) {\n if (event.resourceId === undefined) {\n continue;\n }\n\n if (!(event.resourceId in eventsByResource)) {\n continue;\n }\n\n const eventStart = dayjs(event.start);\n const eventEnd = dayjs(event.end);\n const isOnDay = eventStart.isSame(dayStart, 'day');\n const
|
|
1
|
+
{"version":3,"file":"get-resources-day-view-events.mjs","names":[],"sources":["../../../../src/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.ts"],"sourcesContent":["import dayjs from 'dayjs';\nimport {\n AnyDateValue,\n DayPositionedEventData,\n ScheduleEventData,\n ScheduleResourceData,\n} from '../../../types';\nimport { getDayPosition, isAllDayEvent, isEventInTimeRange, validateEvent } from '../../../utils';\nimport { getDayPositionedEvents } from '../../DayView/get-day-view-events/get-day-positioned-events';\n\ninterface GetResourcesDayViewEventsInput {\n events: ScheduleEventData[] | undefined;\n resources: ScheduleResourceData[];\n date: AnyDateValue;\n startTime?: string;\n endTime?: string;\n}\n\nexport interface ResourcesDayViewEventsResult {\n regularEvents: Record<string | number, DayPositionedEventData[]>;\n allDayEvents: Record<string | number, DayPositionedEventData[]>;\n backgroundTimedEvents: Record<string | number, DayPositionedEventData[]>;\n backgroundAllDayEvents: Record<string | number, DayPositionedEventData[]>;\n}\n\nexport function getResourcesDayViewEvents({\n events,\n resources,\n date,\n startTime,\n endTime,\n}: GetResourcesDayViewEventsInput): ResourcesDayViewEventsResult {\n const result: ResourcesDayViewEventsResult = {\n regularEvents: {},\n allDayEvents: {},\n backgroundTimedEvents: {},\n backgroundAllDayEvents: {},\n };\n\n for (const resource of resources) {\n result.regularEvents[resource.id] = [];\n result.allDayEvents[resource.id] = [];\n result.backgroundTimedEvents[resource.id] = [];\n result.backgroundAllDayEvents[resource.id] = [];\n }\n\n if (events === undefined) {\n return result;\n }\n\n const dayStart = dayjs(date).startOf('day');\n const dayEnd = dayjs(date).endOf('day');\n\n const eventsByResource: Record<string | number, ScheduleEventData[]> = {};\n const backgroundByResource: Record<string | number, ScheduleEventData[]> = {};\n\n for (const resource of resources) {\n eventsByResource[resource.id] = [];\n backgroundByResource[resource.id] = [];\n }\n\n const ids = new Set<string | number>();\n\n for (const event of events) {\n if (event.resourceId === undefined) {\n continue;\n }\n\n if (!(event.resourceId in eventsByResource)) {\n continue;\n }\n\n const eventStart = dayjs(event.start);\n const eventEnd = dayjs(event.end);\n\n const isOnDay = eventStart.isSame(dayStart, 'day');\n const overlapsDay = eventStart.isBefore(dayEnd) && eventEnd.isAfter(dayStart);\n\n if (isOnDay || overlapsDay) {\n if (isOnDay && !isEventInTimeRange({ event, startTime, endTime })) {\n continue;\n }\n\n const validated = validateEvent(event);\n\n if (!ids.has(event.id)) {\n ids.add(event.id);\n } else {\n throw new Error(\n `[@mantine/schedule] ResourcesDayView: Duplicated event ids found: ${event.id}`\n );\n }\n\n if (event.display === 'background') {\n backgroundByResource[event.resourceId].push(validated);\n } else if (isOnDay) {\n eventsByResource[event.resourceId].push(validated);\n } else {\n const clippedStart = eventStart.isBefore(dayStart) ? dayStart : eventStart;\n const clippedEnd = eventEnd.isAfter(dayEnd) ? dayEnd : eventEnd;\n\n const clippedEvent = {\n ...validated,\n start: clippedStart.format('YYYY-MM-DD HH:mm:ss'),\n end: clippedEnd.format('YYYY-MM-DD HH:mm:ss'),\n };\n\n if (isEventInTimeRange({ event: clippedEvent, startTime, endTime })) {\n eventsByResource[event.resourceId].push(clippedEvent);\n }\n }\n }\n }\n\n for (const resource of resources) {\n const positioned = getDayPositionedEvents({\n events: eventsByResource[resource.id],\n startTime,\n endTime,\n date,\n });\n\n for (const event of positioned) {\n if (event.position.allDay) {\n result.allDayEvents[resource.id].push(event);\n } else {\n result.regularEvents[resource.id].push(event);\n }\n }\n\n for (const event of backgroundByResource[resource.id]) {\n const eventStart = dayjs(event.start);\n const eventEnd = dayjs(event.end);\n const clippedStart = eventStart.isBefore(dayStart) ? dayStart : eventStart;\n const clippedEnd = eventEnd.isAfter(dayEnd) ? dayEnd : eventEnd;\n\n const clippedEvent = {\n ...event,\n start: clippedStart.format('YYYY-MM-DD HH:mm:ss'),\n end: clippedEnd.format('YYYY-MM-DD HH:mm:ss'),\n };\n\n const allDay = isAllDayEvent({ event: clippedEvent, date });\n\n if (allDay) {\n result.backgroundAllDayEvents[resource.id].push({\n ...event,\n position: {\n top: 0,\n height: 100,\n allDay: true,\n width: 100,\n offset: 0,\n column: 0,\n overlaps: 1,\n },\n });\n } else {\n const { top, height } = getDayPosition({ event: clippedEvent, startTime, endTime });\n if (height <= 0) {\n continue;\n }\n result.backgroundTimedEvents[resource.id].push({\n ...event,\n position: { top, height, allDay: false, width: 100, offset: 0, column: 0, overlaps: 1 },\n });\n }\n }\n }\n\n return result;\n}\n"],"mappings":"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"}
|
|
@@ -77,6 +77,9 @@ const ResourcesSchedule = factory((_props) => {
|
|
|
77
77
|
case "week": return /* @__PURE__ */ jsx(ResourcesWeekView, {
|
|
78
78
|
...commonProps,
|
|
79
79
|
onTimeSlotClick,
|
|
80
|
+
withEventResize: mode === "static" ? false : withEventResize,
|
|
81
|
+
onEventResize,
|
|
82
|
+
canResizeEvent,
|
|
80
83
|
...weekViewProps
|
|
81
84
|
});
|
|
82
85
|
case "month": return /* @__PURE__ */ jsx(ResourcesMonthView, {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"ResourcesSchedule.mjs","names":["classes"],"sources":["../../../src/components/ResourcesSchedule/ResourcesSchedule.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n ElementProps,\n factory,\n Factory,\n MantineRadius,\n StylesApiProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { ScheduleLabelsOverride } from '../../labels';\nimport {\n DateStringValue,\n DateTimeStringValue,\n ScheduleEventData,\n ScheduleMode,\n ScheduleResourceData,\n ScheduleViewLevel,\n} from '../../types';\nimport {\n ResourcesDayView,\n ResourcesDayViewProps,\n ResourcesDayViewStylesNames,\n} from '../ResourcesDayView/ResourcesDayView';\nimport {\n ResourcesMonthView,\n ResourcesMonthViewProps,\n ResourcesMonthViewStylesNames,\n} from '../ResourcesMonthView/ResourcesMonthView';\nimport {\n ResourcesWeekView,\n ResourcesWeekViewProps,\n ResourcesWeekViewStylesNames,\n} from '../ResourcesWeekView/ResourcesWeekView';\nimport { RenderEventBody } from '../ScheduleEvent/ScheduleEvent';\nimport classes from './ResourcesSchedule.module.css';\n\nexport type ResourcesScheduleStylesNames =\n | 'root'\n | ResourcesDayViewStylesNames\n | ResourcesWeekViewStylesNames\n | ResourcesMonthViewStylesNames;\n\nexport type ResourcesScheduleViewLevel = 'day' | 'week' | 'month';\n\ntype ResourcesScheduleCommonProps =\n | 'date'\n | 'onDateChange'\n | 'resources'\n | 'events'\n | 'locale'\n | 'radius'\n | 'labels'\n | 'renderEventBody'\n | 'renderResourceLabel'\n | 'withEventsDragAndDrop'\n | 'onEventDrop'\n | 'canDragEvent'\n | 'onEventDragStart'\n | 'onEventDragEnd'\n | 'onTimeSlotClick'\n | 'onEventClick'\n | 'onDayClick'\n | 'withDragSlotSelect'\n | 'onSlotDragEnd'\n | 'view'\n | 'onViewChange'\n | 'mode'\n | 'onExternalEventDrop'\n | 'withEventResize'\n | 'onEventResize'\n | 'canResizeEvent'\n | 'recurrenceExpansionLimit';\n\ntype ResourcesScheduleViewProps<T> = Partial<Omit<T, ResourcesScheduleCommonProps>>;\n\nexport interface ResourcesScheduleProps\n extends BoxProps, StylesApiProps<ResourcesScheduleFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** List of resources to display */\n resources: ScheduleResourceData[];\n\n /** Current date to display (controlled) */\n date?: Date | DateStringValue;\n\n /** Default date (uncontrolled) */\n defaultDate?: Date | DateStringValue;\n\n /** Called when date changes via navigation */\n onDateChange?: (date: DateStringValue) => void;\n\n /** Current view level (controlled) */\n view?: ResourcesScheduleViewLevel;\n\n /** Default view level (uncontrolled) @default 'day' */\n defaultView?: ResourcesScheduleViewLevel;\n\n /** Called when view level changes */\n onViewChange?: (view: ResourcesScheduleViewLevel) => void;\n\n /** Events to display across all views */\n events?: ScheduleEventData[];\n\n /** Locale for date formatting */\n locale?: string;\n\n /** Key of theme.radius or any valid CSS value to set border-radius */\n radius?: MantineRadius;\n\n /** Labels override for i18n */\n labels?: ScheduleLabelsOverride;\n\n /** Custom event body renderer */\n renderEventBody?: RenderEventBody;\n\n /** Custom resource label renderer */\n renderResourceLabel?: (resource: ScheduleResourceData) => React.ReactNode;\n\n /** Enable drag and drop for events @default false */\n withEventsDragAndDrop?: boolean;\n\n /** Called when event is dropped */\n onEventDrop?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n resourceId?: string | number;\n }) => void;\n\n /** Function to determine if event can be dragged */\n canDragEvent?: (event: ScheduleEventData) => boolean;\n\n /** Called when any event drag starts */\n onEventDragStart?: (event: ScheduleEventData) => void;\n\n /** Called when any event drag ends */\n onEventDragEnd?: () => void;\n\n /** Called when time slot is clicked */\n onTimeSlotClick?: (data: {\n slotStart: DateTimeStringValue;\n slotEnd: DateTimeStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n resourceId?: string | number;\n }) => void;\n\n /** Called when day is clicked in month view */\n onDayClick?: (data: {\n date: DateStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n resourceId?: string | number;\n }) => void;\n\n /** Called when event is clicked */\n onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** If set, enables drag-to-select slot ranges @default false */\n withDragSlotSelect?: boolean;\n\n /** Called when a slot range is selected by dragging */\n onSlotDragEnd?: (data: {\n rangeStart: DateTimeStringValue;\n rangeEnd: DateTimeStringValue;\n resourceId?: string | number;\n }) => void;\n\n /** Interaction mode @default default */\n mode?: ScheduleMode;\n\n /** Called when an external item is dropped onto the schedule */\n onExternalEventDrop?: (data: {\n dataTransfer: DataTransfer;\n dropDateTime: DateTimeStringValue;\n resourceId?: string | number;\n }) => void;\n\n /** If true, events can be resized @default false */\n withEventResize?: boolean;\n\n /** Called when event is resized */\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be resized */\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n\n /** Max number of generated recurring instances @default 2000 */\n recurrenceExpansionLimit?: number;\n\n /** Props specific to ResourcesDayView */\n dayViewProps?: ResourcesScheduleViewProps<ResourcesDayViewProps>;\n\n /** Props specific to ResourcesWeekView */\n weekViewProps?: ResourcesScheduleViewProps<ResourcesWeekViewProps>;\n\n /** Props specific to ResourcesMonthView */\n monthViewProps?: ResourcesScheduleViewProps<ResourcesMonthViewProps>;\n}\n\nexport type ResourcesScheduleFactory = Factory<{\n props: ResourcesScheduleProps;\n ref: HTMLDivElement;\n stylesNames: ResourcesScheduleStylesNames;\n}>;\n\nconst defaultProps: Partial<ResourcesScheduleProps> = {\n defaultView: 'day',\n mode: 'default',\n};\n\nexport const ResourcesSchedule = factory<ResourcesScheduleFactory>((_props) => {\n const props = useProps('ResourcesSchedule', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n resources,\n date,\n defaultDate,\n onDateChange,\n view,\n defaultView,\n onViewChange,\n events,\n locale,\n radius,\n labels,\n renderEventBody,\n renderResourceLabel,\n withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n onTimeSlotClick,\n onDayClick,\n onEventClick,\n withDragSlotSelect,\n onSlotDragEnd,\n onExternalEventDrop,\n withEventResize,\n onEventResize,\n canResizeEvent,\n recurrenceExpansionLimit,\n mode,\n dayViewProps,\n weekViewProps,\n monthViewProps,\n __staticSelector,\n mod,\n ...others\n } = props;\n\n const getStyles = useStyles<ResourcesScheduleFactory>({\n name: __staticSelector || 'ResourcesSchedule',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n });\n\n const [_view, _setView] = useUncontrolled<ResourcesScheduleViewLevel>({\n value: view,\n defaultValue: defaultView,\n onChange: onViewChange,\n });\n\n const [_date, _setDate] = useUncontrolled<Date | DateStringValue>({\n value: date,\n defaultValue: defaultDate ?? new Date(),\n });\n\n const handleDateChange = (newDate: DateStringValue) => {\n _setDate(newDate);\n onDateChange?.(newDate);\n };\n\n const handleViewChange = (newView: ScheduleViewLevel) => {\n if (newView === 'day' || newView === 'week' || newView === 'month') {\n _setView(newView);\n }\n };\n\n const commonProps = {\n resources,\n date: _date,\n onDateChange: handleDateChange,\n onViewChange: handleViewChange,\n events,\n locale,\n radius,\n labels,\n renderEventBody,\n renderResourceLabel,\n withEventsDragAndDrop: mode === 'static' ? false : withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n onEventClick,\n withDragSlotSelect,\n onSlotDragEnd,\n onExternalEventDrop,\n recurrenceExpansionLimit,\n mode,\n };\n\n const content = (() => {\n switch (_view) {\n case 'day':\n return (\n <ResourcesDayView\n {...commonProps}\n onTimeSlotClick={onTimeSlotClick}\n withEventResize={mode === 'static' ? false : withEventResize}\n onEventResize={onEventResize}\n canResizeEvent={canResizeEvent}\n {...dayViewProps}\n />\n );\n case 'week':\n return (\n <ResourcesWeekView\n {...commonProps}\n onTimeSlotClick={onTimeSlotClick}\n {...weekViewProps}\n />\n );\n case 'month':\n return <ResourcesMonthView {...commonProps} onDayClick={onDayClick} {...monthViewProps} />;\n default:\n return null;\n }\n })();\n\n return (\n <Box {...getStyles('root')} mod={mod} {...others}>\n {content}\n </Box>\n );\n});\n\nResourcesSchedule.displayName = '@mantine/schedule/ResourcesSchedule';\nResourcesSchedule.classes = classes;\n\nexport namespace ResourcesSchedule {\n export type Props = ResourcesScheduleProps;\n export type StylesNames = ResourcesScheduleStylesNames;\n export type Factory = ResourcesScheduleFactory;\n export type ViewLevel = ResourcesScheduleViewLevel;\n}\n"],"mappings":";;;;;;;;;AAqNA,MAAM,eAAgD;CACpD,aAAa;CACb,MAAM;AACR;AAEA,MAAa,oBAAoB,SAAmC,WAAW;CAC7E,MAAM,QAAQ,SAAS,qBAAqB,cAAc,MAAM;CAChE,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,WACA,MACA,aACA,cACA,MACA,aACA,cACA,QACA,QACA,QACA,QACA,iBACA,qBACA,uBACA,aACA,cACA,kBACA,gBACA,iBACA,YACA,cACA,oBACA,eACA,qBACA,iBACA,eACA,gBACA,0BACA,MACA,cACA,eACA,gBACA,kBACA,KACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAAoC;EACpD,MAAM,oBAAoB;EAC1B,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,CAAC,OAAO,YAAY,gBAA4C;EACpE,OAAO;EACP,cAAc;EACd,UAAU;CACZ,CAAC;CAED,MAAM,CAAC,OAAO,YAAY,gBAAwC;EAChE,OAAO;EACP,cAAc,+BAAe,IAAI,KAAK;CACxC,CAAC;CAED,MAAM,oBAAoB,YAA6B;EACrD,SAAS,OAAO;EAChB,eAAe,OAAO;CACxB;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,YAAY,SAAS,YAAY,UAAU,YAAY,SACzD,SAAS,OAAO;CAEpB;CAEA,MAAM,cAAc;EAClB;EACA,MAAM;EACN,cAAc;EACd,cAAc;EACd;EACA;EACA;EACA;EACA;EACA;EACA,uBAAuB,SAAS,WAAW,QAAQ;EACnD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,MAAM,iBAAiB;EACrB,QAAQ,OAAR;GACE,KAAK,OACH,OACE,oBAAC,kBAAD;IACE,GAAI;IACa;IACjB,iBAAiB,SAAS,WAAW,QAAQ;IAC9B;IACC;IAChB,GAAI;GACL,CAAA;GAEL,KAAK,QACH,OACE,oBAAC,mBAAD;IACE,GAAI;IACa;IACjB,GAAI;GACL,CAAA;GAEL,KAAK,SACH,OAAO,oBAAC,oBAAD;IAAoB,GAAI;IAAyB;IAAY,GAAI;GAAiB,CAAA;GAC3F,SACE,OAAO;EACX;CACF,EAAA,CAAG;CAEH,OACE,oBAAC,KAAD;EAAK,GAAI,UAAU,MAAM;EAAQ;EAAK,GAAI;YACvC;CACE,CAAA;AAET,CAAC;AAED,kBAAkB,cAAc;AAChC,kBAAkB,UAAUA"}
|
|
1
|
+
{"version":3,"file":"ResourcesSchedule.mjs","names":["classes"],"sources":["../../../src/components/ResourcesSchedule/ResourcesSchedule.tsx"],"sourcesContent":["import {\n Box,\n BoxProps,\n ElementProps,\n factory,\n Factory,\n MantineRadius,\n StylesApiProps,\n useProps,\n useStyles,\n} from '@mantine/core';\nimport { useUncontrolled } from '@mantine/hooks';\nimport { ScheduleLabelsOverride } from '../../labels';\nimport {\n DateStringValue,\n DateTimeStringValue,\n ScheduleEventData,\n ScheduleMode,\n ScheduleResourceData,\n ScheduleViewLevel,\n} from '../../types';\nimport {\n ResourcesDayView,\n ResourcesDayViewProps,\n ResourcesDayViewStylesNames,\n} from '../ResourcesDayView/ResourcesDayView';\nimport {\n ResourcesMonthView,\n ResourcesMonthViewProps,\n ResourcesMonthViewStylesNames,\n} from '../ResourcesMonthView/ResourcesMonthView';\nimport {\n ResourcesWeekView,\n ResourcesWeekViewProps,\n ResourcesWeekViewStylesNames,\n} from '../ResourcesWeekView/ResourcesWeekView';\nimport { RenderEventBody } from '../ScheduleEvent/ScheduleEvent';\nimport classes from './ResourcesSchedule.module.css';\n\nexport type ResourcesScheduleStylesNames =\n | 'root'\n | ResourcesDayViewStylesNames\n | ResourcesWeekViewStylesNames\n | ResourcesMonthViewStylesNames;\n\nexport type ResourcesScheduleViewLevel = 'day' | 'week' | 'month';\n\ntype ResourcesScheduleCommonProps =\n | 'date'\n | 'onDateChange'\n | 'resources'\n | 'events'\n | 'locale'\n | 'radius'\n | 'labels'\n | 'renderEventBody'\n | 'renderResourceLabel'\n | 'withEventsDragAndDrop'\n | 'onEventDrop'\n | 'canDragEvent'\n | 'onEventDragStart'\n | 'onEventDragEnd'\n | 'onTimeSlotClick'\n | 'onEventClick'\n | 'onDayClick'\n | 'withDragSlotSelect'\n | 'onSlotDragEnd'\n | 'view'\n | 'onViewChange'\n | 'mode'\n | 'onExternalEventDrop'\n | 'withEventResize'\n | 'onEventResize'\n | 'canResizeEvent'\n | 'recurrenceExpansionLimit';\n\ntype ResourcesScheduleViewProps<T> = Partial<Omit<T, ResourcesScheduleCommonProps>>;\n\nexport interface ResourcesScheduleProps\n extends BoxProps, StylesApiProps<ResourcesScheduleFactory>, ElementProps<'div'> {\n __staticSelector?: string;\n\n /** List of resources to display */\n resources: ScheduleResourceData[];\n\n /** Current date to display (controlled) */\n date?: Date | DateStringValue;\n\n /** Default date (uncontrolled) */\n defaultDate?: Date | DateStringValue;\n\n /** Called when date changes via navigation */\n onDateChange?: (date: DateStringValue) => void;\n\n /** Current view level (controlled) */\n view?: ResourcesScheduleViewLevel;\n\n /** Default view level (uncontrolled) @default 'day' */\n defaultView?: ResourcesScheduleViewLevel;\n\n /** Called when view level changes */\n onViewChange?: (view: ResourcesScheduleViewLevel) => void;\n\n /** Events to display across all views */\n events?: ScheduleEventData[];\n\n /** Locale for date formatting */\n locale?: string;\n\n /** Key of theme.radius or any valid CSS value to set border-radius */\n radius?: MantineRadius;\n\n /** Labels override for i18n */\n labels?: ScheduleLabelsOverride;\n\n /** Custom event body renderer */\n renderEventBody?: RenderEventBody;\n\n /** Custom resource label renderer */\n renderResourceLabel?: (resource: ScheduleResourceData) => React.ReactNode;\n\n /** Enable drag and drop for events @default false */\n withEventsDragAndDrop?: boolean;\n\n /** Called when event is dropped */\n onEventDrop?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n resourceId?: string | number;\n }) => void;\n\n /** Function to determine if event can be dragged */\n canDragEvent?: (event: ScheduleEventData) => boolean;\n\n /** Called when any event drag starts */\n onEventDragStart?: (event: ScheduleEventData) => void;\n\n /** Called when any event drag ends */\n onEventDragEnd?: () => void;\n\n /** Called when time slot is clicked */\n onTimeSlotClick?: (data: {\n slotStart: DateTimeStringValue;\n slotEnd: DateTimeStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n resourceId?: string | number;\n }) => void;\n\n /** Called when day is clicked in month view */\n onDayClick?: (data: {\n date: DateStringValue;\n nativeEvent: React.MouseEvent<HTMLButtonElement>;\n resourceId?: string | number;\n }) => void;\n\n /** Called when event is clicked */\n onEventClick?: (event: ScheduleEventData, e: React.MouseEvent<HTMLButtonElement>) => void;\n\n /** If set, enables drag-to-select slot ranges @default false */\n withDragSlotSelect?: boolean;\n\n /** Called when a slot range is selected by dragging */\n onSlotDragEnd?: (data: {\n rangeStart: DateTimeStringValue;\n rangeEnd: DateTimeStringValue;\n resourceId?: string | number;\n }) => void;\n\n /** Interaction mode @default default */\n mode?: ScheduleMode;\n\n /** Called when an external item is dropped onto the schedule */\n onExternalEventDrop?: (data: {\n dataTransfer: DataTransfer;\n dropDateTime: DateTimeStringValue;\n resourceId?: string | number;\n }) => void;\n\n /** If true, events can be resized @default false */\n withEventResize?: boolean;\n\n /** Called when event is resized */\n onEventResize?: (data: {\n eventId: string | number;\n newStart: DateTimeStringValue;\n newEnd: DateTimeStringValue;\n event: ScheduleEventData;\n }) => void;\n\n /** Function to determine if event can be resized */\n canResizeEvent?: (event: ScheduleEventData) => boolean;\n\n /** Max number of generated recurring instances @default 2000 */\n recurrenceExpansionLimit?: number;\n\n /** Props specific to ResourcesDayView */\n dayViewProps?: ResourcesScheduleViewProps<ResourcesDayViewProps>;\n\n /** Props specific to ResourcesWeekView */\n weekViewProps?: ResourcesScheduleViewProps<ResourcesWeekViewProps>;\n\n /** Props specific to ResourcesMonthView */\n monthViewProps?: ResourcesScheduleViewProps<ResourcesMonthViewProps>;\n}\n\nexport type ResourcesScheduleFactory = Factory<{\n props: ResourcesScheduleProps;\n ref: HTMLDivElement;\n stylesNames: ResourcesScheduleStylesNames;\n}>;\n\nconst defaultProps: Partial<ResourcesScheduleProps> = {\n defaultView: 'day',\n mode: 'default',\n};\n\nexport const ResourcesSchedule = factory<ResourcesScheduleFactory>((_props) => {\n const props = useProps('ResourcesSchedule', defaultProps, _props);\n const {\n classNames,\n className,\n style,\n styles,\n unstyled,\n vars,\n resources,\n date,\n defaultDate,\n onDateChange,\n view,\n defaultView,\n onViewChange,\n events,\n locale,\n radius,\n labels,\n renderEventBody,\n renderResourceLabel,\n withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n onTimeSlotClick,\n onDayClick,\n onEventClick,\n withDragSlotSelect,\n onSlotDragEnd,\n onExternalEventDrop,\n withEventResize,\n onEventResize,\n canResizeEvent,\n recurrenceExpansionLimit,\n mode,\n dayViewProps,\n weekViewProps,\n monthViewProps,\n __staticSelector,\n mod,\n ...others\n } = props;\n\n const getStyles = useStyles<ResourcesScheduleFactory>({\n name: __staticSelector || 'ResourcesSchedule',\n classes,\n props,\n className,\n style,\n classNames,\n styles,\n unstyled,\n vars,\n });\n\n const [_view, _setView] = useUncontrolled<ResourcesScheduleViewLevel>({\n value: view,\n defaultValue: defaultView,\n onChange: onViewChange,\n });\n\n const [_date, _setDate] = useUncontrolled<Date | DateStringValue>({\n value: date,\n defaultValue: defaultDate ?? new Date(),\n });\n\n const handleDateChange = (newDate: DateStringValue) => {\n _setDate(newDate);\n onDateChange?.(newDate);\n };\n\n const handleViewChange = (newView: ScheduleViewLevel) => {\n if (newView === 'day' || newView === 'week' || newView === 'month') {\n _setView(newView);\n }\n };\n\n const commonProps = {\n resources,\n date: _date,\n onDateChange: handleDateChange,\n onViewChange: handleViewChange,\n events,\n locale,\n radius,\n labels,\n renderEventBody,\n renderResourceLabel,\n withEventsDragAndDrop: mode === 'static' ? false : withEventsDragAndDrop,\n onEventDrop,\n canDragEvent,\n onEventDragStart,\n onEventDragEnd,\n onEventClick,\n withDragSlotSelect,\n onSlotDragEnd,\n onExternalEventDrop,\n recurrenceExpansionLimit,\n mode,\n };\n\n const content = (() => {\n switch (_view) {\n case 'day':\n return (\n <ResourcesDayView\n {...commonProps}\n onTimeSlotClick={onTimeSlotClick}\n withEventResize={mode === 'static' ? false : withEventResize}\n onEventResize={onEventResize}\n canResizeEvent={canResizeEvent}\n {...dayViewProps}\n />\n );\n case 'week':\n return (\n <ResourcesWeekView\n {...commonProps}\n onTimeSlotClick={onTimeSlotClick}\n withEventResize={mode === 'static' ? false : withEventResize}\n onEventResize={onEventResize}\n canResizeEvent={canResizeEvent}\n {...weekViewProps}\n />\n );\n case 'month':\n return <ResourcesMonthView {...commonProps} onDayClick={onDayClick} {...monthViewProps} />;\n default:\n return null;\n }\n })();\n\n return (\n <Box {...getStyles('root')} mod={mod} {...others}>\n {content}\n </Box>\n );\n});\n\nResourcesSchedule.displayName = '@mantine/schedule/ResourcesSchedule';\nResourcesSchedule.classes = classes;\n\nexport namespace ResourcesSchedule {\n export type Props = ResourcesScheduleProps;\n export type StylesNames = ResourcesScheduleStylesNames;\n export type Factory = ResourcesScheduleFactory;\n export type ViewLevel = ResourcesScheduleViewLevel;\n}\n"],"mappings":";;;;;;;;;AAqNA,MAAM,eAAgD;CACpD,aAAa;CACb,MAAM;AACR;AAEA,MAAa,oBAAoB,SAAmC,WAAW;CAC7E,MAAM,QAAQ,SAAS,qBAAqB,cAAc,MAAM;CAChE,MAAM,EACJ,YACA,WACA,OACA,QACA,UACA,MACA,WACA,MACA,aACA,cACA,MACA,aACA,cACA,QACA,QACA,QACA,QACA,iBACA,qBACA,uBACA,aACA,cACA,kBACA,gBACA,iBACA,YACA,cACA,oBACA,eACA,qBACA,iBACA,eACA,gBACA,0BACA,MACA,cACA,eACA,gBACA,kBACA,KACA,GAAG,WACD;CAEJ,MAAM,YAAY,UAAoC;EACpD,MAAM,oBAAoB;EAC1B,SAAA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF,CAAC;CAED,MAAM,CAAC,OAAO,YAAY,gBAA4C;EACpE,OAAO;EACP,cAAc;EACd,UAAU;CACZ,CAAC;CAED,MAAM,CAAC,OAAO,YAAY,gBAAwC;EAChE,OAAO;EACP,cAAc,+BAAe,IAAI,KAAK;CACxC,CAAC;CAED,MAAM,oBAAoB,YAA6B;EACrD,SAAS,OAAO;EAChB,eAAe,OAAO;CACxB;CAEA,MAAM,oBAAoB,YAA+B;EACvD,IAAI,YAAY,SAAS,YAAY,UAAU,YAAY,SACzD,SAAS,OAAO;CAEpB;CAEA,MAAM,cAAc;EAClB;EACA,MAAM;EACN,cAAc;EACd,cAAc;EACd;EACA;EACA;EACA;EACA;EACA;EACA,uBAAuB,SAAS,WAAW,QAAQ;EACnD;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;EACA;CACF;CAEA,MAAM,iBAAiB;EACrB,QAAQ,OAAR;GACE,KAAK,OACH,OACE,oBAAC,kBAAD;IACE,GAAI;IACa;IACjB,iBAAiB,SAAS,WAAW,QAAQ;IAC9B;IACC;IAChB,GAAI;GACL,CAAA;GAEL,KAAK,QACH,OACE,oBAAC,mBAAD;IACE,GAAI;IACa;IACjB,iBAAiB,SAAS,WAAW,QAAQ;IAC9B;IACC;IAChB,GAAI;GACL,CAAA;GAEL,KAAK,SACH,OAAO,oBAAC,oBAAD;IAAoB,GAAI;IAAyB;IAAY,GAAI;GAAiB,CAAA;GAC3F,SACE,OAAO;EACX;CACF,EAAA,CAAG;CAEH,OACE,oBAAC,KAAD;EAAK,GAAI,UAAU,MAAM;EAAQ;EAAK,GAAI;YACvC;CACE,CAAA;AAET,CAAC;AAED,kBAAkB,cAAc;AAChC,kBAAkB,UAAUA"}
|
|
@@ -22,6 +22,7 @@ import { ScheduleEvent } from "../ScheduleEvent/ScheduleEvent.mjs";
|
|
|
22
22
|
import { MoreEvents } from "../MoreEvents/MoreEvents.mjs";
|
|
23
23
|
import { ScheduleHeaderBase } from "../ScheduleHeader/ScheduleHeaderBase.mjs";
|
|
24
24
|
import { getWeekLabel } from "../WeekView/get-week-label/get-week-label.mjs";
|
|
25
|
+
import { useHorizontalEventResize } from "../../hooks/use-horizontal-event-resize.mjs";
|
|
25
26
|
import { getOverlapClusters } from "../ResourcesDayView/get-overlap-clusters/get-overlap-clusters.mjs";
|
|
26
27
|
import { getResourcesWeekViewEvents } from "./get-resources-week-view-events/get-resources-week-view-events.mjs";
|
|
27
28
|
import { ResourcesWeekViewRow } from "./ResourcesWeekViewRow.mjs";
|
|
@@ -31,7 +32,7 @@ import { Box, ScrollArea, createVarsResolver, factory, getRadius, rem, useMantin
|
|
|
31
32
|
import { useInterval, useIsomorphicEffect, useMergedRef } from "@mantine/hooks";
|
|
32
33
|
import { createElement, useCallback, useMemo, useRef, useState } from "react";
|
|
33
34
|
import { useDatesContext } from "@mantine/dates";
|
|
34
|
-
import { jsx, jsxs } from "react/jsx-runtime";
|
|
35
|
+
import { Fragment, jsx, jsxs } from "react/jsx-runtime";
|
|
35
36
|
//#region packages/@mantine/schedule/src/components/ResourcesWeekView/ResourcesWeekView.tsx
|
|
36
37
|
const defaultProps = {
|
|
37
38
|
__staticSelector: "ResourcesWeekView",
|
|
@@ -45,6 +46,7 @@ const defaultProps = {
|
|
|
45
46
|
highlightBusinessHours: false,
|
|
46
47
|
businessHours: ["09:00:00", "17:00:00"],
|
|
47
48
|
withEventsDragAndDrop: false,
|
|
49
|
+
withEventResize: false,
|
|
48
50
|
withDragSlotSelect: false,
|
|
49
51
|
withWeekendDays: true,
|
|
50
52
|
withCurrentTimeBubble: true,
|
|
@@ -60,7 +62,7 @@ const varsResolver = createVarsResolver((_theme, { radius, slotWidth, rowHeight,
|
|
|
60
62
|
} }));
|
|
61
63
|
const ResourcesWeekView = factory((_props) => {
|
|
62
64
|
const props = useProps("ResourcesWeekView", defaultProps, _props);
|
|
63
|
-
const { classNames, className, style, styles, unstyled, attributes, vars, startTime, endTime, date, onDateChange, resources, intervalMinutes, slotLabelFormat, radius, startScrollDateTime, scrollAreaProps, locale, withCurrentTimeIndicator: _withCurrentTimeIndicator, withCurrentTimeBubble, __staticSelector, withHeader, onViewChange, previousControlProps, nextControlProps, todayControlProps, viewSelectProps, weekLabelFormat, renderWeekLabel, events, slotWidth, rowHeight, labels, highlightBusinessHours, businessHours, renderEventBody, renderEvent, renderResourceLabel, groups, renderGroupLabel, groupLabelWidth, withEventsDragAndDrop, onEventDrop, canDragEvent, onEventDragStart, onEventDragEnd, onTimeSlotClick, onEventClick, withDragSlotSelect, onSlotDragEnd, mode, onExternalEventDrop, recurrenceExpansionLimit, maxEventsPerTimeSlot: _maxEventsPerTimeSlot, moreEventsProps, firstDayOfWeek, weekendDays, withWeekendDays, weekdayFormat, highlightToday, ...others } = props;
|
|
65
|
+
const { classNames, className, style, styles, unstyled, attributes, vars, startTime, endTime, date, onDateChange, resources, intervalMinutes, slotLabelFormat, radius, startScrollDateTime, scrollAreaProps, locale, withCurrentTimeIndicator: _withCurrentTimeIndicator, withCurrentTimeBubble, __staticSelector, withHeader, onViewChange, previousControlProps, nextControlProps, todayControlProps, viewSelectProps, weekLabelFormat, renderWeekLabel, events, slotWidth, rowHeight, labels, highlightBusinessHours, businessHours, renderEventBody, renderEvent, renderResourceLabel, groups, renderGroupLabel, groupLabelWidth, withEventsDragAndDrop, onEventDrop, canDragEvent, onEventDragStart, onEventDragEnd, withEventResize, onEventResize, canResizeEvent, onTimeSlotClick, onEventClick, withDragSlotSelect, onSlotDragEnd, mode, onExternalEventDrop, recurrenceExpansionLimit, maxEventsPerTimeSlot: _maxEventsPerTimeSlot, moreEventsProps, firstDayOfWeek, weekendDays, withWeekendDays, weekdayFormat, highlightToday, ...others } = props;
|
|
64
66
|
const maxEventsPerTimeSlot = _maxEventsPerTimeSlot !== void 0 ? Math.max(1, _maxEventsPerTimeSlot) : void 0;
|
|
65
67
|
const getStyles = useStyles({
|
|
66
68
|
name: __staticSelector,
|
|
@@ -195,6 +197,15 @@ const ResourcesWeekView = factory((_props) => {
|
|
|
195
197
|
});
|
|
196
198
|
}
|
|
197
199
|
});
|
|
200
|
+
const eventResize = useHorizontalEventResize({
|
|
201
|
+
enabled: withEventResize,
|
|
202
|
+
mode,
|
|
203
|
+
startTime,
|
|
204
|
+
endTime,
|
|
205
|
+
intervalMinutes,
|
|
206
|
+
onEventResize,
|
|
207
|
+
canResizeEvent
|
|
208
|
+
});
|
|
198
209
|
const withDragHandlers = (withEventsDragAndDrop || !!onExternalEventDrop) && mode !== "static";
|
|
199
210
|
const handleTimeSlotClick = (resourceId, day, slotTime, e) => {
|
|
200
211
|
if (!onTimeSlotClick) return;
|
|
@@ -345,32 +356,86 @@ const ResourcesWeekView = factory((_props) => {
|
|
|
345
356
|
const visibleEvents = maxEventsPerTimeSlot !== void 0 ? allRegularEvents.filter((event) => event.position.column < maxEventsPerTimeSlot) : allRegularEvents;
|
|
346
357
|
for (const event of visibleEvents) {
|
|
347
358
|
const isDraggable = dragDrop.isDraggableEvent(event);
|
|
348
|
-
const
|
|
349
|
-
const
|
|
359
|
+
const isResizable = eventResize.isResizableEvent(event);
|
|
360
|
+
const resizePosition = eventResize.getResizePosition(event.id);
|
|
361
|
+
const isThisEventResizing = resizePosition !== null;
|
|
362
|
+
const activeEdge = isThisEventResizing && eventResize.resizingEdge ? eventResize.resizingEdge : null;
|
|
363
|
+
const effectiveTop = resizePosition ? resizePosition.left : event.position.top;
|
|
364
|
+
const effectiveHeight = resizePosition ? resizePosition.width : event.position.height;
|
|
365
|
+
const eventLeft = dayOffsetPercent + effectiveTop / 100 * dayWidthPercent;
|
|
366
|
+
const eventWidth = effectiveHeight / 100 * dayWidthPercent;
|
|
367
|
+
const eventColors = isResizable ? theme.variantColorResolver({
|
|
368
|
+
color: event.color || theme.primaryColor,
|
|
369
|
+
theme,
|
|
370
|
+
variant: event.variant || "light",
|
|
371
|
+
autoContrast: true
|
|
372
|
+
}) : null;
|
|
350
373
|
const adjustPosition = maxEventsPerTimeSlot !== void 0 && event.position.overlaps > maxEventsPerTimeSlot;
|
|
351
|
-
|
|
374
|
+
const eventDate = dayjs(day).format("YYYY-MM-DD");
|
|
375
|
+
eventNodes.push(/* @__PURE__ */ jsxs(Box, {
|
|
352
376
|
...getStyles("resourcesWeekViewEventWrapper"),
|
|
377
|
+
__vars: eventColors ? { "--event-color": eventColors.color } : void 0,
|
|
378
|
+
"data-resizing": isThisEventResizing || void 0,
|
|
353
379
|
style: {
|
|
354
380
|
left: `calc(${eventLeft}% + 1px)`,
|
|
355
381
|
top: adjustPosition ? `calc((100% - 22px) * ${event.position.column} / ${maxEventsPerTimeSlot})` : `${event.position.offset}%`,
|
|
356
382
|
width: `calc(${eventWidth}% - 2px)`,
|
|
357
383
|
height: adjustPosition ? `calc((100% - 22px) / ${maxEventsPerTimeSlot})` : `${event.position.width}%`
|
|
358
384
|
},
|
|
359
|
-
children: /* @__PURE__ */ jsx(ScheduleEvent, {
|
|
385
|
+
children: [/* @__PURE__ */ jsx(ScheduleEvent, {
|
|
360
386
|
event,
|
|
361
387
|
autoSize: true,
|
|
362
388
|
nowrap: true,
|
|
363
389
|
draggable: isDraggable,
|
|
390
|
+
isResizing: isThisEventResizing,
|
|
364
391
|
renderEventBody,
|
|
365
392
|
renderEvent,
|
|
366
393
|
radius,
|
|
367
394
|
mode,
|
|
368
|
-
onClick: onEventClick ? (e) =>
|
|
395
|
+
onClick: onEventClick ? (e) => {
|
|
396
|
+
if (!eventResize.wasResizing()) onEventClick(event, e);
|
|
397
|
+
} : void 0,
|
|
369
398
|
style: {
|
|
370
399
|
width: "100%",
|
|
371
400
|
height: "100%"
|
|
372
401
|
}
|
|
373
|
-
})
|
|
402
|
+
}), isResizable && mode !== "static" && /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx("div", {
|
|
403
|
+
...getStyles("resourcesWeekViewResizeHandle"),
|
|
404
|
+
"data-edge": "start",
|
|
405
|
+
"data-active": activeEdge === "start" || void 0,
|
|
406
|
+
onPointerDown: (e) => {
|
|
407
|
+
const container = rowSlotsContainersRef.current[resourceIndex];
|
|
408
|
+
if (container) eventResize.handleResizeStart({
|
|
409
|
+
event,
|
|
410
|
+
edge: "start",
|
|
411
|
+
container,
|
|
412
|
+
originalLeft: event.position.top,
|
|
413
|
+
originalWidth: event.position.height,
|
|
414
|
+
eventDate,
|
|
415
|
+
dayIndex,
|
|
416
|
+
dayCount: weekdays.length,
|
|
417
|
+
pointerEvent: e
|
|
418
|
+
});
|
|
419
|
+
}
|
|
420
|
+
}), /* @__PURE__ */ jsx("div", {
|
|
421
|
+
...getStyles("resourcesWeekViewResizeHandle"),
|
|
422
|
+
"data-edge": "end",
|
|
423
|
+
"data-active": activeEdge === "end" || void 0,
|
|
424
|
+
onPointerDown: (e) => {
|
|
425
|
+
const container = rowSlotsContainersRef.current[resourceIndex];
|
|
426
|
+
if (container) eventResize.handleResizeStart({
|
|
427
|
+
event,
|
|
428
|
+
edge: "end",
|
|
429
|
+
container,
|
|
430
|
+
originalLeft: event.position.top,
|
|
431
|
+
originalWidth: event.position.height,
|
|
432
|
+
eventDate,
|
|
433
|
+
dayIndex,
|
|
434
|
+
dayCount: weekdays.length,
|
|
435
|
+
pointerEvent: e
|
|
436
|
+
});
|
|
437
|
+
}
|
|
438
|
+
})] })]
|
|
374
439
|
}, `${event.id}-${day}`));
|
|
375
440
|
}
|
|
376
441
|
if (maxEventsPerTimeSlot !== void 0) {
|
|
@@ -503,7 +568,8 @@ const ResourcesWeekView = factory((_props) => {
|
|
|
503
568
|
mod: {
|
|
504
569
|
static: mode === "static",
|
|
505
570
|
"slot-dragging": slotDragSelect.isDragging,
|
|
506
|
-
|
|
571
|
+
resizing: eventResize.isResizing,
|
|
572
|
+
"event-interaction": eventResize.isResizing || dragDrop.dragContextValue.isDragging
|
|
507
573
|
},
|
|
508
574
|
...others,
|
|
509
575
|
children: [withHeader && /* @__PURE__ */ jsx(ScheduleHeaderBase, {
|