@mantine-vue/schedule 2.1.0 → 2.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.
Files changed (27) hide show
  1. package/cjs/index.cjs +2228 -1
  2. package/cjs/index.cjs.map +1 -1
  3. package/esm/index.mjs +2220 -3
  4. package/esm/index.mjs.map +1 -1
  5. package/lib/components/ResourcesDayView/ResourcesDayView.d.ts +346 -0
  6. package/lib/components/ResourcesDayView/get-overlap-clusters/get-overlap-clusters.d.ts +2 -0
  7. package/lib/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.d.ts +15 -0
  8. package/lib/components/ResourcesDayView/index.d.ts +3 -0
  9. package/lib/components/ResourcesMonthView/ResourcesMonthView.d.ts +279 -0
  10. package/lib/components/ResourcesMonthView/index.d.ts +1 -0
  11. package/lib/components/ResourcesSchedule/ResourcesSchedule.d.ts +201 -0
  12. package/lib/components/ResourcesSchedule/index.d.ts +1 -0
  13. package/lib/components/ResourcesWeekView/ResourcesWeekView.d.ts +412 -0
  14. package/lib/components/ResourcesWeekView/get-resources-week-view-events/get-resources-week-view-events.d.ts +21 -0
  15. package/lib/components/ResourcesWeekView/index.d.ts +2 -0
  16. package/lib/hooks/use-horizontal-event-resize.d.ts +200 -0
  17. package/lib/index.d.mts +4 -0
  18. package/lib/index.d.ts +4 -0
  19. package/lib/labels.d.ts +3 -0
  20. package/lib/types.d.ts +15 -0
  21. package/lib/utils/get-group-to-resource-id-map/get-group-to-resource-id-map.d.ts +2 -0
  22. package/lib/utils/get-ordered-resources/get-ordered-resources.d.ts +17 -0
  23. package/lib/utils/handle-resources-grid-key-down/handle-resources-grid-key-down.d.ts +8 -0
  24. package/lib/utils/index.d.ts +5 -0
  25. package/package.json +4 -4
  26. package/styles.css +703 -0
  27. package/styles.layer.css +703 -0
package/esm/index.mjs CHANGED
@@ -1,7 +1,7 @@
1
1
  import dayjs from "dayjs";
2
2
  import isoWeek from "dayjs/plugin/isoWeek.js";
3
3
  import * as rruleAll from "rrule";
4
- import { defineComponent, h, inject, onBeforeUnmount, onMounted, provide, ref, watch } from "vue";
4
+ import { computed, defineComponent, h, inject, nextTick, onBeforeUnmount, onMounted, provide, ref, watch } from "vue";
5
5
  import { AccordionChevron, Box, Modal, NativeSelect, Popover, ScrollArea, Text, UnstyledButton, createScopedKeydownHandler, getThemeColor, useDirection, useSafeMantineTheme } from "@mantine-vue/core";
6
6
  //#region src/labels.ts
7
7
  var DEFAULT_SCHEDULE_LABELS = {
@@ -24,7 +24,10 @@ var DEFAULT_SCHEDULE_LABELS = {
24
24
  switchToYearView: "Switch to year view",
25
25
  viewSelectLabel: "Calendar view",
26
26
  noEvents: "No events",
27
- moreLabel: (hiddenEventsCount) => `+${hiddenEventsCount} more`
27
+ moreLabel: (hiddenEventsCount) => `+${hiddenEventsCount} more`,
28
+ resource: "Resource",
29
+ resources: "Resources",
30
+ resourceSlot: "Resource time slot"
28
31
  };
29
32
  function getLabel(key, override) {
30
33
  if (override) return {
@@ -607,6 +610,85 @@ function expandRecurringEvents({ events, rangeStart, rangeEnd, expansionLimit =
607
610
  return output;
608
611
  }
609
612
  //#endregion
613
+ //#region src/utils/get-ordered-resources/get-ordered-resources.ts
614
+ function getOrderedResources(resources, groups) {
615
+ if (!groups?.length) return {
616
+ orderedResources: resources,
617
+ groupRanges: [],
618
+ resourceGroupMap: []
619
+ };
620
+ const resourceMap = new Map(resources.map((resource) => [resource.id, resource]));
621
+ const usedIds = /* @__PURE__ */ new Set();
622
+ const orderedResources = [];
623
+ const groupRanges = [];
624
+ groups.forEach((group) => {
625
+ const startIndex = orderedResources.length;
626
+ group.resourceIds.forEach((id) => {
627
+ const resource = resourceMap.get(id);
628
+ if (resource && !usedIds.has(id)) {
629
+ orderedResources.push(resource);
630
+ usedIds.add(id);
631
+ }
632
+ });
633
+ const count = orderedResources.length - startIndex;
634
+ if (count) groupRanges.push({
635
+ group,
636
+ startIndex,
637
+ count
638
+ });
639
+ });
640
+ resources.forEach((resource) => {
641
+ if (!usedIds.has(resource.id)) orderedResources.push(resource);
642
+ });
643
+ const resourceGroupMap = Array(orderedResources.length).fill(null);
644
+ groupRanges.forEach(({ group, startIndex, count }) => {
645
+ for (let index = 0; index < count; index += 1) {
646
+ const position = count === 1 ? "only" : index === 0 ? "first" : index === count - 1 ? "last" : "middle";
647
+ resourceGroupMap[startIndex + index] = {
648
+ group,
649
+ position,
650
+ count
651
+ };
652
+ }
653
+ });
654
+ return {
655
+ orderedResources,
656
+ groupRanges,
657
+ resourceGroupMap
658
+ };
659
+ }
660
+ //#endregion
661
+ //#region src/utils/get-group-to-resource-id-map/get-group-to-resource-id-map.ts
662
+ function getGroupToResourceIdMap(resources) {
663
+ return new Map(resources.map((resource) => [String(resource.id), resource.id]));
664
+ }
665
+ //#endregion
666
+ //#region src/utils/handle-resources-grid-key-down/handle-resources-grid-key-down.ts
667
+ function handleResourcesGridKeyDown({ controls, resourceIndex, slotIndex, event }) {
668
+ const delta = {
669
+ ArrowLeft: [0, -1],
670
+ ArrowRight: [0, 1],
671
+ ArrowUp: [-1, 0],
672
+ ArrowDown: [1, 0]
673
+ }[event.key];
674
+ if (!delta) return;
675
+ event.preventDefault();
676
+ let row = resourceIndex + delta[0];
677
+ let column = slotIndex + delta[1];
678
+ while (row >= 0 && row < controls.length) {
679
+ const rowControls = controls[row] || [];
680
+ if (delta[0] !== 0) column = Math.min(column, rowControls.length - 1);
681
+ if (column < 0 || column >= rowControls.length) return;
682
+ const control = rowControls[column];
683
+ if (control && !control.disabled && !control.hasAttribute("data-hidden")) {
684
+ control.focus();
685
+ return;
686
+ }
687
+ row += delta[0];
688
+ column += delta[1];
689
+ }
690
+ }
691
+ //#endregion
610
692
  //#region src/hooks/use-event-resize.ts
611
693
  function useEventResize(input) {
612
694
  const resizeState = ref(null);
@@ -4087,6 +4169,2141 @@ var Schedule = defineComponent({
4087
4169
  }
4088
4170
  });
4089
4171
  //#endregion
4172
+ //#region src/hooks/use-horizontal-event-resize.ts
4173
+ function useHorizontalEventResize(input) {
4174
+ const state = ref(null);
4175
+ let justResized = false;
4176
+ let savedUserSelect = "";
4177
+ const metrics = () => {
4178
+ const start = parseTimeString(input.startTime());
4179
+ const end = parseTimeString(input.endTime());
4180
+ const startMinutes = start.hours * 60 + start.minutes;
4181
+ const literalRange = end.hours * 60 + end.minutes - startMinutes;
4182
+ const interval = clampIntervalMinutes(input.intervalMinutes());
4183
+ const total = Math.ceil(literalRange / interval) * interval;
4184
+ return {
4185
+ startMinutes,
4186
+ literalRange,
4187
+ interval,
4188
+ total,
4189
+ minWidth: interval / total * 100
4190
+ };
4191
+ };
4192
+ const snap = (percent) => {
4193
+ const { literalRange, interval, total } = metrics();
4194
+ return Math.max(0, Math.min(literalRange, Math.round(percent / 100 * total / interval) * interval)) / total * 100;
4195
+ };
4196
+ const toDateTime = (percent, date) => {
4197
+ const { startMinutes, total } = metrics();
4198
+ const minutes = startMinutes + Math.round(snap(percent) / 100 * total);
4199
+ return `${date} ${String(Math.floor(minutes / 60)).padStart(2, "0")}:${String(minutes % 60).padStart(2, "0")}:00`;
4200
+ };
4201
+ const move = (event) => {
4202
+ if (!state.value) return;
4203
+ const rect = state.value.container.getBoundingClientRect();
4204
+ const dayWidth = rect.width / state.value.dayCount;
4205
+ const point = snap((event.clientX - rect.left - state.value.dayIndex * dayWidth) / dayWidth * 100);
4206
+ const { minWidth } = metrics();
4207
+ const current = state.value;
4208
+ if (current.edge === "end") current.currentWidth = Math.max(minWidth, point - current.originalLeft);
4209
+ else {
4210
+ const right = current.originalLeft + current.originalWidth;
4211
+ current.currentLeft = Math.min(point, right - minWidth);
4212
+ current.currentWidth = right - current.currentLeft;
4213
+ }
4214
+ state.value = { ...current };
4215
+ };
4216
+ const cleanup = () => {
4217
+ document.removeEventListener("pointermove", move);
4218
+ document.removeEventListener("pointerup", finish);
4219
+ document.body.style.userSelect = savedUserSelect;
4220
+ };
4221
+ const finish = () => {
4222
+ const current = state.value;
4223
+ if (current && (current.currentLeft !== current.originalLeft || current.currentWidth !== current.originalWidth)) input.onEventResize()?.({
4224
+ eventId: current.event.id,
4225
+ newStart: current.edge === "start" ? toDateTime(current.currentLeft, current.eventDate) : current.originalStart,
4226
+ newEnd: current.edge === "end" ? toDateTime(current.currentLeft + current.currentWidth, current.eventDate) : current.originalEnd,
4227
+ event: current.event
4228
+ });
4229
+ state.value = null;
4230
+ cleanup();
4231
+ justResized = true;
4232
+ requestAnimationFrame(() => justResized = false);
4233
+ };
4234
+ const handleResizeStart = (params) => {
4235
+ if (!input.enabled() || input.mode() === "static") return;
4236
+ params.pointerEvent.preventDefault();
4237
+ params.pointerEvent.stopPropagation();
4238
+ state.value = {
4239
+ ...params,
4240
+ currentLeft: params.originalLeft,
4241
+ currentWidth: params.originalWidth,
4242
+ originalStart: dayjs(params.event.start).format("YYYY-MM-DD HH:mm:ss"),
4243
+ originalEnd: dayjs(params.event.end).format("YYYY-MM-DD HH:mm:ss"),
4244
+ dayIndex: params.dayIndex ?? 0,
4245
+ dayCount: params.dayCount ?? 1
4246
+ };
4247
+ savedUserSelect = document.body.style.userSelect;
4248
+ document.body.style.userSelect = "none";
4249
+ document.addEventListener("pointermove", move);
4250
+ document.addEventListener("pointerup", finish);
4251
+ };
4252
+ onBeforeUnmount(cleanup);
4253
+ return {
4254
+ state,
4255
+ handleResizeStart,
4256
+ getResizePosition: (id) => state.value?.event.id === id ? {
4257
+ left: state.value.currentLeft,
4258
+ width: state.value.currentWidth
4259
+ } : null,
4260
+ isResizableEvent: (event) => input.enabled() && input.mode() !== "static" && event.display !== "background" && (input.canResizeEvent()?.(event) ?? true),
4261
+ wasResizing: () => justResized
4262
+ };
4263
+ }
4264
+ //#endregion
4265
+ //#region src/components/ResourcesDayView/get-overlap-clusters/get-overlap-clusters.ts
4266
+ function getOverlapClusters(events) {
4267
+ const sorted = [...events].sort((a, b) => a.position.top - b.position.top);
4268
+ const clusters = [];
4269
+ let current = [];
4270
+ let end = -1;
4271
+ sorted.forEach((event) => {
4272
+ if (current.length && event.position.top >= end) {
4273
+ clusters.push(current);
4274
+ current = [];
4275
+ end = -1;
4276
+ }
4277
+ current.push(event);
4278
+ end = Math.max(end, event.position.top + event.position.height);
4279
+ });
4280
+ if (current.length) clusters.push(current);
4281
+ return clusters;
4282
+ }
4283
+ //#endregion
4284
+ //#region src/components/ResourcesDayView/get-resources-day-view-events/get-resources-day-view-events.ts
4285
+ function getResourcesDayViewEvents({ events, resources, date, startTime, endTime, intervalMinutes }) {
4286
+ const result = {
4287
+ regularEvents: {},
4288
+ allDayEvents: {},
4289
+ backgroundTimedEvents: {},
4290
+ backgroundAllDayEvents: {}
4291
+ };
4292
+ resources.forEach((resource) => {
4293
+ result.regularEvents[resource.id] = [];
4294
+ result.allDayEvents[resource.id] = [];
4295
+ result.backgroundTimedEvents[resource.id] = [];
4296
+ result.backgroundAllDayEvents[resource.id] = [];
4297
+ });
4298
+ if (!events) return result;
4299
+ const dayStart = dayjs(date).startOf("day");
4300
+ const dayEnd = dayjs(date).endOf("day");
4301
+ const regular = new Map(resources.map((resource) => [resource.id, []]));
4302
+ const background = new Map(resources.map((resource) => [resource.id, []]));
4303
+ const seen = /* @__PURE__ */ new Set();
4304
+ events.forEach((event) => {
4305
+ if (event.resourceId === void 0 || !regular.has(event.resourceId)) return;
4306
+ const eventStart = dayjs(event.start);
4307
+ const eventEnd = dayjs(event.end);
4308
+ const startsOnDay = eventStart.isSame(dayStart, "day");
4309
+ if (!startsOnDay && !(eventStart.isBefore(dayEnd) && eventEnd.isAfter(dayStart))) return;
4310
+ if (startsOnDay && !isEventInTimeRange({
4311
+ event,
4312
+ startTime,
4313
+ endTime
4314
+ })) return;
4315
+ if (seen.has(event.id)) throw new Error(`[@mantine/schedule] ResourcesDayView: Duplicated event ids found: ${event.id}`);
4316
+ seen.add(event.id);
4317
+ const validated = validateEvent(event);
4318
+ if (event.display === "background") {
4319
+ background.get(event.resourceId).push(validated);
4320
+ return;
4321
+ }
4322
+ const clipped = startsOnDay ? validated : {
4323
+ ...validated,
4324
+ start: (eventStart.isBefore(dayStart) ? dayStart : eventStart).format("YYYY-MM-DD HH:mm:ss"),
4325
+ end: (eventEnd.isAfter(dayEnd) ? dayEnd : eventEnd).format("YYYY-MM-DD HH:mm:ss")
4326
+ };
4327
+ if (isEventInTimeRange({
4328
+ event: clipped,
4329
+ startTime,
4330
+ endTime
4331
+ })) regular.get(event.resourceId).push(clipped);
4332
+ });
4333
+ resources.forEach((resource) => {
4334
+ getDayPositionedEvents({
4335
+ events: regular.get(resource.id),
4336
+ startTime,
4337
+ endTime,
4338
+ date,
4339
+ intervalMinutes
4340
+ }).forEach((event) => {
4341
+ (event.position.allDay ? result.allDayEvents : result.regularEvents)[resource.id].push(event);
4342
+ });
4343
+ background.get(resource.id).forEach((event) => {
4344
+ const clippedStart = dayjs(event.start).isBefore(dayStart) ? dayStart : dayjs(event.start);
4345
+ const clippedEnd = dayjs(event.end).isAfter(dayEnd) ? dayEnd : dayjs(event.end);
4346
+ const clipped = {
4347
+ ...event,
4348
+ start: clippedStart.format("YYYY-MM-DD HH:mm:ss"),
4349
+ end: clippedEnd.format("YYYY-MM-DD HH:mm:ss")
4350
+ };
4351
+ const allDay = isAllDayEvent({
4352
+ event: clipped,
4353
+ date
4354
+ });
4355
+ const position = allDay ? {
4356
+ top: 0,
4357
+ height: 100
4358
+ } : getDayPosition({
4359
+ event: clipped,
4360
+ startTime,
4361
+ endTime,
4362
+ intervalMinutes
4363
+ });
4364
+ if (!allDay && position.height <= 0) return;
4365
+ (allDay ? result.backgroundAllDayEvents : result.backgroundTimedEvents)[resource.id].push({
4366
+ ...event,
4367
+ position: {
4368
+ ...position,
4369
+ allDay,
4370
+ width: 100,
4371
+ offset: 0,
4372
+ column: 0,
4373
+ overlaps: 1
4374
+ }
4375
+ });
4376
+ });
4377
+ });
4378
+ return result;
4379
+ }
4380
+ var ResourcesDayView_module_default = {
4381
+ resourcesDayView: "_resourcesDayView_7b9z2_1",
4382
+ resourcesDayViewRoot: "_resourcesDayViewRoot_7b9z2_22",
4383
+ resourcesDayViewScrollArea: "_resourcesDayViewScrollArea_7b9z2_30",
4384
+ resourcesDayViewInner: "_resourcesDayViewInner_7b9z2_39",
4385
+ resourcesDayViewTimeLabelsRow: "_resourcesDayViewTimeLabelsRow_7b9z2_44",
4386
+ resourcesDayViewCorner: "_resourcesDayViewCorner_7b9z2_57",
4387
+ resourcesDayViewTimeLabel: "_resourcesDayViewTimeLabel_7b9z2_44",
4388
+ resourcesDayViewRow: "_resourcesDayViewRow_7b9z2_96",
4389
+ resourcesDayViewResourceLabel: "_resourcesDayViewResourceLabel_7b9z2_100",
4390
+ resourcesDayViewGroupColumn: "_resourcesDayViewGroupColumn_7b9z2_124",
4391
+ resourcesDayViewGroupColumnEmpty: "_resourcesDayViewGroupColumnEmpty_7b9z2_125",
4392
+ resourcesDayViewRowSlots: "_resourcesDayViewRowSlots_7b9z2_153",
4393
+ resourcesDayViewRowSlot: "_resourcesDayViewRowSlot_7b9z2_153",
4394
+ resourcesDayViewCurrentTimeIndicator: "_resourcesDayViewCurrentTimeIndicator_7b9z2_231",
4395
+ resourcesDayViewCurrentTimeIndicatorLine: "_resourcesDayViewCurrentTimeIndicatorLine_7b9z2_243",
4396
+ resourcesDayViewCurrentTimeIndicatorThumb: "_resourcesDayViewCurrentTimeIndicatorThumb_7b9z2_249",
4397
+ resourcesDayViewCurrentTimeIndicatorTimeBubble: "_resourcesDayViewCurrentTimeIndicatorTimeBubble_7b9z2_259",
4398
+ resourcesDayViewBackgroundEvent: "_resourcesDayViewBackgroundEvent_7b9z2_278",
4399
+ resourcesDayViewAllDayEvent: "_resourcesDayViewAllDayEvent_7b9z2_290",
4400
+ resourcesDayViewEventWrapper: "_resourcesDayViewEventWrapper_7b9z2_296",
4401
+ resourcesDayViewResizeHandle: "_resourcesDayViewResizeHandle_7b9z2_300"
4402
+ };
4403
+ //#endregion
4404
+ //#region src/components/ResourcesDayView/ResourcesDayView.ts
4405
+ function cssSize$2(value) {
4406
+ return typeof value === "number" ? `${value}px` : value;
4407
+ }
4408
+ var ResourcesDayView = defineComponent({
4409
+ name: "ResourcesDayView",
4410
+ inheritAttrs: false,
4411
+ slots: Object,
4412
+ props: {
4413
+ date: {
4414
+ type: [String, Date],
4415
+ required: true
4416
+ },
4417
+ onDateChange: Function,
4418
+ resources: {
4419
+ type: Array,
4420
+ required: true
4421
+ },
4422
+ startTime: {
4423
+ type: String,
4424
+ default: "00:00:00"
4425
+ },
4426
+ endTime: {
4427
+ type: String,
4428
+ default: "23:59:59"
4429
+ },
4430
+ intervalMinutes: {
4431
+ type: Number,
4432
+ default: 60
4433
+ },
4434
+ slotLabelFormat: {
4435
+ type: [String, Function],
4436
+ default: "HH:mm"
4437
+ },
4438
+ radius: [String, Number],
4439
+ startScrollTime: String,
4440
+ scrollAreaProps: Object,
4441
+ locale: String,
4442
+ withCurrentTimeIndicator: {
4443
+ type: Boolean,
4444
+ default: void 0
4445
+ },
4446
+ withCurrentTimeBubble: {
4447
+ type: Boolean,
4448
+ default: true
4449
+ },
4450
+ getCurrentTime: Function,
4451
+ withHeader: {
4452
+ type: Boolean,
4453
+ default: true
4454
+ },
4455
+ onViewChange: Function,
4456
+ previousControlProps: Object,
4457
+ nextControlProps: Object,
4458
+ todayControlProps: Object,
4459
+ viewSelectProps: Object,
4460
+ headerFormat: {
4461
+ type: [String, Function],
4462
+ default: "MMMM D, YYYY"
4463
+ },
4464
+ events: Array,
4465
+ slotWidth: {
4466
+ type: [String, Number],
4467
+ default: 80
4468
+ },
4469
+ rowHeight: {
4470
+ type: [String, Number],
4471
+ default: 64
4472
+ },
4473
+ labels: Object,
4474
+ highlightBusinessHours: Boolean,
4475
+ businessHours: {
4476
+ type: Array,
4477
+ default: () => ["09:00:00", "17:00:00"]
4478
+ },
4479
+ renderEventBody: Function,
4480
+ renderEvent: Function,
4481
+ renderResourceLabel: Function,
4482
+ groups: Array,
4483
+ renderGroupLabel: Function,
4484
+ groupLabelWidth: {
4485
+ type: [String, Number],
4486
+ default: 80
4487
+ },
4488
+ withEventsDragAndDrop: Boolean,
4489
+ onEventDrop: Function,
4490
+ canDragEvent: Function,
4491
+ onEventDragStart: Function,
4492
+ onEventDragEnd: Function,
4493
+ onTimeSlotClick: Function,
4494
+ onEventClick: Function,
4495
+ withDragSlotSelect: Boolean,
4496
+ onSlotDragEnd: Function,
4497
+ mode: {
4498
+ type: String,
4499
+ default: "default"
4500
+ },
4501
+ onExternalEventDrop: Function,
4502
+ withEventResize: Boolean,
4503
+ onEventResize: Function,
4504
+ canResizeEvent: Function,
4505
+ recurrenceExpansionLimit: {
4506
+ type: Number,
4507
+ default: 2e3
4508
+ },
4509
+ maxEventsPerTimeSlot: {
4510
+ type: Number,
4511
+ default: 2
4512
+ },
4513
+ moreEventsProps: Object
4514
+ },
4515
+ setup(props, { attrs, slots }) {
4516
+ const theme = useSafeMantineTheme();
4517
+ const controls = [];
4518
+ const rootElement = ref(null);
4519
+ const rowContainers = /* @__PURE__ */ new Map();
4520
+ const dropTarget = ref(null);
4521
+ const scrolled = ref(false);
4522
+ const scrolledX = ref(false);
4523
+ const intervals = computed(() => getDayTimeIntervals({
4524
+ startTime: props.startTime,
4525
+ endTime: props.endTime,
4526
+ intervalMinutes: props.intervalMinutes
4527
+ }));
4528
+ const ordered = computed(() => getOrderedResources(props.resources, props.groups));
4529
+ const resourceIdMap = computed(() => getGroupToResourceIdMap(props.resources));
4530
+ const expandedEvents = computed(() => expandRecurringEvents({
4531
+ events: props.events,
4532
+ rangeStart: dayjs(props.date).startOf("day").toDate(),
4533
+ rangeEnd: dayjs(props.date).endOf("day").toDate(),
4534
+ expansionLimit: props.recurrenceExpansionLimit
4535
+ }));
4536
+ onMounted(async () => {
4537
+ if (!props.startScrollTime) return;
4538
+ await nextTick();
4539
+ const targetIndex = intervals.value.findIndex((interval) => interval.startTime >= props.startScrollTime);
4540
+ if (targetIndex < 0) return;
4541
+ const target = controls[0]?.[targetIndex];
4542
+ const viewport = rootElement.value?.querySelector(".mantine-ScrollArea-viewport");
4543
+ if (target && viewport) {
4544
+ viewport.scrollLeft = target.offsetLeft;
4545
+ requestAnimationFrame(() => viewport.scrollLeft = target.offsetLeft);
4546
+ }
4547
+ });
4548
+ const positioned = computed(() => getResourcesDayViewEvents({
4549
+ date: props.date,
4550
+ events: expandedEvents.value,
4551
+ resources: props.resources,
4552
+ startTime: props.startTime,
4553
+ endTime: props.endTime,
4554
+ intervalMinutes: props.intervalMinutes
4555
+ }));
4556
+ const slotSelect = useSlotDragSelect({
4557
+ enabled: () => props.withDragSlotSelect && props.mode !== "static",
4558
+ onDragEnd: () => (start, end, group) => {
4559
+ const first = intervals.value[start];
4560
+ const last = intervals.value[end];
4561
+ if (first && last) {
4562
+ const date = dayjs(props.date).format("YYYY-MM-DD");
4563
+ props.onSlotDragEnd?.({
4564
+ rangeStart: `${date} ${first.startTime}`,
4565
+ rangeEnd: `${date} ${last.endTime}`,
4566
+ resourceId: resourceIdMap.value.get(group)
4567
+ });
4568
+ }
4569
+ }
4570
+ });
4571
+ const resize = useHorizontalEventResize({
4572
+ enabled: () => props.withEventResize,
4573
+ mode: () => props.mode,
4574
+ startTime: () => props.startTime,
4575
+ endTime: () => props.endTime,
4576
+ intervalMinutes: () => props.intervalMinutes,
4577
+ onEventResize: () => props.onEventResize,
4578
+ canResizeEvent: () => props.canResizeEvent
4579
+ });
4580
+ const emitDrop = (nativeEvent, resourceId, slotIndex) => {
4581
+ nativeEvent.preventDefault();
4582
+ dropTarget.value = null;
4583
+ const interval = intervals.value[slotIndex];
4584
+ if (!interval) return;
4585
+ const target = `${dayjs(props.date).format("YYYY-MM-DD")} ${interval.startTime}`;
4586
+ const event = getDropEvent(expandedEvents.value, nativeEvent.dataTransfer);
4587
+ if (event) props.onEventDrop?.({
4588
+ ...moveEventTo(event, target),
4589
+ resourceId
4590
+ });
4591
+ else if (nativeEvent.dataTransfer) props.onExternalEventDrop?.({
4592
+ dataTransfer: nativeEvent.dataTransfer,
4593
+ dropDateTime: target,
4594
+ resourceId
4595
+ });
4596
+ };
4597
+ const getSlotIndexAtPoint = (nativeEvent, resourceIndex) => {
4598
+ const container = rowContainers.get(resourceIndex);
4599
+ if (!container || intervals.value.length === 0) return -1;
4600
+ const rect = container.getBoundingClientRect();
4601
+ if (rect.width <= 0) return -1;
4602
+ return Math.max(0, Math.min(intervals.value.length - 1, Math.floor((nativeEvent.clientX - rect.left) / rect.width * intervals.value.length)));
4603
+ };
4604
+ const renderGroupCell = (info) => {
4605
+ if (info === void 0) return null;
4606
+ if (info === null) return h(Box, { class: ResourcesDayView_module_default.resourcesDayViewGroupColumnEmpty });
4607
+ const starts = info.position === "first" || info.position === "only";
4608
+ return h(Box, {
4609
+ class: ResourcesDayView_module_default.resourcesDayViewGroupColumn,
4610
+ "data-group-position": info.position
4611
+ }, () => starts ? h("span", { style: info.count > 1 ? { transform: `translateY(calc((${info.count - 1} * (var(--resources-day-view-row-height) + 1px)) / 2))` } : void 0 }, slots.groupLabel?.({ group: info.group }) ?? props.renderGroupLabel?.(info.group) ?? info.group.label ?? void 0) : null);
4612
+ };
4613
+ return () => {
4614
+ const date = dayjs(props.date).format("YYYY-MM-DD");
4615
+ const now = dayjs(props.getCurrentTime?.() ?? /* @__PURE__ */ new Date());
4616
+ const isToday = dayjs(props.date).isSame(now, "day");
4617
+ const showIndicator = (props.withCurrentTimeIndicator ?? isToday) && isInTimeRange({
4618
+ date: now.toDate(),
4619
+ startTime: props.startTime,
4620
+ endTime: props.endTime
4621
+ });
4622
+ const indicatorOffset = getCurrentTimePosition({
4623
+ startTime: props.startTime,
4624
+ endTime: props.endTime,
4625
+ intervalMinutes: props.intervalMinutes,
4626
+ now
4627
+ });
4628
+ const currentTime = formatDate({
4629
+ date: now,
4630
+ locale: props.locale || "en",
4631
+ format: props.slotLabelFormat
4632
+ });
4633
+ const hasGroups = ordered.value.groupRanges.length > 0;
4634
+ const timeLabels = intervals.value.map((interval) => {
4635
+ const label = formatDate({
4636
+ date: `${date} ${interval.startTime}`,
4637
+ locale: props.locale || "en",
4638
+ format: props.slotLabelFormat
4639
+ });
4640
+ const mod = getBusinessHoursMod({
4641
+ time: interval.startTime,
4642
+ businessHours: props.businessHours,
4643
+ highlightBusinessHours: props.highlightBusinessHours
4644
+ });
4645
+ return h(Box, {
4646
+ key: interval.startTime,
4647
+ class: ResourcesDayView_module_default.resourcesDayViewTimeLabel,
4648
+ "data-business-hours": mod["business-hours"] || void 0,
4649
+ "data-non-business-hours": mod["non-business-hours"] || void 0
4650
+ }, () => slots.timeLabel?.({
4651
+ label,
4652
+ startTime: interval.startTime,
4653
+ endTime: interval.endTime
4654
+ }) ?? label);
4655
+ });
4656
+ const rows = ordered.value.orderedResources.map((resource, resourceIndex) => {
4657
+ const resourceEvents = positioned.value;
4658
+ const background = [...resourceEvents.backgroundTimedEvents[resource.id] || [], ...resourceEvents.backgroundAllDayEvents[resource.id] || []].map((event) => {
4659
+ const colors = theme.value.variantColorResolver({
4660
+ color: event.color || theme.value.primaryColor,
4661
+ theme: theme.value,
4662
+ variant: "light",
4663
+ autoContrast: true
4664
+ });
4665
+ return slots.backgroundEvent?.({ event }) ?? h(Box, {
4666
+ key: `bg-${event.id}`,
4667
+ class: ResourcesDayView_module_default.resourcesDayViewBackgroundEvent,
4668
+ style: {
4669
+ left: `${event.position.top}%`,
4670
+ width: `${event.position.height}%`,
4671
+ top: 0,
4672
+ height: "100%",
4673
+ "--bg-event-bg": colors.background,
4674
+ "--bg-event-color": colors.color
4675
+ }
4676
+ }, () => props.renderEventBody?.(event) ?? slots.eventBody?.({ event }) ?? event.title);
4677
+ });
4678
+ const allRegular = resourceEvents.regularEvents[resource.id] || [];
4679
+ const regular = allRegular.filter((event) => event.position.column < Math.max(1, props.maxEventsPerTimeSlot)).map((event) => {
4680
+ const colors = theme.value.variantColorResolver({
4681
+ color: event.color || theme.value.primaryColor,
4682
+ theme: theme.value,
4683
+ variant: event.variant || "light",
4684
+ autoContrast: true
4685
+ });
4686
+ const position = resize.getResizePosition(event.id);
4687
+ const left = position?.left ?? event.position.top;
4688
+ const width = position?.width ?? event.position.height;
4689
+ const isResizable = resize.isResizableEvent(event);
4690
+ const isResizing = position !== null;
4691
+ const wrapperStyle = {
4692
+ left: `calc(${left}% + 1px)`,
4693
+ width: `calc(${width}% - 2px)`,
4694
+ top: `${event.position.offset}%`,
4695
+ height: `${event.position.width}%`
4696
+ };
4697
+ return h(Box, {
4698
+ key: event.id,
4699
+ class: ResourcesDayView_module_default.resourcesDayViewEventWrapper,
4700
+ "data-resizing": isResizing || void 0,
4701
+ style: {
4702
+ ...wrapperStyle,
4703
+ "--event-color": colors.color
4704
+ }
4705
+ }, () => [h(ScheduleEvent, {
4706
+ event,
4707
+ autoSize: true,
4708
+ nowrap: true,
4709
+ radius: props.radius,
4710
+ mode: props.mode,
4711
+ renderEvent: props.renderEvent,
4712
+ renderEventBody: props.renderEventBody,
4713
+ draggable: props.withEventsDragAndDrop && props.mode !== "static" && (props.canDragEvent?.(event) ?? true),
4714
+ onEventDragStart: props.onEventDragStart,
4715
+ onEventDragEnd: props.onEventDragEnd,
4716
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => {
4717
+ if (!resize.wasResizing()) props.onEventClick?.(event, nativeEvent);
4718
+ },
4719
+ style: {
4720
+ width: "100%",
4721
+ height: "100%"
4722
+ }
4723
+ }, forwardEventSlots(slots)), isResizable ? ["start", "end"].map((edge) => h("div", {
4724
+ class: ResourcesDayView_module_default.resourcesDayViewResizeHandle,
4725
+ "data-edge": edge,
4726
+ "data-active": resize.state.value?.edge === edge || void 0,
4727
+ "aria-label": `${edge === "start" ? "Resize event start" : "Resize event end"} ${event.title}`,
4728
+ onDragstart: (nativeEvent) => nativeEvent.preventDefault(),
4729
+ onPointerdown: (pointerEvent) => {
4730
+ const container = rowContainers.get(resourceIndex);
4731
+ if (container) resize.handleResizeStart({
4732
+ event,
4733
+ edge,
4734
+ container,
4735
+ originalLeft: event.position.top,
4736
+ originalWidth: event.position.height,
4737
+ eventDate: date,
4738
+ pointerEvent
4739
+ });
4740
+ }
4741
+ })) : null]);
4742
+ });
4743
+ const allDay = (resourceEvents.allDayEvents[resource.id] || []).map((event, index) => h(Box, {
4744
+ key: `all-${event.id}`,
4745
+ class: ResourcesDayView_module_default.resourcesDayViewAllDayEvent,
4746
+ style: { top: `calc(${index} * (var(--resources-day-view-all-day-height) + 2px) + 2px)` }
4747
+ }, () => slots.allDayEvent?.({ event }) ?? h(ScheduleEvent, {
4748
+ event,
4749
+ autoSize: true,
4750
+ nowrap: true,
4751
+ radius: props.radius,
4752
+ mode: props.mode,
4753
+ renderEvent: props.renderEvent,
4754
+ renderEventBody: props.renderEventBody,
4755
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onEventClick?.(event, nativeEvent),
4756
+ style: {
4757
+ width: "100%",
4758
+ height: "100%"
4759
+ }
4760
+ }, forwardEventSlots(slots))));
4761
+ const more = getOverlapClusters(allRegular).filter((cluster) => cluster.some((event) => event.position.column >= props.maxEventsPerTimeSlot)).map((cluster) => {
4762
+ const hiddenCount = cluster.filter((event) => event.position.column >= props.maxEventsPerTimeSlot).length;
4763
+ const left = Math.min(...cluster.map((event) => event.position.top));
4764
+ const right = Math.max(...cluster.map((event) => event.position.top + event.position.height));
4765
+ return slots.moreEvents?.({
4766
+ events: cluster,
4767
+ hiddenCount
4768
+ }) ?? h(MoreEvents, {
4769
+ ...props.moreEventsProps,
4770
+ key: `more-${cluster[0].id}`,
4771
+ events: cluster,
4772
+ moreEventsCount: hiddenCount,
4773
+ mode: props.mode,
4774
+ labels: props.labels,
4775
+ renderEventBody: props.renderEventBody,
4776
+ renderEvent: props.renderEvent,
4777
+ onEventClick: props.onEventClick,
4778
+ style: {
4779
+ position: "absolute",
4780
+ left: `calc(${left}% + 1px)`,
4781
+ width: `calc(${right - left}% - 2px)`,
4782
+ bottom: 0,
4783
+ height: "22px",
4784
+ zIndex: 4
4785
+ }
4786
+ }, forwardEventSlots(slots));
4787
+ });
4788
+ const slotGroup = String(resource.id);
4789
+ const buttons = intervals.value.map((interval, slotIndex) => {
4790
+ const mod = getBusinessHoursMod({
4791
+ time: interval.startTime,
4792
+ businessHours: props.businessHours,
4793
+ highlightBusinessHours: props.highlightBusinessHours
4794
+ });
4795
+ return h(UnstyledButton, {
4796
+ key: interval.startTime,
4797
+ ref: (element) => {
4798
+ const button = element?.$el ?? element;
4799
+ controls[resourceIndex] ||= [];
4800
+ controls[resourceIndex][slotIndex] = button instanceof HTMLButtonElement ? button : void 0;
4801
+ },
4802
+ class: ResourcesDayView_module_default.resourcesDayViewRowSlot,
4803
+ "data-business-hours": mod["business-hours"] || void 0,
4804
+ "data-non-business-hours": mod["non-business-hours"] || void 0,
4805
+ "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.slotIndex === slotIndex ? true : void 0,
4806
+ "data-drag-selected": slotSelect.isSlotSelected(slotIndex, slotGroup) || void 0,
4807
+ "data-static": props.mode === "static" || void 0,
4808
+ "data-drag-slot-index": props.withDragSlotSelect ? slotIndex : void 0,
4809
+ "data-drag-slot-group": props.withDragSlotSelect ? slotGroup : void 0,
4810
+ "aria-label": `${getLabel("resourceSlot", props.labels)} ${String(resource.label)} ${date} ${interval.startTime} - ${interval.endTime}`,
4811
+ tabindex: props.mode === "static" ? -1 : resourceIndex === 0 && slotIndex === 0 ? 0 : -1,
4812
+ onKeydown: (event) => handleResourcesGridKeyDown({
4813
+ controls,
4814
+ resourceIndex,
4815
+ slotIndex,
4816
+ event
4817
+ }),
4818
+ onPointerdown: props.mode === "static" ? void 0 : (event) => slotSelect.handleSlotPointerDown(event, slotIndex, slotGroup),
4819
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onTimeSlotClick?.({
4820
+ slotStart: `${date} ${interval.startTime}`,
4821
+ slotEnd: `${date} ${interval.endTime}`,
4822
+ nativeEvent,
4823
+ resourceId: resource.id
4824
+ })
4825
+ }, () => slots.timeSlot?.({
4826
+ resource,
4827
+ startTime: interval.startTime,
4828
+ endTime: interval.endTime
4829
+ }));
4830
+ });
4831
+ const groupInfo = hasGroups ? ordered.value.resourceGroupMap[resourceIndex] : void 0;
4832
+ const allDayCount = resourceEvents.allDayEvents[resource.id]?.length || 0;
4833
+ return h(Box, {
4834
+ key: resource.id,
4835
+ class: ResourcesDayView_module_default.resourcesDayViewRow
4836
+ }, () => [
4837
+ renderGroupCell(groupInfo),
4838
+ h(Box, {
4839
+ class: ResourcesDayView_module_default.resourcesDayViewResourceLabel,
4840
+ "data-scrolled-x": scrolledX.value || void 0,
4841
+ "data-has-groups": groupInfo !== void 0 || void 0
4842
+ }, () => slots.resourceLabel?.({ resource }) ?? props.renderResourceLabel?.(resource) ?? resource.label),
4843
+ h(Box, {
4844
+ class: ResourcesDayView_module_default.resourcesDayViewRowSlots,
4845
+ ref: (element) => {
4846
+ const node = element?.$el ?? element;
4847
+ if (node instanceof HTMLElement) rowContainers.set(resourceIndex, node);
4848
+ },
4849
+ style: allDayCount ? { minHeight: `max(var(--resources-day-view-row-height), calc(${allDayCount} * (var(--resources-day-view-all-day-height) + 2px) + 4px))` } : void 0,
4850
+ onDragover: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
4851
+ if (props.mode === "static") return;
4852
+ nativeEvent.preventDefault();
4853
+ const slotIndex = getSlotIndexAtPoint(nativeEvent, resourceIndex);
4854
+ if (slotIndex >= 0 && (dropTarget.value?.resourceId !== resource.id || dropTarget.value.slotIndex !== slotIndex)) dropTarget.value = {
4855
+ resourceId: resource.id,
4856
+ slotIndex
4857
+ };
4858
+ } : void 0,
4859
+ onDragleave: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
4860
+ const related = nativeEvent.relatedTarget;
4861
+ const current = nativeEvent.currentTarget;
4862
+ if (!(related instanceof Node) || !(current instanceof HTMLElement) || !current.contains(related)) dropTarget.value = null;
4863
+ } : void 0,
4864
+ onDrop: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
4865
+ const slotIndex = getSlotIndexAtPoint(nativeEvent, resourceIndex);
4866
+ if (slotIndex >= 0) emitDrop(nativeEvent, resource.id, slotIndex);
4867
+ } : void 0
4868
+ }, () => [
4869
+ ...background,
4870
+ ...allDay,
4871
+ ...regular,
4872
+ ...more,
4873
+ ...buttons
4874
+ ])
4875
+ ]);
4876
+ });
4877
+ const headerLabel = formatDate({
4878
+ date: props.date,
4879
+ locale: props.locale || "en",
4880
+ format: props.headerFormat
4881
+ });
4882
+ const header = props.withHeader ? slots.header?.({
4883
+ date,
4884
+ label: headerLabel
4885
+ }) ?? h(ScheduleHeaderBase, {
4886
+ view: "day",
4887
+ navigationHandlers: {
4888
+ previous: () => dayjs(props.date).subtract(1, "day").format("YYYY-MM-DD"),
4889
+ next: () => dayjs(props.date).add(1, "day").format("YYYY-MM-DD"),
4890
+ today: () => now.format("YYYY-MM-DD")
4891
+ },
4892
+ control: { title: headerLabel },
4893
+ labels: props.labels,
4894
+ onDateChange: props.onDateChange,
4895
+ onViewChange: props.onViewChange,
4896
+ previousControlProps: props.previousControlProps,
4897
+ nextControlProps: props.nextControlProps,
4898
+ todayControlProps: props.todayControlProps,
4899
+ viewSelectProps: {
4900
+ views: [
4901
+ "day",
4902
+ "week",
4903
+ "month"
4904
+ ],
4905
+ ...props.viewSelectProps
4906
+ }
4907
+ }) : null;
4908
+ const indicator = showIndicator ? slots.currentTimeIndicator?.({
4909
+ time: currentTime,
4910
+ offset: indicatorOffset
4911
+ }) ?? h(Box, {
4912
+ class: ResourcesDayView_module_default.resourcesDayViewCurrentTimeIndicator,
4913
+ style: {
4914
+ "--indicator-left-offset": hasGroups ? `calc(var(--resources-day-view-resource-label-width) + var(--resources-day-view-group-label-width) + (100% - var(--resources-day-view-resource-label-width) - var(--resources-day-view-group-label-width)) * ${indicatorOffset} / 100)` : `calc(var(--resources-day-view-resource-label-width) + (100% - var(--resources-day-view-resource-label-width)) * ${indicatorOffset} / 100)`,
4915
+ "--_time-bubble-width": String(currentTime).toLowerCase().includes("m") ? "64px" : "46px"
4916
+ }
4917
+ }, () => [props.withCurrentTimeBubble ? h("div", { class: ResourcesDayView_module_default.resourcesDayViewCurrentTimeIndicatorTimeBubble }, currentTime) : h("div", { class: ResourcesDayView_module_default.resourcesDayViewCurrentTimeIndicatorThumb }), h("div", { class: ResourcesDayView_module_default.resourcesDayViewCurrentTimeIndicatorLine })]) : null;
4918
+ return h(Box, {
4919
+ ...attrs,
4920
+ ref: (element) => {
4921
+ const node = element?.$el ?? element;
4922
+ rootElement.value = node instanceof HTMLElement ? node : null;
4923
+ },
4924
+ class: [ResourcesDayView_module_default.resourcesDayView, attrs.class],
4925
+ style: [{
4926
+ "--resources-day-view-radius": resolveScheduleRadius(props.radius),
4927
+ "--resources-day-view-slot-width": cssSize$2(props.slotWidth),
4928
+ "--resources-day-view-row-height": cssSize$2(props.rowHeight),
4929
+ "--resources-day-view-group-label-width": cssSize$2(props.groupLabelWidth)
4930
+ }, attrs.style],
4931
+ "data-resizing": resize.state.value ? true : void 0,
4932
+ "data-event-interaction": resize.state.value ? true : void 0
4933
+ }, () => [header, h(Box, { class: ResourcesDayView_module_default.resourcesDayViewRoot }, () => h(ScrollArea, {
4934
+ scrollbarSize: 4,
4935
+ ...props.scrollAreaProps,
4936
+ class: ResourcesDayView_module_default.resourcesDayViewScrollArea,
4937
+ onScrollPositionChange: (position) => {
4938
+ scrolled.value = position.y !== 0;
4939
+ scrolledX.value = position.x !== 0;
4940
+ }
4941
+ }, () => h("div", { class: ResourcesDayView_module_default.resourcesDayViewInner }, [
4942
+ h(Box, {
4943
+ class: ResourcesDayView_module_default.resourcesDayViewTimeLabelsRow,
4944
+ "data-scrolled": scrolled.value || void 0
4945
+ }, () => [h("div", {
4946
+ class: ResourcesDayView_module_default.resourcesDayViewCorner,
4947
+ style: hasGroups ? {
4948
+ flexBasis: "calc(var(--resources-day-view-resource-label-width) + var(--resources-day-view-group-label-width))",
4949
+ minWidth: "calc(var(--resources-day-view-resource-label-width) + var(--resources-day-view-group-label-width))"
4950
+ } : void 0
4951
+ }, slots.corner?.({ resources: ordered.value.orderedResources }) ?? getLabel("resources", props.labels)), ...timeLabels]),
4952
+ ...rows,
4953
+ indicator
4954
+ ])))]);
4955
+ };
4956
+ }
4957
+ });
4958
+ //#endregion
4959
+ //#region src/components/ResourcesWeekView/get-resources-week-view-events/get-resources-week-view-events.ts
4960
+ function assignAllDayRows(bars) {
4961
+ const rowEnds = [];
4962
+ [...bars].sort((a, b) => a.startDayIndex - b.startDayIndex || a.endDayIndex - b.endDayIndex).forEach((bar) => {
4963
+ let row = 0;
4964
+ while (row < rowEnds.length && rowEnds[row] >= bar.startDayIndex) row += 1;
4965
+ rowEnds[row] = bar.endDayIndex;
4966
+ bar.row = row;
4967
+ });
4968
+ }
4969
+ function getResourcesWeekViewEvents({ events, resources, weekdays, startTime, endTime, intervalMinutes, expansionLimit }) {
4970
+ const expanded = expandRecurringEvents({
4971
+ events,
4972
+ rangeStart: dayjs(weekdays[0]).startOf("day").toDate(),
4973
+ rangeEnd: dayjs(weekdays.at(-1)).endOf("day").toDate(),
4974
+ expansionLimit
4975
+ });
4976
+ const seen = /* @__PURE__ */ new Set();
4977
+ expanded?.forEach((event) => {
4978
+ if (seen.has(event.id)) throw new Error(`[@mantine/schedule] ResourcesWeekView: Duplicated event ids found: ${event.id}`);
4979
+ seen.add(event.id);
4980
+ });
4981
+ const byDay = {};
4982
+ const assigned = /* @__PURE__ */ new Set();
4983
+ const spanning = (event) => event.display !== "background" && isMultidayEvent(event);
4984
+ weekdays.forEach((day) => {
4985
+ const dayEvents = expanded?.filter((event) => {
4986
+ if (assigned.has(event.id) || spanning(event)) return false;
4987
+ const start = dayjs(event.start);
4988
+ const dayStart = dayjs(day).startOf("day");
4989
+ if (start.isSame(dayStart, "day")) {
4990
+ assigned.add(event.id);
4991
+ return true;
4992
+ }
4993
+ return event.display === "background" && start.isBefore(dayjs(day).endOf("day")) && dayjs(event.end).isAfter(dayStart);
4994
+ });
4995
+ byDay[day] = getResourcesDayViewEvents({
4996
+ events: dayEvents,
4997
+ resources,
4998
+ date: day,
4999
+ startTime,
5000
+ endTime,
5001
+ intervalMinutes
5002
+ });
5003
+ });
5004
+ const allDayBars = {};
5005
+ resources.forEach((resource) => allDayBars[resource.id] = []);
5006
+ weekdays.forEach((day, dayIndex) => {
5007
+ resources.forEach((resource) => {
5008
+ byDay[day].allDayEvents[resource.id]?.forEach((event) => allDayBars[resource.id].push({
5009
+ event,
5010
+ startDayIndex: dayIndex,
5011
+ endDayIndex: dayIndex,
5012
+ row: 0
5013
+ }));
5014
+ });
5015
+ });
5016
+ expanded?.forEach((event) => {
5017
+ if (!spanning(event) || event.resourceId === void 0 || !(event.resourceId in allDayBars)) return;
5018
+ const days = calculateEventDays({
5019
+ event,
5020
+ weekDays: weekdays,
5021
+ actualEndDate: getEventEndDate(event)
5022
+ });
5023
+ if (!days.length) return;
5024
+ allDayBars[event.resourceId].push({
5025
+ event,
5026
+ startDayIndex: weekdays.indexOf(days[0]),
5027
+ endDayIndex: weekdays.indexOf(days.at(-1)),
5028
+ row: 0
5029
+ });
5030
+ });
5031
+ resources.forEach((resource) => assignAllDayRows(allDayBars[resource.id]));
5032
+ return {
5033
+ byDay,
5034
+ allDayBars
5035
+ };
5036
+ }
5037
+ var ResourcesWeekView_module_default = {
5038
+ resourcesWeekView: "_resourcesWeekView_jzd1a_1",
5039
+ resourcesWeekViewRoot: "_resourcesWeekViewRoot_jzd1a_19",
5040
+ resourcesWeekViewScrollArea: "_resourcesWeekViewScrollArea_jzd1a_26",
5041
+ resourcesWeekViewInner: "_resourcesWeekViewInner_jzd1a_34",
5042
+ resourcesWeekViewHeaderRows: "_resourcesWeekViewHeaderRows_jzd1a_39",
5043
+ resourcesWeekViewCorner: "_resourcesWeekViewCorner_jzd1a_48",
5044
+ resourcesWeekViewHeaderContent: "_resourcesWeekViewHeaderContent_jzd1a_63",
5045
+ resourcesWeekViewDayLabelsRow: "_resourcesWeekViewDayLabelsRow_jzd1a_67",
5046
+ resourcesWeekViewDayLabel: "_resourcesWeekViewDayLabel_jzd1a_67",
5047
+ resourcesWeekViewTimeLabelsRow: "_resourcesWeekViewTimeLabelsRow_jzd1a_94",
5048
+ resourcesWeekViewTimeLabel: "_resourcesWeekViewTimeLabel_jzd1a_94",
5049
+ resourcesWeekViewRow: "_resourcesWeekViewRow_jzd1a_121",
5050
+ resourcesWeekViewResourceLabel: "_resourcesWeekViewResourceLabel_jzd1a_125",
5051
+ resourcesWeekViewGroupColumn: "_resourcesWeekViewGroupColumn_jzd1a_149",
5052
+ resourcesWeekViewGroupColumnEmpty: "_resourcesWeekViewGroupColumnEmpty_jzd1a_150",
5053
+ resourcesWeekViewRowSlots: "_resourcesWeekViewRowSlots_jzd1a_178",
5054
+ resourcesWeekViewRowSlot: "_resourcesWeekViewRowSlot_jzd1a_178",
5055
+ resourcesWeekViewBackgroundEvent: "_resourcesWeekViewBackgroundEvent_jzd1a_250",
5056
+ resourcesWeekViewAllDayEvent: "_resourcesWeekViewAllDayEvent_jzd1a_262",
5057
+ resourcesWeekViewEventWrapper: "_resourcesWeekViewEventWrapper_jzd1a_267",
5058
+ resourcesWeekViewResizeHandle: "_resourcesWeekViewResizeHandle_jzd1a_271",
5059
+ resourcesWeekViewCurrentTimeIndicator: "_resourcesWeekViewCurrentTimeIndicator_jzd1a_312",
5060
+ resourcesWeekViewCurrentTimeIndicatorLine: "_resourcesWeekViewCurrentTimeIndicatorLine_jzd1a_324",
5061
+ resourcesWeekViewCurrentTimeIndicatorThumb: "_resourcesWeekViewCurrentTimeIndicatorThumb_jzd1a_330",
5062
+ resourcesWeekViewCurrentTimeIndicatorTimeBubble: "_resourcesWeekViewCurrentTimeIndicatorTimeBubble_jzd1a_340"
5063
+ };
5064
+ //#endregion
5065
+ //#region src/components/ResourcesWeekView/ResourcesWeekView.ts
5066
+ function cssSize$1(value) {
5067
+ return typeof value === "number" ? `${value}px` : value;
5068
+ }
5069
+ var ResourcesWeekView = defineComponent({
5070
+ name: "ResourcesWeekView",
5071
+ inheritAttrs: false,
5072
+ slots: Object,
5073
+ props: {
5074
+ date: {
5075
+ type: [String, Date],
5076
+ required: true
5077
+ },
5078
+ onDateChange: Function,
5079
+ resources: {
5080
+ type: Array,
5081
+ required: true
5082
+ },
5083
+ startTime: {
5084
+ type: String,
5085
+ default: "00:00:00"
5086
+ },
5087
+ endTime: {
5088
+ type: String,
5089
+ default: "23:59:59"
5090
+ },
5091
+ intervalMinutes: {
5092
+ type: Number,
5093
+ default: 60
5094
+ },
5095
+ slotLabelFormat: {
5096
+ type: [String, Function],
5097
+ default: "HH:mm"
5098
+ },
5099
+ radius: [String, Number],
5100
+ startScrollDateTime: String,
5101
+ scrollAreaProps: Object,
5102
+ locale: String,
5103
+ withCurrentTimeIndicator: {
5104
+ type: Boolean,
5105
+ default: void 0
5106
+ },
5107
+ withCurrentTimeBubble: {
5108
+ type: Boolean,
5109
+ default: true
5110
+ },
5111
+ getCurrentTime: Function,
5112
+ withHeader: {
5113
+ type: Boolean,
5114
+ default: true
5115
+ },
5116
+ onViewChange: Function,
5117
+ previousControlProps: Object,
5118
+ nextControlProps: Object,
5119
+ todayControlProps: Object,
5120
+ viewSelectProps: Object,
5121
+ weekLabelFormat: {
5122
+ type: [String, Function],
5123
+ default: "MMM DD"
5124
+ },
5125
+ renderWeekLabel: Function,
5126
+ events: Array,
5127
+ slotWidth: {
5128
+ type: [String, Number],
5129
+ default: 60
5130
+ },
5131
+ rowHeight: {
5132
+ type: [String, Number],
5133
+ default: 64
5134
+ },
5135
+ labels: Object,
5136
+ highlightBusinessHours: Boolean,
5137
+ businessHours: {
5138
+ type: Array,
5139
+ default: () => ["09:00:00", "17:00:00"]
5140
+ },
5141
+ renderEventBody: Function,
5142
+ renderEvent: Function,
5143
+ renderResourceLabel: Function,
5144
+ groups: Array,
5145
+ renderGroupLabel: Function,
5146
+ groupLabelWidth: {
5147
+ type: [String, Number],
5148
+ default: 80
5149
+ },
5150
+ withEventsDragAndDrop: Boolean,
5151
+ onEventDrop: Function,
5152
+ canDragEvent: Function,
5153
+ onEventDragStart: Function,
5154
+ onEventDragEnd: Function,
5155
+ onTimeSlotClick: Function,
5156
+ onEventClick: Function,
5157
+ withDragSlotSelect: Boolean,
5158
+ onSlotDragEnd: Function,
5159
+ mode: {
5160
+ type: String,
5161
+ default: "default"
5162
+ },
5163
+ onExternalEventDrop: Function,
5164
+ withEventResize: Boolean,
5165
+ onEventResize: Function,
5166
+ canResizeEvent: Function,
5167
+ recurrenceExpansionLimit: {
5168
+ type: Number,
5169
+ default: 2e3
5170
+ },
5171
+ maxEventsPerTimeSlot: {
5172
+ type: Number,
5173
+ default: 2
5174
+ },
5175
+ moreEventsProps: Object,
5176
+ firstDayOfWeek: {
5177
+ type: Number,
5178
+ default: 1
5179
+ },
5180
+ weekendDays: {
5181
+ type: Array,
5182
+ default: () => [0, 6]
5183
+ },
5184
+ withWeekendDays: {
5185
+ type: Boolean,
5186
+ default: true
5187
+ },
5188
+ weekdayFormat: {
5189
+ type: [String, Function],
5190
+ default: "ddd D"
5191
+ },
5192
+ highlightToday: {
5193
+ type: Boolean,
5194
+ default: true
5195
+ }
5196
+ },
5197
+ setup(props, { attrs, slots }) {
5198
+ const theme = useSafeMantineTheme();
5199
+ const controls = [];
5200
+ const rootElement = ref(null);
5201
+ const rowContainers = /* @__PURE__ */ new Map();
5202
+ const dropTarget = ref(null);
5203
+ const scrolledX = ref(false);
5204
+ const intervals = computed(() => getDayTimeIntervals({
5205
+ startTime: props.startTime,
5206
+ endTime: props.endTime,
5207
+ intervalMinutes: props.intervalMinutes
5208
+ }));
5209
+ const weekdays = computed(() => getWeekDays({
5210
+ week: props.date,
5211
+ firstDayOfWeek: props.firstDayOfWeek,
5212
+ weekendDays: props.weekendDays,
5213
+ withWeekendDays: props.withWeekendDays
5214
+ }).map((day) => dayjs(day).format("YYYY-MM-DD")));
5215
+ const ordered = computed(() => getOrderedResources(props.resources, props.groups));
5216
+ const resourceIdMap = computed(() => getGroupToResourceIdMap(props.resources));
5217
+ const weekEvents = computed(() => getResourcesWeekViewEvents({
5218
+ events: props.events,
5219
+ resources: props.resources,
5220
+ weekdays: weekdays.value,
5221
+ startTime: props.startTime,
5222
+ endTime: props.endTime,
5223
+ intervalMinutes: props.intervalMinutes,
5224
+ expansionLimit: props.recurrenceExpansionLimit
5225
+ }));
5226
+ onMounted(async () => {
5227
+ if (!props.startScrollDateTime) return;
5228
+ await nextTick();
5229
+ const target = dayjs(props.startScrollDateTime);
5230
+ const dayIndex = weekdays.value.findIndex((day) => dayjs(day).isSame(target, "day"));
5231
+ if (dayIndex < 0) return;
5232
+ const targetTime = target.format("HH:mm:ss");
5233
+ const intervalIndex = intervals.value.findIndex((interval) => interval.startTime >= targetTime);
5234
+ if (intervalIndex < 0) return;
5235
+ const flatIndex = dayIndex * intervals.value.length + intervalIndex;
5236
+ const targetSlot = controls[0]?.[flatIndex];
5237
+ const viewport = rootElement.value?.querySelector(".mantine-ScrollArea-viewport");
5238
+ if (targetSlot && viewport) {
5239
+ viewport.scrollLeft = targetSlot.offsetLeft;
5240
+ requestAnimationFrame(() => viewport.scrollLeft = targetSlot.offsetLeft);
5241
+ }
5242
+ });
5243
+ const slotSelect = useSlotDragSelect({
5244
+ enabled: () => props.withDragSlotSelect && props.mode !== "static",
5245
+ onDragEnd: () => (start, end, group) => {
5246
+ const count = intervals.value.length;
5247
+ const startDay = Math.floor(start / count);
5248
+ const endDay = Math.floor(end / count);
5249
+ const first = intervals.value[start % count];
5250
+ const last = intervals.value[end % count];
5251
+ if (first && last && weekdays.value[startDay] && weekdays.value[endDay]) props.onSlotDragEnd?.({
5252
+ rangeStart: `${dayjs(weekdays.value[startDay]).format("YYYY-MM-DD")} ${first.startTime}`,
5253
+ rangeEnd: `${dayjs(weekdays.value[endDay]).format("YYYY-MM-DD")} ${last.endTime}`,
5254
+ resourceId: resourceIdMap.value.get(group)
5255
+ });
5256
+ }
5257
+ });
5258
+ const resize = useHorizontalEventResize({
5259
+ enabled: () => props.withEventResize,
5260
+ mode: () => props.mode,
5261
+ startTime: () => props.startTime,
5262
+ endTime: () => props.endTime,
5263
+ intervalMinutes: () => props.intervalMinutes,
5264
+ onEventResize: () => props.onEventResize,
5265
+ canResizeEvent: () => props.canResizeEvent
5266
+ });
5267
+ const emitDrop = (nativeEvent, resourceId, flatIndex) => {
5268
+ nativeEvent.preventDefault();
5269
+ dropTarget.value = null;
5270
+ const count = intervals.value.length;
5271
+ const day = weekdays.value[Math.floor(flatIndex / count)];
5272
+ const interval = intervals.value[flatIndex % count];
5273
+ if (!day || !interval) return;
5274
+ const target = `${dayjs(day).format("YYYY-MM-DD")} ${interval.startTime}`;
5275
+ const event = getDropEvent(props.events, nativeEvent.dataTransfer);
5276
+ if (event) props.onEventDrop?.({
5277
+ ...moveEventTo(event, target),
5278
+ resourceId
5279
+ });
5280
+ else if (nativeEvent.dataTransfer) props.onExternalEventDrop?.({
5281
+ dataTransfer: nativeEvent.dataTransfer,
5282
+ dropDateTime: target,
5283
+ resourceId
5284
+ });
5285
+ };
5286
+ const getFlatIndexAtPoint = (nativeEvent, resourceIndex) => {
5287
+ const container = rowContainers.get(resourceIndex);
5288
+ const count = intervals.value.length * weekdays.value.length;
5289
+ if (!container || count === 0) return -1;
5290
+ const rect = container.getBoundingClientRect();
5291
+ if (rect.width <= 0) return -1;
5292
+ return Math.max(0, Math.min(count - 1, Math.floor((nativeEvent.clientX - rect.left) / rect.width * count)));
5293
+ };
5294
+ const groupCell = (info) => {
5295
+ if (info === void 0) return null;
5296
+ if (info === null) return h(Box, { class: ResourcesWeekView_module_default.resourcesWeekViewGroupColumnEmpty });
5297
+ const starts = info.position === "first" || info.position === "only";
5298
+ return h(Box, {
5299
+ class: ResourcesWeekView_module_default.resourcesWeekViewGroupColumn,
5300
+ "data-group-position": info.position
5301
+ }, () => starts ? h("span", { style: info.count > 1 ? { transform: `translateY(calc((${info.count - 1} * (var(--resources-week-view-row-height) + 1px)) / 2))` } : void 0 }, slots.groupLabel?.({ group: info.group }) ?? props.renderGroupLabel?.(info.group) ?? info.group.label ?? void 0) : null);
5302
+ };
5303
+ return () => {
5304
+ const dayCount = weekdays.value.length;
5305
+ const slotsPerDay = intervals.value.length;
5306
+ const hasGroups = ordered.value.groupRanges.length > 0;
5307
+ const now = dayjs(props.getCurrentTime?.() ?? /* @__PURE__ */ new Date());
5308
+ const todayIndex = weekdays.value.findIndex((day) => dayjs(day).isSame(now, "day"));
5309
+ const showIndicator = (props.withCurrentTimeIndicator ?? todayIndex !== -1) && todayIndex !== -1 && isInTimeRange({
5310
+ date: now.toDate(),
5311
+ startTime: props.startTime,
5312
+ endTime: props.endTime
5313
+ });
5314
+ const indicatorOffset = (todayIndex + getCurrentTimePosition({
5315
+ startTime: props.startTime,
5316
+ endTime: props.endTime,
5317
+ intervalMinutes: props.intervalMinutes,
5318
+ now
5319
+ }) / 100) / dayCount * 100;
5320
+ const currentTime = formatDate({
5321
+ date: now,
5322
+ locale: props.locale || "en",
5323
+ format: props.slotLabelFormat
5324
+ });
5325
+ const dayLabels = weekdays.value.map((day) => {
5326
+ const label = formatDate({
5327
+ date: day,
5328
+ locale: props.locale || "en",
5329
+ format: props.weekdayFormat
5330
+ });
5331
+ return h(Box, {
5332
+ key: day,
5333
+ class: ResourcesWeekView_module_default.resourcesWeekViewDayLabel,
5334
+ style: { flex: `0 0 calc(var(--resources-week-view-slot-width) * ${slotsPerDay})` },
5335
+ "data-weekend": props.weekendDays.includes(dayjs(day).day()) || void 0,
5336
+ "data-today": props.highlightToday && dayjs(day).isSame(now, "day") || void 0
5337
+ }, () => slots.dayLabel?.({
5338
+ date: day,
5339
+ label
5340
+ }) ?? label);
5341
+ });
5342
+ const timeLabels = weekdays.value.flatMap((day) => intervals.value.map((interval) => {
5343
+ const label = formatDate({
5344
+ date: `${day} ${interval.startTime}`,
5345
+ locale: props.locale || "en",
5346
+ format: props.slotLabelFormat
5347
+ });
5348
+ const mod = getBusinessHoursMod({
5349
+ time: interval.startTime,
5350
+ businessHours: props.businessHours,
5351
+ highlightBusinessHours: props.highlightBusinessHours,
5352
+ dayOfWeek: dayjs(day).day()
5353
+ });
5354
+ return h(Box, {
5355
+ key: `${day}-${interval.startTime}`,
5356
+ class: ResourcesWeekView_module_default.resourcesWeekViewTimeLabel,
5357
+ "data-business-hours": mod["business-hours"] || void 0,
5358
+ "data-non-business-hours": mod["non-business-hours"] || void 0
5359
+ }, () => slots.timeLabel?.({
5360
+ date: day,
5361
+ label,
5362
+ startTime: interval.startTime,
5363
+ endTime: interval.endTime
5364
+ }) ?? label);
5365
+ }));
5366
+ const rows = ordered.value.orderedResources.map((resource, resourceIndex) => {
5367
+ const background = [];
5368
+ const regular = [];
5369
+ const more = [];
5370
+ weekdays.value.forEach((day, dayIndex) => {
5371
+ const data = weekEvents.value.byDay[day];
5372
+ const dayOffset = dayIndex / dayCount * 100;
5373
+ const dayWidth = 100 / dayCount;
5374
+ [...data.backgroundTimedEvents[resource.id] || [], ...data.backgroundAllDayEvents[resource.id] || []].forEach((event) => {
5375
+ const colors = theme.value.variantColorResolver({
5376
+ color: event.color || theme.value.primaryColor,
5377
+ theme: theme.value,
5378
+ variant: "light",
5379
+ autoContrast: true
5380
+ });
5381
+ background.push(slots.backgroundEvent?.({
5382
+ event,
5383
+ date: day
5384
+ }) ?? h(Box, {
5385
+ key: `bg-${day}-${event.id}`,
5386
+ class: ResourcesWeekView_module_default.resourcesWeekViewBackgroundEvent,
5387
+ style: {
5388
+ left: `${dayOffset + event.position.top / 100 * dayWidth}%`,
5389
+ width: `${event.position.height / 100 * dayWidth}%`,
5390
+ top: 0,
5391
+ height: "100%",
5392
+ "--bg-event-bg": colors.background,
5393
+ "--bg-event-color": colors.color
5394
+ }
5395
+ }, () => props.renderEventBody?.(event) ?? slots.eventBody?.({ event }) ?? event.title));
5396
+ });
5397
+ const allRegular = data.regularEvents[resource.id] || [];
5398
+ allRegular.filter((event) => event.position.column < Math.max(1, props.maxEventsPerTimeSlot)).forEach((event) => {
5399
+ const colors = theme.value.variantColorResolver({
5400
+ color: event.color || theme.value.primaryColor,
5401
+ theme: theme.value,
5402
+ variant: event.variant || "light",
5403
+ autoContrast: true
5404
+ });
5405
+ const position = resize.getResizePosition(event.id);
5406
+ const relativeLeft = position?.left ?? event.position.top;
5407
+ const relativeWidth = position?.width ?? event.position.height;
5408
+ const isResizable = resize.isResizableEvent(event);
5409
+ regular.push(h(Box, {
5410
+ key: `${day}-${event.id}`,
5411
+ class: ResourcesWeekView_module_default.resourcesWeekViewEventWrapper,
5412
+ "data-resizing": position !== null || void 0,
5413
+ style: {
5414
+ "--event-color": colors.color,
5415
+ left: `calc(${dayOffset + relativeLeft / 100 * dayWidth}% + 1px)`,
5416
+ width: `calc(${relativeWidth / 100 * dayWidth}% - 2px)`,
5417
+ top: `${event.position.offset}%`,
5418
+ height: `${event.position.width}%`
5419
+ }
5420
+ }, () => [h(ScheduleEvent, {
5421
+ event,
5422
+ autoSize: true,
5423
+ nowrap: true,
5424
+ radius: props.radius,
5425
+ mode: props.mode,
5426
+ renderEvent: props.renderEvent,
5427
+ renderEventBody: props.renderEventBody,
5428
+ draggable: props.withEventsDragAndDrop && props.mode !== "static" && (props.canDragEvent?.(event) ?? true),
5429
+ onEventDragStart: props.onEventDragStart,
5430
+ onEventDragEnd: props.onEventDragEnd,
5431
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => {
5432
+ if (!resize.wasResizing()) props.onEventClick?.(event, nativeEvent);
5433
+ },
5434
+ style: {
5435
+ width: "100%",
5436
+ height: "100%"
5437
+ }
5438
+ }, forwardEventSlots(slots)), isResizable ? ["start", "end"].map((edge) => h("div", {
5439
+ class: ResourcesWeekView_module_default.resourcesWeekViewResizeHandle,
5440
+ "data-edge": edge,
5441
+ "data-active": resize.state.value?.edge === edge || void 0,
5442
+ "aria-label": `${edge === "start" ? "Resize event start" : "Resize event end"} ${event.title}`,
5443
+ onDragstart: (nativeEvent) => nativeEvent.preventDefault(),
5444
+ onPointerdown: (pointerEvent) => {
5445
+ const container = rowContainers.get(resourceIndex);
5446
+ if (container) resize.handleResizeStart({
5447
+ event,
5448
+ edge,
5449
+ container,
5450
+ originalLeft: event.position.top,
5451
+ originalWidth: event.position.height,
5452
+ eventDate: dayjs(day).format("YYYY-MM-DD"),
5453
+ dayIndex,
5454
+ dayCount,
5455
+ pointerEvent
5456
+ });
5457
+ }
5458
+ })) : null]));
5459
+ });
5460
+ getOverlapClusters(allRegular).filter((cluster) => cluster.some((event) => event.position.column >= props.maxEventsPerTimeSlot)).forEach((cluster) => {
5461
+ const hiddenCount = cluster.filter((event) => event.position.column >= props.maxEventsPerTimeSlot).length;
5462
+ const left = Math.min(...cluster.map((event) => event.position.top));
5463
+ const right = Math.max(...cluster.map((event) => event.position.top + event.position.height));
5464
+ more.push(slots.moreEvents?.({
5465
+ events: cluster,
5466
+ hiddenCount,
5467
+ date: day
5468
+ }) ?? h(MoreEvents, {
5469
+ ...props.moreEventsProps,
5470
+ key: `more-${day}-${cluster[0].id}`,
5471
+ events: cluster,
5472
+ moreEventsCount: hiddenCount,
5473
+ mode: props.mode,
5474
+ labels: props.labels,
5475
+ renderEventBody: props.renderEventBody,
5476
+ renderEvent: props.renderEvent,
5477
+ onEventClick: props.onEventClick,
5478
+ style: {
5479
+ position: "absolute",
5480
+ left: `calc(${dayOffset + left / 100 * dayWidth}% + 1px)`,
5481
+ width: `calc(${(right - left) / 100 * dayWidth}% - 2px)`,
5482
+ bottom: 0,
5483
+ height: "22px",
5484
+ zIndex: 4
5485
+ }
5486
+ }, forwardEventSlots(slots)));
5487
+ });
5488
+ });
5489
+ const allDayBars = weekEvents.value.allDayBars[resource.id] || [];
5490
+ const allDay = allDayBars.map((bar) => h(Box, {
5491
+ key: `all-${bar.event.id}`,
5492
+ class: ResourcesWeekView_module_default.resourcesWeekViewAllDayEvent,
5493
+ style: {
5494
+ left: `calc(${bar.startDayIndex / dayCount * 100}% + 1px)`,
5495
+ width: `calc(${(bar.endDayIndex - bar.startDayIndex + 1) / dayCount * 100}% - 2px)`,
5496
+ top: `calc(${bar.row} * (var(--resources-week-view-all-day-height) + 2px) + 2px)`
5497
+ }
5498
+ }, () => slots.allDayEvent?.({
5499
+ event: bar.event,
5500
+ startDayIndex: bar.startDayIndex,
5501
+ endDayIndex: bar.endDayIndex
5502
+ }) ?? h(ScheduleEvent, {
5503
+ event: bar.event,
5504
+ autoSize: true,
5505
+ nowrap: true,
5506
+ radius: props.radius,
5507
+ mode: props.mode,
5508
+ renderEvent: props.renderEvent,
5509
+ renderEventBody: props.renderEventBody,
5510
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onEventClick?.(bar.event, nativeEvent),
5511
+ style: {
5512
+ width: "100%",
5513
+ height: "100%"
5514
+ }
5515
+ }, forwardEventSlots(slots))));
5516
+ const slotGroup = String(resource.id);
5517
+ const buttons = weekdays.value.flatMap((day, dayIndex) => intervals.value.map((interval, slotIndex) => {
5518
+ const flatIndex = dayIndex * slotsPerDay + slotIndex;
5519
+ const mod = getBusinessHoursMod({
5520
+ time: interval.startTime,
5521
+ businessHours: props.businessHours,
5522
+ highlightBusinessHours: props.highlightBusinessHours,
5523
+ dayOfWeek: dayjs(day).day()
5524
+ });
5525
+ return h(UnstyledButton, {
5526
+ key: `${day}-${interval.startTime}`,
5527
+ ref: (element) => {
5528
+ const button = element?.$el ?? element;
5529
+ controls[resourceIndex] ||= [];
5530
+ controls[resourceIndex][flatIndex] = button instanceof HTMLButtonElement ? button : void 0;
5531
+ },
5532
+ class: ResourcesWeekView_module_default.resourcesWeekViewRowSlot,
5533
+ "data-business-hours": mod["business-hours"] || void 0,
5534
+ "data-non-business-hours": mod["non-business-hours"] || void 0,
5535
+ "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.flatIndex === flatIndex ? true : void 0,
5536
+ "data-drag-selected": slotSelect.isSlotSelected(flatIndex, slotGroup) || void 0,
5537
+ "data-static": props.mode === "static" || void 0,
5538
+ "data-drag-slot-index": props.withDragSlotSelect ? flatIndex : void 0,
5539
+ "data-drag-slot-group": props.withDragSlotSelect ? slotGroup : void 0,
5540
+ "aria-label": `${getLabel("resourceSlot", props.labels)} ${String(resource.label)} ${day} ${interval.startTime} - ${interval.endTime}`,
5541
+ tabindex: props.mode === "static" ? -1 : resourceIndex === 0 && flatIndex === 0 ? 0 : -1,
5542
+ onKeydown: (event) => handleResourcesGridKeyDown({
5543
+ controls,
5544
+ resourceIndex,
5545
+ slotIndex: flatIndex,
5546
+ event
5547
+ }),
5548
+ onPointerdown: props.mode === "static" ? void 0 : (event) => slotSelect.handleSlotPointerDown(event, flatIndex, slotGroup),
5549
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onTimeSlotClick?.({
5550
+ slotStart: `${day} ${interval.startTime}`,
5551
+ slotEnd: `${day} ${interval.endTime}`,
5552
+ nativeEvent,
5553
+ resourceId: resource.id
5554
+ })
5555
+ }, () => slots.timeSlot?.({
5556
+ resource,
5557
+ date: day,
5558
+ startTime: interval.startTime,
5559
+ endTime: interval.endTime
5560
+ }));
5561
+ }));
5562
+ const info = hasGroups ? ordered.value.resourceGroupMap[resourceIndex] : void 0;
5563
+ const allDayRows = allDayBars.length ? Math.max(...allDayBars.map((bar) => bar.row)) + 1 : 0;
5564
+ return h(Box, {
5565
+ key: resource.id,
5566
+ class: ResourcesWeekView_module_default.resourcesWeekViewRow
5567
+ }, () => [
5568
+ groupCell(info),
5569
+ h(Box, {
5570
+ class: ResourcesWeekView_module_default.resourcesWeekViewResourceLabel,
5571
+ "data-scrolled-x": scrolledX.value || void 0,
5572
+ "data-has-groups": info !== void 0 || void 0
5573
+ }, () => slots.resourceLabel?.({ resource }) ?? props.renderResourceLabel?.(resource) ?? resource.label),
5574
+ h(Box, {
5575
+ class: ResourcesWeekView_module_default.resourcesWeekViewRowSlots,
5576
+ ref: (element) => {
5577
+ const node = element?.$el ?? element;
5578
+ if (node instanceof HTMLElement) rowContainers.set(resourceIndex, node);
5579
+ },
5580
+ style: allDayRows ? { minHeight: `max(var(--resources-week-view-row-height), calc(${allDayRows} * (var(--resources-week-view-all-day-height) + 2px) + 4px))` } : void 0,
5581
+ onDragover: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
5582
+ if (props.mode === "static") return;
5583
+ nativeEvent.preventDefault();
5584
+ const flatIndex = getFlatIndexAtPoint(nativeEvent, resourceIndex);
5585
+ if (flatIndex >= 0 && (dropTarget.value?.resourceId !== resource.id || dropTarget.value.flatIndex !== flatIndex)) dropTarget.value = {
5586
+ resourceId: resource.id,
5587
+ flatIndex
5588
+ };
5589
+ } : void 0,
5590
+ onDragleave: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
5591
+ const related = nativeEvent.relatedTarget;
5592
+ const current = nativeEvent.currentTarget;
5593
+ if (!(related instanceof Node) || !(current instanceof HTMLElement) || !current.contains(related)) dropTarget.value = null;
5594
+ } : void 0,
5595
+ onDrop: props.withEventsDragAndDrop || props.onExternalEventDrop ? (nativeEvent) => {
5596
+ const flatIndex = getFlatIndexAtPoint(nativeEvent, resourceIndex);
5597
+ if (flatIndex >= 0) emitDrop(nativeEvent, resource.id, flatIndex);
5598
+ } : void 0
5599
+ }, () => [
5600
+ ...background,
5601
+ ...allDay,
5602
+ ...regular,
5603
+ ...more,
5604
+ ...buttons
5605
+ ])
5606
+ ]);
5607
+ });
5608
+ const weekStart = dayjs(weekdays.value[0]).format("YYYY-MM-DD");
5609
+ const weekEnd = dayjs(weekdays.value.at(-1)).format("YYYY-MM-DD");
5610
+ const headerLabel = props.renderWeekLabel?.({
5611
+ weekStart,
5612
+ weekEnd
5613
+ }) ?? getWeekLabel({
5614
+ weekdays: weekdays.value,
5615
+ locale: props.locale || "en",
5616
+ weekLabelFormat: props.weekLabelFormat
5617
+ });
5618
+ const header = props.withHeader ? slots.header?.({
5619
+ weekStart,
5620
+ weekEnd,
5621
+ label: headerLabel
5622
+ }) ?? h(ScheduleHeaderBase, {
5623
+ view: "week",
5624
+ navigationHandlers: {
5625
+ previous: () => dayjs(props.date).subtract(1, "week").format("YYYY-MM-DD"),
5626
+ next: () => dayjs(props.date).add(1, "week").format("YYYY-MM-DD"),
5627
+ today: () => now.format("YYYY-MM-DD")
5628
+ },
5629
+ control: { title: headerLabel },
5630
+ labels: props.labels,
5631
+ onDateChange: props.onDateChange,
5632
+ onViewChange: props.onViewChange,
5633
+ previousControlProps: props.previousControlProps,
5634
+ nextControlProps: props.nextControlProps,
5635
+ todayControlProps: props.todayControlProps,
5636
+ viewSelectProps: {
5637
+ views: [
5638
+ "day",
5639
+ "week",
5640
+ "month"
5641
+ ],
5642
+ ...props.viewSelectProps
5643
+ }
5644
+ }) : null;
5645
+ const indicator = showIndicator ? slots.currentTimeIndicator?.({
5646
+ time: currentTime,
5647
+ offset: indicatorOffset,
5648
+ date: weekdays.value[todayIndex]
5649
+ }) ?? h(Box, {
5650
+ class: ResourcesWeekView_module_default.resourcesWeekViewCurrentTimeIndicator,
5651
+ style: {
5652
+ "--indicator-left-offset": hasGroups ? `calc(var(--resources-week-view-resource-label-width) + var(--resources-week-view-group-label-width) + (100% - var(--resources-week-view-resource-label-width) - var(--resources-week-view-group-label-width)) * ${indicatorOffset} / 100)` : `calc(var(--resources-week-view-resource-label-width) + (100% - var(--resources-week-view-resource-label-width)) * ${indicatorOffset} / 100)`,
5653
+ "--_time-bubble-width": String(currentTime).toLowerCase().includes("m") ? "64px" : "46px"
5654
+ }
5655
+ }, () => [props.withCurrentTimeBubble ? h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewCurrentTimeIndicatorTimeBubble }, currentTime) : h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewCurrentTimeIndicatorThumb }), h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewCurrentTimeIndicatorLine })]) : null;
5656
+ return h(Box, {
5657
+ ...attrs,
5658
+ ref: (element) => {
5659
+ const node = element?.$el ?? element;
5660
+ rootElement.value = node instanceof HTMLElement ? node : null;
5661
+ },
5662
+ class: [ResourcesWeekView_module_default.resourcesWeekView, attrs.class],
5663
+ style: [{
5664
+ "--resources-week-view-radius": resolveScheduleRadius(props.radius),
5665
+ "--resources-week-view-slot-width": cssSize$1(props.slotWidth),
5666
+ "--resources-week-view-row-height": cssSize$1(props.rowHeight),
5667
+ "--resources-week-view-group-label-width": cssSize$1(props.groupLabelWidth)
5668
+ }, attrs.style],
5669
+ "data-resizing": resize.state.value ? true : void 0,
5670
+ "data-event-interaction": resize.state.value ? true : void 0
5671
+ }, () => [header, h(Box, { class: ResourcesWeekView_module_default.resourcesWeekViewRoot }, () => h(ScrollArea, {
5672
+ scrollbarSize: 4,
5673
+ ...props.scrollAreaProps,
5674
+ class: ResourcesWeekView_module_default.resourcesWeekViewScrollArea,
5675
+ onScrollPositionChange: (position) => scrolledX.value = position.x !== 0
5676
+ }, () => h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewInner }, [
5677
+ h(Box, { class: ResourcesWeekView_module_default.resourcesWeekViewHeaderRows }, () => [h("div", {
5678
+ class: ResourcesWeekView_module_default.resourcesWeekViewCorner,
5679
+ style: hasGroups ? {
5680
+ flexBasis: "calc(var(--resources-week-view-resource-label-width) + var(--resources-week-view-group-label-width))",
5681
+ minWidth: "calc(var(--resources-week-view-resource-label-width) + var(--resources-week-view-group-label-width))"
5682
+ } : void 0
5683
+ }, slots.corner?.({ resources: ordered.value.orderedResources }) ?? getLabel("resources", props.labels)), h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewHeaderContent }, [h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewDayLabelsRow }, dayLabels), h("div", { class: ResourcesWeekView_module_default.resourcesWeekViewTimeLabelsRow }, timeLabels)])]),
5684
+ ...rows,
5685
+ indicator
5686
+ ])))]);
5687
+ };
5688
+ }
5689
+ });
5690
+ var ResourcesMonthView_module_default = {
5691
+ resourcesMonthView: "_resourcesMonthView_wgbmp_1",
5692
+ resourcesMonthViewRoot: "_resourcesMonthViewRoot_wgbmp_17",
5693
+ resourcesMonthViewScrollArea: "_resourcesMonthViewScrollArea_wgbmp_24",
5694
+ resourcesMonthViewInner: "_resourcesMonthViewInner_wgbmp_33",
5695
+ resourcesMonthViewDayLabelsRow: "_resourcesMonthViewDayLabelsRow_wgbmp_37",
5696
+ resourcesMonthViewCorner: "_resourcesMonthViewCorner_wgbmp_46",
5697
+ resourcesMonthViewDayLabel: "_resourcesMonthViewDayLabel_wgbmp_37",
5698
+ resourcesMonthViewDayLabelWeekday: "_resourcesMonthViewDayLabelWeekday_wgbmp_85",
5699
+ resourcesMonthViewDayLabelNumber: "_resourcesMonthViewDayLabelNumber_wgbmp_92",
5700
+ resourcesMonthViewRow: "_resourcesMonthViewRow_wgbmp_97",
5701
+ resourcesMonthViewResourceLabel: "_resourcesMonthViewResourceLabel_wgbmp_101",
5702
+ resourcesMonthViewGroupColumn: "_resourcesMonthViewGroupColumn_wgbmp_120",
5703
+ resourcesMonthViewGroupColumnEmpty: "_resourcesMonthViewGroupColumnEmpty_wgbmp_121",
5704
+ resourcesMonthViewRowSlots: "_resourcesMonthViewRowSlots_wgbmp_149",
5705
+ resourcesMonthViewCell: "_resourcesMonthViewCell_wgbmp_154"
5706
+ };
5707
+ //#endregion
5708
+ //#region src/components/ResourcesMonthView/ResourcesMonthView.ts
5709
+ var cssSize = (value) => typeof value === "number" ? `${value}px` : value;
5710
+ var isMulti = (event) => dayjs(event.end).startOf("day").isAfter(dayjs(event.start).startOf("day"));
5711
+ var compareEvents = (a, b) => {
5712
+ const aSpan = dayjs(a.end).startOf("day").diff(dayjs(a.start).startOf("day"), "day");
5713
+ const bSpan = dayjs(b.end).startOf("day").diff(dayjs(b.start).startOf("day"), "day");
5714
+ return aSpan === bSpan ? dayjs(a.start).valueOf() - dayjs(b.start).valueOf() : bSpan - aSpan;
5715
+ };
5716
+ var ResourcesMonthView = defineComponent({
5717
+ name: "ResourcesMonthView",
5718
+ inheritAttrs: false,
5719
+ slots: Object,
5720
+ props: {
5721
+ date: {
5722
+ type: [String, Date],
5723
+ required: true
5724
+ },
5725
+ onDateChange: Function,
5726
+ resources: {
5727
+ type: Array,
5728
+ required: true
5729
+ },
5730
+ locale: String,
5731
+ weekdayFormat: {
5732
+ type: [String, Function],
5733
+ default: "ddd"
5734
+ },
5735
+ weekendDays: {
5736
+ type: Array,
5737
+ default: () => [0, 6]
5738
+ },
5739
+ withWeekendDays: {
5740
+ type: Boolean,
5741
+ default: true
5742
+ },
5743
+ startScrollDate: String,
5744
+ onDayClick: Function,
5745
+ highlightToday: {
5746
+ type: Boolean,
5747
+ default: true
5748
+ },
5749
+ radius: [String, Number],
5750
+ withHeader: {
5751
+ type: Boolean,
5752
+ default: true
5753
+ },
5754
+ monthYearSelectProps: Object,
5755
+ onViewChange: Function,
5756
+ previousControlProps: Object,
5757
+ nextControlProps: Object,
5758
+ todayControlProps: Object,
5759
+ viewSelectProps: Object,
5760
+ events: Array,
5761
+ dayWidth: {
5762
+ type: [String, Number],
5763
+ default: 80
5764
+ },
5765
+ rowHeight: {
5766
+ type: [String, Number],
5767
+ default: 64
5768
+ },
5769
+ renderEventBody: Function,
5770
+ renderEvent: Function,
5771
+ renderResourceLabel: Function,
5772
+ groups: Array,
5773
+ renderGroupLabel: Function,
5774
+ groupLabelWidth: {
5775
+ type: [String, Number],
5776
+ default: 80
5777
+ },
5778
+ withEventsDragAndDrop: Boolean,
5779
+ onEventDrop: Function,
5780
+ canDragEvent: Function,
5781
+ onEventDragStart: Function,
5782
+ onEventDragEnd: Function,
5783
+ onEventClick: Function,
5784
+ withDragSlotSelect: Boolean,
5785
+ onSlotDragEnd: Function,
5786
+ labels: Object,
5787
+ mode: {
5788
+ type: String,
5789
+ default: "default"
5790
+ },
5791
+ scrollAreaProps: Object,
5792
+ onExternalEventDrop: Function,
5793
+ maxEventsPerTimeSlot: {
5794
+ type: Number,
5795
+ default: 2
5796
+ },
5797
+ moreEventsProps: Object,
5798
+ recurrenceExpansionLimit: {
5799
+ type: Number,
5800
+ default: 2e3
5801
+ }
5802
+ },
5803
+ setup(props, { attrs, slots }) {
5804
+ const controls = [];
5805
+ const rowContainers = /* @__PURE__ */ new Map();
5806
+ const rootElement = ref(null);
5807
+ const dropTarget = ref(null);
5808
+ const days = computed(() => {
5809
+ const month = dayjs(props.date).startOf("month");
5810
+ return Array.from({ length: month.daysInMonth() }, (_, index) => month.date(index + 1)).filter((day) => props.withWeekendDays || !props.weekendDays.includes(day.day())).map((day) => day.format("YYYY-MM-DD"));
5811
+ });
5812
+ const ordered = computed(() => getOrderedResources(props.resources, props.groups));
5813
+ const idMap = computed(() => getGroupToResourceIdMap(props.resources));
5814
+ const expanded = computed(() => expandRecurringEvents({
5815
+ events: props.events,
5816
+ rangeStart: dayjs(props.date).startOf("month").toDate(),
5817
+ rangeEnd: dayjs(props.date).endOf("month").toDate(),
5818
+ expansionLimit: props.recurrenceExpansionLimit
5819
+ }));
5820
+ const slotSelect = useSlotDragSelect({
5821
+ enabled: () => props.withDragSlotSelect && props.mode !== "static",
5822
+ onDragEnd: () => props.onSlotDragEnd ? (start, end, group) => {
5823
+ const first = days.value[start];
5824
+ const last = days.value[end];
5825
+ if (first && last) props.onSlotDragEnd?.({
5826
+ rangeStart: `${first} 00:00:00`,
5827
+ rangeEnd: dayjs(last).endOf("day").format("YYYY-MM-DD HH:mm:ss"),
5828
+ resourceId: idMap.value.get(group) ?? group
5829
+ });
5830
+ } : void 0
5831
+ });
5832
+ onMounted(async () => {
5833
+ if (!props.startScrollDate) return;
5834
+ await nextTick();
5835
+ const index = days.value.indexOf(dayjs(props.startScrollDate).format("YYYY-MM-DD"));
5836
+ const target = controls[0]?.[index];
5837
+ const viewport = rootElement.value?.querySelector(".mantine-ScrollArea-viewport");
5838
+ if (target && viewport) {
5839
+ viewport.scrollLeft = target.offsetLeft;
5840
+ requestAnimationFrame(() => viewport.scrollLeft = target.offsetLeft);
5841
+ }
5842
+ });
5843
+ const indexAtPoint = (event, resourceIndex) => {
5844
+ const container = rowContainers.get(resourceIndex);
5845
+ if (!container || !days.value.length) return -1;
5846
+ const rect = container.getBoundingClientRect();
5847
+ if (rect.width <= 0) return -1;
5848
+ return Math.max(0, Math.min(days.value.length - 1, Math.floor((event.clientX - rect.left) / rect.width * days.value.length)));
5849
+ };
5850
+ const emitDrop = (event, resourceId, dayIndex) => {
5851
+ event.preventDefault();
5852
+ dropTarget.value = null;
5853
+ const day = days.value[dayIndex];
5854
+ if (!day) return;
5855
+ const dragged = getDropEvent(expanded.value, event.dataTransfer);
5856
+ if (dragged) {
5857
+ const next = calculateMonthDropDate({
5858
+ draggedEvent: dragged,
5859
+ targetDay: day
5860
+ });
5861
+ props.onEventDrop?.({
5862
+ eventId: dragged.id,
5863
+ newStart: dayjs(next.start).format("YYYY-MM-DD HH:mm:ss"),
5864
+ newEnd: dayjs(next.end).format("YYYY-MM-DD HH:mm:ss"),
5865
+ event: dragged,
5866
+ resourceId
5867
+ });
5868
+ } else if (event.dataTransfer) props.onExternalEventDrop?.({
5869
+ dataTransfer: event.dataTransfer,
5870
+ dropDateTime: `${day} 00:00:00`,
5871
+ resourceId
5872
+ });
5873
+ };
5874
+ return () => {
5875
+ const maxRows = Math.min(10, Math.max(1, props.maxEventsPerTimeSlot));
5876
+ const hasGroups = ordered.value.groupRanges.length > 0;
5877
+ const monthStart = dayjs(days.value[0]).startOf("day");
5878
+ const monthEnd = dayjs(days.value.at(-1)).add(1, "day").startOf("day");
5879
+ const rows = ordered.value.orderedResources.map((resource, resourceIndex) => {
5880
+ const eventsByDay = days.value.map((day) => (expanded.value || []).filter((event) => event.resourceId === resource.id && dayjs(event.start).isBefore(dayjs(day).endOf("day")) && dayjs(event.end).isAfter(dayjs(day).startOf("day"))).sort(compareEvents));
5881
+ const layouts = [];
5882
+ const lastRow = /* @__PURE__ */ new Map();
5883
+ const rowByEvent = /* @__PURE__ */ new Map();
5884
+ eventsByDay.forEach((eventList, dayIndex) => {
5885
+ const used = /* @__PURE__ */ new Set();
5886
+ const visible = [];
5887
+ let hiddenCount = 0;
5888
+ eventList.forEach((event) => {
5889
+ let row = lastRow.get(event.id);
5890
+ if (row === void 0 || row >= maxRows || used.has(row)) row = Array.from({ length: maxRows }, (_, i) => i).find((i) => !used.has(i));
5891
+ if (row === void 0) {
5892
+ hiddenCount++;
5893
+ return;
5894
+ }
5895
+ used.add(row);
5896
+ visible.push({
5897
+ event,
5898
+ row
5899
+ });
5900
+ lastRow.set(event.id, row);
5901
+ if (!rowByEvent.has(event.id)) rowByEvent.set(event.id, /* @__PURE__ */ new Map());
5902
+ rowByEvent.get(event.id).set(dayIndex, row);
5903
+ });
5904
+ layouts.push({
5905
+ visible,
5906
+ hiddenCount
5907
+ });
5908
+ });
5909
+ const segments = [];
5910
+ Array.from(new Map(eventsByDay.flat().filter(isMulti).map((event) => [event.id, event])).values()).forEach((event) => {
5911
+ const rowsForEvent = rowByEvent.get(event.id);
5912
+ let run = null;
5913
+ const flush = () => {
5914
+ if (!run) return;
5915
+ const before = dayjs(event.start).isBefore(monthStart);
5916
+ const after = dayjs(event.end).isAfter(monthEnd);
5917
+ segments.push({
5918
+ event,
5919
+ ...run,
5920
+ hanging: before && after ? "both" : before ? "start" : after ? "end" : "none",
5921
+ hidden: Array.from({ length: run.end - run.start + 1 }, (_, i) => layouts[run.start + i].hiddenCount > 0).some(Boolean)
5922
+ });
5923
+ run = null;
5924
+ };
5925
+ days.value.forEach((_day, index) => {
5926
+ const row = rowsForEvent?.get(index);
5927
+ if (row === void 0) flush();
5928
+ else if (run && run.row === row && run.end === index - 1) run.end = index;
5929
+ else {
5930
+ flush();
5931
+ run = {
5932
+ start: index,
5933
+ end: index,
5934
+ row
5935
+ };
5936
+ }
5937
+ });
5938
+ flush();
5939
+ });
5940
+ const eventNodes = [];
5941
+ layouts.forEach((layout, dayIndex) => layout.visible.forEach(({ event, row }) => {
5942
+ if (isMulti(event)) return;
5943
+ const compressed = layout.hiddenCount > 0 && props.mode !== "static";
5944
+ eventNodes.push(h(ScheduleEvent, {
5945
+ key: `${event.id}-${dayIndex}`,
5946
+ event,
5947
+ autoSize: true,
5948
+ nowrap: true,
5949
+ radius: props.radius,
5950
+ mode: props.mode,
5951
+ renderEvent: props.renderEvent,
5952
+ renderEventBody: props.renderEventBody,
5953
+ draggable: props.withEventsDragAndDrop && props.mode !== "static" && (props.canDragEvent?.(event) ?? true),
5954
+ onEventDragStart: props.onEventDragStart,
5955
+ onEventDragEnd: props.onEventDragEnd,
5956
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onEventClick?.(event, nativeEvent),
5957
+ style: {
5958
+ position: "absolute",
5959
+ left: `calc(${dayIndex / days.value.length * 100}% + 1px)`,
5960
+ width: `calc(${100 / days.value.length}% - 2px)`,
5961
+ top: compressed ? `calc((100% - 18px) * ${row} / ${maxRows} + 1px)` : `calc(${row / maxRows * 100}% + 1px)`,
5962
+ height: compressed ? `calc((100% - 18px) / ${maxRows} - 2px)` : `calc(${100 / maxRows}% - 2px)`,
5963
+ zIndex: 3
5964
+ }
5965
+ }, forwardEventSlots(slots)));
5966
+ }));
5967
+ segments.forEach((segment) => eventNodes.push(h(ScheduleEvent, {
5968
+ key: `${segment.event.id}-${segment.start}`,
5969
+ event: segment.event,
5970
+ hanging: segment.hanging,
5971
+ autoSize: true,
5972
+ nowrap: true,
5973
+ radius: props.radius,
5974
+ mode: props.mode,
5975
+ renderEvent: props.renderEvent,
5976
+ renderEventBody: props.renderEventBody,
5977
+ draggable: props.withEventsDragAndDrop && props.mode !== "static" && (props.canDragEvent?.(segment.event) ?? true),
5978
+ onEventDragStart: props.onEventDragStart,
5979
+ onEventDragEnd: props.onEventDragEnd,
5980
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onEventClick?.(segment.event, nativeEvent),
5981
+ style: {
5982
+ position: "absolute",
5983
+ left: `calc(${segment.start / days.value.length * 100}% + 1px)`,
5984
+ width: `calc(${(segment.end - segment.start + 1) / days.value.length * 100}% - 2px)`,
5985
+ top: segment.hidden ? `calc((100% - 18px) * ${segment.row} / ${maxRows} + 1px)` : `calc(${segment.row / maxRows * 100}% + 1px)`,
5986
+ height: segment.hidden ? `calc((100% - 18px) / ${maxRows} - 2px)` : `calc(${100 / maxRows}% - 2px)`,
5987
+ zIndex: 3
5988
+ }
5989
+ }, forwardEventSlots(slots))));
5990
+ const moreNodes = layouts.map((layout, dayIndex) => layout.hiddenCount && props.mode !== "static" ? slots.moreEvents?.({
5991
+ events: eventsByDay[dayIndex],
5992
+ hiddenCount: layout.hiddenCount,
5993
+ resource,
5994
+ date: days.value[dayIndex]
5995
+ }) ?? h(MoreEvents, {
5996
+ ...props.moreEventsProps,
5997
+ key: `more-${dayIndex}`,
5998
+ events: eventsByDay[dayIndex],
5999
+ moreEventsCount: layout.hiddenCount,
6000
+ mode: props.mode,
6001
+ labels: props.labels,
6002
+ renderEvent: props.renderEvent,
6003
+ renderEventBody: props.renderEventBody,
6004
+ onEventClick: props.onEventClick,
6005
+ style: {
6006
+ position: "absolute",
6007
+ bottom: "1px",
6008
+ left: `calc(${dayIndex / days.value.length * 100}% + 1px)`,
6009
+ width: `calc(${100 / days.value.length}% - 2px)`,
6010
+ height: "18px",
6011
+ zIndex: 4
6012
+ }
6013
+ }, forwardEventSlots(slots)) : null);
6014
+ const group = hasGroups ? ordered.value.resourceGroupMap[resourceIndex] : void 0;
6015
+ const groupCell = group === void 0 ? null : group === null ? h(Box, { class: ResourcesMonthView_module_default.resourcesMonthViewGroupColumnEmpty }) : h(Box, {
6016
+ class: ResourcesMonthView_module_default.resourcesMonthViewGroupColumn,
6017
+ "data-group-position": group.position
6018
+ }, () => group.position === "first" || group.position === "only" ? h("span", { style: group.count > 1 ? { transform: `translateY(calc((${group.count - 1} * (var(--resources-month-view-row-height) + 1px)) / 2))` } : void 0 }, slots.groupLabel?.({ group: group.group }) ?? props.renderGroupLabel?.(group.group) ?? group.group.label ?? void 0) : null);
6019
+ const cells = days.value.map((day, dayIndex) => {
6020
+ const weekend = props.weekendDays.includes(dayjs(day).day());
6021
+ const groupId = String(resource.id);
6022
+ return h(UnstyledButton, {
6023
+ key: day,
6024
+ ref: (element) => {
6025
+ const button = element?.$el ?? element;
6026
+ controls[resourceIndex] ||= [];
6027
+ controls[resourceIndex][dayIndex] = button instanceof HTMLButtonElement ? button : void 0;
6028
+ },
6029
+ class: ResourcesMonthView_module_default.resourcesMonthViewCell,
6030
+ "data-weekend": weekend || void 0,
6031
+ "data-drop-target": dropTarget.value?.resourceId === resource.id && dropTarget.value.dayIndex === dayIndex || void 0,
6032
+ "data-drag-selected": slotSelect.isSlotSelected(dayIndex, groupId) || void 0,
6033
+ "data-static": props.mode === "static" || void 0,
6034
+ "data-drag-slot-index": props.withDragSlotSelect ? dayIndex : void 0,
6035
+ "data-drag-slot-group": props.withDragSlotSelect ? groupId : void 0,
6036
+ tabindex: props.mode === "static" ? -1 : resourceIndex === 0 && dayIndex === 0 ? 0 : -1,
6037
+ "aria-label": `${String(resource.label)} ${dayjs(day).format("MMMM D, YYYY")}`,
6038
+ onKeydown: (event) => handleResourcesGridKeyDown({
6039
+ controls,
6040
+ resourceIndex,
6041
+ slotIndex: dayIndex,
6042
+ event
6043
+ }),
6044
+ onPointerdown: props.mode === "static" ? void 0 : (event) => slotSelect.handleSlotPointerDown(event, dayIndex, groupId),
6045
+ onClick: props.mode === "static" ? void 0 : (nativeEvent) => props.onDayClick?.({
6046
+ date: day,
6047
+ nativeEvent,
6048
+ resourceId: resource.id
6049
+ })
6050
+ }, () => slots.dayCell?.({
6051
+ resource,
6052
+ date: day
6053
+ }));
6054
+ });
6055
+ return h("div", {
6056
+ class: ResourcesMonthView_module_default.resourcesMonthViewRow,
6057
+ key: resource.id
6058
+ }, [
6059
+ groupCell,
6060
+ h("div", {
6061
+ class: ResourcesMonthView_module_default.resourcesMonthViewResourceLabel,
6062
+ "data-has-groups": hasGroups || void 0
6063
+ }, slots.resourceLabel?.({ resource }) ?? props.renderResourceLabel?.(resource) ?? resource.label ?? void 0),
6064
+ h("div", {
6065
+ class: ResourcesMonthView_module_default.resourcesMonthViewRowSlots,
6066
+ ref: (element) => {
6067
+ if (element instanceof HTMLElement) rowContainers.set(resourceIndex, element);
6068
+ },
6069
+ onDragover: props.mode !== "static" && (props.withEventsDragAndDrop || props.onExternalEventDrop) ? (event) => {
6070
+ event.preventDefault();
6071
+ const dayIndex = indexAtPoint(event, resourceIndex);
6072
+ if (dayIndex >= 0 && (dropTarget.value?.resourceId !== resource.id || dropTarget.value.dayIndex !== dayIndex)) dropTarget.value = {
6073
+ resourceId: resource.id,
6074
+ dayIndex
6075
+ };
6076
+ } : void 0,
6077
+ onDragleave: (event) => {
6078
+ const current = event.currentTarget;
6079
+ if (!(event.relatedTarget instanceof Node) || !(current instanceof HTMLElement) || !current.contains(event.relatedTarget)) dropTarget.value = null;
6080
+ },
6081
+ onDrop: props.mode !== "static" && (props.withEventsDragAndDrop || props.onExternalEventDrop) ? (event) => {
6082
+ const dayIndex = indexAtPoint(event, resourceIndex);
6083
+ if (dayIndex >= 0) emitDrop(event, resource.id, dayIndex);
6084
+ } : void 0
6085
+ }, [
6086
+ ...eventNodes,
6087
+ ...moreNodes,
6088
+ ...cells
6089
+ ])
6090
+ ]);
6091
+ });
6092
+ const month = dayjs(props.date).startOf("month");
6093
+ const monthString = month.format("YYYY-MM-DD");
6094
+ const header = props.withHeader ? slots.header?.({ month: monthString }) ?? h(ScheduleHeaderBase, {
6095
+ view: "month",
6096
+ navigationHandlers: {
6097
+ previous: () => month.subtract(1, "month").format("YYYY-MM-DD"),
6098
+ next: () => month.add(1, "month").format("YYYY-MM-DD"),
6099
+ today: () => dayjs().format("YYYY-MM-DD")
6100
+ },
6101
+ control: { monthYearSelect: {
6102
+ locale: props.locale,
6103
+ monthValue: month.month(),
6104
+ yearValue: month.year(),
6105
+ onMonthChange: (value) => props.onDateChange?.(month.month(value).format("YYYY-MM-DD")),
6106
+ onYearChange: (value) => props.onDateChange?.(month.year(value).format("YYYY-MM-DD")),
6107
+ ...props.monthYearSelectProps
6108
+ } },
6109
+ labels: props.labels,
6110
+ onDateChange: props.onDateChange,
6111
+ onViewChange: props.onViewChange,
6112
+ previousControlProps: props.previousControlProps,
6113
+ nextControlProps: props.nextControlProps,
6114
+ todayControlProps: props.todayControlProps,
6115
+ viewSelectProps: {
6116
+ views: [
6117
+ "day",
6118
+ "week",
6119
+ "month"
6120
+ ],
6121
+ ...props.viewSelectProps
6122
+ }
6123
+ }) : null;
6124
+ const labels = days.value.map((day) => {
6125
+ const weekday = formatDate({
6126
+ date: day,
6127
+ locale: props.locale || "en",
6128
+ format: props.weekdayFormat
6129
+ });
6130
+ return slots.dayLabel?.({
6131
+ date: day,
6132
+ weekday,
6133
+ day: dayjs(day).date()
6134
+ }) ?? h("div", {
6135
+ key: day,
6136
+ class: ResourcesMonthView_module_default.resourcesMonthViewDayLabel,
6137
+ "data-weekend": props.weekendDays.includes(dayjs(day).day()) || void 0,
6138
+ "data-today": props.highlightToday && dayjs(day).isSame(dayjs(), "day") || void 0
6139
+ }, [h("span", { class: ResourcesMonthView_module_default.resourcesMonthViewDayLabelWeekday }, weekday), h("span", { class: ResourcesMonthView_module_default.resourcesMonthViewDayLabelNumber }, dayjs(day).date())]);
6140
+ });
6141
+ return h(Box, {
6142
+ ...attrs,
6143
+ ref: (element) => {
6144
+ const node = element?.$el ?? element;
6145
+ rootElement.value = node instanceof HTMLElement ? node : null;
6146
+ },
6147
+ class: [ResourcesMonthView_module_default.resourcesMonthView, attrs.class],
6148
+ style: [{
6149
+ "--resources-month-view-radius": resolveScheduleRadius(props.radius),
6150
+ "--resources-month-view-day-width": cssSize(props.dayWidth),
6151
+ "--resources-month-view-row-height": cssSize(props.rowHeight),
6152
+ "--resources-month-view-group-label-width": cssSize(props.groupLabelWidth)
6153
+ }, attrs.style],
6154
+ "data-event-interaction": dropTarget.value ? true : void 0
6155
+ }, () => [header, h(Box, { class: ResourcesMonthView_module_default.resourcesMonthViewRoot }, () => h(ScrollArea, {
6156
+ scrollbarSize: 4,
6157
+ scrollbars: "x",
6158
+ ...props.scrollAreaProps,
6159
+ class: ResourcesMonthView_module_default.resourcesMonthViewScrollArea
6160
+ }, () => h("div", { class: ResourcesMonthView_module_default.resourcesMonthViewInner }, [h("div", { class: ResourcesMonthView_module_default.resourcesMonthViewDayLabelsRow }, [h("div", {
6161
+ class: ResourcesMonthView_module_default.resourcesMonthViewCorner,
6162
+ style: hasGroups ? {
6163
+ flexBasis: "calc(var(--resources-month-view-resource-label-width) + var(--resources-month-view-group-label-width))",
6164
+ minWidth: "calc(var(--resources-month-view-resource-label-width) + var(--resources-month-view-group-label-width))"
6165
+ } : void 0
6166
+ }, slots.corner?.({ resources: ordered.value.orderedResources }) ?? getLabel("resources", props.labels)), ...labels]), ...rows])))]);
6167
+ };
6168
+ }
6169
+ });
6170
+ var ResourcesSchedule_module_default = { root: "_root_13xbl_1" };
6171
+ //#endregion
6172
+ //#region src/components/ResourcesSchedule/ResourcesSchedule.ts
6173
+ var ResourcesSchedule = defineComponent({
6174
+ name: "ResourcesSchedule",
6175
+ inheritAttrs: false,
6176
+ slots: Object,
6177
+ props: {
6178
+ resources: {
6179
+ type: Array,
6180
+ required: true
6181
+ },
6182
+ date: [String, Date],
6183
+ defaultDate: [String, Date],
6184
+ onDateChange: Function,
6185
+ view: String,
6186
+ defaultView: {
6187
+ type: String,
6188
+ default: "day"
6189
+ },
6190
+ onViewChange: Function,
6191
+ events: Array,
6192
+ locale: String,
6193
+ radius: [String, Number],
6194
+ labels: Object,
6195
+ renderEventBody: Function,
6196
+ renderResourceLabel: Function,
6197
+ withEventsDragAndDrop: Boolean,
6198
+ onEventDrop: Function,
6199
+ canDragEvent: Function,
6200
+ onEventDragStart: Function,
6201
+ onEventDragEnd: Function,
6202
+ onTimeSlotClick: Function,
6203
+ onDayClick: Function,
6204
+ onEventClick: Function,
6205
+ withDragSlotSelect: Boolean,
6206
+ onSlotDragEnd: Function,
6207
+ mode: {
6208
+ type: String,
6209
+ default: "default"
6210
+ },
6211
+ onExternalEventDrop: Function,
6212
+ withEventResize: Boolean,
6213
+ onEventResize: Function,
6214
+ canResizeEvent: Function,
6215
+ recurrenceExpansionLimit: {
6216
+ type: Number,
6217
+ default: 2e3
6218
+ },
6219
+ dayViewProps: Object,
6220
+ weekViewProps: Object,
6221
+ monthViewProps: Object
6222
+ },
6223
+ setup(props, { attrs, slots }) {
6224
+ const currentDate = ref(toDateString(props.date ?? props.defaultDate ?? dayjs()));
6225
+ const currentView = ref(props.view ?? props.defaultView);
6226
+ watch(() => props.date, (value) => {
6227
+ if (value !== void 0) currentDate.value = toDateString(value);
6228
+ });
6229
+ watch(() => props.view, (value) => {
6230
+ if (value !== void 0) currentView.value = value;
6231
+ });
6232
+ const changeDate = (date) => {
6233
+ if (props.date === void 0) currentDate.value = date;
6234
+ props.onDateChange?.(date);
6235
+ };
6236
+ const changeView = (view) => {
6237
+ if (view !== "day" && view !== "week" && view !== "month") return;
6238
+ if (props.view === void 0) currentView.value = view;
6239
+ props.onViewChange?.(view);
6240
+ };
6241
+ return () => {
6242
+ const isStatic = props.mode === "static";
6243
+ const shared = {
6244
+ resources: props.resources,
6245
+ date: currentDate.value,
6246
+ onDateChange: changeDate,
6247
+ onViewChange: changeView,
6248
+ events: props.events,
6249
+ locale: props.locale,
6250
+ radius: props.radius,
6251
+ labels: props.labels,
6252
+ renderEventBody: props.renderEventBody,
6253
+ renderResourceLabel: props.renderResourceLabel,
6254
+ withEventsDragAndDrop: isStatic ? false : props.withEventsDragAndDrop,
6255
+ onEventDrop: props.onEventDrop,
6256
+ canDragEvent: props.canDragEvent,
6257
+ onEventDragStart: props.onEventDragStart,
6258
+ onEventDragEnd: props.onEventDragEnd,
6259
+ onEventClick: props.onEventClick,
6260
+ withDragSlotSelect: props.withDragSlotSelect,
6261
+ onSlotDragEnd: props.onSlotDragEnd,
6262
+ onExternalEventDrop: props.onExternalEventDrop,
6263
+ recurrenceExpansionLimit: props.recurrenceExpansionLimit,
6264
+ mode: props.mode
6265
+ };
6266
+ const forwarded = {};
6267
+ for (const key of Object.keys(slots)) {
6268
+ const slot = slots[key];
6269
+ if (typeof slot === "function") forwarded[key] = slot;
6270
+ }
6271
+ const forwardedSlots = Object.keys(forwarded).length ? forwarded : void 0;
6272
+ const content = (() => {
6273
+ switch (currentView.value) {
6274
+ case "day": return h(ResourcesDayView, {
6275
+ ...shared,
6276
+ onTimeSlotClick: props.onTimeSlotClick,
6277
+ withEventResize: isStatic ? false : props.withEventResize,
6278
+ onEventResize: props.onEventResize,
6279
+ canResizeEvent: props.canResizeEvent,
6280
+ ...props.dayViewProps
6281
+ }, forwardedSlots);
6282
+ case "week": return h(ResourcesWeekView, {
6283
+ ...shared,
6284
+ onTimeSlotClick: props.onTimeSlotClick,
6285
+ withEventResize: isStatic ? false : props.withEventResize,
6286
+ onEventResize: props.onEventResize,
6287
+ canResizeEvent: props.canResizeEvent,
6288
+ ...props.weekViewProps
6289
+ }, forwardedSlots);
6290
+ case "month": return h(ResourcesMonthView, {
6291
+ ...shared,
6292
+ onDayClick: props.onDayClick,
6293
+ ...props.monthViewProps
6294
+ }, forwardedSlots);
6295
+ default: return null;
6296
+ }
6297
+ })();
6298
+ return h(Box, {
6299
+ ...attrs,
6300
+ class: [ResourcesSchedule_module_default.root, attrs.class],
6301
+ style: attrs.style
6302
+ }, () => [content]);
6303
+ };
6304
+ }
6305
+ });
6306
+ //#endregion
4090
6307
  //#region src/components/DragContext/DragContext.ts
4091
6308
  var DragContext = Symbol("mantine-schedule-drag-context");
4092
6309
  function provideDragContext(value) {
@@ -4101,6 +6318,6 @@ function useDragContext() {
4101
6318
  });
4102
6319
  }
4103
6320
  //#endregion
4104
- export { CurrentTimeIndicator, DEFAULT_SCHEDULE_LABELS, DayView, DragContext, HeaderControl, MobileMonthView, MonthView, MonthYearSelect, MoreEvents, Schedule, ScheduleEvent, ScheduleHeader, ScheduleHeaderBase, ScheduleHeaderNext, ScheduleHeaderPrevious, ScheduleHeaderToday, ViewSelect, WeekView, YearView, calculateDropTime, calculateMonthDropDate, clampIntervalMinutes, createHeaderNavigation, expandRecurringEvents, formatDate, getBusinessHoursMod, getCurrentTimePosition, getDayPosition, getDayPositionedEvents, getDayTimeIntervals, getDayViewEvents, getEndOfWeek, getLabel, getMonthDays, getMonthPositionedEvents, getMonthRange, getMonthViewEvents, getMonthsByQuarter, getMonthsList, getRenderableMonthEventSegments, getStartOfWeek, getVisibleEvents, getWeekDays, getWeekLabel, getWeekNumber, getWeekPositionedEvents, getWeekViewEvents, getWeekdaysNames, getYearsList, isAfterMinDate, isAllDayEvent, isBeforeMaxDate, isEventInTimeRange, isEventsOverlap, isInTimeRange, isMultidayEvent, isSameMonth, isWithinWeek, nextWeek, parseTimeString, previousWeek, provideDragContext, sortEvents, toDateString, toTimeString, useDragContext, validateEvent };
6321
+ export { CurrentTimeIndicator, DEFAULT_SCHEDULE_LABELS, DayView, DragContext, HeaderControl, MobileMonthView, MonthView, MonthYearSelect, MoreEvents, ResourcesDayView, ResourcesMonthView, ResourcesSchedule, ResourcesWeekView, Schedule, ScheduleEvent, ScheduleHeader, ScheduleHeaderBase, ScheduleHeaderNext, ScheduleHeaderPrevious, ScheduleHeaderToday, ViewSelect, WeekView, YearView, calculateDropTime, calculateMonthDropDate, clampIntervalMinutes, createHeaderNavigation, expandRecurringEvents, formatDate, getBusinessHoursMod, getCurrentTimePosition, getDayPosition, getDayPositionedEvents, getDayTimeIntervals, getDayViewEvents, getEndOfWeek, getGroupToResourceIdMap, getLabel, getMonthDays, getMonthPositionedEvents, getMonthRange, getMonthViewEvents, getMonthsByQuarter, getMonthsList, getOrderedResources, getOverlapClusters, getRenderableMonthEventSegments, getResourcesDayViewEvents, getResourcesWeekViewEvents, getStartOfWeek, getVisibleEvents, getWeekDays, getWeekLabel, getWeekNumber, getWeekPositionedEvents, getWeekViewEvents, getWeekdaysNames, getYearsList, handleResourcesGridKeyDown, isAfterMinDate, isAllDayEvent, isBeforeMaxDate, isEventInTimeRange, isEventsOverlap, isInTimeRange, isMultidayEvent, isSameMonth, isWithinWeek, nextWeek, parseTimeString, previousWeek, provideDragContext, sortEvents, toDateString, toTimeString, useDragContext, validateEvent };
4105
6322
 
4106
6323
  //# sourceMappingURL=index.mjs.map