@zendir/ui 0.1.15 → 0.2.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +39 -0
- package/dist/index.js +6 -0
- package/dist/index.js.map +1 -1
- package/dist/react/astro/SimulationControls.js +3 -3
- package/dist/react/astro/SimulationControls.js.map +1 -1
- package/dist/react/astro/UnifiedTimeline.d.ts +56 -6
- package/dist/react/astro/UnifiedTimeline.js +628 -428
- package/dist/react/astro/UnifiedTimeline.js.map +1 -1
- package/dist/react/astro/index.d.ts +2 -2
- package/dist/react/charts/GroundTrackMap.d.ts +40 -1
- package/dist/react/charts/GroundTrackMap.js +98 -47
- package/dist/react/charts/GroundTrackMap.js.map +1 -1
- package/dist/react/charts/GroundTrackMapLeaflet.d.ts +11 -2
- package/dist/react/charts/GroundTrackMapLeaflet.js +128 -15
- package/dist/react/charts/GroundTrackMapLeaflet.js.map +1 -1
- package/dist/react/charts/index.d.ts +1 -1
- package/dist/react/charts/unified/theme.d.ts +7 -7
- package/dist/react/context/CategoryContext.d.ts +51 -0
- package/dist/react/context/CategoryContext.js +36 -0
- package/dist/react/context/CategoryContext.js.map +1 -0
- package/dist/react/context/index.d.ts +2 -0
- package/dist/react/index.d.ts +6 -4
- package/dist/react/types.d.ts +26 -0
- package/dist/react/types.js.map +1 -1
- package/dist/react/utils/categoryPalette.d.ts +43 -0
- package/dist/react/utils/categoryPalette.js +104 -0
- package/dist/react/utils/categoryPalette.js.map +1 -0
- package/dist/react/utils/index.d.ts +1 -0
- package/dist/react/utils/index.js.map +1 -1
- package/dist/react.js +6 -0
- package/dist/react.js.map +1 -1
- package/dist/style.css +49 -0
- package/package.json +1 -1
|
@@ -1,11 +1,53 @@
|
|
|
1
1
|
import { jsxs, jsx, Fragment } from "react/jsx-runtime";
|
|
2
2
|
import { memo, useState, useCallback, useMemo, useRef } from "react";
|
|
3
3
|
import { classNames, safeAccentText } from "../utils/index.js";
|
|
4
|
+
import { useCategoryPalette } from "../context/CategoryContext.js";
|
|
4
5
|
import { Icon } from "../core/Icon.js";
|
|
5
6
|
import { Badge } from "../core/Badge.js";
|
|
6
7
|
import { Tooltip } from "../core/Tooltip.js";
|
|
7
|
-
import {
|
|
8
|
+
import { Button } from "../core/Button.js";
|
|
9
|
+
import { useBreakpoint } from "../core/layout/useBreakpoint.js";
|
|
8
10
|
import { useTheme } from "../theme/ThemeProvider.js";
|
|
11
|
+
const Z = {
|
|
12
|
+
/** Base layer for track events / scatter dots */
|
|
13
|
+
trackEvent: 1,
|
|
14
|
+
/** Hovered track event raised above siblings */
|
|
15
|
+
trackEventHovered: 20,
|
|
16
|
+
/** Sticky column elements (playhead, track labels) */
|
|
17
|
+
sticky: 15,
|
|
18
|
+
/** Floating day-marker lines above track content */
|
|
19
|
+
dayMarker: 5,
|
|
20
|
+
/** Loading overlay covering chart content */
|
|
21
|
+
loadingOverlay: 100,
|
|
22
|
+
/** Floating tooltips — above all chart chrome */
|
|
23
|
+
tooltip: 1e3
|
|
24
|
+
};
|
|
25
|
+
const TIMELINE_FILTER_TEAM_NONE = "__zendir_team_none__";
|
|
26
|
+
const TIMELINE_FILTER_TEAM_LEGACY = "__zendir_team_legacy__";
|
|
27
|
+
function getTimelineTeamAccent(event) {
|
|
28
|
+
const t = event.team;
|
|
29
|
+
if (t == null ? void 0 : t.color) {
|
|
30
|
+
return { color: t.color, id: t.id, label: t.label };
|
|
31
|
+
}
|
|
32
|
+
if (event.color) {
|
|
33
|
+
return { color: event.color };
|
|
34
|
+
}
|
|
35
|
+
return null;
|
|
36
|
+
}
|
|
37
|
+
function getTimelineTeamDisplayLabel(event, accent) {
|
|
38
|
+
if (accent.label) return accent.label;
|
|
39
|
+
if (accent.id !== void 0 && accent.id !== "") return String(accent.id);
|
|
40
|
+
const args = event.arguments;
|
|
41
|
+
const argsTeam = args == null ? void 0 : args.Team;
|
|
42
|
+
if (argsTeam !== void 0 && argsTeam !== "") return String(argsTeam);
|
|
43
|
+
return event.badge || "Team";
|
|
44
|
+
}
|
|
45
|
+
function getTimelineTeamFilterKey(event) {
|
|
46
|
+
const accent = getTimelineTeamAccent(event);
|
|
47
|
+
if (!accent) return TIMELINE_FILTER_TEAM_NONE;
|
|
48
|
+
if (accent.id === void 0 || accent.id === "") return TIMELINE_FILTER_TEAM_LEGACY;
|
|
49
|
+
return String(accent.id);
|
|
50
|
+
}
|
|
9
51
|
const ALL_TIMELINE_STATUSES = [
|
|
10
52
|
"off",
|
|
11
53
|
"standby",
|
|
@@ -22,22 +64,23 @@ function getTimelineEventDisplayStatus(event) {
|
|
|
22
64
|
}
|
|
23
65
|
function isTimelineFilterActive(filter) {
|
|
24
66
|
return Boolean(
|
|
25
|
-
filter.search && filter.search.trim() || filter.tracks && filter.tracks.length > 0 || filter.status && filter.status.length > 0 || filter.eventShape && filter.eventShape !== "all" || filter.teamColoredOnly
|
|
67
|
+
filter.search && filter.search.trim() || filter.tracks && filter.tracks.length > 0 || filter.status && filter.status.length > 0 || filter.eventShape && filter.eventShape !== "all" || filter.teams && filter.teams.length > 0 || filter.teamColoredOnly
|
|
26
68
|
);
|
|
27
69
|
}
|
|
28
70
|
function normalizeTimelineFilter(f) {
|
|
29
|
-
var _a, _b, _c;
|
|
71
|
+
var _a, _b, _c, _d;
|
|
30
72
|
const o = {};
|
|
31
73
|
const s = (_a = f.search) == null ? void 0 : _a.trim();
|
|
32
74
|
if (s) o.search = s;
|
|
33
75
|
if ((_b = f.tracks) == null ? void 0 : _b.length) o.tracks = [...f.tracks];
|
|
34
76
|
if ((_c = f.status) == null ? void 0 : _c.length) o.status = [...f.status];
|
|
35
77
|
if (f.eventShape && f.eventShape !== "all") o.eventShape = f.eventShape;
|
|
78
|
+
if ((_d = f.teams) == null ? void 0 : _d.length) o.teams = [...f.teams];
|
|
36
79
|
if (f.teamColoredOnly) o.teamColoredOnly = true;
|
|
37
80
|
return o;
|
|
38
81
|
}
|
|
39
82
|
function matchesTimelineFilter(event, filter) {
|
|
40
|
-
var _a, _b, _c, _d, _e;
|
|
83
|
+
var _a, _b, _c, _d, _e, _f;
|
|
41
84
|
if (!isTimelineFilterActive(filter)) return true;
|
|
42
85
|
if ((_a = filter.tracks) == null ? void 0 : _a.length) {
|
|
43
86
|
const tid = event.track ?? "default";
|
|
@@ -50,12 +93,15 @@ function matchesTimelineFilter(event, filter) {
|
|
|
50
93
|
const q = (_c = filter.search) == null ? void 0 : _c.trim().toLowerCase();
|
|
51
94
|
if (q) {
|
|
52
95
|
const argStr = event.arguments ? Object.values(event.arguments).map((v) => String(v)).join(" ") : "";
|
|
96
|
+
const accent = getTimelineTeamAccent(event);
|
|
97
|
+
const teamHay = accent ? [accent.label, accent.id !== void 0 ? String(accent.id) : ""].filter(Boolean).join(" ") : "";
|
|
53
98
|
const hay = [
|
|
54
99
|
event.title,
|
|
55
100
|
event.subtitle,
|
|
56
101
|
event.badge,
|
|
57
102
|
event.track,
|
|
58
|
-
argStr
|
|
103
|
+
argStr,
|
|
104
|
+
teamHay
|
|
59
105
|
].filter(Boolean).join(" ").toLowerCase();
|
|
60
106
|
if (!hay.includes(q)) return false;
|
|
61
107
|
}
|
|
@@ -69,7 +115,13 @@ function matchesTimelineFilter(event, filter) {
|
|
|
69
115
|
const st = event.start.getTime();
|
|
70
116
|
if (endT == null || endT <= st) return false;
|
|
71
117
|
}
|
|
72
|
-
if (filter.
|
|
118
|
+
if ((_f = filter.teams) == null ? void 0 : _f.length) {
|
|
119
|
+
const teamKey = getTimelineTeamFilterKey(event);
|
|
120
|
+
if (!filter.teams.includes(teamKey)) return false;
|
|
121
|
+
}
|
|
122
|
+
if (filter.teamColoredOnly && !(filter.teams && filter.teams.length > 0) && !getTimelineTeamAccent(event)) {
|
|
123
|
+
return false;
|
|
124
|
+
}
|
|
73
125
|
return true;
|
|
74
126
|
}
|
|
75
127
|
function countTimelineFilterChips(filter) {
|
|
@@ -79,7 +131,8 @@ function countTimelineFilterChips(filter) {
|
|
|
79
131
|
if ((_b = filter.tracks) == null ? void 0 : _b.length) n++;
|
|
80
132
|
if ((_c = filter.status) == null ? void 0 : _c.length) n++;
|
|
81
133
|
if (filter.eventShape && filter.eventShape !== "all") n++;
|
|
82
|
-
if (filter.
|
|
134
|
+
if (filter.teams && filter.teams.length > 0) n++;
|
|
135
|
+
if (filter.teamColoredOnly && !(filter.teams && filter.teams.length > 0)) n++;
|
|
83
136
|
return n;
|
|
84
137
|
}
|
|
85
138
|
function TimelineStatusMarker({
|
|
@@ -121,6 +174,7 @@ const EventListItem = memo(function EventListItem2({
|
|
|
121
174
|
];
|
|
122
175
|
const displayStatus = event.badgeVariant && event.badgeVariant !== "default" && event.badgeVariant !== "primary" ? event.badgeVariant : event.status ?? "normal";
|
|
123
176
|
const markerColor = tokens.colors.status[displayStatus];
|
|
177
|
+
const teamAccent = getTimelineTeamAccent(event);
|
|
124
178
|
return /* @__PURE__ */ jsxs("div", { style: { display: "flex", gap: "16px" }, children: [
|
|
125
179
|
/* @__PURE__ */ jsxs(
|
|
126
180
|
"div",
|
|
@@ -158,7 +212,7 @@ const EventListItem = memo(function EventListItem2({
|
|
|
158
212
|
position: "relative",
|
|
159
213
|
flex: 1,
|
|
160
214
|
marginBottom: "16px",
|
|
161
|
-
padding:
|
|
215
|
+
padding: teamAccent ? "19px 20px 16px 20px" : "16px 20px",
|
|
162
216
|
backgroundColor: tokens.colors.background.surface,
|
|
163
217
|
border: `1px solid ${hovered ? tokens.colors.accent.primary : tokens.colors.border.muted}`,
|
|
164
218
|
borderRadius: tokens.borderRadius.lg,
|
|
@@ -168,7 +222,7 @@ const EventListItem = memo(function EventListItem2({
|
|
|
168
222
|
boxShadow: hovered ? `0 4px 20px ${tokens.colors.accent.primary}15, 0 0 0 1px ${tokens.colors.accent.primary}20` : "none"
|
|
169
223
|
},
|
|
170
224
|
children: [
|
|
171
|
-
|
|
225
|
+
teamAccent && /* @__PURE__ */ jsx(
|
|
172
226
|
"div",
|
|
173
227
|
{
|
|
174
228
|
style: {
|
|
@@ -177,7 +231,7 @@ const EventListItem = memo(function EventListItem2({
|
|
|
177
231
|
left: 0,
|
|
178
232
|
right: 0,
|
|
179
233
|
height: 3,
|
|
180
|
-
backgroundColor:
|
|
234
|
+
backgroundColor: teamAccent.color
|
|
181
235
|
}
|
|
182
236
|
}
|
|
183
237
|
),
|
|
@@ -390,6 +444,7 @@ const ChartView = memo(function ChartView2({
|
|
|
390
444
|
const [hoveredEvent, setHoveredEvent] = useState(null);
|
|
391
445
|
const [tooltipPos, setTooltipPos] = useState(null);
|
|
392
446
|
const scrollContainerRef = useRef(null);
|
|
447
|
+
const [scrollX, setScrollX] = useState(0);
|
|
393
448
|
const totalDuration = end.getTime() - start.getTime();
|
|
394
449
|
const trackLabelWidth = 130;
|
|
395
450
|
const timeLabels = useMemo(() => {
|
|
@@ -493,6 +548,22 @@ const ChartView = memo(function ChartView2({
|
|
|
493
548
|
if (!status) return tokens.colors.accent.primary;
|
|
494
549
|
return tokens.colors.status[status] || tokens.colors.accent.primary;
|
|
495
550
|
};
|
|
551
|
+
const isEventVisible = useCallback(
|
|
552
|
+
(event) => {
|
|
553
|
+
const container = scrollContainerRef.current;
|
|
554
|
+
if (!container) return true;
|
|
555
|
+
const viewportWidth = container.clientWidth - trackLabelWidth;
|
|
556
|
+
if (viewportWidth <= 0) return true;
|
|
557
|
+
const totalWidth = container.scrollWidth - trackLabelWidth;
|
|
558
|
+
const eventStartMs = event.start.getTime();
|
|
559
|
+
const eventEndMs = (event.end ?? new Date(eventStartMs + 3e5)).getTime();
|
|
560
|
+
const leftPx = (eventStartMs - start.getTime()) / totalDuration * totalWidth;
|
|
561
|
+
const rightPx = (eventEndMs - start.getTime()) / totalDuration * totalWidth;
|
|
562
|
+
const overscan = 50;
|
|
563
|
+
return rightPx >= scrollX - overscan && leftPx <= scrollX + viewportWidth + overscan;
|
|
564
|
+
},
|
|
565
|
+
[start, totalDuration, scrollX, trackLabelWidth]
|
|
566
|
+
);
|
|
496
567
|
const getStatusLabel = (status) => {
|
|
497
568
|
const labels = {
|
|
498
569
|
normal: "Normal",
|
|
@@ -514,6 +585,7 @@ const ChartView = memo(function ChartView2({
|
|
|
514
585
|
{
|
|
515
586
|
ref: scrollContainerRef,
|
|
516
587
|
className: "zendir-timeline-scroll",
|
|
588
|
+
onScroll: (e) => setScrollX(e.currentTarget.scrollLeft),
|
|
517
589
|
style: {
|
|
518
590
|
overflowX: "auto",
|
|
519
591
|
overflowY: "hidden",
|
|
@@ -537,7 +609,7 @@ const ChartView = memo(function ChartView2({
|
|
|
537
609
|
borderBottom: `1px solid ${tokens.colors.accent.primary}20`,
|
|
538
610
|
position: "sticky",
|
|
539
611
|
top: 0,
|
|
540
|
-
zIndex:
|
|
612
|
+
zIndex: Z.trackEventHovered,
|
|
541
613
|
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.surface,
|
|
542
614
|
...isTransparentTheme && { backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)" }
|
|
543
615
|
},
|
|
@@ -550,7 +622,7 @@ const ChartView = memo(function ChartView2({
|
|
|
550
622
|
flexShrink: 0,
|
|
551
623
|
position: "sticky",
|
|
552
624
|
left: 0,
|
|
553
|
-
zIndex:
|
|
625
|
+
zIndex: Z.trackEventHovered + 5,
|
|
554
626
|
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.surface,
|
|
555
627
|
...isTransparentTheme && { backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)" },
|
|
556
628
|
borderRight: `1px solid ${tokens.colors.border.muted}30`,
|
|
@@ -579,7 +651,7 @@ const ChartView = memo(function ChartView2({
|
|
|
579
651
|
display: "flex",
|
|
580
652
|
flexDirection: "column",
|
|
581
653
|
alignItems: "center",
|
|
582
|
-
zIndex:
|
|
654
|
+
zIndex: Z.dayMarker
|
|
583
655
|
},
|
|
584
656
|
children: /* @__PURE__ */ jsx(
|
|
585
657
|
"span",
|
|
@@ -639,7 +711,7 @@ const ChartView = memo(function ChartView2({
|
|
|
639
711
|
flexShrink: 0,
|
|
640
712
|
position: "sticky",
|
|
641
713
|
left: 0,
|
|
642
|
-
zIndex:
|
|
714
|
+
zIndex: Z.sticky,
|
|
643
715
|
display: "flex",
|
|
644
716
|
alignItems: "center",
|
|
645
717
|
paddingLeft: 12,
|
|
@@ -676,19 +748,20 @@ const ChartView = memo(function ChartView2({
|
|
|
676
748
|
bottom: 0,
|
|
677
749
|
width: 1,
|
|
678
750
|
backgroundColor: `${tokens.colors.status.caution}25`,
|
|
679
|
-
zIndex:
|
|
751
|
+
zIndex: Z.trackEvent,
|
|
680
752
|
pointerEvents: "none"
|
|
681
753
|
}
|
|
682
754
|
},
|
|
683
755
|
`day-line-${index}`
|
|
684
756
|
)),
|
|
685
|
-
(eventsByTrack[track.id] || []).map((event) => {
|
|
757
|
+
(eventsByTrack[track.id] || []).filter(isEventVisible).map((event) => {
|
|
686
758
|
const { left, width } = getEventPosition(event);
|
|
687
759
|
const displayStatus = event.badgeVariant && event.badgeVariant !== "default" && event.badgeVariant !== "primary" ? event.badgeVariant : event.status ?? "normal";
|
|
688
760
|
const color = getStatusColor(displayStatus);
|
|
689
761
|
const isHovered = hoveredEvent === event.id;
|
|
690
762
|
const overlap = eventOverlaps[event.id];
|
|
691
763
|
const hasOverlap = overlap && overlap.overlapCount > 0;
|
|
764
|
+
const teamAccent = getTimelineTeamAccent(event);
|
|
692
765
|
const cardHeight = hasOverlap ? 30 : 38;
|
|
693
766
|
const stackOffset = overlap ? overlap.stackIndex * 30 : 0;
|
|
694
767
|
const baseTop = ((track.height || trackHeight) - cardHeight) / 2;
|
|
@@ -696,6 +769,7 @@ const ChartView = memo(function ChartView2({
|
|
|
696
769
|
"button",
|
|
697
770
|
{
|
|
698
771
|
type: "button",
|
|
772
|
+
"aria-label": `${event.title}${event.status ? `, status: ${event.status}` : ""}`,
|
|
699
773
|
onClick: () => onEventClick == null ? void 0 : onEventClick(event),
|
|
700
774
|
onMouseEnter: (e) => {
|
|
701
775
|
setHoveredEvent(event.id);
|
|
@@ -706,6 +780,15 @@ const ChartView = memo(function ChartView2({
|
|
|
706
780
|
setHoveredEvent(null);
|
|
707
781
|
setTooltipPos(null);
|
|
708
782
|
},
|
|
783
|
+
onFocus: (e) => {
|
|
784
|
+
setHoveredEvent(event.id);
|
|
785
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
786
|
+
setTooltipPos({ x: rect.left + rect.width / 2, y: rect.top - 8 });
|
|
787
|
+
},
|
|
788
|
+
onBlur: () => {
|
|
789
|
+
setHoveredEvent(null);
|
|
790
|
+
setTooltipPos(null);
|
|
791
|
+
},
|
|
709
792
|
className: "zendir-timeline-region",
|
|
710
793
|
style: {
|
|
711
794
|
position: "absolute",
|
|
@@ -721,13 +804,13 @@ const ChartView = memo(function ChartView2({
|
|
|
721
804
|
display: "flex",
|
|
722
805
|
alignItems: "center",
|
|
723
806
|
overflow: "hidden",
|
|
724
|
-
zIndex: isHovered ?
|
|
807
|
+
zIndex: isHovered ? Z.trackEventHovered : Z.trackEvent,
|
|
725
808
|
boxShadow: isHovered ? `0 8px 24px rgba(0, 0, 0, 0.5), 0 0 0 1px ${color}60` : "0 2px 6px rgba(0, 0, 0, 0.25)",
|
|
726
809
|
transition: "all 150ms cubic-bezier(0.4, 0, 0.2, 1)",
|
|
727
810
|
transform: isHovered ? "translateY(-3px) scale(1.02)" : "none"
|
|
728
811
|
},
|
|
729
812
|
children: [
|
|
730
|
-
|
|
813
|
+
teamAccent ? /* @__PURE__ */ jsx(
|
|
731
814
|
"div",
|
|
732
815
|
{
|
|
733
816
|
style: {
|
|
@@ -736,7 +819,7 @@ const ChartView = memo(function ChartView2({
|
|
|
736
819
|
left: 0,
|
|
737
820
|
right: 0,
|
|
738
821
|
height: 2,
|
|
739
|
-
backgroundColor:
|
|
822
|
+
backgroundColor: teamAccent.color,
|
|
740
823
|
borderRadius: "4px 4px 0 0",
|
|
741
824
|
zIndex: 1,
|
|
742
825
|
pointerEvents: "none"
|
|
@@ -749,7 +832,7 @@ const ChartView = memo(function ChartView2({
|
|
|
749
832
|
{
|
|
750
833
|
style: {
|
|
751
834
|
flex: 1,
|
|
752
|
-
padding: `${
|
|
835
|
+
padding: `${teamAccent ? 6 : 4}px 8px 4px 8px`,
|
|
753
836
|
overflow: "hidden",
|
|
754
837
|
minWidth: 0,
|
|
755
838
|
display: "flex",
|
|
@@ -830,7 +913,7 @@ const ChartView = memo(function ChartView2({
|
|
|
830
913
|
fontWeight: 700,
|
|
831
914
|
color: "#000",
|
|
832
915
|
boxShadow: "0 2px 6px rgba(0, 0, 0, 0.3)",
|
|
833
|
-
zIndex:
|
|
916
|
+
zIndex: Z.sticky - 5
|
|
834
917
|
},
|
|
835
918
|
title: `${overlap.overlapCount + 1} overlapping events`,
|
|
836
919
|
children: [
|
|
@@ -862,7 +945,7 @@ const ChartView = memo(function ChartView2({
|
|
|
862
945
|
width: 2,
|
|
863
946
|
backgroundColor: tokens.colors.accent.primary,
|
|
864
947
|
boxShadow: `0 0 12px ${tokens.colors.accent.primary}`,
|
|
865
|
-
zIndex:
|
|
948
|
+
zIndex: Z.trackEventHovered,
|
|
866
949
|
pointerEvents: "none"
|
|
867
950
|
},
|
|
868
951
|
children: [
|
|
@@ -913,8 +996,8 @@ const ChartView = memo(function ChartView2({
|
|
|
913
996
|
}
|
|
914
997
|
),
|
|
915
998
|
hoveredEventData && tooltipPos && (() => {
|
|
916
|
-
var _a;
|
|
917
999
|
const tooltipColor = getStatusColor(hoveredEventData.status);
|
|
1000
|
+
const teamTip = getTimelineTeamAccent(hoveredEventData);
|
|
918
1001
|
return /* @__PURE__ */ jsxs(
|
|
919
1002
|
"div",
|
|
920
1003
|
{
|
|
@@ -923,7 +1006,7 @@ const ChartView = memo(function ChartView2({
|
|
|
923
1006
|
left: tooltipPos.x,
|
|
924
1007
|
top: tooltipPos.y,
|
|
925
1008
|
transform: "translate(-50%, -100%)",
|
|
926
|
-
zIndex:
|
|
1009
|
+
zIndex: Z.tooltip,
|
|
927
1010
|
pointerEvents: "none",
|
|
928
1011
|
animation: "zendir-tooltip-appear 150ms ease"
|
|
929
1012
|
},
|
|
@@ -982,9 +1065,9 @@ const ChartView = memo(function ChartView2({
|
|
|
982
1065
|
}
|
|
983
1066
|
)
|
|
984
1067
|
] }),
|
|
985
|
-
|
|
986
|
-
/* @__PURE__ */ jsx("div", { style: { width: 8, height: 8, borderRadius: 2, backgroundColor:
|
|
987
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6875rem", color:
|
|
1068
|
+
teamTip && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }, children: [
|
|
1069
|
+
/* @__PURE__ */ jsx("div", { style: { width: 8, height: 8, borderRadius: 2, backgroundColor: teamTip.color, flexShrink: 0 } }),
|
|
1070
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6875rem", color: teamTip.color, fontWeight: 500 }, children: getTimelineTeamDisplayLabel(hoveredEventData, teamTip) })
|
|
988
1071
|
] }),
|
|
989
1072
|
/* @__PURE__ */ jsx(
|
|
990
1073
|
"div",
|
|
@@ -1265,11 +1348,14 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1265
1348
|
const color = getStatusColor(event.status);
|
|
1266
1349
|
const isHovered = hoveredEvent === event.id;
|
|
1267
1350
|
const dotSize = isHovered ? 16 : 12;
|
|
1351
|
+
const hitboxPad = Math.max(0, (24 - dotSize) / 2);
|
|
1268
1352
|
const effectiveStatus = event.status ?? "normal";
|
|
1353
|
+
const scatterTeamAccent = getTimelineTeamAccent(event);
|
|
1269
1354
|
return /* @__PURE__ */ jsx(
|
|
1270
1355
|
"button",
|
|
1271
1356
|
{
|
|
1272
1357
|
type: "button",
|
|
1358
|
+
"aria-label": `${event.title}${event.status ? `, status: ${event.status}` : ""}`,
|
|
1273
1359
|
onClick: () => onEventClick == null ? void 0 : onEventClick(event),
|
|
1274
1360
|
onMouseEnter: (e) => {
|
|
1275
1361
|
setHoveredEvent(event.id);
|
|
@@ -1280,23 +1366,33 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1280
1366
|
setHoveredEvent(null);
|
|
1281
1367
|
setTooltipPosition(null);
|
|
1282
1368
|
},
|
|
1369
|
+
onFocus: (e) => {
|
|
1370
|
+
setHoveredEvent(event.id);
|
|
1371
|
+
const rect = e.currentTarget.getBoundingClientRect();
|
|
1372
|
+
setTooltipPosition({ x: rect.left + rect.width / 2, y: rect.top });
|
|
1373
|
+
},
|
|
1374
|
+
onBlur: () => {
|
|
1375
|
+
setHoveredEvent(null);
|
|
1376
|
+
setTooltipPosition(null);
|
|
1377
|
+
},
|
|
1283
1378
|
style: {
|
|
1284
1379
|
position: "absolute",
|
|
1285
1380
|
left: `${leftPercent}%`,
|
|
1286
1381
|
transform: "translateX(-50%)",
|
|
1382
|
+
/* visible size + transparent padding = ≥24px touch/click target */
|
|
1287
1383
|
width: dotSize,
|
|
1288
1384
|
height: dotSize,
|
|
1289
|
-
padding:
|
|
1385
|
+
padding: hitboxPad,
|
|
1290
1386
|
background: "none",
|
|
1291
1387
|
border: "none",
|
|
1292
1388
|
cursor: "pointer",
|
|
1293
1389
|
transition: "all 200ms cubic-bezier(0.34, 1.56, 0.64, 1)",
|
|
1294
|
-
zIndex: isHovered ?
|
|
1390
|
+
zIndex: isHovered ? Z.trackEventHovered : Z.trackEvent,
|
|
1295
1391
|
lineHeight: 0,
|
|
1296
1392
|
borderRadius: "50%",
|
|
1297
|
-
|
|
1393
|
+
boxSizing: "content-box",
|
|
1394
|
+
boxShadow: scatterTeamAccent ? `0 0 0 2px ${scatterTeamAccent.color}` : void 0
|
|
1298
1395
|
},
|
|
1299
|
-
"aria-label": event.title,
|
|
1300
1396
|
children: /* @__PURE__ */ jsx(TimelineStatusMarker, { status: effectiveStatus, fillColor: color, size: dotSize })
|
|
1301
1397
|
},
|
|
1302
1398
|
event.id
|
|
@@ -1313,8 +1409,8 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1313
1409
|
}
|
|
1314
1410
|
),
|
|
1315
1411
|
hoveredEventData && tooltipPosition && (() => {
|
|
1316
|
-
var _a;
|
|
1317
1412
|
const scatterTipColor = getStatusColor(hoveredEventData.status);
|
|
1413
|
+
const scatterTeamTip = getTimelineTeamAccent(hoveredEventData);
|
|
1318
1414
|
return /* @__PURE__ */ jsxs(
|
|
1319
1415
|
"div",
|
|
1320
1416
|
{
|
|
@@ -1330,7 +1426,7 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1330
1426
|
padding: "12px 16px",
|
|
1331
1427
|
minWidth: 200,
|
|
1332
1428
|
maxWidth: 320,
|
|
1333
|
-
zIndex:
|
|
1429
|
+
zIndex: Z.tooltip,
|
|
1334
1430
|
boxShadow: `0 12px 40px rgba(0, 0, 0, 0.5), 0 0 0 1px ${scatterTipColor}20`,
|
|
1335
1431
|
backdropFilter: "blur(12px)",
|
|
1336
1432
|
animation: "zendir-tooltip-in 150ms cubic-bezier(0.34, 1.56, 0.64, 1)"
|
|
@@ -1390,9 +1486,9 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1390
1486
|
}
|
|
1391
1487
|
)
|
|
1392
1488
|
] }),
|
|
1393
|
-
|
|
1394
|
-
/* @__PURE__ */ jsx("div", { style: { width: 8, height: 8, borderRadius: 2, backgroundColor:
|
|
1395
|
-
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6875rem", color:
|
|
1489
|
+
scatterTeamTip && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 6, marginBottom: 6 }, children: [
|
|
1490
|
+
/* @__PURE__ */ jsx("div", { style: { width: 8, height: 8, borderRadius: 2, backgroundColor: scatterTeamTip.color, flexShrink: 0 } }),
|
|
1491
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.6875rem", color: scatterTeamTip.color, fontWeight: 500 }, children: getTimelineTeamDisplayLabel(hoveredEventData, scatterTeamTip) })
|
|
1396
1492
|
] }),
|
|
1397
1493
|
/* @__PURE__ */ jsx(
|
|
1398
1494
|
"div",
|
|
@@ -1489,16 +1585,39 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1489
1585
|
` })
|
|
1490
1586
|
] });
|
|
1491
1587
|
});
|
|
1492
|
-
|
|
1588
|
+
function buildTeamFilterOptions(events, tokens, categoryLabel = "team") {
|
|
1589
|
+
const map = /* @__PURE__ */ new Map();
|
|
1590
|
+
for (const event of events) {
|
|
1591
|
+
const key = getTimelineTeamFilterKey(event);
|
|
1592
|
+
if (map.has(key)) continue;
|
|
1593
|
+
const accent = getTimelineTeamAccent(event);
|
|
1594
|
+
const isNone = key === TIMELINE_FILTER_TEAM_NONE;
|
|
1595
|
+
const isLegacy = key === TIMELINE_FILTER_TEAM_LEGACY;
|
|
1596
|
+
const label = isNone ? `No ${categoryLabel.toLowerCase()}` : isLegacy ? "Accent only" : accent ? getTimelineTeamDisplayLabel(event, accent) : key;
|
|
1597
|
+
const color = isNone ? "" : (accent == null ? void 0 : accent.color) ?? tokens.colors.text.tertiary;
|
|
1598
|
+
map.set(key, { key, label, color, isNoneBucket: isNone });
|
|
1599
|
+
}
|
|
1600
|
+
const list = [...map.values()];
|
|
1601
|
+
list.sort((a, b) => {
|
|
1602
|
+
if (a.isNoneBucket !== b.isNoneBucket) return a.isNoneBucket ? 1 : -1;
|
|
1603
|
+
if (a.key === TIMELINE_FILTER_TEAM_LEGACY) return b.key === TIMELINE_FILTER_TEAM_NONE ? -1 : 1;
|
|
1604
|
+
if (b.key === TIMELINE_FILTER_TEAM_LEGACY) return a.key === TIMELINE_FILTER_TEAM_NONE ? 1 : -1;
|
|
1605
|
+
return a.label.localeCompare(b.label, void 0, { sensitivity: "base" });
|
|
1606
|
+
});
|
|
1607
|
+
return list;
|
|
1608
|
+
}
|
|
1609
|
+
const TimelineFiltersPanel = memo(function TimelineFiltersPanel2({
|
|
1493
1610
|
filter,
|
|
1494
1611
|
onFilterChange,
|
|
1495
1612
|
trackOptions,
|
|
1496
|
-
|
|
1613
|
+
events,
|
|
1614
|
+
expanded,
|
|
1615
|
+
teamLabel
|
|
1497
1616
|
}) {
|
|
1498
1617
|
const { tokens, theme } = useTheme();
|
|
1499
1618
|
const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
|
|
1500
|
-
const
|
|
1501
|
-
const
|
|
1619
|
+
const accentColor = tokens.colors.accent.primary;
|
|
1620
|
+
const teamOptions = useMemo(() => buildTeamFilterOptions(events, tokens, teamLabel), [events, tokens, teamLabel]);
|
|
1502
1621
|
const patch = useCallback(
|
|
1503
1622
|
(partial) => {
|
|
1504
1623
|
onFilterChange(normalizeTimelineFilter({ ...filter, ...partial }));
|
|
@@ -1524,234 +1643,181 @@ const TimelineFiltersToolbar = memo(function TimelineFiltersToolbar2({
|
|
|
1524
1643
|
},
|
|
1525
1644
|
[filter.status, patch]
|
|
1526
1645
|
);
|
|
1527
|
-
const
|
|
1528
|
-
|
|
1529
|
-
|
|
1530
|
-
|
|
1531
|
-
|
|
1532
|
-
|
|
1533
|
-
|
|
1534
|
-
|
|
1535
|
-
|
|
1536
|
-
|
|
1537
|
-
|
|
1646
|
+
const toggleTeam = useCallback(
|
|
1647
|
+
(teamKey) => {
|
|
1648
|
+
const cur = filter.teams ?? [];
|
|
1649
|
+
const next = cur.includes(teamKey) ? cur.filter((k) => k !== teamKey) : [...cur, teamKey];
|
|
1650
|
+
patch({ teams: next.length ? next : void 0 });
|
|
1651
|
+
},
|
|
1652
|
+
[filter.teams, patch]
|
|
1653
|
+
);
|
|
1654
|
+
const pillStyle = useCallback(
|
|
1655
|
+
(active, tintColor) => {
|
|
1656
|
+
const c = tintColor || accentColor;
|
|
1657
|
+
return {
|
|
1658
|
+
padding: "2px 8px",
|
|
1659
|
+
borderRadius: tokens.borderRadius.md,
|
|
1660
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
1661
|
+
fontWeight: 500,
|
|
1662
|
+
textTransform: "uppercase",
|
|
1663
|
+
letterSpacing: "0.06em",
|
|
1664
|
+
lineHeight: 1.4,
|
|
1665
|
+
border: `1px solid ${active ? `${c}66` : tokens.colors.border.muted}`,
|
|
1666
|
+
backgroundColor: active ? `${c}22` : "transparent",
|
|
1667
|
+
color: active ? c : tokens.colors.text.secondary,
|
|
1668
|
+
cursor: "pointer",
|
|
1669
|
+
transition: tokens.animation.fast
|
|
1670
|
+
};
|
|
1671
|
+
},
|
|
1672
|
+
[accentColor, tokens]
|
|
1673
|
+
);
|
|
1674
|
+
const sectionHeader = (text) => /* @__PURE__ */ jsx(
|
|
1675
|
+
"div",
|
|
1676
|
+
{
|
|
1677
|
+
style: {
|
|
1678
|
+
fontSize: tokens.typography.fontSize.xs,
|
|
1679
|
+
fontWeight: 700,
|
|
1680
|
+
letterSpacing: "0.06em",
|
|
1681
|
+
textTransform: "uppercase",
|
|
1682
|
+
color: tokens.colors.text.tertiary,
|
|
1683
|
+
marginBottom: 8
|
|
1684
|
+
},
|
|
1685
|
+
children: text
|
|
1686
|
+
}
|
|
1687
|
+
);
|
|
1688
|
+
if (!expanded) return null;
|
|
1538
1689
|
return /* @__PURE__ */ jsxs(
|
|
1539
1690
|
"div",
|
|
1540
1691
|
{
|
|
1692
|
+
id: "zendir-timeline-filters-panel",
|
|
1541
1693
|
style: {
|
|
1542
|
-
padding:
|
|
1694
|
+
padding: `${tokens.spacing.smd} ${tokens.spacing.md}`,
|
|
1543
1695
|
borderBottom: `1px solid ${tokens.colors.border.muted}`,
|
|
1544
|
-
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.
|
|
1545
|
-
...isTransparentTheme && { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }
|
|
1696
|
+
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.surface,
|
|
1697
|
+
...isTransparentTheme && { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" },
|
|
1698
|
+
display: "flex",
|
|
1699
|
+
flexDirection: "column",
|
|
1700
|
+
gap: tokens.spacing.smd
|
|
1546
1701
|
},
|
|
1547
1702
|
children: [
|
|
1703
|
+
trackOptions.length > 0 ? /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": "Filter by track", children: [
|
|
1704
|
+
sectionHeader("Tracks"),
|
|
1705
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: tokens.spacing.xs }, children: trackOptions.map((t) => {
|
|
1706
|
+
var _a;
|
|
1707
|
+
const active = ((_a = filter.tracks) == null ? void 0 : _a.includes(t.id)) ?? false;
|
|
1708
|
+
return /* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": active, onClick: () => toggleTrack(t.id), style: pillStyle(active), children: t.label }, t.id);
|
|
1709
|
+
}) })
|
|
1710
|
+
] }) : null,
|
|
1711
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-label": "Filter by status", children: [
|
|
1712
|
+
sectionHeader("Status"),
|
|
1713
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: tokens.spacing.xs }, children: ALL_TIMELINE_STATUSES.map((st) => {
|
|
1714
|
+
var _a;
|
|
1715
|
+
const active = ((_a = filter.status) == null ? void 0 : _a.includes(st)) ?? false;
|
|
1716
|
+
const statusColor = st ? tokens.colors.status[st] : accentColor;
|
|
1717
|
+
return /* @__PURE__ */ jsxs(
|
|
1718
|
+
"button",
|
|
1719
|
+
{
|
|
1720
|
+
type: "button",
|
|
1721
|
+
"aria-pressed": active,
|
|
1722
|
+
onClick: () => toggleStatus(st),
|
|
1723
|
+
style: {
|
|
1724
|
+
...pillStyle(active, statusColor),
|
|
1725
|
+
display: "inline-flex",
|
|
1726
|
+
alignItems: "center",
|
|
1727
|
+
gap: 6
|
|
1728
|
+
},
|
|
1729
|
+
children: [
|
|
1730
|
+
/* @__PURE__ */ jsx(
|
|
1731
|
+
"span",
|
|
1732
|
+
{
|
|
1733
|
+
style: {
|
|
1734
|
+
width: 8,
|
|
1735
|
+
height: 8,
|
|
1736
|
+
borderRadius: "50%",
|
|
1737
|
+
backgroundColor: active ? statusColor : `${statusColor}50`,
|
|
1738
|
+
flexShrink: 0,
|
|
1739
|
+
transition: tokens.animation.fast
|
|
1740
|
+
}
|
|
1741
|
+
}
|
|
1742
|
+
),
|
|
1743
|
+
st
|
|
1744
|
+
]
|
|
1745
|
+
},
|
|
1746
|
+
st
|
|
1747
|
+
);
|
|
1748
|
+
}) })
|
|
1749
|
+
] }),
|
|
1548
1750
|
/* @__PURE__ */ jsxs(
|
|
1549
1751
|
"div",
|
|
1550
1752
|
{
|
|
1551
1753
|
style: {
|
|
1552
1754
|
display: "flex",
|
|
1553
1755
|
flexWrap: "wrap",
|
|
1554
|
-
|
|
1555
|
-
|
|
1756
|
+
gap: `${tokens.spacing.smd} ${tokens.spacing.lg}`,
|
|
1757
|
+
alignItems: "flex-start"
|
|
1556
1758
|
},
|
|
1557
1759
|
children: [
|
|
1558
|
-
/* @__PURE__ */ jsxs("div", {
|
|
1559
|
-
|
|
1560
|
-
|
|
1561
|
-
|
|
1562
|
-
|
|
1563
|
-
|
|
1564
|
-
style: {
|
|
1565
|
-
position: "absolute",
|
|
1566
|
-
left: 12,
|
|
1567
|
-
top: "50%",
|
|
1568
|
-
transform: "translateY(-50%)",
|
|
1569
|
-
color: tokens.colors.text.tertiary,
|
|
1570
|
-
pointerEvents: "none"
|
|
1571
|
-
}
|
|
1572
|
-
}
|
|
1573
|
-
),
|
|
1574
|
-
/* @__PURE__ */ jsx(
|
|
1575
|
-
"input",
|
|
1576
|
-
{
|
|
1577
|
-
type: "search",
|
|
1578
|
-
value: filter.search ?? "",
|
|
1579
|
-
onChange: (e) => patch({ search: e.target.value || void 0 }),
|
|
1580
|
-
placeholder: "Search title, badge, track, fields…",
|
|
1581
|
-
"aria-label": "Search timeline events",
|
|
1582
|
-
style: {
|
|
1583
|
-
width: "100%",
|
|
1584
|
-
boxSizing: "border-box",
|
|
1585
|
-
height: 36,
|
|
1586
|
-
paddingLeft: 40,
|
|
1587
|
-
paddingRight: 12,
|
|
1588
|
-
borderRadius: tokens.borderRadius.md,
|
|
1589
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1590
|
-
backgroundColor: tokens.colors.background.surface,
|
|
1591
|
-
color: tokens.colors.text.primary,
|
|
1592
|
-
fontSize: "0.8125rem",
|
|
1593
|
-
outline: "none"
|
|
1594
|
-
}
|
|
1595
|
-
}
|
|
1596
|
-
)
|
|
1760
|
+
/* @__PURE__ */ jsxs("div", { role: "group", "aria-label": "Filter by duration", style: { minWidth: 0 }, children: [
|
|
1761
|
+
sectionHeader("Duration"),
|
|
1762
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: tokens.spacing.xs }, children: ["all", "point", "range"].map((key) => {
|
|
1763
|
+
const active = (filter.eventShape ?? "all") === key;
|
|
1764
|
+
return /* @__PURE__ */ jsx("button", { type: "button", "aria-pressed": active, onClick: () => patch({ eventShape: key }), style: pillStyle(active), children: key === "all" ? "All" : key === "point" ? "Instant" : "Range" }, key);
|
|
1765
|
+
}) })
|
|
1597
1766
|
] }),
|
|
1598
|
-
/* @__PURE__ */ jsxs(
|
|
1599
|
-
|
|
1600
|
-
{
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
"aria-controls": "zendir-timeline-filters-panel",
|
|
1605
|
-
style: {
|
|
1606
|
-
display: "inline-flex",
|
|
1607
|
-
alignItems: "center",
|
|
1608
|
-
gap: 6,
|
|
1609
|
-
height: 36,
|
|
1610
|
-
padding: "0 14px",
|
|
1611
|
-
borderRadius: tokens.borderRadius.md,
|
|
1612
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1613
|
-
backgroundColor: tokens.colors.background.surface,
|
|
1614
|
-
color: tokens.colors.text.primary,
|
|
1615
|
-
cursor: "pointer",
|
|
1616
|
-
fontSize: "0.8125rem",
|
|
1617
|
-
fontWeight: 500
|
|
1618
|
-
},
|
|
1619
|
-
children: [
|
|
1620
|
-
"Filters",
|
|
1621
|
-
chipCount > 0 ? /* @__PURE__ */ jsx(Badge, { variant: "filled", size: "small", status: "normal", children: chipCount }) : null,
|
|
1622
|
-
/* @__PURE__ */ jsx(Icon, { name: expanded ? "chevron-up" : "chevron-down", size: 18 })
|
|
1623
|
-
]
|
|
1624
|
-
}
|
|
1625
|
-
),
|
|
1626
|
-
isTimelineFilterActive(filter) ? /* @__PURE__ */ jsx(
|
|
1627
|
-
"button",
|
|
1628
|
-
{
|
|
1629
|
-
type: "button",
|
|
1630
|
-
onClick: clearAll,
|
|
1631
|
-
style: {
|
|
1632
|
-
height: 36,
|
|
1633
|
-
padding: "0 12px",
|
|
1634
|
-
borderRadius: tokens.borderRadius.md,
|
|
1635
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1636
|
-
backgroundColor: "transparent",
|
|
1637
|
-
color: tokens.colors.text.secondary,
|
|
1638
|
-
cursor: "pointer",
|
|
1639
|
-
fontSize: "0.75rem",
|
|
1640
|
-
fontWeight: 500
|
|
1641
|
-
},
|
|
1642
|
-
children: "Clear all"
|
|
1643
|
-
}
|
|
1644
|
-
) : null
|
|
1645
|
-
]
|
|
1646
|
-
}
|
|
1647
|
-
),
|
|
1648
|
-
expanded ? /* @__PURE__ */ jsxs(
|
|
1649
|
-
"div",
|
|
1650
|
-
{
|
|
1651
|
-
id: "zendir-timeline-filters-panel",
|
|
1652
|
-
style: {
|
|
1653
|
-
marginTop: 14,
|
|
1654
|
-
display: "flex",
|
|
1655
|
-
flexDirection: "column",
|
|
1656
|
-
gap: 14
|
|
1657
|
-
},
|
|
1658
|
-
children: [
|
|
1659
|
-
trackOptions.length > 0 ? /* @__PURE__ */ jsxs("div", { children: [
|
|
1660
|
-
/* @__PURE__ */ jsx(
|
|
1661
|
-
"div",
|
|
1662
|
-
{
|
|
1663
|
-
style: {
|
|
1664
|
-
fontSize: "0.625rem",
|
|
1665
|
-
fontWeight: 600,
|
|
1666
|
-
letterSpacing: "0.06em",
|
|
1667
|
-
textTransform: "uppercase",
|
|
1668
|
-
color: tokens.colors.text.tertiary,
|
|
1669
|
-
marginBottom: 8
|
|
1670
|
-
},
|
|
1671
|
-
children: "Tracks"
|
|
1672
|
-
}
|
|
1673
|
-
),
|
|
1674
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: trackOptions.map((t) => {
|
|
1675
|
-
var _a;
|
|
1676
|
-
const active = ((_a = filter.tracks) == null ? void 0 : _a.includes(t.id)) ?? false;
|
|
1677
|
-
return /* @__PURE__ */ jsx(
|
|
1767
|
+
teamOptions.length > 0 ? /* @__PURE__ */ jsxs("div", { role: "group", "aria-label": `Filter by ${teamLabel.toLowerCase()}`, style: { flex: 1, minWidth: 180 }, children: [
|
|
1768
|
+
sectionHeader(teamLabel),
|
|
1769
|
+
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: tokens.spacing.xs }, children: teamOptions.map((opt) => {
|
|
1770
|
+
var _a, _b, _c;
|
|
1771
|
+
const active = ((_a = filter.teams) == null ? void 0 : _a.includes(opt.key)) ?? false;
|
|
1772
|
+
return /* @__PURE__ */ jsxs(
|
|
1678
1773
|
"button",
|
|
1679
1774
|
{
|
|
1680
1775
|
type: "button",
|
|
1681
|
-
|
|
1682
|
-
|
|
1683
|
-
|
|
1776
|
+
"aria-pressed": active,
|
|
1777
|
+
onClick: () => toggleTeam(opt.key),
|
|
1778
|
+
style: {
|
|
1779
|
+
...pillStyle(active, opt.color || void 0),
|
|
1780
|
+
display: "inline-flex",
|
|
1781
|
+
alignItems: "center",
|
|
1782
|
+
gap: 6,
|
|
1783
|
+
maxWidth: "100%"
|
|
1784
|
+
},
|
|
1785
|
+
children: [
|
|
1786
|
+
opt.isNoneBucket ? /* @__PURE__ */ jsx(
|
|
1787
|
+
"span",
|
|
1788
|
+
{
|
|
1789
|
+
style: {
|
|
1790
|
+
width: 8,
|
|
1791
|
+
height: 8,
|
|
1792
|
+
borderRadius: "50%",
|
|
1793
|
+
border: `${((_c = (_b = tokens.borders) == null ? void 0 : _b.width) == null ? void 0 : _c.thick) ?? "2px"} solid ${tokens.colors.border.muted}`,
|
|
1794
|
+
flexShrink: 0,
|
|
1795
|
+
boxSizing: "border-box"
|
|
1796
|
+
}
|
|
1797
|
+
}
|
|
1798
|
+
) : /* @__PURE__ */ jsx(
|
|
1799
|
+
"span",
|
|
1800
|
+
{
|
|
1801
|
+
style: {
|
|
1802
|
+
width: 8,
|
|
1803
|
+
height: 8,
|
|
1804
|
+
borderRadius: "50%",
|
|
1805
|
+
backgroundColor: opt.color,
|
|
1806
|
+
flexShrink: 0
|
|
1807
|
+
}
|
|
1808
|
+
}
|
|
1809
|
+
),
|
|
1810
|
+
/* @__PURE__ */ jsx("span", { style: { overflow: "hidden", textOverflow: "ellipsis", whiteSpace: "nowrap" }, children: opt.label })
|
|
1811
|
+
]
|
|
1684
1812
|
},
|
|
1685
|
-
|
|
1813
|
+
opt.key
|
|
1686
1814
|
);
|
|
1687
1815
|
}) })
|
|
1688
|
-
] }) : null
|
|
1689
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1690
|
-
/* @__PURE__ */ jsx(
|
|
1691
|
-
"div",
|
|
1692
|
-
{
|
|
1693
|
-
style: {
|
|
1694
|
-
fontSize: "0.625rem",
|
|
1695
|
-
fontWeight: 600,
|
|
1696
|
-
letterSpacing: "0.06em",
|
|
1697
|
-
textTransform: "uppercase",
|
|
1698
|
-
color: tokens.colors.text.tertiary,
|
|
1699
|
-
marginBottom: 8
|
|
1700
|
-
},
|
|
1701
|
-
children: "Status"
|
|
1702
|
-
}
|
|
1703
|
-
),
|
|
1704
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 6 }, children: ALL_TIMELINE_STATUSES.map((st) => {
|
|
1705
|
-
var _a;
|
|
1706
|
-
const active = ((_a = filter.status) == null ? void 0 : _a.includes(st)) ?? false;
|
|
1707
|
-
return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => toggleStatus(st), style: pillBase(active), children: st }, st);
|
|
1708
|
-
}) })
|
|
1709
|
-
] }),
|
|
1710
|
-
/* @__PURE__ */ jsxs(
|
|
1711
|
-
"div",
|
|
1712
|
-
{
|
|
1713
|
-
style: {
|
|
1714
|
-
display: "flex",
|
|
1715
|
-
flexWrap: "wrap",
|
|
1716
|
-
alignItems: "center",
|
|
1717
|
-
gap: 16
|
|
1718
|
-
},
|
|
1719
|
-
children: [
|
|
1720
|
-
/* @__PURE__ */ jsxs("div", { children: [
|
|
1721
|
-
/* @__PURE__ */ jsx(
|
|
1722
|
-
"div",
|
|
1723
|
-
{
|
|
1724
|
-
style: {
|
|
1725
|
-
fontSize: "0.625rem",
|
|
1726
|
-
fontWeight: 600,
|
|
1727
|
-
letterSpacing: "0.06em",
|
|
1728
|
-
textTransform: "uppercase",
|
|
1729
|
-
color: tokens.colors.text.tertiary,
|
|
1730
|
-
marginBottom: 8
|
|
1731
|
-
},
|
|
1732
|
-
children: "Duration"
|
|
1733
|
-
}
|
|
1734
|
-
),
|
|
1735
|
-
/* @__PURE__ */ jsx("div", { style: { display: "flex", flexWrap: "wrap", gap: 8 }, children: ["all", "point", "range"].map((key) => {
|
|
1736
|
-
const active = (filter.eventShape ?? "all") === key;
|
|
1737
|
-
return /* @__PURE__ */ jsx("button", { type: "button", onClick: () => patch({ eventShape: key }), style: pillBase(active), children: key === "all" ? "All" : key === "point" ? "Instant" : "Range" }, key);
|
|
1738
|
-
}) })
|
|
1739
|
-
] }),
|
|
1740
|
-
/* @__PURE__ */ jsx(
|
|
1741
|
-
Checkbox,
|
|
1742
|
-
{
|
|
1743
|
-
label: "Team color only",
|
|
1744
|
-
checked: Boolean(filter.teamColoredOnly),
|
|
1745
|
-
onChange: (checked) => patch({ teamColoredOnly: checked || void 0 }),
|
|
1746
|
-
size: "small"
|
|
1747
|
-
}
|
|
1748
|
-
)
|
|
1749
|
-
]
|
|
1750
|
-
}
|
|
1751
|
-
)
|
|
1816
|
+
] }) : null
|
|
1752
1817
|
]
|
|
1753
1818
|
}
|
|
1754
|
-
)
|
|
1819
|
+
),
|
|
1820
|
+
isTimelineFilterActive(filter) ? /* @__PURE__ */ jsx("div", { style: { display: "flex", justifyContent: "flex-end" }, children: /* @__PURE__ */ jsx(Button, { variant: "borderless", size: "small", onClick: clearAll, children: "Clear all" }) }) : null
|
|
1755
1821
|
]
|
|
1756
1822
|
}
|
|
1757
1823
|
);
|
|
@@ -1773,7 +1839,7 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1773
1839
|
timeFormat = "absolute",
|
|
1774
1840
|
zoomable = false,
|
|
1775
1841
|
initialZoom = 1,
|
|
1776
|
-
showFilters: _showFilters =
|
|
1842
|
+
showFilters: _showFilters = true,
|
|
1777
1843
|
filtersDefaultExpanded = false,
|
|
1778
1844
|
hideEmptyTracksWhenFiltered = true,
|
|
1779
1845
|
filter: _filter,
|
|
@@ -1784,14 +1850,20 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1784
1850
|
showPlayhead = true,
|
|
1785
1851
|
playheadTime,
|
|
1786
1852
|
onPlayheadChange: _onPlayheadChangeTimeline,
|
|
1787
|
-
showDayMarkers = true
|
|
1853
|
+
showDayMarkers = true,
|
|
1854
|
+
teamLabel: teamLabelProp
|
|
1788
1855
|
}) {
|
|
1789
1856
|
const { tokens, theme } = useTheme();
|
|
1790
1857
|
const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
|
|
1858
|
+
const { isMobile } = useBreakpoint();
|
|
1859
|
+
const categoryCtx = useCategoryPalette();
|
|
1860
|
+
const teamLabel = teamLabelProp ?? (categoryCtx == null ? void 0 : categoryCtx.categoryLabel) ?? "Teams";
|
|
1791
1861
|
const [internalViewMode, setInternalViewMode] = useState(defaultView);
|
|
1792
1862
|
const [zoom, setZoom] = useState(initialZoom);
|
|
1793
1863
|
const [_internalFilter, _setInternalFilter] = useState({});
|
|
1864
|
+
const [filtersExpanded, setFiltersExpanded] = useState(filtersDefaultExpanded);
|
|
1794
1865
|
const filter = _filter !== void 0 ? _filter : _internalFilter;
|
|
1866
|
+
const filterChipCount = _showFilters ? countTimelineFilterChips(filter) : 0;
|
|
1795
1867
|
const setFilter = useCallback(
|
|
1796
1868
|
(next) => {
|
|
1797
1869
|
const n = normalizeTimelineFilter(next);
|
|
@@ -1800,6 +1872,12 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1800
1872
|
},
|
|
1801
1873
|
[_filter, _onFilterChange]
|
|
1802
1874
|
);
|
|
1875
|
+
const patchFilter = useCallback(
|
|
1876
|
+
(partial) => {
|
|
1877
|
+
setFilter(normalizeTimelineFilter({ ...filter, ...partial }));
|
|
1878
|
+
},
|
|
1879
|
+
[filter, setFilter]
|
|
1880
|
+
);
|
|
1803
1881
|
const viewMode = controlledViewMode ?? internalViewMode;
|
|
1804
1882
|
const handleViewModeChange = useCallback((mode) => {
|
|
1805
1883
|
setInternalViewMode(mode);
|
|
@@ -1883,204 +1961,321 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1883
1961
|
{
|
|
1884
1962
|
style: {
|
|
1885
1963
|
display: "flex",
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
padding:
|
|
1964
|
+
flexDirection: isMobile ? "column" : "row",
|
|
1965
|
+
alignItems: isMobile ? "stretch" : "center",
|
|
1966
|
+
padding: `${tokens.spacing.smd} ${tokens.spacing.md}`,
|
|
1967
|
+
gap: isMobile ? tokens.spacing.xs : tokens.spacing.sm,
|
|
1889
1968
|
borderBottom: `1px solid ${tokens.colors.border.muted}`
|
|
1890
1969
|
},
|
|
1891
1970
|
children: [
|
|
1892
|
-
/* @__PURE__ */
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
style: {
|
|
1896
|
-
margin: 0,
|
|
1897
|
-
fontSize: "1rem",
|
|
1898
|
-
fontWeight: 500,
|
|
1899
|
-
// AstroUXDS medium (was 600)
|
|
1900
|
-
color: tokens.colors.text.primary
|
|
1901
|
-
},
|
|
1902
|
-
children: countLabel
|
|
1903
|
-
}
|
|
1904
|
-
),
|
|
1905
|
-
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
1906
|
-
zoomable && (viewMode === "chart" || viewMode === "scatter") && /* @__PURE__ */ jsxs(
|
|
1907
|
-
"div",
|
|
1971
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm }, children: [
|
|
1972
|
+
/* @__PURE__ */ jsx(
|
|
1973
|
+
"h3",
|
|
1908
1974
|
{
|
|
1909
1975
|
style: {
|
|
1910
|
-
|
|
1911
|
-
|
|
1912
|
-
|
|
1913
|
-
|
|
1914
|
-
|
|
1976
|
+
margin: 0,
|
|
1977
|
+
fontSize: "1rem",
|
|
1978
|
+
fontWeight: 500,
|
|
1979
|
+
// AstroUXDS medium
|
|
1980
|
+
color: tokens.colors.text.primary,
|
|
1981
|
+
whiteSpace: "nowrap",
|
|
1982
|
+
flexShrink: 0
|
|
1915
1983
|
},
|
|
1916
|
-
children:
|
|
1917
|
-
/* @__PURE__ */ jsx(Tooltip, { content: "Zoom out", children: /* @__PURE__ */ jsx(
|
|
1918
|
-
"button",
|
|
1919
|
-
{
|
|
1920
|
-
type: "button",
|
|
1921
|
-
"aria-label": "Zoom out",
|
|
1922
|
-
onClick: () => setZoom(Math.max(zoom - 0.5, 1)),
|
|
1923
|
-
disabled: zoom <= 1,
|
|
1924
|
-
style: {
|
|
1925
|
-
width: 28,
|
|
1926
|
-
height: 28,
|
|
1927
|
-
display: "flex",
|
|
1928
|
-
alignItems: "center",
|
|
1929
|
-
justifyContent: "center",
|
|
1930
|
-
backgroundColor: zoom <= 1 ? "transparent" : tokens.colors.background.elevated,
|
|
1931
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1932
|
-
borderRadius: tokens.borderRadius.sm,
|
|
1933
|
-
color: zoom <= 1 ? tokens.colors.text.tertiary : tokens.colors.text.primary,
|
|
1934
|
-
cursor: zoom <= 1 ? "not-allowed" : "pointer",
|
|
1935
|
-
fontSize: "1rem",
|
|
1936
|
-
fontWeight: 500,
|
|
1937
|
-
// AstroUXDS medium (was 600)
|
|
1938
|
-
opacity: zoom <= 1 ? 0.5 : 1
|
|
1939
|
-
},
|
|
1940
|
-
children: "−"
|
|
1941
|
-
}
|
|
1942
|
-
) }),
|
|
1943
|
-
/* @__PURE__ */ jsxs(
|
|
1944
|
-
"span",
|
|
1945
|
-
{
|
|
1946
|
-
style: {
|
|
1947
|
-
minWidth: 40,
|
|
1948
|
-
textAlign: "center",
|
|
1949
|
-
fontSize: "0.75rem",
|
|
1950
|
-
fontFamily: tokens.typography.fontFamily.mono,
|
|
1951
|
-
color: tokens.colors.text.secondary
|
|
1952
|
-
},
|
|
1953
|
-
children: [
|
|
1954
|
-
Math.round(zoom * 100),
|
|
1955
|
-
"%"
|
|
1956
|
-
]
|
|
1957
|
-
}
|
|
1958
|
-
),
|
|
1959
|
-
/* @__PURE__ */ jsx(Tooltip, { content: "Zoom in", children: /* @__PURE__ */ jsx(
|
|
1960
|
-
"button",
|
|
1961
|
-
{
|
|
1962
|
-
type: "button",
|
|
1963
|
-
"aria-label": "Zoom in",
|
|
1964
|
-
onClick: () => setZoom(Math.min(zoom + 0.5, 4)),
|
|
1965
|
-
disabled: zoom >= 4,
|
|
1966
|
-
style: {
|
|
1967
|
-
width: 28,
|
|
1968
|
-
height: 28,
|
|
1969
|
-
display: "flex",
|
|
1970
|
-
alignItems: "center",
|
|
1971
|
-
justifyContent: "center",
|
|
1972
|
-
backgroundColor: zoom >= 4 ? "transparent" : tokens.colors.background.elevated,
|
|
1973
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1974
|
-
borderRadius: tokens.borderRadius.sm,
|
|
1975
|
-
color: zoom >= 4 ? tokens.colors.text.tertiary : tokens.colors.text.primary,
|
|
1976
|
-
cursor: zoom >= 4 ? "not-allowed" : "pointer",
|
|
1977
|
-
fontSize: "1rem",
|
|
1978
|
-
fontWeight: 500,
|
|
1979
|
-
// AstroUXDS medium (was 600)
|
|
1980
|
-
opacity: zoom >= 4 ? 0.5 : 1
|
|
1981
|
-
},
|
|
1982
|
-
children: "+"
|
|
1983
|
-
}
|
|
1984
|
-
) }),
|
|
1985
|
-
/* @__PURE__ */ jsx(Tooltip, { content: "Reset zoom", children: /* @__PURE__ */ jsx(
|
|
1986
|
-
"button",
|
|
1987
|
-
{
|
|
1988
|
-
type: "button",
|
|
1989
|
-
"aria-label": "Reset zoom",
|
|
1990
|
-
onClick: () => setZoom(1),
|
|
1991
|
-
style: {
|
|
1992
|
-
height: 28,
|
|
1993
|
-
padding: "0 10px",
|
|
1994
|
-
display: "flex",
|
|
1995
|
-
alignItems: "center",
|
|
1996
|
-
justifyContent: "center",
|
|
1997
|
-
backgroundColor: tokens.colors.background.elevated,
|
|
1998
|
-
border: `1px solid ${tokens.colors.border.muted}`,
|
|
1999
|
-
borderRadius: tokens.borderRadius.sm,
|
|
2000
|
-
color: tokens.colors.text.secondary,
|
|
2001
|
-
cursor: "pointer",
|
|
2002
|
-
fontSize: "0.6875rem",
|
|
2003
|
-
fontWeight: 500
|
|
2004
|
-
},
|
|
2005
|
-
children: "FIT"
|
|
2006
|
-
}
|
|
2007
|
-
) })
|
|
2008
|
-
]
|
|
1984
|
+
children: countLabel
|
|
2009
1985
|
}
|
|
2010
1986
|
),
|
|
2011
|
-
|
|
2012
|
-
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
};
|
|
2029
|
-
const labels = {
|
|
2030
|
-
chart: "Gantt Chart",
|
|
2031
|
-
list: "List View",
|
|
2032
|
-
scatter: "Scatter View"
|
|
2033
|
-
};
|
|
2034
|
-
return /* @__PURE__ */ jsx(Tooltip, { content: labels[mode], children: /* @__PURE__ */ jsx(
|
|
2035
|
-
"button",
|
|
2036
|
-
{
|
|
2037
|
-
type: "button",
|
|
2038
|
-
"aria-label": labels[mode],
|
|
2039
|
-
onClick: () => handleViewModeChange(mode),
|
|
2040
|
-
style: {
|
|
2041
|
-
display: "flex",
|
|
2042
|
-
alignItems: "center",
|
|
2043
|
-
justifyContent: "center",
|
|
2044
|
-
width: "32px",
|
|
2045
|
-
height: "32px",
|
|
2046
|
-
backgroundColor: isActive ? tokens.colors.accent.primary : "transparent",
|
|
2047
|
-
border: "none",
|
|
2048
|
-
borderRadius: tokens.borderRadius.md,
|
|
2049
|
-
color: isActive ? "#ffffff" : tokens.colors.text.secondary,
|
|
2050
|
-
cursor: "pointer",
|
|
2051
|
-
transition: "all 200ms cubic-bezier(0.4, 0, 0.2, 1)",
|
|
2052
|
-
transform: isActive ? "scale(1)" : "scale(0.95)",
|
|
2053
|
-
boxShadow: isActive ? `0 2px 8px ${tokens.colors.accent.primary}40` : "none"
|
|
2054
|
-
},
|
|
2055
|
-
onMouseEnter: (e) => {
|
|
2056
|
-
if (!isActive) {
|
|
2057
|
-
e.currentTarget.style.backgroundColor = `${tokens.colors.accent.primary}20`;
|
|
2058
|
-
e.currentTarget.style.transform = "scale(1)";
|
|
2059
|
-
}
|
|
2060
|
-
},
|
|
2061
|
-
onMouseLeave: (e) => {
|
|
2062
|
-
if (!isActive) {
|
|
2063
|
-
e.currentTarget.style.backgroundColor = "transparent";
|
|
2064
|
-
e.currentTarget.style.transform = "scale(0.95)";
|
|
2065
|
-
}
|
|
2066
|
-
},
|
|
2067
|
-
children: /* @__PURE__ */ jsx(Icon, { name: icons[mode], size: 16 })
|
|
1987
|
+
!isMobile && /* @__PURE__ */ jsx("div", { style: { flex: 1 } })
|
|
1988
|
+
] }),
|
|
1989
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.sm, flex: isMobile ? void 0 : 1, justifyContent: isMobile ? "space-between" : "flex-end" }, children: [
|
|
1990
|
+
_showFilters && /* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: tokens.spacing.xs, flex: isMobile ? 1 : void 0, flexShrink: 0 }, children: [
|
|
1991
|
+
/* @__PURE__ */ jsxs("div", { style: { position: "relative", width: isMobile ? "100%" : 180 }, children: [
|
|
1992
|
+
/* @__PURE__ */ jsx(
|
|
1993
|
+
Icon,
|
|
1994
|
+
{
|
|
1995
|
+
name: "search",
|
|
1996
|
+
size: 14,
|
|
1997
|
+
style: {
|
|
1998
|
+
position: "absolute",
|
|
1999
|
+
left: 8,
|
|
2000
|
+
top: "50%",
|
|
2001
|
+
transform: "translateY(-50%)",
|
|
2002
|
+
color: tokens.colors.text.tertiary,
|
|
2003
|
+
pointerEvents: "none"
|
|
2068
2004
|
}
|
|
2069
|
-
|
|
2070
|
-
|
|
2071
|
-
|
|
2072
|
-
|
|
2073
|
-
|
|
2005
|
+
}
|
|
2006
|
+
),
|
|
2007
|
+
/* @__PURE__ */ jsx(
|
|
2008
|
+
"input",
|
|
2009
|
+
{
|
|
2010
|
+
type: "search",
|
|
2011
|
+
value: filter.search ?? "",
|
|
2012
|
+
onChange: (e) => patchFilter({ search: e.target.value || void 0 }),
|
|
2013
|
+
placeholder: "Search…",
|
|
2014
|
+
"aria-label": "Search timeline events",
|
|
2015
|
+
style: {
|
|
2016
|
+
width: "100%",
|
|
2017
|
+
boxSizing: "border-box",
|
|
2018
|
+
height: tokens.elementSize.sm,
|
|
2019
|
+
paddingLeft: 28,
|
|
2020
|
+
paddingRight: 8,
|
|
2021
|
+
borderRadius: tokens.borderRadius.md,
|
|
2022
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
2023
|
+
backgroundColor: tokens.colors.background.base,
|
|
2024
|
+
color: tokens.colors.text.primary,
|
|
2025
|
+
fontSize: tokens.typography.fontSize.sm,
|
|
2026
|
+
fontFamily: "inherit",
|
|
2027
|
+
outline: "none",
|
|
2028
|
+
transition: "all 200ms cubic-bezier(0.4, 0, 0.2, 1)"
|
|
2029
|
+
},
|
|
2030
|
+
onFocus: (e) => {
|
|
2031
|
+
e.target.style.borderColor = tokens.colors.accent.primary;
|
|
2032
|
+
e.target.style.boxShadow = `0 0 0 3px ${tokens.colors.accent.primary}50, 0 0 20px ${tokens.colors.accent.primary}15`;
|
|
2033
|
+
},
|
|
2034
|
+
onBlur: (e) => {
|
|
2035
|
+
e.target.style.borderColor = tokens.colors.border.muted;
|
|
2036
|
+
e.target.style.boxShadow = "none";
|
|
2037
|
+
}
|
|
2038
|
+
}
|
|
2039
|
+
)
|
|
2040
|
+
] }),
|
|
2041
|
+
/* @__PURE__ */ jsx(Tooltip, { content: filtersExpanded ? "Hide filters" : "Show filters", children: /* @__PURE__ */ jsxs(
|
|
2042
|
+
"button",
|
|
2043
|
+
{
|
|
2044
|
+
type: "button",
|
|
2045
|
+
"aria-label": filtersExpanded ? "Hide filters" : "Show filters",
|
|
2046
|
+
"aria-expanded": filtersExpanded,
|
|
2047
|
+
"aria-controls": "zendir-timeline-filters-panel",
|
|
2048
|
+
onClick: () => setFiltersExpanded((v) => !v),
|
|
2049
|
+
style: {
|
|
2050
|
+
position: "relative",
|
|
2051
|
+
display: "flex",
|
|
2052
|
+
alignItems: "center",
|
|
2053
|
+
justifyContent: "center",
|
|
2054
|
+
width: 28,
|
|
2055
|
+
height: 28,
|
|
2056
|
+
border: `1px solid ${filterChipCount > 0 ? `${tokens.colors.accent.primary}80` : tokens.colors.border.muted}`,
|
|
2057
|
+
borderRadius: tokens.borderRadius.sm,
|
|
2058
|
+
backgroundColor: filterChipCount > 0 ? `${tokens.colors.accent.primary}12` : "transparent",
|
|
2059
|
+
color: filterChipCount > 0 ? tokens.colors.accent.primary : tokens.colors.text.secondary,
|
|
2060
|
+
cursor: "pointer",
|
|
2061
|
+
transition: tokens.animation.fast
|
|
2062
|
+
},
|
|
2063
|
+
children: [
|
|
2064
|
+
/* @__PURE__ */ jsx(Icon, { name: "filter", size: 16 }),
|
|
2065
|
+
filterChipCount > 0 ? /* @__PURE__ */ jsx(
|
|
2066
|
+
"span",
|
|
2067
|
+
{
|
|
2068
|
+
style: {
|
|
2069
|
+
position: "absolute",
|
|
2070
|
+
top: -4,
|
|
2071
|
+
right: -4,
|
|
2072
|
+
minWidth: 14,
|
|
2073
|
+
height: 14,
|
|
2074
|
+
borderRadius: "50%",
|
|
2075
|
+
backgroundColor: tokens.colors.accent.primary,
|
|
2076
|
+
color: "#fff",
|
|
2077
|
+
fontSize: "0.5625rem",
|
|
2078
|
+
fontWeight: 700,
|
|
2079
|
+
display: "flex",
|
|
2080
|
+
alignItems: "center",
|
|
2081
|
+
justifyContent: "center",
|
|
2082
|
+
lineHeight: 1
|
|
2083
|
+
},
|
|
2084
|
+
children: filterChipCount
|
|
2085
|
+
}
|
|
2086
|
+
) : null
|
|
2087
|
+
]
|
|
2088
|
+
}
|
|
2089
|
+
) })
|
|
2090
|
+
] }),
|
|
2091
|
+
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12, flexShrink: 0 }, children: [
|
|
2092
|
+
zoomable && (viewMode === "chart" || viewMode === "scatter") && /* @__PURE__ */ jsxs(
|
|
2093
|
+
"div",
|
|
2094
|
+
{
|
|
2095
|
+
style: {
|
|
2096
|
+
display: "flex",
|
|
2097
|
+
alignItems: "center",
|
|
2098
|
+
gap: 4,
|
|
2099
|
+
paddingRight: 12,
|
|
2100
|
+
borderRight: `1px solid ${tokens.colors.border.muted}`
|
|
2101
|
+
},
|
|
2102
|
+
children: [
|
|
2103
|
+
/* @__PURE__ */ jsx(Tooltip, { content: "Zoom out", children: /* @__PURE__ */ jsx(
|
|
2104
|
+
"button",
|
|
2105
|
+
{
|
|
2106
|
+
type: "button",
|
|
2107
|
+
"aria-label": "Zoom out",
|
|
2108
|
+
onClick: () => setZoom(Math.max(zoom - 0.5, 1)),
|
|
2109
|
+
disabled: zoom <= 1,
|
|
2110
|
+
style: {
|
|
2111
|
+
width: 28,
|
|
2112
|
+
height: 28,
|
|
2113
|
+
display: "flex",
|
|
2114
|
+
alignItems: "center",
|
|
2115
|
+
justifyContent: "center",
|
|
2116
|
+
backgroundColor: zoom <= 1 ? "transparent" : tokens.colors.background.elevated,
|
|
2117
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
2118
|
+
borderRadius: tokens.borderRadius.sm,
|
|
2119
|
+
color: zoom <= 1 ? tokens.colors.text.tertiary : tokens.colors.text.primary,
|
|
2120
|
+
cursor: zoom <= 1 ? "not-allowed" : "pointer",
|
|
2121
|
+
fontSize: "1rem",
|
|
2122
|
+
fontWeight: 500,
|
|
2123
|
+
// AstroUXDS medium (was 600)
|
|
2124
|
+
opacity: zoom <= 1 ? 0.5 : 1
|
|
2125
|
+
},
|
|
2126
|
+
children: "−"
|
|
2127
|
+
}
|
|
2128
|
+
) }),
|
|
2129
|
+
/* @__PURE__ */ jsxs(
|
|
2130
|
+
"span",
|
|
2131
|
+
{
|
|
2132
|
+
style: {
|
|
2133
|
+
minWidth: 40,
|
|
2134
|
+
textAlign: "center",
|
|
2135
|
+
fontSize: "0.75rem",
|
|
2136
|
+
fontFamily: tokens.typography.fontFamily.mono,
|
|
2137
|
+
color: tokens.colors.text.secondary
|
|
2138
|
+
},
|
|
2139
|
+
children: [
|
|
2140
|
+
Math.round(zoom * 100),
|
|
2141
|
+
"%"
|
|
2142
|
+
]
|
|
2143
|
+
}
|
|
2144
|
+
),
|
|
2145
|
+
/* @__PURE__ */ jsx(Tooltip, { content: "Zoom in", children: /* @__PURE__ */ jsx(
|
|
2146
|
+
"button",
|
|
2147
|
+
{
|
|
2148
|
+
type: "button",
|
|
2149
|
+
"aria-label": "Zoom in",
|
|
2150
|
+
onClick: () => setZoom(Math.min(zoom + 0.5, 4)),
|
|
2151
|
+
disabled: zoom >= 4,
|
|
2152
|
+
style: {
|
|
2153
|
+
width: 28,
|
|
2154
|
+
height: 28,
|
|
2155
|
+
display: "flex",
|
|
2156
|
+
alignItems: "center",
|
|
2157
|
+
justifyContent: "center",
|
|
2158
|
+
backgroundColor: zoom >= 4 ? "transparent" : tokens.colors.background.elevated,
|
|
2159
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
2160
|
+
borderRadius: tokens.borderRadius.sm,
|
|
2161
|
+
color: zoom >= 4 ? tokens.colors.text.tertiary : tokens.colors.text.primary,
|
|
2162
|
+
cursor: zoom >= 4 ? "not-allowed" : "pointer",
|
|
2163
|
+
fontSize: "1rem",
|
|
2164
|
+
fontWeight: 500,
|
|
2165
|
+
// AstroUXDS medium (was 600)
|
|
2166
|
+
opacity: zoom >= 4 ? 0.5 : 1
|
|
2167
|
+
},
|
|
2168
|
+
children: "+"
|
|
2169
|
+
}
|
|
2170
|
+
) }),
|
|
2171
|
+
/* @__PURE__ */ jsx(Tooltip, { content: "Reset zoom", children: /* @__PURE__ */ jsx(
|
|
2172
|
+
"button",
|
|
2173
|
+
{
|
|
2174
|
+
type: "button",
|
|
2175
|
+
"aria-label": "Reset zoom",
|
|
2176
|
+
onClick: () => setZoom(1),
|
|
2177
|
+
style: {
|
|
2178
|
+
height: 28,
|
|
2179
|
+
padding: "0 10px",
|
|
2180
|
+
display: "flex",
|
|
2181
|
+
alignItems: "center",
|
|
2182
|
+
justifyContent: "center",
|
|
2183
|
+
backgroundColor: tokens.colors.background.elevated,
|
|
2184
|
+
border: `1px solid ${tokens.colors.border.muted}`,
|
|
2185
|
+
borderRadius: tokens.borderRadius.sm,
|
|
2186
|
+
color: tokens.colors.text.secondary,
|
|
2187
|
+
cursor: "pointer",
|
|
2188
|
+
fontSize: "0.6875rem",
|
|
2189
|
+
fontWeight: 500
|
|
2190
|
+
},
|
|
2191
|
+
children: "FIT"
|
|
2192
|
+
}
|
|
2193
|
+
) })
|
|
2194
|
+
]
|
|
2195
|
+
}
|
|
2196
|
+
),
|
|
2197
|
+
showViewToggle && /* @__PURE__ */ jsx(
|
|
2198
|
+
"div",
|
|
2199
|
+
{
|
|
2200
|
+
role: "group",
|
|
2201
|
+
"aria-label": "View mode",
|
|
2202
|
+
style: {
|
|
2203
|
+
display: "flex",
|
|
2204
|
+
gap: "2px",
|
|
2205
|
+
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.elevated,
|
|
2206
|
+
...isTransparentTheme && { backdropFilter: "blur(12px)", WebkitBackdropFilter: "blur(12px)" },
|
|
2207
|
+
padding: "4px",
|
|
2208
|
+
borderRadius: tokens.borderRadius.lg
|
|
2209
|
+
},
|
|
2210
|
+
children: ["chart", "list", "scatter"].map((mode) => {
|
|
2211
|
+
const isActive = viewMode === mode;
|
|
2212
|
+
const icons = {
|
|
2213
|
+
chart: "chart",
|
|
2214
|
+
list: "list",
|
|
2215
|
+
scatter: "timeline"
|
|
2216
|
+
};
|
|
2217
|
+
const labels = {
|
|
2218
|
+
chart: "Gantt Chart",
|
|
2219
|
+
list: "List View",
|
|
2220
|
+
scatter: "Scatter View"
|
|
2221
|
+
};
|
|
2222
|
+
return /* @__PURE__ */ jsx(Tooltip, { content: labels[mode], children: /* @__PURE__ */ jsx(
|
|
2223
|
+
"button",
|
|
2224
|
+
{
|
|
2225
|
+
type: "button",
|
|
2226
|
+
"aria-label": labels[mode],
|
|
2227
|
+
"aria-pressed": isActive,
|
|
2228
|
+
onClick: () => handleViewModeChange(mode),
|
|
2229
|
+
style: {
|
|
2230
|
+
display: "flex",
|
|
2231
|
+
alignItems: "center",
|
|
2232
|
+
justifyContent: "center",
|
|
2233
|
+
width: "32px",
|
|
2234
|
+
height: "32px",
|
|
2235
|
+
backgroundColor: isActive ? tokens.colors.accent.primary : "transparent",
|
|
2236
|
+
border: "none",
|
|
2237
|
+
borderRadius: tokens.borderRadius.md,
|
|
2238
|
+
color: isActive ? "#ffffff" : tokens.colors.text.secondary,
|
|
2239
|
+
cursor: "pointer",
|
|
2240
|
+
transition: "all 200ms cubic-bezier(0.4, 0, 0.2, 1)",
|
|
2241
|
+
transform: isActive ? "scale(1)" : "scale(0.95)",
|
|
2242
|
+
boxShadow: isActive ? `0 2px 8px ${tokens.colors.accent.primary}40` : "none"
|
|
2243
|
+
},
|
|
2244
|
+
onMouseEnter: (e) => {
|
|
2245
|
+
if (!isActive) {
|
|
2246
|
+
e.currentTarget.style.backgroundColor = `${tokens.colors.accent.primary}20`;
|
|
2247
|
+
e.currentTarget.style.transform = "scale(1)";
|
|
2248
|
+
}
|
|
2249
|
+
},
|
|
2250
|
+
onMouseLeave: (e) => {
|
|
2251
|
+
if (!isActive) {
|
|
2252
|
+
e.currentTarget.style.backgroundColor = "transparent";
|
|
2253
|
+
e.currentTarget.style.transform = "scale(0.95)";
|
|
2254
|
+
}
|
|
2255
|
+
},
|
|
2256
|
+
children: /* @__PURE__ */ jsx(Icon, { name: icons[mode], size: 16 })
|
|
2257
|
+
}
|
|
2258
|
+
) }, mode);
|
|
2259
|
+
})
|
|
2260
|
+
}
|
|
2261
|
+
)
|
|
2262
|
+
] }),
|
|
2263
|
+
" "
|
|
2264
|
+
] }),
|
|
2265
|
+
" "
|
|
2074
2266
|
]
|
|
2075
2267
|
}
|
|
2076
2268
|
),
|
|
2269
|
+
" ",
|
|
2077
2270
|
_showFilters ? /* @__PURE__ */ jsx(
|
|
2078
|
-
|
|
2271
|
+
TimelineFiltersPanel,
|
|
2079
2272
|
{
|
|
2080
2273
|
filter,
|
|
2081
2274
|
onFilterChange: setFilter,
|
|
2082
2275
|
trackOptions: trackOptionsForToolbar,
|
|
2083
|
-
|
|
2276
|
+
events,
|
|
2277
|
+
expanded: filtersExpanded,
|
|
2278
|
+
teamLabel
|
|
2084
2279
|
}
|
|
2085
2280
|
) : null,
|
|
2086
2281
|
loading && /* @__PURE__ */ jsx(
|
|
@@ -2094,7 +2289,7 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
2094
2289
|
justifyContent: "center",
|
|
2095
2290
|
backgroundColor: `${tokens.colors.background.overlay}80`,
|
|
2096
2291
|
backdropFilter: "blur(4px)",
|
|
2097
|
-
zIndex:
|
|
2292
|
+
zIndex: Z.loadingOverlay
|
|
2098
2293
|
},
|
|
2099
2294
|
children: /* @__PURE__ */ jsx(
|
|
2100
2295
|
"div",
|
|
@@ -2233,8 +2428,13 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
2233
2428
|
);
|
|
2234
2429
|
});
|
|
2235
2430
|
export {
|
|
2431
|
+
TIMELINE_FILTER_TEAM_LEGACY,
|
|
2432
|
+
TIMELINE_FILTER_TEAM_NONE,
|
|
2236
2433
|
UnifiedTimeline,
|
|
2237
2434
|
getTimelineEventDisplayStatus,
|
|
2435
|
+
getTimelineTeamAccent,
|
|
2436
|
+
getTimelineTeamDisplayLabel,
|
|
2437
|
+
getTimelineTeamFilterKey,
|
|
2238
2438
|
isTimelineFilterActive,
|
|
2239
2439
|
matchesTimelineFilter
|
|
2240
2440
|
};
|