@mogura/moguchart-core 0.9.1 → 0.10.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.
@@ -21,6 +21,7 @@ export declare class GanttBarElement extends LitElement {
21
21
  private getX;
22
22
  private setupDragEvents;
23
23
  private onResizeStart;
24
+ private getGanttChartElement;
24
25
  /** ドラッグ開始と判定するための移動閾値(px) */
25
26
  private static readonly DRAG_THRESHOLD;
26
27
  private onMoveStart;
@@ -355,6 +355,8 @@ export interface GanttChartOption {
355
355
  customTheme?: Partial<ThemeColorPalette>;
356
356
  /** 行の並び替えを有効にするかどうか */
357
357
  enableRowReordering?: boolean;
358
+ /** タスクの行間移動を有効にするかどうか (デフォルト: true) */
359
+ enableCrossRowMove?: boolean;
358
360
  /** スナップする時間単位(分)。デフォルトは1440(1日) */
359
361
  snapDuration?: number;
360
362
  /** 非表示に設定された行を表示するかどうか (デフォルト: false) */
@@ -400,10 +402,20 @@ export interface TaskUpdateEventDetail extends GanttTask {
400
402
  x?: number;
401
403
  /** マウスのY座標(ドラッグ中のみ) */
402
404
  y?: number;
405
+ /** タスクバーの中心X座標(ドラッグ中のみ) */
406
+ barX?: number;
407
+ /** タスクバーの上端Y座標(ドラッグ中のみ) */
408
+ barTop?: number;
409
+ /** タスクバーの下端Y座標(ドラッグ中のみ) */
410
+ barBottom?: number;
403
411
  /** タスク移動モード(move/copy) */
404
412
  mode: GanttTaskMoveMode;
405
413
  /** 複数選択移動時の対象タスクID配列 */
406
414
  selectedTaskIds?: string[];
415
+ /** ガントチャート外にカーソルがあるかどうか */
416
+ isOutside?: boolean;
417
+ /** ドラッグがキャンセルされたかどうか */
418
+ isCancel?: boolean;
407
419
  }
408
420
  /**
409
421
  * バーのホバーイベント詳細
@@ -277,7 +277,7 @@ var R = (e, t, n) => {
277
277
  BORDER: "#e2e8f0"
278
278
  }.BAR;
279
279
  //#endregion
280
- //#region \0@oxc-project+runtime@0.144.0/helpers/esm/decorate.js
280
+ //#region \0@oxc-project+runtime@0.146.0/helpers/esm/decorate.js
281
281
  function B(e, t, n, r) {
282
282
  var i = arguments.length, a = i < 3 ? t : r === null ? r = Object.getOwnPropertyDescriptor(t, n) : r, o;
283
283
  if (typeof Reflect == "object" && typeof Reflect.decorate == "function") a = Reflect.decorate(e, t, n, r);
@@ -514,6 +514,7 @@ var V, H = class extends e {
514
514
  s.style.left = `${e}px`, s.style.width = `${t}px`;
515
515
  }
516
516
  this._dragAnimationFrame && cancelAnimationFrame(this._dragAnimationFrame), this._dragAnimationFrame = requestAnimationFrame(() => {
517
+ let t = s?.getBoundingClientRect();
517
518
  this.dispatchEvent(new CustomEvent("task-update", {
518
519
  detail: {
519
520
  ...this.task,
@@ -522,7 +523,10 @@ var V, H = class extends e {
522
523
  dy: 0,
523
524
  isDragging: !0,
524
525
  x: e.clientX,
525
- y: e.clientY
526
+ y: e.clientY,
527
+ barX: t ? t.left + t.width / 2 : void 0,
528
+ barTop: t?.top,
529
+ barBottom: t?.bottom
526
530
  },
527
531
  bubbles: !0,
528
532
  composed: !0
@@ -560,6 +564,16 @@ var V, H = class extends e {
560
564
  });
561
565
  });
562
566
  }
567
+ getGanttChartElement() {
568
+ let e = this;
569
+ for (; e;) {
570
+ if (e instanceof HTMLElement && e.tagName.toLowerCase() === "gantt-chart") return e;
571
+ if (e.parentNode) e = e.parentNode;
572
+ else if (e.host) e = e.host;
573
+ else break;
574
+ }
575
+ return null;
576
+ }
563
577
  static {
564
578
  this.DRAG_THRESHOLD = 3;
565
579
  }
@@ -571,97 +585,136 @@ var V, H = class extends e {
571
585
  let r = this.task.movable ?? "both";
572
586
  if (r === "none") return;
573
587
  t.setPointerCapture(e.pointerId);
574
- let i = e.clientX, a = e.clientY, o = new Date(this.task.start), s = new Date(this.task.end), c = this.option.snapDuration ?? 1440, l = !1;
588
+ let i = this.getGanttChartElement(), a = e.clientX, o = e.clientY, s = new Date(this.task.start), c = new Date(this.task.end), l = this.option.snapDuration ?? 1440, u = !1, d = (e, t) => {
589
+ if (!i) return !1;
590
+ let n = i.getBoundingClientRect();
591
+ if (e < n.left || e > n.right || t < n.top || t > n.bottom) return !0;
592
+ if (this.option.enableCrossRowMove !== !1) {
593
+ let e = i.shadowRoot?.querySelectorAll("gantt-row");
594
+ if (e && e.length > 0) {
595
+ let n = e[0].getBoundingClientRect(), r = e[e.length - 1].getBoundingClientRect();
596
+ if (r.bottom > n.top && (t < n.top || t > r.bottom)) return !0;
597
+ }
598
+ }
599
+ return !1;
600
+ };
575
601
  this.setupDragEvents(t, e.pointerId, (e) => {
576
- let u = e.clientX - i, d = e.clientY - a;
577
- if (!l) {
578
- if (Math.abs(u) < V.DRAG_THRESHOLD && Math.abs(d) < V.DRAG_THRESHOLD) return;
579
- l = !0;
602
+ let i = e.clientX - a, f = e.clientY - o;
603
+ if (!u) {
604
+ if (Math.abs(i) < V.DRAG_THRESHOLD && Math.abs(f) < V.DRAG_THRESHOLD) return;
605
+ u = !0;
580
606
  let r = e.ctrlKey || e.altKey ? "copy" : "grabbing";
581
607
  this._currentDragCursor = r, t.style.cursor = r, n.classList.add("dragging");
582
608
  }
583
- let f = e.ctrlKey || e.altKey ? "copy" : "grabbing";
584
- this._currentDragCursor = f, t.style.cursor = f;
585
- let p = u, m = d;
586
- r === "y" && (p = 0), r === "x" && (m = 0), this.multiDragActive && !this.multiDragSameRow && (m = 0);
587
- let h = p;
609
+ let p = e.ctrlKey || e.altKey, m = p ? "copy" : "grabbing";
610
+ if (this._currentDragCursor = m, t.style.cursor = m, d(e.clientX, e.clientY)) {
611
+ n.style.transform = "", this._dragAnimationFrame && cancelAnimationFrame(this._dragAnimationFrame), this._dragAnimationFrame = requestAnimationFrame(() => {
612
+ this.dispatchEvent(new CustomEvent("task-update", {
613
+ detail: {
614
+ ...this.task,
615
+ start: s,
616
+ end: c,
617
+ dx: 0,
618
+ dy: 0,
619
+ isDragging: !0,
620
+ isOutside: !0,
621
+ x: e.clientX,
622
+ y: e.clientY,
623
+ mode: p ? "copy" : "move"
624
+ },
625
+ bubbles: !0,
626
+ composed: !0
627
+ }));
628
+ });
629
+ return;
630
+ }
631
+ let h = i, g = f;
632
+ r === "y" && (h = 0), r === "x" && (g = 0), this.option.enableCrossRowMove === !1 && (g = 0), this.multiDragActive && !this.multiDragSameRow && (g = 0);
633
+ let _ = h;
588
634
  if (this.option.calendar.pxPerMonth) {
589
- let e = N(this.getX(o) + p, this.option.calendar.start, 50, this.option.calendar.pxPerMonth), t = (e.getFullYear() - o.getFullYear()) * 12 + (e.getMonth() - o.getMonth()) + +(e.getDate() > 15), n = new Date(o);
590
- n.setMonth(n.getMonth() + t), h = this.getX(n) - this.getX(o);
635
+ let e = N(this.getX(s) + h, this.option.calendar.start, 50, this.option.calendar.pxPerMonth), t = (e.getFullYear() - s.getFullYear()) * 12 + (e.getMonth() - s.getMonth()) + +(e.getDate() > 15), n = new Date(s);
636
+ n.setMonth(n.getMonth() + t), _ = this.getX(n) - this.getX(s);
591
637
  } else {
592
- let e = this.option.calendar.pxPerDay / 1440 * c;
593
- h = Math.round(p / e) * e;
638
+ let e = this.option.calendar.pxPerDay / 1440 * l;
639
+ _ = Math.round(h / e) * e;
594
640
  }
595
- n.style.transform = `translate(${h}px, ${m}px)`, this._dragAnimationFrame && cancelAnimationFrame(this._dragAnimationFrame), this._dragAnimationFrame = requestAnimationFrame(() => {
596
- let t = e.ctrlKey || e.altKey;
641
+ n.style.transform = `translate(${_}px, ${g}px)`, this._dragAnimationFrame && cancelAnimationFrame(this._dragAnimationFrame), this._dragAnimationFrame = requestAnimationFrame(() => {
642
+ let t = n?.getBoundingClientRect();
597
643
  this.dispatchEvent(new CustomEvent("task-update", {
598
644
  detail: {
599
645
  ...this.task,
600
- start: o,
601
- end: s,
602
- dx: h,
603
- dy: m,
646
+ start: s,
647
+ end: c,
648
+ dx: _,
649
+ dy: g,
604
650
  isDragging: !0,
651
+ isOutside: !1,
605
652
  x: e.clientX,
606
653
  y: e.clientY,
607
- mode: t ? "copy" : "move"
654
+ barX: t ? t.left + t.width / 2 : void 0,
655
+ barTop: t?.top,
656
+ barBottom: t?.bottom,
657
+ mode: p ? "copy" : "move"
608
658
  },
609
659
  bubbles: !0,
610
660
  composed: !0
611
661
  }));
612
662
  });
613
- }, (e, u) => {
614
- if (this._currentDragCursor = null, n.classList.remove("dragging"), n.style.transform = "", t.style.cursor = "", this._dragAnimationFrame &&= (cancelAnimationFrame(this._dragAnimationFrame), null), !l) {
615
- u && (this.dispatchEvent(new CustomEvent("bar-click", {
663
+ }, (e, i) => {
664
+ if (this._currentDragCursor = null, n.classList.remove("dragging"), n.style.transform = "", t.style.cursor = "", this._dragAnimationFrame &&= (cancelAnimationFrame(this._dragAnimationFrame), null), !u) {
665
+ i && (this.dispatchEvent(new CustomEvent("bar-click", {
616
666
  detail: {
617
667
  task: this.task,
618
- event: u,
619
- isMultiSelect: u.metaKey || u.ctrlKey
668
+ event: i,
669
+ isMultiSelect: i.metaKey || i.ctrlKey
620
670
  },
621
671
  bubbles: !0,
622
672
  composed: !0
623
673
  })), this._wasDragging = !0);
624
674
  return;
625
675
  }
626
- if (e) this.requestUpdate(), this.dispatchEvent(new CustomEvent("task-update", {
676
+ let f = i ? d(i.clientX, i.clientY) : !1;
677
+ if (e || f) this._wasDragging = !0, this.requestUpdate(), this.dispatchEvent(new CustomEvent("task-update", {
627
678
  detail: {
628
679
  ...this.task,
629
- start: o,
630
- end: s,
680
+ start: s,
681
+ end: c,
631
682
  dx: 0,
632
683
  dy: 0,
633
- isDragging: !1
684
+ isDragging: !1,
685
+ isCancel: !0,
686
+ isOutside: f
634
687
  },
635
688
  bubbles: !0,
636
689
  composed: !0
637
690
  }));
638
- else if (u) {
639
- let e = u.clientX - i, t = e;
691
+ else if (i) {
692
+ let e = i.clientX - a, t = e;
640
693
  if (this.option.calendar.pxPerMonth) {
641
- let n = N(this.getX(o) + e, this.option.calendar.start, 50, this.option.calendar.pxPerMonth), r = (n.getFullYear() - o.getFullYear()) * 12 + (n.getMonth() - o.getMonth()) + +(n.getDate() > 15), i = new Date(o);
642
- i.setMonth(i.getMonth() + r), t = this.getX(i) - this.getX(o);
694
+ let n = N(this.getX(s) + e, this.option.calendar.start, 50, this.option.calendar.pxPerMonth), r = (n.getFullYear() - s.getFullYear()) * 12 + (n.getMonth() - s.getMonth()) + +(n.getDate() > 15), i = new Date(s);
695
+ i.setMonth(i.getMonth() + r), t = this.getX(i) - this.getX(s);
643
696
  } else {
644
- let n = this.option.calendar.pxPerDay / 1440 * c;
697
+ let n = this.option.calendar.pxPerDay / 1440 * l;
645
698
  t = Math.round(e / n) * n;
646
699
  }
647
- let n = u.clientY - a;
648
- if (r === "y" && (t = 0), r === "x" && (n = 0), this.multiDragActive && !this.multiDragSameRow && (n = 0), t === 0 && Math.abs(n) < 5) {
700
+ let n = i.clientY - o;
701
+ if (r === "y" && (t = 0), r === "x" && (n = 0), this.option.enableCrossRowMove === !1 && (n = 0), this.multiDragActive && !this.multiDragSameRow && (n = 0), t === 0 && Math.abs(n) < 5) {
649
702
  this.dispatchEvent(new CustomEvent("bar-click", {
650
703
  detail: {
651
704
  task: this.task,
652
- event: u,
653
- isMultiSelect: u.metaKey || u.ctrlKey
705
+ event: i,
706
+ isMultiSelect: i.metaKey || i.ctrlKey
654
707
  },
655
708
  bubbles: !0,
656
709
  composed: !0
657
710
  })), this._wasDragging = !0;
658
711
  return;
659
712
  }
660
- let l = u.ctrlKey || u.altKey;
713
+ let u = i.ctrlKey || i.altKey;
661
714
  this._wasDragging = !0, this.multiDragActive || this.dispatchEvent(new CustomEvent("bar-click", {
662
715
  detail: {
663
716
  task: this.task,
664
- event: u,
717
+ event: i,
665
718
  isMultiSelect: !1
666
719
  },
667
720
  bubbles: !0,
@@ -669,12 +722,13 @@ var V, H = class extends e {
669
722
  })), this.dispatchEvent(new CustomEvent("task-update", {
670
723
  detail: {
671
724
  ...this.task,
672
- start: o,
673
- end: s,
725
+ start: s,
726
+ end: c,
674
727
  dx: t,
675
728
  dy: n,
676
729
  isDragging: !1,
677
- mode: l ? "copy" : "move"
730
+ isOutside: !1,
731
+ mode: u ? "copy" : "move"
678
732
  },
679
733
  bubbles: !0,
680
734
  composed: !0
@@ -2556,16 +2610,16 @@ var Q = class extends e {
2556
2610
  ${i ? n`<div class="drag-info-sub" style="margin-top: 4px; border-top: 1px solid ${e.dragOverlayDivider}; padding-top: 4px; width: 100%;">${(this.option.locale ?? k).dragOverlay.moveTo(i.name)}</div>` : ""}
2557
2611
  `, t);
2558
2612
  }
2559
- if (this.dragOverlayInfo.clientY !== void 0) {
2560
- let e = this.dragOverlayInfo.clientX ?? 0, n = this.dragOverlayInfo.clientY, r = this.getBoundingClientRect();
2561
- if (e < r.left || e > r.right || n < r.top || n > r.bottom) {
2613
+ if (this.dragOverlayInfo.barTop !== void 0 || this.dragOverlayInfo.clientY !== void 0) {
2614
+ let e = this.dragOverlayInfo.clientX ?? 0, n = this.dragOverlayInfo.clientY ?? 0, r = this.getBoundingClientRect();
2615
+ if (this.dragOverlayInfo.clientY !== void 0 && (e < r.left || e > r.right || n < r.top || n > r.bottom)) {
2562
2616
  t.classList.remove("visible");
2563
2617
  return;
2564
2618
  }
2565
- let i = t.offsetWidth || 200, a = t.offsetHeight || 60, o = window.innerWidth, s = window.innerHeight, c = e - i / 2;
2566
- c = Math.max(8, Math.min(c, o - i - 8));
2567
- let l = n - a - 40;
2568
- l < 8 && (l = n + 40), l + a > s - 8 && (l = s - a - 8), t.style.left = `${c}px`, t.style.transform = "none", t.style.top = `${l}px`, t.style.bottom = "auto";
2619
+ let i = t.offsetWidth || 200, a = t.offsetHeight || 60, o = window.innerWidth, s = window.innerHeight, c = this.dragOverlayInfo.barX ?? e, l = this.dragOverlayInfo.barTop ?? n, u = this.dragOverlayInfo.barBottom ?? n, d = c - i / 2;
2620
+ d = Math.max(8, Math.min(d, o - i - 8));
2621
+ let f = l - a - 10;
2622
+ f < 8 && (f = u + 10), f + a > s - 8 && (f = s - a - 8), t.style.left = `${d}px`, t.style.transform = "none", t.style.top = `${f}px`, t.style.bottom = "auto";
2569
2623
  }
2570
2624
  }
2571
2625
  hideDragOverlay() {
@@ -2658,28 +2712,39 @@ var Q = class extends e {
2658
2712
  }), f === -1 || !p) return;
2659
2713
  let { layouts: h } = this.calculateLayout(), g = this.displayRows.findIndex((e) => e.id === this.rows[f].id);
2660
2714
  if (g === -1) return;
2661
- let _ = h[g].top, { tasksWithLanes: v } = P(this.rows[f].tasks), y = v.find((e) => e.id === t), b = y ? y.lane : 0, x = this.option.bar?.height ?? 28, S = this.option.bar?.margin ?? 4, C = _ + (b * (x + S) + S) + s + x / 2, w = -1;
2662
- for (let e = 0; e < h.length; e++) {
2715
+ let _ = h[g].top, { tasksWithLanes: v } = P(this.rows[f].tasks), y = v.find((e) => e.id === t), b = y ? y.lane : 0, x = this.option.bar?.height ?? 28, S = this.option.bar?.margin ?? 4, C = _ + (b * (x + S) + S) + s + x / 2, w = this.option.enableCrossRowMove !== !1, T = -1;
2716
+ if (w) for (let e = 0; e < h.length; e++) {
2663
2717
  let t = h[e];
2664
2718
  if (C >= t.top && C < t.top + t.height) {
2665
- w = e;
2719
+ T = e;
2666
2720
  break;
2667
2721
  }
2668
2722
  }
2669
- let T = w === -1 ? void 0 : this.displayRows[w].id, E = c ? [...this.selectedTasks] : void 0;
2723
+ else {
2724
+ let e = this.rows[f];
2725
+ T = this.displayRows.findIndex((t) => t.id === e.id);
2726
+ }
2727
+ let E = T === -1 ? void 0 : this.displayRows[T].id, D = c ? [...this.selectedTasks] : void 0;
2670
2728
  if (this.dispatchEvent(new CustomEvent("task-update", {
2671
2729
  detail: {
2672
2730
  ...e.detail,
2673
2731
  dy: s,
2674
2732
  start: u,
2675
2733
  end: d,
2676
- targetRowId: T,
2677
- selectedTaskIds: E
2734
+ targetRowId: E,
2735
+ selectedTaskIds: D
2678
2736
  },
2679
2737
  bubbles: !0,
2680
2738
  composed: !0
2681
2739
  })), a) {
2682
- if (this.hoverTimer !== void 0 && window.clearTimeout(this.hoverTimer), this.tooltip &&= null, (!this.draggingTask || this.draggingTask.id !== t) && (this.draggingTask = {
2740
+ if (this.hoverTimer !== void 0 && window.clearTimeout(this.hoverTimer), this.tooltip &&= null, e.detail.isOutside || w && T === -1) {
2741
+ this.multiDragDx = 0, this.multiDragDy = 0, this.dragTargetRowIndex = null, this.dragOverlayInfo && (this.dragOverlayInfo = {
2742
+ ...this.dragOverlayInfo,
2743
+ visible: !1
2744
+ }, this.hideDragOverlay());
2745
+ return;
2746
+ }
2747
+ if ((!this.draggingTask || this.draggingTask.id !== t) && (this.draggingTask = {
2683
2748
  id: t,
2684
2749
  name: e.detail.name,
2685
2750
  start: n,
@@ -2688,7 +2753,7 @@ var Q = class extends e {
2688
2753
  currentEnd: d,
2689
2754
  mode: o
2690
2755
  }, this.draggingTaskIds = c ? [...this.selectedTasks] : []), c ? (this.multiDragDx = i ?? 0, this.multiDragSameRow = l, this.multiDragDy = l ? s : 0) : (this.multiDragDx !== 0 || this.multiDragDy !== 0) && (this.multiDragDx = 0, this.multiDragDy = 0), !c || l) {
2691
- let e = w >= 0 ? w : null;
2756
+ let e = T >= 0 ? T : null;
2692
2757
  this.dragTargetRowIndex !== e && (this.dragTargetRowIndex = e);
2693
2758
  }
2694
2759
  this.dragOverlayInfo = c ? {
@@ -2700,7 +2765,10 @@ var Q = class extends e {
2700
2765
  currentEnd: d,
2701
2766
  visible: !0,
2702
2767
  clientX: e.detail.x,
2703
- clientY: e.detail.y
2768
+ clientY: e.detail.y,
2769
+ barX: e.detail.barX,
2770
+ barTop: e.detail.barTop,
2771
+ barBottom: e.detail.barBottom
2704
2772
  } : {
2705
2773
  id: t,
2706
2774
  name: e.detail.name,
@@ -2708,30 +2776,33 @@ var Q = class extends e {
2708
2776
  end: r,
2709
2777
  currentStart: u,
2710
2778
  currentEnd: d,
2711
- targetRow: w >= 0 ? this.displayRows[w] : void 0,
2779
+ targetRow: T >= 0 && this.displayRows[T]?.id !== this.rows[f]?.id ? this.displayRows[T] : void 0,
2712
2780
  visible: !0,
2713
2781
  clientX: e.detail.x,
2714
- clientY: e.detail.y
2782
+ clientY: e.detail.y,
2783
+ barX: e.detail.barX,
2784
+ barTop: e.detail.barTop,
2785
+ barBottom: e.detail.barBottom
2715
2786
  }, this.updateDragOverlay();
2716
2787
  return;
2717
2788
  }
2718
- let D = this.draggingTaskIds.length >= 2, O = this.multiDragSameRow;
2719
- this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.dragTargetRowIndex = null, this.dragOverlayInfo && (this.dragOverlayInfo = {
2789
+ let O = this.draggingTaskIds.length >= 2, A = this.multiDragSameRow;
2790
+ if (this.draggingTask = null, this.draggingTaskIds = [], this.multiDragDx = 0, this.multiDragDy = 0, this.multiDragSameRow = !1, this.dragTargetRowIndex = null, this.dragOverlayInfo && (this.dragOverlayInfo = {
2720
2791
  ...this.dragOverlayInfo,
2721
2792
  visible: !1
2722
2793
  }, this.hideDragOverlay()), this.tooltip &&= {
2723
2794
  ...this.tooltip,
2724
2795
  visible: !1
2725
- };
2726
- let A = -1;
2727
- if (w !== -1) {
2728
- let e = this.displayRows[w];
2729
- A = this.rows.findIndex((t) => t.id === e.id);
2796
+ }, e.detail.isCancel || e.detail.isOutside || w && T === -1) return;
2797
+ let j = -1;
2798
+ if (T !== -1) {
2799
+ let e = this.displayRows[T];
2800
+ j = this.rows.findIndex((t) => t.id === e.id);
2730
2801
  }
2731
- if (D && i !== void 0) {
2802
+ if (O && i !== void 0) {
2732
2803
  let e = this.effectivePxPerDay, t = this.effectivePxPerMonth;
2733
- if (O && A !== -1 && f !== A) {
2734
- let n = [...this.rows], r = { ...n[f] }, a = { ...n[A] };
2804
+ if (A && j !== -1 && f !== j) {
2805
+ let n = [...this.rows], r = { ...n[f] }, a = { ...n[j] };
2735
2806
  r.tasks = [...r.tasks], a.tasks = [...a.tasks];
2736
2807
  let o = [];
2737
2808
  r.tasks = r.tasks.filter((n) => {
@@ -2744,7 +2815,7 @@ var Q = class extends e {
2744
2815
  }), !1;
2745
2816
  }
2746
2817
  return !0;
2747
- }), a.tasks.push(...o), n[f] = r, n[A] = a, requestAnimationFrame(() => {
2818
+ }), a.tasks.push(...o), n[f] = r, n[j] = a, requestAnimationFrame(() => {
2748
2819
  this.rows = n, this.dispatchEvent(new CustomEvent("rows-change", {
2749
2820
  detail: this.rows,
2750
2821
  bubbles: !0,
@@ -2775,8 +2846,8 @@ var Q = class extends e {
2775
2846
  return;
2776
2847
  }
2777
2848
  if (o === "copy") {
2778
- if (A !== -1) {
2779
- let e = [...this.rows], t = { ...e[A] };
2849
+ if (j !== -1) {
2850
+ let e = [...this.rows], t = { ...e[j] };
2780
2851
  t.tasks = [...t.tasks];
2781
2852
  let n = `task-${Date.now()}-${Math.random().toString(36).substr(2, 9)}`, r = {
2782
2853
  ...p,
@@ -2785,7 +2856,7 @@ var Q = class extends e {
2785
2856
  end: d,
2786
2857
  dependencies: []
2787
2858
  };
2788
- t.tasks.push(r), e[A] = t, requestAnimationFrame(() => {
2859
+ t.tasks.push(r), e[j] = t, requestAnimationFrame(() => {
2789
2860
  this.rows = e, this.dispatchEvent(new CustomEvent("rows-change", {
2790
2861
  detail: this.rows,
2791
2862
  bubbles: !0,
@@ -2795,9 +2866,9 @@ var Q = class extends e {
2795
2866
  }
2796
2867
  } else {
2797
2868
  let e = [...this.rows], t = { ...e[f] };
2798
- if (t.tasks = [...t.tasks], e[f] = t, A !== -1 && f !== A) {
2799
- let n = { ...e[A] };
2800
- n.tasks = [...n.tasks], e[A] = n;
2869
+ if (t.tasks = [...t.tasks], e[f] = t, j !== -1 && f !== j) {
2870
+ let n = { ...e[j] };
2871
+ n.tasks = [...n.tasks], e[j] = n;
2801
2872
  let [r] = t.tasks.splice(m, 1);
2802
2873
  n.tasks.push({
2803
2874
  ...r,
@@ -215,7 +215,7 @@
215
215
  filter: brightness(1.08);
216
216
  }
217
217
  }
218
- `}getX(e){return P(e,this.option.calendar.start,this.option.calendar.pxPerDay??50,this.option.calendar.pxPerMonth)}setupDragEvents(e,t,n,r){let i=()=>{e.releasePointerCapture(t),window.removeEventListener(`pointermove`,a),window.removeEventListener(`pointerup`,o),window.removeEventListener(`keydown`,s)},a=e=>{n(e)},o=e=>{i(),r(!1,e)},s=e=>{e.key===`Escape`&&(i(),r(!0))};window.addEventListener(`pointermove`,a),window.addEventListener(`pointerup`,o),window.addEventListener(`keydown`,s)}onResizeStart(e,t){e.stopPropagation();let n=e.target,r=this.task.movable??`both`,i=this.task.resizable,a=!this.option.readOnly;if(a&&=i===void 0?r!==`y`&&r!==`none`:i,!a)return;let o=this.shadowRoot?.querySelector(`.bar`);if(!o)return;o.style.pointerEvents=`none`;let s=this.shadowRoot?.querySelector(`.task-group`);s?.classList.add(`dragging`),n.setPointerCapture(e.pointerId);let c=e.clientX,l=new Date(this.task.start),u=new Date(this.task.end),d=new Date(l),f=new Date(u);this.setupDragEvents(n,e.pointerId,e=>{let n=e.clientX-c,r=new Date(l),i=new Date(u),a=this.option.calendar.pxPerDay??50,o=this.option.calendar.pxPerMonth,p=Math.max(this.option.snapDuration??1440,1);if(o){let e=this.getX(l),s=this.getX(u);if(t===`left`){let t=F(e+n,this.option.calendar.start,a,o);t.getDate()>15&&t.setMonth(t.getMonth()+1),t.setDate(1),t.setHours(0,0,0,0),r=t,r>=i&&(r=new Date(i),r.setMonth(r.getMonth()-1))}else{let e=F(s+n,this.option.calendar.start,a,o);e.getDate()>15&&e.setMonth(e.getMonth()+1),e.setDate(1),e.setHours(0,0,0,0),i=e,i<=r&&(i=new Date(r),i.setMonth(i.getMonth()+1))}}else{let e=a/1440,o=e*p,s=Math.round(n/o)*o,c=Math.round(s/e);t===`left`?(r=new Date(l.getTime()+c*60*1e3),r>=i&&(r=new Date(i.getTime()-p*60*1e3))):(i=new Date(u.getTime()+c*60*1e3),i<=r&&(i=new Date(r.getTime()+p*60*1e3)))}if(d=r,f=i,s){let e=this.getX(r),t=this.getX(i)-e;s.style.left=`${e}px`,s.style.width=`${t}px`}this._dragAnimationFrame&&cancelAnimationFrame(this._dragAnimationFrame),this._dragAnimationFrame=requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:r,end:i,dy:0,isDragging:!0,x:e.clientX,y:e.clientY},bubbles:!0,composed:!0}))})},e=>{if(s?.classList.remove(`dragging`),o.style.pointerEvents=``,this._dragAnimationFrame&&=(cancelAnimationFrame(this._dragAnimationFrame),null),e){if(s){let e=this.getX(l),t=this.getX(u)-e;s.style.left=`${e}px`,s.style.width=`${t}px`}this.requestUpdate(),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:l,end:u,dy:0,isDragging:!1},bubbles:!0,composed:!0}))}else requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:d,end:f,dy:0,isDragging:!1},bubbles:!0,composed:!0}))})})}static{this.DRAG_THRESHOLD=3}onMoveStart(e){if(e.button===2)return;e.stopPropagation();let t=e.target,n=this.shadowRoot?.querySelector(`.task-group`);if(!t||!n)return;let r=this.task.movable??`both`;if(r===`none`)return;t.setPointerCapture(e.pointerId);let i=e.clientX,a=e.clientY,o=new Date(this.task.start),s=new Date(this.task.end),c=this.option.snapDuration??1440,l=!1;this.setupDragEvents(t,e.pointerId,e=>{let u=e.clientX-i,d=e.clientY-a;if(!l){if(Math.abs(u)<U.DRAG_THRESHOLD&&Math.abs(d)<U.DRAG_THRESHOLD)return;l=!0;let r=e.ctrlKey||e.altKey?`copy`:`grabbing`;this._currentDragCursor=r,t.style.cursor=r,n.classList.add(`dragging`)}let f=e.ctrlKey||e.altKey?`copy`:`grabbing`;this._currentDragCursor=f,t.style.cursor=f;let p=u,m=d;r===`y`&&(p=0),r===`x`&&(m=0),this.multiDragActive&&!this.multiDragSameRow&&(m=0);let h=p;if(this.option.calendar.pxPerMonth){let e=F(this.getX(o)+p,this.option.calendar.start,50,this.option.calendar.pxPerMonth),t=(e.getFullYear()-o.getFullYear())*12+(e.getMonth()-o.getMonth())+ +(e.getDate()>15),n=new Date(o);n.setMonth(n.getMonth()+t),h=this.getX(n)-this.getX(o)}else{let e=this.option.calendar.pxPerDay/1440*c;h=Math.round(p/e)*e}n.style.transform=`translate(${h}px, ${m}px)`,this._dragAnimationFrame&&cancelAnimationFrame(this._dragAnimationFrame),this._dragAnimationFrame=requestAnimationFrame(()=>{let t=e.ctrlKey||e.altKey;this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:o,end:s,dx:h,dy:m,isDragging:!0,x:e.clientX,y:e.clientY,mode:t?`copy`:`move`},bubbles:!0,composed:!0}))})},(e,u)=>{if(this._currentDragCursor=null,n.classList.remove(`dragging`),n.style.transform=``,t.style.cursor=``,this._dragAnimationFrame&&=(cancelAnimationFrame(this._dragAnimationFrame),null),!l){u&&(this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:u,isMultiSelect:u.metaKey||u.ctrlKey},bubbles:!0,composed:!0})),this._wasDragging=!0);return}if(e)this.requestUpdate(),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:o,end:s,dx:0,dy:0,isDragging:!1},bubbles:!0,composed:!0}));else if(u){let e=u.clientX-i,t=e;if(this.option.calendar.pxPerMonth){let n=F(this.getX(o)+e,this.option.calendar.start,50,this.option.calendar.pxPerMonth),r=(n.getFullYear()-o.getFullYear())*12+(n.getMonth()-o.getMonth())+ +(n.getDate()>15),i=new Date(o);i.setMonth(i.getMonth()+r),t=this.getX(i)-this.getX(o)}else{let n=this.option.calendar.pxPerDay/1440*c;t=Math.round(e/n)*n}let n=u.clientY-a;if(r===`y`&&(t=0),r===`x`&&(n=0),this.multiDragActive&&!this.multiDragSameRow&&(n=0),t===0&&Math.abs(n)<5){this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:u,isMultiSelect:u.metaKey||u.ctrlKey},bubbles:!0,composed:!0})),this._wasDragging=!0;return}let l=u.ctrlKey||u.altKey;this._wasDragging=!0,this.multiDragActive||this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:u,isMultiSelect:!1},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:o,end:s,dx:t,dy:n,isDragging:!1,mode:l?`copy`:`move`},bubbles:!0,composed:!0}))}})}updated(e){super.updated(e);let t=this.shadowRoot?.querySelector(`.bar`);if(t&&(this.option.customRendering?.barContent,this.dispatchEvent(new CustomEvent(`render-bar-content`,{detail:{container:t,task:this.task},bubbles:!0,composed:!0})),this._currentDragCursor?t.style.cursor=this._currentDragCursor:this.option.readOnly||(t.style.cursor=``)),e.has(`multiDragDx`)||e.has(`multiDragDy`)){let e=this.shadowRoot?.querySelector(`.task-group`);e&&(this.multiDragDx!==0||this.multiDragDy!==0?(e.style.transform=`translate(${this.multiDragDx}px, ${this.multiDragDy}px)`,e.style.opacity=`0.6`,e.style.pointerEvents=`none`):(e.style.transform=``,e.style.opacity=``,e.style.pointerEvents=``))}}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener(`keydown`,this.handleKeyDown),window.removeEventListener(`keyup`,this.handleKeyUp)}updateCursor(e){let t=this.shadowRoot?.querySelector(`.bar`);t&&!this._currentDragCursor&&(t.style.cursor=e?`copy`:``)}onMouseEnter(e){let t=e.currentTarget;if(t.classList.contains(`dragging`))return;this.option.readOnly||(window.addEventListener(`keydown`,this.handleKeyDown),window.addEventListener(`keyup`,this.handleKeyUp),(e.ctrlKey||e.altKey)&&this.updateCursor(!0),t.addEventListener(`mousemove`,this.onMouseMoveOnBar));let n=t.getBoundingClientRect();this.dispatchEvent(new CustomEvent(`bar-mouseenter`,{detail:{task:this.task,x:n.left+n.width/2,y:n.top,barBottom:n.bottom},bubbles:!0,composed:!0}))}onMouseLeave(){let e=this.shadowRoot?.querySelector(`.task-group`);if(!this.option.readOnly){window.removeEventListener(`keydown`,this.handleKeyDown),window.removeEventListener(`keyup`,this.handleKeyUp),this.updateCursor(!1),e&&e.removeEventListener(`mousemove`,this.onMouseMoveOnBar);let t=this.shadowRoot?.querySelector(`.connector-left`),n=this.shadowRoot?.querySelector(`.connector-right`);t&&t.classList.remove(`show-connector`),n&&n.classList.remove(`show-connector`)}this.dispatchEvent(new CustomEvent(`bar-mouseleave`,{bubbles:!0,composed:!0}))}onDblClick(e){this.dispatchEvent(new CustomEvent(`task-dblclick`,{detail:{task:this.task,event:e},bubbles:!0,composed:!0}))}onClick(e){if(e.stopPropagation(),this._wasDragging){this._wasDragging=!1;return}this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:e,isMultiSelect:e.metaKey||e.ctrlKey},bubbles:!0,composed:!0}))}onConnectorDragStart(e,t){e.stopPropagation(),e.preventDefault();let n=e.target;if(n.setPointerCapture(e.pointerId),!this.shadowRoot?.querySelector(`.task-group`))return;let r=this.option.bar?.height??28,i=this.option.bar?.margin??4,a=this.getX(this.task.start),o=this.getX(this.task.end)-a,s=this.lane*(r+i)+i,c=t===`start`?a:a+o,l=s+r/2;this.dispatchEvent(new CustomEvent(`connector-drag-start`,{detail:{taskId:this.task.id,endpoint:t,startX:c,startY:l,clientX:e.clientX,clientY:e.clientY},bubbles:!0,composed:!0})),this.setupDragEvents(n,e.pointerId,e=>{this.dispatchEvent(new CustomEvent(`connector-drag-move`,{detail:{taskId:this.task.id,endpoint:t,startX:c,startY:l,clientX:e.clientX,clientY:e.clientY},bubbles:!0,composed:!0}))},e=>{this.dispatchEvent(new CustomEvent(`connector-drag-end`,{detail:{taskId:this.task.id,endpoint:t,cancelled:e},bubbles:!0,composed:!0}))})}onContextMenu(e){if(e.ctrlKey){e.preventDefault(),e.stopPropagation();return}e.preventDefault(),e.stopPropagation(),this.dispatchEvent(new CustomEvent(`task-contextmenu`,{detail:{task:this.task,event:e},bubbles:!0,composed:!0}))}render(){if(!this.task||!this.option)return t.html``;let e=this.getX(this.task.start),n=this.getX(this.task.end)-e,r=this.option.bar?.height??28,i=this.option.bar?.margin??4,a=this.option.bar?.cornerRadius??4,o=this.lane*(r+i)+i,s=this.option.readOnly,c=this.task.movable??`both`,l=this.task.resizable,u=!s&&c!==`none`,d=!s;return d&&=l===void 0?c!==`y`&&c!==`none`:l,t.html`
218
+ `}getX(e){return P(e,this.option.calendar.start,this.option.calendar.pxPerDay??50,this.option.calendar.pxPerMonth)}setupDragEvents(e,t,n,r){let i=()=>{e.releasePointerCapture(t),window.removeEventListener(`pointermove`,a),window.removeEventListener(`pointerup`,o),window.removeEventListener(`keydown`,s)},a=e=>{n(e)},o=e=>{i(),r(!1,e)},s=e=>{e.key===`Escape`&&(i(),r(!0))};window.addEventListener(`pointermove`,a),window.addEventListener(`pointerup`,o),window.addEventListener(`keydown`,s)}onResizeStart(e,t){e.stopPropagation();let n=e.target,r=this.task.movable??`both`,i=this.task.resizable,a=!this.option.readOnly;if(a&&=i===void 0?r!==`y`&&r!==`none`:i,!a)return;let o=this.shadowRoot?.querySelector(`.bar`);if(!o)return;o.style.pointerEvents=`none`;let s=this.shadowRoot?.querySelector(`.task-group`);s?.classList.add(`dragging`),n.setPointerCapture(e.pointerId);let c=e.clientX,l=new Date(this.task.start),u=new Date(this.task.end),d=new Date(l),f=new Date(u);this.setupDragEvents(n,e.pointerId,e=>{let n=e.clientX-c,r=new Date(l),i=new Date(u),a=this.option.calendar.pxPerDay??50,o=this.option.calendar.pxPerMonth,p=Math.max(this.option.snapDuration??1440,1);if(o){let e=this.getX(l),s=this.getX(u);if(t===`left`){let t=F(e+n,this.option.calendar.start,a,o);t.getDate()>15&&t.setMonth(t.getMonth()+1),t.setDate(1),t.setHours(0,0,0,0),r=t,r>=i&&(r=new Date(i),r.setMonth(r.getMonth()-1))}else{let e=F(s+n,this.option.calendar.start,a,o);e.getDate()>15&&e.setMonth(e.getMonth()+1),e.setDate(1),e.setHours(0,0,0,0),i=e,i<=r&&(i=new Date(r),i.setMonth(i.getMonth()+1))}}else{let e=a/1440,o=e*p,s=Math.round(n/o)*o,c=Math.round(s/e);t===`left`?(r=new Date(l.getTime()+c*60*1e3),r>=i&&(r=new Date(i.getTime()-p*60*1e3))):(i=new Date(u.getTime()+c*60*1e3),i<=r&&(i=new Date(r.getTime()+p*60*1e3)))}if(d=r,f=i,s){let e=this.getX(r),t=this.getX(i)-e;s.style.left=`${e}px`,s.style.width=`${t}px`}this._dragAnimationFrame&&cancelAnimationFrame(this._dragAnimationFrame),this._dragAnimationFrame=requestAnimationFrame(()=>{let t=s?.getBoundingClientRect();this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:r,end:i,dy:0,isDragging:!0,x:e.clientX,y:e.clientY,barX:t?t.left+t.width/2:void 0,barTop:t?.top,barBottom:t?.bottom},bubbles:!0,composed:!0}))})},e=>{if(s?.classList.remove(`dragging`),o.style.pointerEvents=``,this._dragAnimationFrame&&=(cancelAnimationFrame(this._dragAnimationFrame),null),e){if(s){let e=this.getX(l),t=this.getX(u)-e;s.style.left=`${e}px`,s.style.width=`${t}px`}this.requestUpdate(),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:l,end:u,dy:0,isDragging:!1},bubbles:!0,composed:!0}))}else requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:d,end:f,dy:0,isDragging:!1},bubbles:!0,composed:!0}))})})}getGanttChartElement(){let e=this;for(;e;){if(e instanceof HTMLElement&&e.tagName.toLowerCase()===`gantt-chart`)return e;if(e.parentNode)e=e.parentNode;else if(e.host)e=e.host;else break}return null}static{this.DRAG_THRESHOLD=3}onMoveStart(e){if(e.button===2)return;e.stopPropagation();let t=e.target,n=this.shadowRoot?.querySelector(`.task-group`);if(!t||!n)return;let r=this.task.movable??`both`;if(r===`none`)return;t.setPointerCapture(e.pointerId);let i=this.getGanttChartElement(),a=e.clientX,o=e.clientY,s=new Date(this.task.start),c=new Date(this.task.end),l=this.option.snapDuration??1440,u=!1,d=(e,t)=>{if(!i)return!1;let n=i.getBoundingClientRect();if(e<n.left||e>n.right||t<n.top||t>n.bottom)return!0;if(this.option.enableCrossRowMove!==!1){let e=i.shadowRoot?.querySelectorAll(`gantt-row`);if(e&&e.length>0){let n=e[0].getBoundingClientRect(),r=e[e.length-1].getBoundingClientRect();if(r.bottom>n.top&&(t<n.top||t>r.bottom))return!0}}return!1};this.setupDragEvents(t,e.pointerId,e=>{let i=e.clientX-a,f=e.clientY-o;if(!u){if(Math.abs(i)<U.DRAG_THRESHOLD&&Math.abs(f)<U.DRAG_THRESHOLD)return;u=!0;let r=e.ctrlKey||e.altKey?`copy`:`grabbing`;this._currentDragCursor=r,t.style.cursor=r,n.classList.add(`dragging`)}let p=e.ctrlKey||e.altKey,m=p?`copy`:`grabbing`;if(this._currentDragCursor=m,t.style.cursor=m,d(e.clientX,e.clientY)){n.style.transform=``,this._dragAnimationFrame&&cancelAnimationFrame(this._dragAnimationFrame),this._dragAnimationFrame=requestAnimationFrame(()=>{this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:s,end:c,dx:0,dy:0,isDragging:!0,isOutside:!0,x:e.clientX,y:e.clientY,mode:p?`copy`:`move`},bubbles:!0,composed:!0}))});return}let h=i,g=f;r===`y`&&(h=0),r===`x`&&(g=0),this.option.enableCrossRowMove===!1&&(g=0),this.multiDragActive&&!this.multiDragSameRow&&(g=0);let _=h;if(this.option.calendar.pxPerMonth){let e=F(this.getX(s)+h,this.option.calendar.start,50,this.option.calendar.pxPerMonth),t=(e.getFullYear()-s.getFullYear())*12+(e.getMonth()-s.getMonth())+ +(e.getDate()>15),n=new Date(s);n.setMonth(n.getMonth()+t),_=this.getX(n)-this.getX(s)}else{let e=this.option.calendar.pxPerDay/1440*l;_=Math.round(h/e)*e}n.style.transform=`translate(${_}px, ${g}px)`,this._dragAnimationFrame&&cancelAnimationFrame(this._dragAnimationFrame),this._dragAnimationFrame=requestAnimationFrame(()=>{let t=n?.getBoundingClientRect();this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:s,end:c,dx:_,dy:g,isDragging:!0,isOutside:!1,x:e.clientX,y:e.clientY,barX:t?t.left+t.width/2:void 0,barTop:t?.top,barBottom:t?.bottom,mode:p?`copy`:`move`},bubbles:!0,composed:!0}))})},(e,i)=>{if(this._currentDragCursor=null,n.classList.remove(`dragging`),n.style.transform=``,t.style.cursor=``,this._dragAnimationFrame&&=(cancelAnimationFrame(this._dragAnimationFrame),null),!u){i&&(this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:i,isMultiSelect:i.metaKey||i.ctrlKey},bubbles:!0,composed:!0})),this._wasDragging=!0);return}let f=i?d(i.clientX,i.clientY):!1;if(e||f)this._wasDragging=!0,this.requestUpdate(),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:s,end:c,dx:0,dy:0,isDragging:!1,isCancel:!0,isOutside:f},bubbles:!0,composed:!0}));else if(i){let e=i.clientX-a,t=e;if(this.option.calendar.pxPerMonth){let n=F(this.getX(s)+e,this.option.calendar.start,50,this.option.calendar.pxPerMonth),r=(n.getFullYear()-s.getFullYear())*12+(n.getMonth()-s.getMonth())+ +(n.getDate()>15),i=new Date(s);i.setMonth(i.getMonth()+r),t=this.getX(i)-this.getX(s)}else{let n=this.option.calendar.pxPerDay/1440*l;t=Math.round(e/n)*n}let n=i.clientY-o;if(r===`y`&&(t=0),r===`x`&&(n=0),this.option.enableCrossRowMove===!1&&(n=0),this.multiDragActive&&!this.multiDragSameRow&&(n=0),t===0&&Math.abs(n)<5){this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:i,isMultiSelect:i.metaKey||i.ctrlKey},bubbles:!0,composed:!0})),this._wasDragging=!0;return}let u=i.ctrlKey||i.altKey;this._wasDragging=!0,this.multiDragActive||this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:i,isMultiSelect:!1},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...this.task,start:s,end:c,dx:t,dy:n,isDragging:!1,isOutside:!1,mode:u?`copy`:`move`},bubbles:!0,composed:!0}))}})}updated(e){super.updated(e);let t=this.shadowRoot?.querySelector(`.bar`);if(t&&(this.option.customRendering?.barContent,this.dispatchEvent(new CustomEvent(`render-bar-content`,{detail:{container:t,task:this.task},bubbles:!0,composed:!0})),this._currentDragCursor?t.style.cursor=this._currentDragCursor:this.option.readOnly||(t.style.cursor=``)),e.has(`multiDragDx`)||e.has(`multiDragDy`)){let e=this.shadowRoot?.querySelector(`.task-group`);e&&(this.multiDragDx!==0||this.multiDragDy!==0?(e.style.transform=`translate(${this.multiDragDx}px, ${this.multiDragDy}px)`,e.style.opacity=`0.6`,e.style.pointerEvents=`none`):(e.style.transform=``,e.style.opacity=``,e.style.pointerEvents=``))}}disconnectedCallback(){super.disconnectedCallback(),window.removeEventListener(`keydown`,this.handleKeyDown),window.removeEventListener(`keyup`,this.handleKeyUp)}updateCursor(e){let t=this.shadowRoot?.querySelector(`.bar`);t&&!this._currentDragCursor&&(t.style.cursor=e?`copy`:``)}onMouseEnter(e){let t=e.currentTarget;if(t.classList.contains(`dragging`))return;this.option.readOnly||(window.addEventListener(`keydown`,this.handleKeyDown),window.addEventListener(`keyup`,this.handleKeyUp),(e.ctrlKey||e.altKey)&&this.updateCursor(!0),t.addEventListener(`mousemove`,this.onMouseMoveOnBar));let n=t.getBoundingClientRect();this.dispatchEvent(new CustomEvent(`bar-mouseenter`,{detail:{task:this.task,x:n.left+n.width/2,y:n.top,barBottom:n.bottom},bubbles:!0,composed:!0}))}onMouseLeave(){let e=this.shadowRoot?.querySelector(`.task-group`);if(!this.option.readOnly){window.removeEventListener(`keydown`,this.handleKeyDown),window.removeEventListener(`keyup`,this.handleKeyUp),this.updateCursor(!1),e&&e.removeEventListener(`mousemove`,this.onMouseMoveOnBar);let t=this.shadowRoot?.querySelector(`.connector-left`),n=this.shadowRoot?.querySelector(`.connector-right`);t&&t.classList.remove(`show-connector`),n&&n.classList.remove(`show-connector`)}this.dispatchEvent(new CustomEvent(`bar-mouseleave`,{bubbles:!0,composed:!0}))}onDblClick(e){this.dispatchEvent(new CustomEvent(`task-dblclick`,{detail:{task:this.task,event:e},bubbles:!0,composed:!0}))}onClick(e){if(e.stopPropagation(),this._wasDragging){this._wasDragging=!1;return}this.dispatchEvent(new CustomEvent(`bar-click`,{detail:{task:this.task,event:e,isMultiSelect:e.metaKey||e.ctrlKey},bubbles:!0,composed:!0}))}onConnectorDragStart(e,t){e.stopPropagation(),e.preventDefault();let n=e.target;if(n.setPointerCapture(e.pointerId),!this.shadowRoot?.querySelector(`.task-group`))return;let r=this.option.bar?.height??28,i=this.option.bar?.margin??4,a=this.getX(this.task.start),o=this.getX(this.task.end)-a,s=this.lane*(r+i)+i,c=t===`start`?a:a+o,l=s+r/2;this.dispatchEvent(new CustomEvent(`connector-drag-start`,{detail:{taskId:this.task.id,endpoint:t,startX:c,startY:l,clientX:e.clientX,clientY:e.clientY},bubbles:!0,composed:!0})),this.setupDragEvents(n,e.pointerId,e=>{this.dispatchEvent(new CustomEvent(`connector-drag-move`,{detail:{taskId:this.task.id,endpoint:t,startX:c,startY:l,clientX:e.clientX,clientY:e.clientY},bubbles:!0,composed:!0}))},e=>{this.dispatchEvent(new CustomEvent(`connector-drag-end`,{detail:{taskId:this.task.id,endpoint:t,cancelled:e},bubbles:!0,composed:!0}))})}onContextMenu(e){if(e.ctrlKey){e.preventDefault(),e.stopPropagation();return}e.preventDefault(),e.stopPropagation(),this.dispatchEvent(new CustomEvent(`task-contextmenu`,{detail:{task:this.task,event:e},bubbles:!0,composed:!0}))}render(){if(!this.task||!this.option)return t.html``;let e=this.getX(this.task.start),n=this.getX(this.task.end)-e,r=this.option.bar?.height??28,i=this.option.bar?.margin??4,a=this.option.bar?.cornerRadius??4,o=this.lane*(r+i)+i,s=this.option.readOnly,c=this.task.movable??`both`,l=this.task.resizable,u=!s&&c!==`none`,d=!s;return d&&=l===void 0?c!==`y`&&c!==`none`:l,t.html`
219
219
  <div
220
220
  class="task-group"
221
221
  style="
@@ -1016,7 +1016,7 @@
1016
1016
  (${B(this.dragOverlayInfo.currentStart,this.dragOverlayInfo.currentEnd,this.option.locale)})
1017
1017
  </div>
1018
1018
  ${r?t.html`<div class="drag-info-sub" style="margin-top: 4px; border-top: 1px solid ${e.dragOverlayDivider}; padding-top: 4px; width: 100%;">${(this.option.locale??j).dragOverlay.moveTo(r.name)}</div>`:``}
1019
- `,n)}if(this.dragOverlayInfo.clientY!==void 0){let e=this.dragOverlayInfo.clientX??0,t=this.dragOverlayInfo.clientY,r=this.getBoundingClientRect();if(e<r.left||e>r.right||t<r.top||t>r.bottom){n.classList.remove(`visible`);return}let i=n.offsetWidth||200,a=n.offsetHeight||60,o=window.innerWidth,s=window.innerHeight,c=e-i/2;c=Math.max(8,Math.min(c,o-i-8));let l=t-a-40;l<8&&(l=t+40),l+a>s-8&&(l=s-a-8),n.style.left=`${c}px`,n.style.transform=`none`,n.style.top=`${l}px`,n.style.bottom=`auto`}}hideDragOverlay(){let e=this.shadowRoot?.querySelector(`.drag-info-overlay`);e&&e.classList.remove(`visible`)}setupCurrentTimeTimer(){this.stopCurrentTimeTimer();let e=this.option.calendar.currentTimeUpdateInterval;e&&e>0&&(this.currentTimeTimer=window.setInterval(()=>{this.currentTime=new Date},e))}stopCurrentTimeTimer(){this.currentTimeTimer!==void 0&&(window.clearInterval(this.currentTimeTimer),this.currentTimeTimer=void 0)}handleHeaderResizeStart(e){e.preventDefault(),e.stopPropagation(),this.isResizingHeader=!0;let t=e.clientX,n=this.currentRowHeaderWidth,r=e.target;r.setPointerCapture(e.pointerId);let i=this.option.rowHeader?.minWidth??50,a=this.option.rowHeader?.maxWidth??2**53-1,o=e=>{let r=e.clientX-t,o=n+r;this.currentRowHeaderWidth=Math.max(i,Math.min(a,o))},s=()=>{this.isResizingHeader=!1,r.releasePointerCapture(e.pointerId),r.removeEventListener(`pointermove`,o),r.removeEventListener(`pointerup`,s);let t=Math.round(this.currentRowHeaderWidth);this.currentRowHeaderWidth=t,this.dispatchEvent(new CustomEvent(`row-header-resize`,{detail:{width:t},bubbles:!0,composed:!0}))};r.addEventListener(`pointermove`,o),r.addEventListener(`pointerup`,s)}getDateX(e){return P(e,this.option.calendar.start,this.effectivePxPerDay,this.effectivePxPerMonth)}calculateLayout(){if(this._layoutCache)return this._layoutCache;let e=0,t=this.currentRowHeaderWidth,n=new Map,r={layouts:this.displayRows.map(r=>{let{tasksWithLanes:i,laneCount:a}=I(r.tasks),o=this.option.bar?.height??28,s=this.option.bar?.margin??4;i.forEach(r=>{let i=this.getDateX(r.start)+t,a=this.getDateX(r.end)+t-i,c=e+r.lane*(o+s)+s;n.set(r.id,{x:i,y:c,width:a,height:o,dependencies:r.dependencies})});let c=a*(o+s)+s,l={top:e,height:c};return e+=c,l}),taskCoords:n,totalHeight:e};return this._layoutCache=r,r}isMultiDrag(e){return this.selectedTasks.size>=2&&this.selectedTasks.has(e)}isMultiDragSameRow(){if(this.selectedTasks.size<2)return!1;let e=null;for(let t of this.rows)for(let n of t.tasks)if(this.selectedTasks.has(n.id)){if(e===null)e=t.id;else if(e!==t.id)return!1}return e!==null}handleTaskUpdate(e){e.stopPropagation();let{id:t,start:n,end:r,dx:i,isDragging:a,mode:o}=e.detail,{dy:s}=e.detail,c=this.isMultiDrag(t),l=c&&this.isMultiDragSameRow();c&&!l&&(s=0);let u=n,d=r;if(i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth,a=this.getDateX(n),o=this.getDateX(r);u=F(a+i,this.option.calendar.start,e,t),d=F(o+i,this.option.calendar.start,e,t)}(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(u.getDate()>15&&u.setMonth(u.getMonth()+1),u.setDate(1),u.setHours(0,0,0,0),d.getDate()>15&&d.setMonth(d.getMonth()+1),d.setDate(1),d.setHours(0,0,0,0));let f=-1,p,m=-1;if(this.rows.find((e,n)=>{let r=e.tasks.findIndex(e=>e.id===t);return r!==-1&&(f=n,p=e.tasks[r],m=r,!0)}),f===-1||!p)return;let{layouts:h}=this.calculateLayout(),g=this.displayRows.findIndex(e=>e.id===this.rows[f].id);if(g===-1)return;let _=h[g].top,{tasksWithLanes:v}=I(this.rows[f].tasks),y=v.find(e=>e.id===t),b=y?y.lane:0,x=this.option.bar?.height??28,S=this.option.bar?.margin??4,C=_+(b*(x+S)+S)+s+x/2,w=-1;for(let e=0;e<h.length;e++){let t=h[e];if(C>=t.top&&C<t.top+t.height){w=e;break}}let T=w===-1?void 0:this.displayRows[w].id,E=c?[...this.selectedTasks]:void 0;if(this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...e.detail,dy:s,start:u,end:d,targetRowId:T,selectedTaskIds:E},bubbles:!0,composed:!0})),a){if(this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&=null,(!this.draggingTask||this.draggingTask.id!==t)&&(this.draggingTask={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,mode:o},this.draggingTaskIds=c?[...this.selectedTasks]:[]),c?(this.multiDragDx=i??0,this.multiDragSameRow=l,this.multiDragDy=l?s:0):(this.multiDragDx!==0||this.multiDragDy!==0)&&(this.multiDragDx=0,this.multiDragDy=0),!c||l){let e=w>=0?w:null;this.dragTargetRowIndex!==e&&(this.dragTargetRowIndex=e)}this.dragOverlayInfo=c?{id:t,name:(this.option.locale??j).dragOverlay.movingTasks(this.selectedTasks.size),start:n,end:r,currentStart:u,currentEnd:d,visible:!0,clientX:e.detail.x,clientY:e.detail.y}:{id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,targetRow:w>=0?this.displayRows[w]:void 0,visible:!0,clientX:e.detail.x,clientY:e.detail.y},this.updateDragOverlay();return}let D=this.draggingTaskIds.length>=2,O=this.multiDragSameRow;this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay()),this.tooltip&&={...this.tooltip,visible:!1};let k=-1;if(w!==-1){let e=this.displayRows[w];k=this.rows.findIndex(t=>t.id===e.id)}if(D&&i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth;if(O&&k!==-1&&f!==k){let n=[...this.rows],r={...n[f]},a={...n[k]};r.tasks=[...r.tasks],a.tasks=[...a.tasks];let o=[];r.tasks=r.tasks.filter(n=>{if(this.selectedTasks.has(n.id)){let r=this.getDateX(n.start),a=this.getDateX(n.end),s=F(r+i,this.option.calendar.start,e,t),c=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0),c.getDate()>15&&c.setMonth(c.getMonth()+1),c.setDate(1),c.setHours(0,0,0,0)),o.push({...n,start:s,end:c}),!1}return!0}),a.tasks.push(...o),n[f]=r,n[k]=a,requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}else{let n=this.rows.map(n=>n.tasks.some(e=>this.selectedTasks.has(e.id))?{...n,tasks:n.tasks.map(n=>{if(!this.selectedTasks.has(n.id))return n;let r=this.getDateX(n.start),a=this.getDateX(n.end),o=F(r+i,this.option.calendar.start,e,t),s=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(o.getDate()>15&&o.setMonth(o.getMonth()+1),o.setDate(1),o.setHours(0,0,0,0),s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0)),{...n,start:o,end:s}})}:n);requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}return}if(o===`copy`){if(k!==-1){let e=[...this.rows],t={...e[k]};t.tasks=[...t.tasks];let n=`task-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,r={...p,id:n,start:u,end:d,dependencies:[]};t.tasks.push(r),e[k]=t,requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}else{let e=[...this.rows],t={...e[f]};if(t.tasks=[...t.tasks],e[f]=t,k!==-1&&f!==k){let n={...e[k]};n.tasks=[...n.tasks],e[k]=n;let[r]=t.tasks.splice(m,1);n.tasks.push({...r,start:u,end:d})}else t.tasks[m]={...p,start:u,end:d};requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}handleBarMouseEnter(e){if(this.draggingTask||this.option.showTooltip===!1)return;this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer);let t=this.option.tooltipDelay??500;t>0?this.hoverTimer=window.setTimeout(()=>{this.tooltip={...e.detail,visible:!0,below:!1}},t):this.tooltip={...e.detail,visible:!0,below:!1}}handleBarMouseLeave(){this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}}async reorderRows(e,t,n){let r=Array.isArray(e)?e:[e],i=Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]),a=new Map;i.forEach(e=>{e.row&&a.set(e.row.id,e.getBoundingClientRect().top)});let o=[...this.rows],s=[];if(o.findIndex(e=>e.id===t)===-1)return;r.forEach(e=>{let t=o.findIndex(t=>t.id===e);t!==-1&&s.push(o[t])});let c=o.filter(e=>!r.includes(e.id));if(r.includes(t))return;let l=c.findIndex(e=>e.id===t);n===`bottom`&&l++,c.splice(l,0,...s),this.rows=c,await this.updateComplete,Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]).forEach(e=>{if(e.row){let t=a.get(e.row.id);if(t!==void 0){let n=t-e.getBoundingClientRect().top;n!==0&&e.animate([{transform:`translateY(${n}px)`,zIndex:`1`},{transform:`translateY(0)`,zIndex:`1`}],{duration:300,easing:`ease-out`})}}}),this.dispatchEvent(new CustomEvent(`row-reordered`,{detail:{sourceId:r[0],sourceIds:r,targetId:t,position:n,rows:this.rows},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleContainerDragOver(e){e.preventDefault();let t=e.dataTransfer&&e.dataTransfer.types.includes(`application/json`);if(t&&(e.dataTransfer.dropEffect=`copy`),!this.option.enableRowReordering&&!t)return;let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return;let r=n.getBoundingClientRect(),i=e.clientY-r.top+n.scrollTop-this.calendarHeight,{layouts:a}=this.calculateLayout(),o=-1;for(let e=0;e<a.length;e++){let t=a[e];if(i>=t.top&&i<t.top+t.height){o=e;break}}if(o!==-1){let s=this.displayRows[o];if(t){if((this.dragOverRowId!==s.id||this.dragOverPosition!==null)&&(this.dragOverRowId=s.id,this.dragOverPosition=null),this.externalDraggingTask){let t=this.currentRowHeaderWidth,i=n.scrollLeft,a=e.clientX-r.left+i-t,o=this.effectivePxPerDay,c=this.effectivePxPerMonth,l=this.option.snapDuration??1440,u=o/1440*l,d=F(Math.round(a/u)*u,this.option.calendar.start,o,c),f=this.externalDraggingTask.end.getTime()-this.externalDraggingTask.start.getTime(),p=new Date(d.getTime()+f);(!this.dragPreview||this.dragPreview.rowId!==s.id||this.dragPreview.currentStart.getTime()!==d.getTime())&&(this.dragPreview={task:this.externalDraggingTask,currentStart:d,currentEnd:p,rowId:s.id})}}else{let e=a[o],t=i-e.top<e.height/2?`top`:`bottom`;(this.dragOverRowId!==s.id||this.dragOverPosition!==t)&&(this.dragOverRowId=s.id,this.dragOverPosition=t)}}else this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null}handleContainerDragLeave(e){let t=this.shadowRoot?.querySelector(`.scroll-container`),n=e.relatedTarget;t&&t.contains(n)||(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null)}handleContainerDrop(e){e.preventDefault();let t=e.dataTransfer?.getData(`application/json`);if(t){this.handleExternalTaskDrop(e,t),this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null;return}if(!this.option.enableRowReordering)return;let n=e.dataTransfer?.getData(`text/plain`),r=this.dragOverRowId,i=this.dragOverPosition;if(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null,n&&r&&n!==r&&i){if(this.selectedRows.has(n)&&this.selectedRows.size>1){let e=Array.from(this.selectedRows);this.reorderRows(e,r,i)}else this.reorderRows(n,r,i)}}handleExternalTaskDrop(e,t){try{let n=JSON.parse(t);if(!n||typeof n!=`object`||typeof n.id!=`string`||typeof n.name!=`string`||!n.start||!n.end){console.warn(`Invalid dropped task data: missing required fields (id, name, start, end)`);return}let r=new Date(n.start),i=new Date(n.end);if(isNaN(r.getTime())||isNaN(i.getTime())){console.warn(`Invalid dropped task data: start or end is not a valid date`);return}let a={...n,start:r,end:i},o=this.shadowRoot?.querySelector(`.scroll-container`);if(!o)return;let s=o.getBoundingClientRect(),c=o.scrollLeft,l=o.scrollTop,u=this.currentRowHeaderWidth,d=e.clientX-s.left+c-u,f=this.effectivePxPerDay,p=this.effectivePxPerMonth,m=F(d,this.option.calendar.start,f,p),h=e.clientY-s.top+l-this.calendarHeight,{layouts:g}=this.calculateLayout(),_;for(let e=0;e<g.length;e++){let t=g[e];if(h>=t.top&&h<t.top+t.height){_=this.displayRows[e].id;break}}_&&this.dispatchEvent(new CustomEvent(`task-drop`,{detail:{task:a,dropDate:m,targetRowId:_},bubbles:!0,composed:!0}))}catch(e){console.warn(`Failed to parse dropped task data`,e)}}handleRowClicked(e){let{rowId:t,event:n}=e.detail,{shiftKey:r,ctrlKey:i,metaKey:a}=n,o=new Set(this.selectedRows);if(r&&this.lastClickedRowId){let e=this.rows.findIndex(e=>e.id===this.lastClickedRowId),n=this.rows.findIndex(e=>e.id===t);if(e!==-1&&n!==-1){let t=Math.min(e,n),r=Math.max(e,n);for(let e=t;e<=r;e++)o.add(this.rows[e].id)}}else if(i||a)o.has(t)?o.delete(t):o.add(t),this.lastClickedRowId=t;else{if(o.has(t)){this.lastClickedRowId=t;return}o.clear(),o.add(t),this.lastClickedRowId=t}this.selectedRows=o,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:Array.from(this.selectedRows)},bubbles:!0,composed:!0}))}handleRowContextMenu(e){this.selectedRows.has(e.detail.rowId)||this.handleRowClicked(e)}handleContainerClick(e){e.defaultPrevented||this.clearSelection()}handleContainerContextMenu(e){if(e.defaultPrevented)return;e.preventDefault();let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=t.scrollLeft,i=t.scrollTop,a=this.currentRowHeaderWidth,o=e.clientY-n.top+i-this.calendarHeight,{layouts:s}=this.calculateLayout(),c;for(let e=0;e<s.length;e++){let t=s[e];if(o>=t.top&&o<t.top+t.height){c=this.displayRows[e].id;break}}if(c){let t=e.clientX-n.left+r-a,i=this.effectivePxPerDay,o=this.effectivePxPerMonth,s=F(t,this.option.calendar.start,i,o);this.dispatchEvent(new CustomEvent(`chart-contextmenu`,{detail:{event:e,date:s,rowId:c},bubbles:!0,composed:!0}))}this.clearSelection()}hitTest(e,t){let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return null;let r=n.getBoundingClientRect(),i=n.scrollLeft,a=n.scrollTop,o=this.currentRowHeaderWidth,s=t-r.top+a-this.calendarHeight,{layouts:c}=this.calculateLayout(),l;for(let e=0;e<c.length;e++){let t=c[e];if(s>=t.top&&s<t.top+t.height){l=this.displayRows[e].id;break}}if(!l)return null;let u=e-r.left+i-o,d=this.effectivePxPerDay,f=this.effectivePxPerMonth,p=F(u,this.option.calendar.start,d,f);return{rowId:l,date:p}}getRowPositions(){let{layouts:e}=this.calculateLayout();return e.map(e=>({top:e.top,height:e.height,bottom:e.top+e.height}))}async exportImage(e=`png`,t={}){this.isExporting=!0,await this.updateComplete,await new Promise(e=>requestAnimationFrame(e));try{return await ee(this,e,t)}finally{this.isExporting=!1,await this.updateComplete}}zoomTo(e){let t=this.effectivePxPerMonth!==void 0,n=t?20:2,r=t?600:200,i=this.option.zoom?.min??n,a=this.option.zoom?.max??r,o=Math.max(i,Math.min(a,e));t?this.zoomPxPerMonth=o:this.zoomPxPerDay=o,this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:t?this.effectivePxPerDay:o,pxPerMonth:t?o:void 0},bubbles:!0,composed:!0}))}zoomToFit(){let e=this.shadowRoot?.querySelector(`.scroll-container`);if(!e)return;let t=null,n=null;for(let e of this.displayRows)for(let r of e.tasks)(!t||r.start<t)&&(t=r.start),(!n||r.end>n)&&(n=r.end);if(!t||!n)return;let r=this.currentRowHeaderWidth,i=e.clientWidth-r;if(!(i<=0)){if(this.effectivePxPerMonth!==void 0){let e=(n.getFullYear()-t.getFullYear())*12+(n.getMonth()-t.getMonth()),r=i/Math.max(1,e);this.zoomTo(r)}else{let e=n.getTime()-t.getTime(),r=i/Math.max(1,e/864e5);this.zoomTo(r)}requestAnimationFrame(()=>{let n=this.getDateX(t)+r;e.scrollLeft=Math.max(0,n-10)})}}resetZoom(){let e=this.zoomPxPerDay!==null||this.zoomPxPerMonth!==null;if(this.zoomPxPerDay=null,this.zoomPxPerMonth=null,e){let e=this.option.calendar.pxPerMonth!==void 0;this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:this.option.calendar.pxPerDay??50,pxPerMonth:e?this.option.calendar.pxPerMonth:void 0},bubbles:!0,composed:!0}))}}clearSelection(){(this.selectedRows.size!==0||this.selectedTasks.size!==0)&&(this.selectedRows.size>0&&(this.selectedRows=new Set,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))),this.selectedTasks.size>0&&(this.selectedTasks=new Set,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))))}moveFocusHorizontal(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}let r=t[n],i=[...r.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),a=i.findIndex(e=>e.id===this.focusedTaskId);if(a===-1){i.length>0&&this.setFocus(i[0].id,r.id);return}let o=a+e;o>=0&&o<i.length?this.setFocus(i[o].id,r.id):this.moveFocusVertical(e)}moveFocusVertical(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}for(let r=n+e;r>=0&&r<t.length;r+=e){let n=t[r];if(n.tasks.length>0){let t=[...n.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e>0?t[0]:t[t.length-1];this.setFocus(r.id,n.id);return}}}focusFirstAvailableTask(){for(let e of this.displayRows)if(e.tasks.length>0){let t=[...e.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime());this.setFocus(t[0].id,e.id);return}}focusFirstOrLastTaskInRow(e){if(!this.focusedRowId){this.focusFirstAvailableTask();return}let t=this.displayRows.find(e=>e.id===this.focusedRowId);if(!t||t.tasks.length===0)return;let n=[...t.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e===`first`?n[0]:n[n.length-1];this.setFocus(r.id,t.id)}setFocus(e,t){this.focusedTaskId=e,this.focusedRowId=t,this.scrollToTask(e)}toggleTaskSelection(e){let t=new Set(this.selectedTasks);t.has(e)?t.delete(e):t.add(e),this.selectedTasks=t,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...t]},bubbles:!0,composed:!0}))}selectSingleTask(e){this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0}))}moveSelectedTasksByKeyboard(e){if(this.selectedTasks.size===0)return;let t=(this.option.keyboard?.moveStep??this.option.snapDuration??1440)*60*1e3*e,n=this.rows.map(e=>e.tasks.some(e=>this.selectedTasks.has(e.id))?{...e,tasks:e.tasks.map(e=>this.selectedTasks.has(e.id)?{...e,start:new Date(e.start.getTime()+t),end:new Date(e.end.getTime()+t)}:e)}:e);for(let e of this.rows)for(let n of e.tasks){if(!this.selectedTasks.has(n.id))continue;let r=new Date(n.start.getTime()+t),i=new Date(n.end.getTime()+t);this.dispatchEvent(new CustomEvent(`task-update`,{detail:{id:n.id,name:n.name,start:r,end:i,dx:0,dy:0,isDragging:!1,mode:`move`,targetRowId:e.id},bubbles:!0,composed:!0}))}this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleBarClick(e){e.stopPropagation();let{task:t,isMultiSelect:n}=e.detail;this.draggingTask=null,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay());let r;n?(r=new Set(this.selectedTasks),r.has(t.id)?r.delete(t.id):r.add(t.id)):r=new Set([t.id]),this.selectedTasks=r,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...r]},bubbles:!0,composed:!0}))}handleBarContextMenu(e){let{task:t}=e.detail;this.selectedTasks.has(t.id)||(this.selectedTasks=new Set([t.id]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[t.id]},bubbles:!0,composed:!0})))}handleConnectorDragStart(e){let{taskId:t,endpoint:n,clientX:r,clientY:i}=e.detail;e.stopPropagation();let{taskCoords:a}=this.calculateLayout(),o=a.get(t),s=this.currentRowHeaderWidth,c=e.detail.startX+s,l=e.detail.startY;o&&(c=n===`start`?o.x:o.x+o.width,l=o.y+o.height/2),this.connectorDrag={sourceTaskId:t,sourceEndpoint:n,startX:c,startY:l,currentClientX:r,currentClientY:i,targetTaskId:null,targetEndpoint:null},this.tooltip&&=null}handleConnectorDragMove(e){if(!this.connectorDrag)return;e.stopPropagation();let{clientX:t,clientY:n}=e.detail,r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=r.getBoundingClientRect(),a=t-i.left+r.scrollLeft,o=n-i.top+r.scrollTop-this.calendarHeight,{taskCoords:s}=this.calculateLayout(),c=null,l=null,u=30;for(let[e,t]of s){if(e===this.connectorDrag.sourceTaskId)continue;let n=t.y+t.height/2,r=t.x,i=t.x+t.width,s=Math.sqrt((a-r)**2+(o-n)**2),d=Math.sqrt((a-i)**2+(o-n)**2);s<u&&(u=s,c=e,l=`start`),d<u&&(u=d,c=e,l=`end`)}let d=this.connectorDrag.targetTaskId;d!==c&&(d&&this._setConnectorDropTarget(d,!1),c&&this._setConnectorDropTarget(c,!0)),this.connectorDrag={...this.connectorDrag,currentClientX:t,currentClientY:n,targetTaskId:c,targetEndpoint:l}}handleConnectorDragEnd(e){if(!this.connectorDrag)return;e.stopPropagation();let{cancelled:t}=e.detail,{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a}=this.connectorDrag;i&&this._setConnectorDropTarget(i,!1),!t&&i&&a&&this.dispatchEvent(new CustomEvent(`dependency-create`,{detail:{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a},bubbles:!0,composed:!0})),this.connectorDrag=null}_setConnectorDropTarget(e,t){let n=this.shadowRoot?.querySelectorAll(`gantt-row`);if(n)for(let r of n){let n=r.shadowRoot?.querySelectorAll(`gantt-bar`);if(n){for(let r of n)if(r.task?.id===e){r.connectorDropTarget=t;return}}}}handleDependencyLineClick(e,t,n){this.dispatchEvent(new CustomEvent(`dependency-click`,{detail:{event:e,sourceTaskId:n,targetTaskId:t},bubbles:!0,composed:!0}))}selectTask(e){let t=!1;for(let n of this.displayRows)if(n.tasks.some(t=>t.id===e)){t=!0;break}return t?(this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0})),this.scrollToTask(e),!0):!1}scrollToTask(e){let{taskCoords:t}=this.calculateLayout(),n=t.get(e);if(!n)return;let r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=this.currentRowHeaderWidth,a=n.y+this.calendarHeight,o=a+n.height,s=r.scrollTop,c=r.scrollTop+r.clientHeight;if(a<s||o>c){let e=a-r.clientHeight/2+n.height/2;r.scrollTo({top:Math.max(0,e),behavior:`smooth`})}let l=n.x,u=n.x+n.width,d=r.scrollLeft+i,f=r.scrollLeft+r.clientWidth;if(l<d||u>f){let e=l-i-20;r.scrollTo({left:Math.max(0,e),behavior:`smooth`})}}render(){let e=L(this.theme,this.option.customTheme),{layouts:n,taskCoords:r,totalHeight:a}=this.calculateLayout(),o=this.currentRowHeaderWidth;(this._lastOptionRef!==this.option||this._lastLabelWidth!==o||this._lastZoomPxPerDay!==this.zoomPxPerDay||this._lastZoomPxPerMonth!==this.zoomPxPerMonth)&&(this._cachedCurrentOption={...this.option,rowHeader:{...this.option.rowHeader,width:o},calendar:{...this.option.calendar,pxPerDay:this.effectivePxPerDay,pxPerMonth:this.effectivePxPerMonth}},this._lastOptionRef=this.option,this._lastLabelWidth=o,this._lastZoomPxPerDay=this.zoomPxPerDay,this._lastZoomPxPerMonth=this.zoomPxPerMonth);let s=this._cachedCurrentOption,c=0,l=this.displayRows.length-1;if(!this.isExporting){for(let e=0;e<n.length;e++)if(n[e].top+n[e].height>this.virtualScrollTop){c=Math.max(0,e-5);break}for(let e=c;e<n.length;e++)if(n[e].top>this.virtualScrollTop+this.viewportHeight){l=Math.min(this.displayRows.length-1,e+5);break}}let u=this.displayRows.slice(c,l+1),d=this.isExporting?0:n[c]?n[c].top:0,f=n[l],p=f?f.top+f.height:0,m=Math.max(0,a-p),h=a>this.viewportHeight,g=[],_=this.option.readOnly===!0,v=this.option.dependency?.showArrows!==!1,y=this.option.dependency?.arrowSize??8,b=this.option.dependency?.lineStyle??`orthogonal`,x=this.option.dependency?.cornerRadius??8,S=this.option.dependency?.showCriticalPath===!0,C=S?Q(this.displayRows):new Set;for(let[e,n]of r)if(n.dependencies)for(let i of n.dependencies){let a=r.get(i);if(a){let r=a.x+a.width,o=a.y+a.height/2,s=n.x,c=n.y+n.height/2,l=r<s,u=v?s-y:s,d=l?Math.max(r,u):u,f,p,m,h=this.option.bar?.height??28,w=this.option.bar?.margin??4;if(Math.abs(o-c)<1&&l)f=d>r?`M ${r} ${o} L ${d} ${c}`:``,p=s>r?`M ${r} ${o} L ${s} ${c}`:``;else if(b===`orthogonal`){let e=J(r,o,s,c,d,h,w,x);f=e.pathD,p=e.hitPathD}else if(l){let e=(r+d)/2;f=`M ${r} ${o} C ${e} ${o} ${e} ${c} ${d} ${c}`,p=`M ${r} ${o} C ${(r+s)/2} ${o} ${(r+s)/2} ${c} ${s} ${c}`}else{let e=Math.max(12,(r-s)*.15),t=(o+c)/2,n=Math.abs(o-c)<h?t+h+w:t;f=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+d)/2} ${n} S ${d-e} ${c}, ${d} ${c}`,p=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+s)/2} ${n} S ${s-e} ${c}, ${s} ${c}`}m=v?`M ${d} ${c} L ${s} ${c}`:``,g.push(t.svg`<g class="dependency-group">
1019
+ `,n)}if(this.dragOverlayInfo.barTop!==void 0||this.dragOverlayInfo.clientY!==void 0){let e=this.dragOverlayInfo.clientX??0,t=this.dragOverlayInfo.clientY??0,r=this.getBoundingClientRect();if(this.dragOverlayInfo.clientY!==void 0&&(e<r.left||e>r.right||t<r.top||t>r.bottom)){n.classList.remove(`visible`);return}let i=n.offsetWidth||200,a=n.offsetHeight||60,o=window.innerWidth,s=window.innerHeight,c=this.dragOverlayInfo.barX??e,l=this.dragOverlayInfo.barTop??t,u=this.dragOverlayInfo.barBottom??t,d=c-i/2;d=Math.max(8,Math.min(d,o-i-8));let f=l-a-10;f<8&&(f=u+10),f+a>s-8&&(f=s-a-8),n.style.left=`${d}px`,n.style.transform=`none`,n.style.top=`${f}px`,n.style.bottom=`auto`}}hideDragOverlay(){let e=this.shadowRoot?.querySelector(`.drag-info-overlay`);e&&e.classList.remove(`visible`)}setupCurrentTimeTimer(){this.stopCurrentTimeTimer();let e=this.option.calendar.currentTimeUpdateInterval;e&&e>0&&(this.currentTimeTimer=window.setInterval(()=>{this.currentTime=new Date},e))}stopCurrentTimeTimer(){this.currentTimeTimer!==void 0&&(window.clearInterval(this.currentTimeTimer),this.currentTimeTimer=void 0)}handleHeaderResizeStart(e){e.preventDefault(),e.stopPropagation(),this.isResizingHeader=!0;let t=e.clientX,n=this.currentRowHeaderWidth,r=e.target;r.setPointerCapture(e.pointerId);let i=this.option.rowHeader?.minWidth??50,a=this.option.rowHeader?.maxWidth??2**53-1,o=e=>{let r=e.clientX-t,o=n+r;this.currentRowHeaderWidth=Math.max(i,Math.min(a,o))},s=()=>{this.isResizingHeader=!1,r.releasePointerCapture(e.pointerId),r.removeEventListener(`pointermove`,o),r.removeEventListener(`pointerup`,s);let t=Math.round(this.currentRowHeaderWidth);this.currentRowHeaderWidth=t,this.dispatchEvent(new CustomEvent(`row-header-resize`,{detail:{width:t},bubbles:!0,composed:!0}))};r.addEventListener(`pointermove`,o),r.addEventListener(`pointerup`,s)}getDateX(e){return P(e,this.option.calendar.start,this.effectivePxPerDay,this.effectivePxPerMonth)}calculateLayout(){if(this._layoutCache)return this._layoutCache;let e=0,t=this.currentRowHeaderWidth,n=new Map,r={layouts:this.displayRows.map(r=>{let{tasksWithLanes:i,laneCount:a}=I(r.tasks),o=this.option.bar?.height??28,s=this.option.bar?.margin??4;i.forEach(r=>{let i=this.getDateX(r.start)+t,a=this.getDateX(r.end)+t-i,c=e+r.lane*(o+s)+s;n.set(r.id,{x:i,y:c,width:a,height:o,dependencies:r.dependencies})});let c=a*(o+s)+s,l={top:e,height:c};return e+=c,l}),taskCoords:n,totalHeight:e};return this._layoutCache=r,r}isMultiDrag(e){return this.selectedTasks.size>=2&&this.selectedTasks.has(e)}isMultiDragSameRow(){if(this.selectedTasks.size<2)return!1;let e=null;for(let t of this.rows)for(let n of t.tasks)if(this.selectedTasks.has(n.id)){if(e===null)e=t.id;else if(e!==t.id)return!1}return e!==null}handleTaskUpdate(e){e.stopPropagation();let{id:t,start:n,end:r,dx:i,isDragging:a,mode:o}=e.detail,{dy:s}=e.detail,c=this.isMultiDrag(t),l=c&&this.isMultiDragSameRow();c&&!l&&(s=0);let u=n,d=r;if(i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth,a=this.getDateX(n),o=this.getDateX(r);u=F(a+i,this.option.calendar.start,e,t),d=F(o+i,this.option.calendar.start,e,t)}(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(u.getDate()>15&&u.setMonth(u.getMonth()+1),u.setDate(1),u.setHours(0,0,0,0),d.getDate()>15&&d.setMonth(d.getMonth()+1),d.setDate(1),d.setHours(0,0,0,0));let f=-1,p,m=-1;if(this.rows.find((e,n)=>{let r=e.tasks.findIndex(e=>e.id===t);return r!==-1&&(f=n,p=e.tasks[r],m=r,!0)}),f===-1||!p)return;let{layouts:h}=this.calculateLayout(),g=this.displayRows.findIndex(e=>e.id===this.rows[f].id);if(g===-1)return;let _=h[g].top,{tasksWithLanes:v}=I(this.rows[f].tasks),y=v.find(e=>e.id===t),b=y?y.lane:0,x=this.option.bar?.height??28,S=this.option.bar?.margin??4,C=_+(b*(x+S)+S)+s+x/2,w=this.option.enableCrossRowMove!==!1,T=-1;if(w)for(let e=0;e<h.length;e++){let t=h[e];if(C>=t.top&&C<t.top+t.height){T=e;break}}else{let e=this.rows[f];T=this.displayRows.findIndex(t=>t.id===e.id)}let E=T===-1?void 0:this.displayRows[T].id,D=c?[...this.selectedTasks]:void 0;if(this.dispatchEvent(new CustomEvent(`task-update`,{detail:{...e.detail,dy:s,start:u,end:d,targetRowId:E,selectedTaskIds:D},bubbles:!0,composed:!0})),a){if(this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&=null,e.detail.isOutside||w&&T===-1){this.multiDragDx=0,this.multiDragDy=0,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay());return}if((!this.draggingTask||this.draggingTask.id!==t)&&(this.draggingTask={id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,mode:o},this.draggingTaskIds=c?[...this.selectedTasks]:[]),c?(this.multiDragDx=i??0,this.multiDragSameRow=l,this.multiDragDy=l?s:0):(this.multiDragDx!==0||this.multiDragDy!==0)&&(this.multiDragDx=0,this.multiDragDy=0),!c||l){let e=T>=0?T:null;this.dragTargetRowIndex!==e&&(this.dragTargetRowIndex=e)}this.dragOverlayInfo=c?{id:t,name:(this.option.locale??j).dragOverlay.movingTasks(this.selectedTasks.size),start:n,end:r,currentStart:u,currentEnd:d,visible:!0,clientX:e.detail.x,clientY:e.detail.y,barX:e.detail.barX,barTop:e.detail.barTop,barBottom:e.detail.barBottom}:{id:t,name:e.detail.name,start:n,end:r,currentStart:u,currentEnd:d,targetRow:T>=0&&this.displayRows[T]?.id!==this.rows[f]?.id?this.displayRows[T]:void 0,visible:!0,clientX:e.detail.x,clientY:e.detail.y,barX:e.detail.barX,barTop:e.detail.barTop,barBottom:e.detail.barBottom},this.updateDragOverlay();return}let O=this.draggingTaskIds.length>=2,k=this.multiDragSameRow;if(this.draggingTask=null,this.draggingTaskIds=[],this.multiDragDx=0,this.multiDragDy=0,this.multiDragSameRow=!1,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay()),this.tooltip&&={...this.tooltip,visible:!1},e.detail.isCancel||e.detail.isOutside||w&&T===-1)return;let A=-1;if(T!==-1){let e=this.displayRows[T];A=this.rows.findIndex(t=>t.id===e.id)}if(O&&i!==void 0){let e=this.effectivePxPerDay,t=this.effectivePxPerMonth;if(k&&A!==-1&&f!==A){let n=[...this.rows],r={...n[f]},a={...n[A]};r.tasks=[...r.tasks],a.tasks=[...a.tasks];let o=[];r.tasks=r.tasks.filter(n=>{if(this.selectedTasks.has(n.id)){let r=this.getDateX(n.start),a=this.getDateX(n.end),s=F(r+i,this.option.calendar.start,e,t),c=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0),c.getDate()>15&&c.setMonth(c.getMonth()+1),c.setDate(1),c.setHours(0,0,0,0)),o.push({...n,start:s,end:c}),!1}return!0}),a.tasks.push(...o),n[f]=r,n[A]=a,requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}else{let n=this.rows.map(n=>n.tasks.some(e=>this.selectedTasks.has(e.id))?{...n,tasks:n.tasks.map(n=>{if(!this.selectedTasks.has(n.id))return n;let r=this.getDateX(n.start),a=this.getDateX(n.end),o=F(r+i,this.option.calendar.start,e,t),s=F(a+i,this.option.calendar.start,e,t);return(this.option.calendar.pxPerMonth||this.option.snapDuration&&this.option.snapDuration>=43200)&&(o.getDate()>15&&o.setMonth(o.getMonth()+1),o.setDate(1),o.setHours(0,0,0,0),s.getDate()>15&&s.setMonth(s.getMonth()+1),s.setDate(1),s.setHours(0,0,0,0)),{...n,start:o,end:s}})}:n);requestAnimationFrame(()=>{this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}return}if(o===`copy`){if(A!==-1){let e=[...this.rows],t={...e[A]};t.tasks=[...t.tasks];let n=`task-${Date.now()}-${Math.random().toString(36).substr(2,9)}`,r={...p,id:n,start:u,end:d,dependencies:[]};t.tasks.push(r),e[A]=t,requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}else{let e=[...this.rows],t={...e[f]};if(t.tasks=[...t.tasks],e[f]=t,A!==-1&&f!==A){let n={...e[A]};n.tasks=[...n.tasks],e[A]=n;let[r]=t.tasks.splice(m,1);n.tasks.push({...r,start:u,end:d})}else t.tasks[m]={...p,start:u,end:d};requestAnimationFrame(()=>{this.rows=e,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))})}}handleBarMouseEnter(e){if(this.draggingTask||this.option.showTooltip===!1)return;this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer);let t=this.option.tooltipDelay??500;t>0?this.hoverTimer=window.setTimeout(()=>{this.tooltip={...e.detail,visible:!0,below:!1}},t):this.tooltip={...e.detail,visible:!0,below:!1}}handleBarMouseLeave(){this.hoverTimer!==void 0&&window.clearTimeout(this.hoverTimer),this.tooltip&&={...this.tooltip,visible:!1}}async reorderRows(e,t,n){let r=Array.isArray(e)?e:[e],i=Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]),a=new Map;i.forEach(e=>{e.row&&a.set(e.row.id,e.getBoundingClientRect().top)});let o=[...this.rows],s=[];if(o.findIndex(e=>e.id===t)===-1)return;r.forEach(e=>{let t=o.findIndex(t=>t.id===e);t!==-1&&s.push(o[t])});let c=o.filter(e=>!r.includes(e.id));if(r.includes(t))return;let l=c.findIndex(e=>e.id===t);n===`bottom`&&l++,c.splice(l,0,...s),this.rows=c,await this.updateComplete,Array.from(this.shadowRoot?.querySelectorAll(`gantt-row`)??[]).forEach(e=>{if(e.row){let t=a.get(e.row.id);if(t!==void 0){let n=t-e.getBoundingClientRect().top;n!==0&&e.animate([{transform:`translateY(${n}px)`,zIndex:`1`},{transform:`translateY(0)`,zIndex:`1`}],{duration:300,easing:`ease-out`})}}}),this.dispatchEvent(new CustomEvent(`row-reordered`,{detail:{sourceId:r[0],sourceIds:r,targetId:t,position:n,rows:this.rows},bubbles:!0,composed:!0})),this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleContainerDragOver(e){e.preventDefault();let t=e.dataTransfer&&e.dataTransfer.types.includes(`application/json`);if(t&&(e.dataTransfer.dropEffect=`copy`),!this.option.enableRowReordering&&!t)return;let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return;let r=n.getBoundingClientRect(),i=e.clientY-r.top+n.scrollTop-this.calendarHeight,{layouts:a}=this.calculateLayout(),o=-1;for(let e=0;e<a.length;e++){let t=a[e];if(i>=t.top&&i<t.top+t.height){o=e;break}}if(o!==-1){let s=this.displayRows[o];if(t){if((this.dragOverRowId!==s.id||this.dragOverPosition!==null)&&(this.dragOverRowId=s.id,this.dragOverPosition=null),this.externalDraggingTask){let t=this.currentRowHeaderWidth,i=n.scrollLeft,a=e.clientX-r.left+i-t,o=this.effectivePxPerDay,c=this.effectivePxPerMonth,l=this.option.snapDuration??1440,u=o/1440*l,d=F(Math.round(a/u)*u,this.option.calendar.start,o,c),f=this.externalDraggingTask.end.getTime()-this.externalDraggingTask.start.getTime(),p=new Date(d.getTime()+f);(!this.dragPreview||this.dragPreview.rowId!==s.id||this.dragPreview.currentStart.getTime()!==d.getTime())&&(this.dragPreview={task:this.externalDraggingTask,currentStart:d,currentEnd:p,rowId:s.id})}}else{let e=a[o],t=i-e.top<e.height/2?`top`:`bottom`;(this.dragOverRowId!==s.id||this.dragOverPosition!==t)&&(this.dragOverRowId=s.id,this.dragOverPosition=t)}}else this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null}handleContainerDragLeave(e){let t=this.shadowRoot?.querySelector(`.scroll-container`),n=e.relatedTarget;t&&t.contains(n)||(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null)}handleContainerDrop(e){e.preventDefault();let t=e.dataTransfer?.getData(`application/json`);if(t){this.handleExternalTaskDrop(e,t),this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null;return}if(!this.option.enableRowReordering)return;let n=e.dataTransfer?.getData(`text/plain`),r=this.dragOverRowId,i=this.dragOverPosition;if(this.dragOverRowId=null,this.dragOverPosition=null,this.dragPreview=null,n&&r&&n!==r&&i){if(this.selectedRows.has(n)&&this.selectedRows.size>1){let e=Array.from(this.selectedRows);this.reorderRows(e,r,i)}else this.reorderRows(n,r,i)}}handleExternalTaskDrop(e,t){try{let n=JSON.parse(t);if(!n||typeof n!=`object`||typeof n.id!=`string`||typeof n.name!=`string`||!n.start||!n.end){console.warn(`Invalid dropped task data: missing required fields (id, name, start, end)`);return}let r=new Date(n.start),i=new Date(n.end);if(isNaN(r.getTime())||isNaN(i.getTime())){console.warn(`Invalid dropped task data: start or end is not a valid date`);return}let a={...n,start:r,end:i},o=this.shadowRoot?.querySelector(`.scroll-container`);if(!o)return;let s=o.getBoundingClientRect(),c=o.scrollLeft,l=o.scrollTop,u=this.currentRowHeaderWidth,d=e.clientX-s.left+c-u,f=this.effectivePxPerDay,p=this.effectivePxPerMonth,m=F(d,this.option.calendar.start,f,p),h=e.clientY-s.top+l-this.calendarHeight,{layouts:g}=this.calculateLayout(),_;for(let e=0;e<g.length;e++){let t=g[e];if(h>=t.top&&h<t.top+t.height){_=this.displayRows[e].id;break}}_&&this.dispatchEvent(new CustomEvent(`task-drop`,{detail:{task:a,dropDate:m,targetRowId:_},bubbles:!0,composed:!0}))}catch(e){console.warn(`Failed to parse dropped task data`,e)}}handleRowClicked(e){let{rowId:t,event:n}=e.detail,{shiftKey:r,ctrlKey:i,metaKey:a}=n,o=new Set(this.selectedRows);if(r&&this.lastClickedRowId){let e=this.rows.findIndex(e=>e.id===this.lastClickedRowId),n=this.rows.findIndex(e=>e.id===t);if(e!==-1&&n!==-1){let t=Math.min(e,n),r=Math.max(e,n);for(let e=t;e<=r;e++)o.add(this.rows[e].id)}}else if(i||a)o.has(t)?o.delete(t):o.add(t),this.lastClickedRowId=t;else{if(o.has(t)){this.lastClickedRowId=t;return}o.clear(),o.add(t),this.lastClickedRowId=t}this.selectedRows=o,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:Array.from(this.selectedRows)},bubbles:!0,composed:!0}))}handleRowContextMenu(e){this.selectedRows.has(e.detail.rowId)||this.handleRowClicked(e)}handleContainerClick(e){e.defaultPrevented||this.clearSelection()}handleContainerContextMenu(e){if(e.defaultPrevented)return;e.preventDefault();let t=this.shadowRoot?.querySelector(`.scroll-container`);if(!t)return;let n=t.getBoundingClientRect(),r=t.scrollLeft,i=t.scrollTop,a=this.currentRowHeaderWidth,o=e.clientY-n.top+i-this.calendarHeight,{layouts:s}=this.calculateLayout(),c;for(let e=0;e<s.length;e++){let t=s[e];if(o>=t.top&&o<t.top+t.height){c=this.displayRows[e].id;break}}if(c){let t=e.clientX-n.left+r-a,i=this.effectivePxPerDay,o=this.effectivePxPerMonth,s=F(t,this.option.calendar.start,i,o);this.dispatchEvent(new CustomEvent(`chart-contextmenu`,{detail:{event:e,date:s,rowId:c},bubbles:!0,composed:!0}))}this.clearSelection()}hitTest(e,t){let n=this.shadowRoot?.querySelector(`.scroll-container`);if(!n)return null;let r=n.getBoundingClientRect(),i=n.scrollLeft,a=n.scrollTop,o=this.currentRowHeaderWidth,s=t-r.top+a-this.calendarHeight,{layouts:c}=this.calculateLayout(),l;for(let e=0;e<c.length;e++){let t=c[e];if(s>=t.top&&s<t.top+t.height){l=this.displayRows[e].id;break}}if(!l)return null;let u=e-r.left+i-o,d=this.effectivePxPerDay,f=this.effectivePxPerMonth,p=F(u,this.option.calendar.start,d,f);return{rowId:l,date:p}}getRowPositions(){let{layouts:e}=this.calculateLayout();return e.map(e=>({top:e.top,height:e.height,bottom:e.top+e.height}))}async exportImage(e=`png`,t={}){this.isExporting=!0,await this.updateComplete,await new Promise(e=>requestAnimationFrame(e));try{return await ee(this,e,t)}finally{this.isExporting=!1,await this.updateComplete}}zoomTo(e){let t=this.effectivePxPerMonth!==void 0,n=t?20:2,r=t?600:200,i=this.option.zoom?.min??n,a=this.option.zoom?.max??r,o=Math.max(i,Math.min(a,e));t?this.zoomPxPerMonth=o:this.zoomPxPerDay=o,this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:t?this.effectivePxPerDay:o,pxPerMonth:t?o:void 0},bubbles:!0,composed:!0}))}zoomToFit(){let e=this.shadowRoot?.querySelector(`.scroll-container`);if(!e)return;let t=null,n=null;for(let e of this.displayRows)for(let r of e.tasks)(!t||r.start<t)&&(t=r.start),(!n||r.end>n)&&(n=r.end);if(!t||!n)return;let r=this.currentRowHeaderWidth,i=e.clientWidth-r;if(!(i<=0)){if(this.effectivePxPerMonth!==void 0){let e=(n.getFullYear()-t.getFullYear())*12+(n.getMonth()-t.getMonth()),r=i/Math.max(1,e);this.zoomTo(r)}else{let e=n.getTime()-t.getTime(),r=i/Math.max(1,e/864e5);this.zoomTo(r)}requestAnimationFrame(()=>{let n=this.getDateX(t)+r;e.scrollLeft=Math.max(0,n-10)})}}resetZoom(){let e=this.zoomPxPerDay!==null||this.zoomPxPerMonth!==null;if(this.zoomPxPerDay=null,this.zoomPxPerMonth=null,e){let e=this.option.calendar.pxPerMonth!==void 0;this.dispatchEvent(new CustomEvent(`zoom-change`,{detail:{pxPerDay:this.option.calendar.pxPerDay??50,pxPerMonth:e?this.option.calendar.pxPerMonth:void 0},bubbles:!0,composed:!0}))}}clearSelection(){(this.selectedRows.size!==0||this.selectedTasks.size!==0)&&(this.selectedRows.size>0&&(this.selectedRows=new Set,this.dispatchEvent(new CustomEvent(`row-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))),this.selectedTasks.size>0&&(this.selectedTasks=new Set,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[]},bubbles:!0,composed:!0}))))}moveFocusHorizontal(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}let r=t[n],i=[...r.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),a=i.findIndex(e=>e.id===this.focusedTaskId);if(a===-1){i.length>0&&this.setFocus(i[0].id,r.id);return}let o=a+e;o>=0&&o<i.length?this.setFocus(i[o].id,r.id):this.moveFocusVertical(e)}moveFocusVertical(e){let t=this.displayRows;if(t.length===0)return;if(!this.focusedTaskId||!this.focusedRowId){this.focusFirstAvailableTask();return}let n=t.findIndex(e=>e.id===this.focusedRowId);if(n===-1){this.focusFirstAvailableTask();return}for(let r=n+e;r>=0&&r<t.length;r+=e){let n=t[r];if(n.tasks.length>0){let t=[...n.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e>0?t[0]:t[t.length-1];this.setFocus(r.id,n.id);return}}}focusFirstAvailableTask(){for(let e of this.displayRows)if(e.tasks.length>0){let t=[...e.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime());this.setFocus(t[0].id,e.id);return}}focusFirstOrLastTaskInRow(e){if(!this.focusedRowId){this.focusFirstAvailableTask();return}let t=this.displayRows.find(e=>e.id===this.focusedRowId);if(!t||t.tasks.length===0)return;let n=[...t.tasks].sort((e,t)=>e.start.getTime()-t.start.getTime()),r=e===`first`?n[0]:n[n.length-1];this.setFocus(r.id,t.id)}setFocus(e,t){this.focusedTaskId=e,this.focusedRowId=t,this.scrollToTask(e)}toggleTaskSelection(e){let t=new Set(this.selectedTasks);t.has(e)?t.delete(e):t.add(e),this.selectedTasks=t,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...t]},bubbles:!0,composed:!0}))}selectSingleTask(e){this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0}))}moveSelectedTasksByKeyboard(e){if(this.selectedTasks.size===0)return;let t=(this.option.keyboard?.moveStep??this.option.snapDuration??1440)*60*1e3*e,n=this.rows.map(e=>e.tasks.some(e=>this.selectedTasks.has(e.id))?{...e,tasks:e.tasks.map(e=>this.selectedTasks.has(e.id)?{...e,start:new Date(e.start.getTime()+t),end:new Date(e.end.getTime()+t)}:e)}:e);for(let e of this.rows)for(let n of e.tasks){if(!this.selectedTasks.has(n.id))continue;let r=new Date(n.start.getTime()+t),i=new Date(n.end.getTime()+t);this.dispatchEvent(new CustomEvent(`task-update`,{detail:{id:n.id,name:n.name,start:r,end:i,dx:0,dy:0,isDragging:!1,mode:`move`,targetRowId:e.id},bubbles:!0,composed:!0}))}this.rows=n,this.dispatchEvent(new CustomEvent(`rows-change`,{detail:this.rows,bubbles:!0,composed:!0}))}handleBarClick(e){e.stopPropagation();let{task:t,isMultiSelect:n}=e.detail;this.draggingTask=null,this.dragTargetRowIndex=null,this.dragOverlayInfo&&(this.dragOverlayInfo={...this.dragOverlayInfo,visible:!1},this.hideDragOverlay());let r;n?(r=new Set(this.selectedTasks),r.has(t.id)?r.delete(t.id):r.add(t.id)):r=new Set([t.id]),this.selectedTasks=r,this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[...r]},bubbles:!0,composed:!0}))}handleBarContextMenu(e){let{task:t}=e.detail;this.selectedTasks.has(t.id)||(this.selectedTasks=new Set([t.id]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[t.id]},bubbles:!0,composed:!0})))}handleConnectorDragStart(e){let{taskId:t,endpoint:n,clientX:r,clientY:i}=e.detail;e.stopPropagation();let{taskCoords:a}=this.calculateLayout(),o=a.get(t),s=this.currentRowHeaderWidth,c=e.detail.startX+s,l=e.detail.startY;o&&(c=n===`start`?o.x:o.x+o.width,l=o.y+o.height/2),this.connectorDrag={sourceTaskId:t,sourceEndpoint:n,startX:c,startY:l,currentClientX:r,currentClientY:i,targetTaskId:null,targetEndpoint:null},this.tooltip&&=null}handleConnectorDragMove(e){if(!this.connectorDrag)return;e.stopPropagation();let{clientX:t,clientY:n}=e.detail,r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=r.getBoundingClientRect(),a=t-i.left+r.scrollLeft,o=n-i.top+r.scrollTop-this.calendarHeight,{taskCoords:s}=this.calculateLayout(),c=null,l=null,u=30;for(let[e,t]of s){if(e===this.connectorDrag.sourceTaskId)continue;let n=t.y+t.height/2,r=t.x,i=t.x+t.width,s=Math.sqrt((a-r)**2+(o-n)**2),d=Math.sqrt((a-i)**2+(o-n)**2);s<u&&(u=s,c=e,l=`start`),d<u&&(u=d,c=e,l=`end`)}let d=this.connectorDrag.targetTaskId;d!==c&&(d&&this._setConnectorDropTarget(d,!1),c&&this._setConnectorDropTarget(c,!0)),this.connectorDrag={...this.connectorDrag,currentClientX:t,currentClientY:n,targetTaskId:c,targetEndpoint:l}}handleConnectorDragEnd(e){if(!this.connectorDrag)return;e.stopPropagation();let{cancelled:t}=e.detail,{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a}=this.connectorDrag;i&&this._setConnectorDropTarget(i,!1),!t&&i&&a&&this.dispatchEvent(new CustomEvent(`dependency-create`,{detail:{sourceTaskId:n,sourceEndpoint:r,targetTaskId:i,targetEndpoint:a},bubbles:!0,composed:!0})),this.connectorDrag=null}_setConnectorDropTarget(e,t){let n=this.shadowRoot?.querySelectorAll(`gantt-row`);if(n)for(let r of n){let n=r.shadowRoot?.querySelectorAll(`gantt-bar`);if(n){for(let r of n)if(r.task?.id===e){r.connectorDropTarget=t;return}}}}handleDependencyLineClick(e,t,n){this.dispatchEvent(new CustomEvent(`dependency-click`,{detail:{event:e,sourceTaskId:n,targetTaskId:t},bubbles:!0,composed:!0}))}selectTask(e){let t=!1;for(let n of this.displayRows)if(n.tasks.some(t=>t.id===e)){t=!0;break}return t?(this.selectedTasks=new Set([e]),this.dispatchEvent(new CustomEvent(`bar-selection-change`,{detail:{selectedIds:[e]},bubbles:!0,composed:!0})),this.scrollToTask(e),!0):!1}scrollToTask(e){let{taskCoords:t}=this.calculateLayout(),n=t.get(e);if(!n)return;let r=this.shadowRoot?.querySelector(`.scroll-container`);if(!r)return;let i=this.currentRowHeaderWidth,a=n.y+this.calendarHeight,o=a+n.height,s=r.scrollTop,c=r.scrollTop+r.clientHeight;if(a<s||o>c){let e=a-r.clientHeight/2+n.height/2;r.scrollTo({top:Math.max(0,e),behavior:`smooth`})}let l=n.x,u=n.x+n.width,d=r.scrollLeft+i,f=r.scrollLeft+r.clientWidth;if(l<d||u>f){let e=l-i-20;r.scrollTo({left:Math.max(0,e),behavior:`smooth`})}}render(){let e=L(this.theme,this.option.customTheme),{layouts:n,taskCoords:r,totalHeight:a}=this.calculateLayout(),o=this.currentRowHeaderWidth;(this._lastOptionRef!==this.option||this._lastLabelWidth!==o||this._lastZoomPxPerDay!==this.zoomPxPerDay||this._lastZoomPxPerMonth!==this.zoomPxPerMonth)&&(this._cachedCurrentOption={...this.option,rowHeader:{...this.option.rowHeader,width:o},calendar:{...this.option.calendar,pxPerDay:this.effectivePxPerDay,pxPerMonth:this.effectivePxPerMonth}},this._lastOptionRef=this.option,this._lastLabelWidth=o,this._lastZoomPxPerDay=this.zoomPxPerDay,this._lastZoomPxPerMonth=this.zoomPxPerMonth);let s=this._cachedCurrentOption,c=0,l=this.displayRows.length-1;if(!this.isExporting){for(let e=0;e<n.length;e++)if(n[e].top+n[e].height>this.virtualScrollTop){c=Math.max(0,e-5);break}for(let e=c;e<n.length;e++)if(n[e].top>this.virtualScrollTop+this.viewportHeight){l=Math.min(this.displayRows.length-1,e+5);break}}let u=this.displayRows.slice(c,l+1),d=this.isExporting?0:n[c]?n[c].top:0,f=n[l],p=f?f.top+f.height:0,m=Math.max(0,a-p),h=a>this.viewportHeight,g=[],_=this.option.readOnly===!0,v=this.option.dependency?.showArrows!==!1,y=this.option.dependency?.arrowSize??8,b=this.option.dependency?.lineStyle??`orthogonal`,x=this.option.dependency?.cornerRadius??8,S=this.option.dependency?.showCriticalPath===!0,C=S?Q(this.displayRows):new Set;for(let[e,n]of r)if(n.dependencies)for(let i of n.dependencies){let a=r.get(i);if(a){let r=a.x+a.width,o=a.y+a.height/2,s=n.x,c=n.y+n.height/2,l=r<s,u=v?s-y:s,d=l?Math.max(r,u):u,f,p,m,h=this.option.bar?.height??28,w=this.option.bar?.margin??4;if(Math.abs(o-c)<1&&l)f=d>r?`M ${r} ${o} L ${d} ${c}`:``,p=s>r?`M ${r} ${o} L ${s} ${c}`:``;else if(b===`orthogonal`){let e=J(r,o,s,c,d,h,w,x);f=e.pathD,p=e.hitPathD}else if(l){let e=(r+d)/2;f=`M ${r} ${o} C ${e} ${o} ${e} ${c} ${d} ${c}`,p=`M ${r} ${o} C ${(r+s)/2} ${o} ${(r+s)/2} ${c} ${s} ${c}`}else{let e=Math.max(12,(r-s)*.15),t=(o+c)/2,n=Math.abs(o-c)<h?t+h+w:t;f=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+d)/2} ${n} S ${d-e} ${c}, ${d} ${c}`,p=`M ${r} ${o} C ${r+e} ${o}, ${r+e} ${n}, ${(r+s)/2} ${n} S ${s-e} ${c}, ${s} ${c}`}m=v?`M ${d} ${c} L ${s} ${c}`:``,g.push(t.svg`<g class="dependency-group">
1020
1020
  ${_?``:t.svg`<path class="dependency-hit-area" d="${p}" @click="${t=>{t.stopPropagation(),this.handleDependencyLineClick(t,e,i)}}" />`}
1021
1021
  <path class="dependency-line ${S&&C.has(e)&&C.has(i)?`critical-path`:``}" d="${f}" />
1022
1022
  ${v?t.svg`<path class="dependency-line dependency-arrow-line ${S&&C.has(e)&&C.has(i)?`critical-path`:``}" d="${m}" marker-end="url(#dependency-arrowhead)" />`:``}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@mogura/moguchart-core",
3
3
  "type": "module",
4
- "version": "0.9.1",
4
+ "version": "0.10.0",
5
5
  "description": "軽量でフレームワーク非依存のWeb Components製ガントチャートコンポーネント (Lit)。A lightweight, framework-agnostic Gantt chart Web Component for Vue, React, Angular, and Svelte.",
6
6
  "license": "MIT",
7
7
  "author": "Murakami Hiroyuki",