@zendir/ui 0.1.14 → 0.1.15
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.
|
@@ -4,7 +4,84 @@ import { classNames, safeAccentText } from "../utils/index.js";
|
|
|
4
4
|
import { Icon } from "../core/Icon.js";
|
|
5
5
|
import { Badge } from "../core/Badge.js";
|
|
6
6
|
import { Tooltip } from "../core/Tooltip.js";
|
|
7
|
+
import { Checkbox } from "../core/Checkbox.js";
|
|
7
8
|
import { useTheme } from "../theme/ThemeProvider.js";
|
|
9
|
+
const ALL_TIMELINE_STATUSES = [
|
|
10
|
+
"off",
|
|
11
|
+
"standby",
|
|
12
|
+
"normal",
|
|
13
|
+
"caution",
|
|
14
|
+
"serious",
|
|
15
|
+
"critical"
|
|
16
|
+
];
|
|
17
|
+
function getTimelineEventDisplayStatus(event) {
|
|
18
|
+
if (event.badgeVariant && event.badgeVariant !== "default" && event.badgeVariant !== "primary") {
|
|
19
|
+
return event.badgeVariant;
|
|
20
|
+
}
|
|
21
|
+
return event.status ?? "normal";
|
|
22
|
+
}
|
|
23
|
+
function isTimelineFilterActive(filter) {
|
|
24
|
+
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
|
|
26
|
+
);
|
|
27
|
+
}
|
|
28
|
+
function normalizeTimelineFilter(f) {
|
|
29
|
+
var _a, _b, _c;
|
|
30
|
+
const o = {};
|
|
31
|
+
const s = (_a = f.search) == null ? void 0 : _a.trim();
|
|
32
|
+
if (s) o.search = s;
|
|
33
|
+
if ((_b = f.tracks) == null ? void 0 : _b.length) o.tracks = [...f.tracks];
|
|
34
|
+
if ((_c = f.status) == null ? void 0 : _c.length) o.status = [...f.status];
|
|
35
|
+
if (f.eventShape && f.eventShape !== "all") o.eventShape = f.eventShape;
|
|
36
|
+
if (f.teamColoredOnly) o.teamColoredOnly = true;
|
|
37
|
+
return o;
|
|
38
|
+
}
|
|
39
|
+
function matchesTimelineFilter(event, filter) {
|
|
40
|
+
var _a, _b, _c, _d, _e;
|
|
41
|
+
if (!isTimelineFilterActive(filter)) return true;
|
|
42
|
+
if ((_a = filter.tracks) == null ? void 0 : _a.length) {
|
|
43
|
+
const tid = event.track ?? "default";
|
|
44
|
+
if (!filter.tracks.includes(tid)) return false;
|
|
45
|
+
}
|
|
46
|
+
if ((_b = filter.status) == null ? void 0 : _b.length) {
|
|
47
|
+
const ds = getTimelineEventDisplayStatus(event);
|
|
48
|
+
if (!filter.status.includes(ds)) return false;
|
|
49
|
+
}
|
|
50
|
+
const q = (_c = filter.search) == null ? void 0 : _c.trim().toLowerCase();
|
|
51
|
+
if (q) {
|
|
52
|
+
const argStr = event.arguments ? Object.values(event.arguments).map((v) => String(v)).join(" ") : "";
|
|
53
|
+
const hay = [
|
|
54
|
+
event.title,
|
|
55
|
+
event.subtitle,
|
|
56
|
+
event.badge,
|
|
57
|
+
event.track,
|
|
58
|
+
argStr
|
|
59
|
+
].filter(Boolean).join(" ").toLowerCase();
|
|
60
|
+
if (!hay.includes(q)) return false;
|
|
61
|
+
}
|
|
62
|
+
if (filter.eventShape === "point") {
|
|
63
|
+
const endT = (_d = event.end) == null ? void 0 : _d.getTime();
|
|
64
|
+
const st = event.start.getTime();
|
|
65
|
+
if (endT != null && endT > st) return false;
|
|
66
|
+
}
|
|
67
|
+
if (filter.eventShape === "range") {
|
|
68
|
+
const endT = (_e = event.end) == null ? void 0 : _e.getTime();
|
|
69
|
+
const st = event.start.getTime();
|
|
70
|
+
if (endT == null || endT <= st) return false;
|
|
71
|
+
}
|
|
72
|
+
if (filter.teamColoredOnly && !event.color) return false;
|
|
73
|
+
return true;
|
|
74
|
+
}
|
|
75
|
+
function countTimelineFilterChips(filter) {
|
|
76
|
+
var _a, _b, _c;
|
|
77
|
+
let n = 0;
|
|
78
|
+
if ((_a = filter.search) == null ? void 0 : _a.trim()) n++;
|
|
79
|
+
if ((_b = filter.tracks) == null ? void 0 : _b.length) n++;
|
|
80
|
+
if ((_c = filter.status) == null ? void 0 : _c.length) n++;
|
|
81
|
+
if (filter.eventShape && filter.eventShape !== "all") n++;
|
|
82
|
+
if (filter.teamColoredOnly) n++;
|
|
83
|
+
return n;
|
|
84
|
+
}
|
|
8
85
|
function TimelineStatusMarker({
|
|
9
86
|
status,
|
|
10
87
|
fillColor,
|
|
@@ -607,11 +684,12 @@ const ChartView = memo(function ChartView2({
|
|
|
607
684
|
)),
|
|
608
685
|
(eventsByTrack[track.id] || []).map((event) => {
|
|
609
686
|
const { left, width } = getEventPosition(event);
|
|
610
|
-
const
|
|
687
|
+
const displayStatus = event.badgeVariant && event.badgeVariant !== "default" && event.badgeVariant !== "primary" ? event.badgeVariant : event.status ?? "normal";
|
|
688
|
+
const color = getStatusColor(displayStatus);
|
|
611
689
|
const isHovered = hoveredEvent === event.id;
|
|
612
690
|
const overlap = eventOverlaps[event.id];
|
|
613
691
|
const hasOverlap = overlap && overlap.overlapCount > 0;
|
|
614
|
-
const cardHeight = hasOverlap ?
|
|
692
|
+
const cardHeight = hasOverlap ? 30 : 38;
|
|
615
693
|
const stackOffset = overlap ? overlap.stackIndex * 30 : 0;
|
|
616
694
|
const baseTop = ((track.height || trackHeight) - cardHeight) / 2;
|
|
617
695
|
return /* @__PURE__ */ jsxs(
|
|
@@ -649,7 +727,7 @@ const ChartView = memo(function ChartView2({
|
|
|
649
727
|
transform: isHovered ? "translateY(-3px) scale(1.02)" : "none"
|
|
650
728
|
},
|
|
651
729
|
children: [
|
|
652
|
-
event.color
|
|
730
|
+
event.color ? /* @__PURE__ */ jsx(
|
|
653
731
|
"div",
|
|
654
732
|
{
|
|
655
733
|
style: {
|
|
@@ -657,57 +735,63 @@ const ChartView = memo(function ChartView2({
|
|
|
657
735
|
top: 0,
|
|
658
736
|
left: 0,
|
|
659
737
|
right: 0,
|
|
660
|
-
height:
|
|
738
|
+
height: 2,
|
|
661
739
|
backgroundColor: event.color,
|
|
662
|
-
borderRadius: "4px 4px 0 0"
|
|
663
|
-
|
|
664
|
-
|
|
665
|
-
|
|
666
|
-
|
|
667
|
-
"div",
|
|
668
|
-
{
|
|
669
|
-
style: {
|
|
670
|
-
width: 4,
|
|
671
|
-
height: "100%",
|
|
672
|
-
backgroundColor: color,
|
|
673
|
-
flexShrink: 0,
|
|
674
|
-
borderRadius: "2px 0 0 2px"
|
|
675
|
-
}
|
|
740
|
+
borderRadius: "4px 4px 0 0",
|
|
741
|
+
zIndex: 1,
|
|
742
|
+
pointerEvents: "none"
|
|
743
|
+
},
|
|
744
|
+
"aria-hidden": true
|
|
676
745
|
}
|
|
677
|
-
),
|
|
746
|
+
) : null,
|
|
678
747
|
/* @__PURE__ */ jsxs(
|
|
679
748
|
"div",
|
|
680
749
|
{
|
|
681
750
|
style: {
|
|
682
751
|
flex: 1,
|
|
683
|
-
padding:
|
|
752
|
+
padding: `${event.color ? 6 : 4}px 8px 4px 8px`,
|
|
684
753
|
overflow: "hidden",
|
|
685
|
-
minWidth: 0
|
|
754
|
+
minWidth: 0,
|
|
755
|
+
display: "flex",
|
|
756
|
+
flexDirection: "column",
|
|
757
|
+
justifyContent: "center"
|
|
686
758
|
},
|
|
687
759
|
children: [
|
|
688
|
-
/* @__PURE__ */
|
|
760
|
+
/* @__PURE__ */ jsxs(
|
|
689
761
|
"div",
|
|
690
762
|
{
|
|
691
763
|
style: {
|
|
692
764
|
display: "flex",
|
|
693
765
|
alignItems: "center",
|
|
694
|
-
gap:
|
|
766
|
+
gap: 6,
|
|
767
|
+
minWidth: 0
|
|
695
768
|
},
|
|
696
|
-
children:
|
|
697
|
-
|
|
698
|
-
|
|
699
|
-
|
|
700
|
-
|
|
701
|
-
|
|
702
|
-
|
|
703
|
-
|
|
704
|
-
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
708
|
-
|
|
709
|
-
|
|
710
|
-
|
|
769
|
+
children: [
|
|
770
|
+
/* @__PURE__ */ jsx(
|
|
771
|
+
TimelineStatusMarker,
|
|
772
|
+
{
|
|
773
|
+
status: displayStatus,
|
|
774
|
+
fillColor: color,
|
|
775
|
+
size: hasOverlap ? 8 : 10
|
|
776
|
+
}
|
|
777
|
+
),
|
|
778
|
+
/* @__PURE__ */ jsx(
|
|
779
|
+
"span",
|
|
780
|
+
{
|
|
781
|
+
style: {
|
|
782
|
+
fontSize: "0.6875rem",
|
|
783
|
+
fontWeight: 500,
|
|
784
|
+
// AstroUXDS medium (was 600)
|
|
785
|
+
color: "#fff",
|
|
786
|
+
whiteSpace: "nowrap",
|
|
787
|
+
overflow: "hidden",
|
|
788
|
+
textOverflow: "ellipsis",
|
|
789
|
+
minWidth: 0
|
|
790
|
+
},
|
|
791
|
+
children: event.title
|
|
792
|
+
}
|
|
793
|
+
)
|
|
794
|
+
]
|
|
711
795
|
}
|
|
712
796
|
),
|
|
713
797
|
event.subtitle && !hasOverlap && /* @__PURE__ */ jsx(
|
|
@@ -719,7 +803,8 @@ const ChartView = memo(function ChartView2({
|
|
|
719
803
|
whiteSpace: "nowrap",
|
|
720
804
|
overflow: "hidden",
|
|
721
805
|
textOverflow: "ellipsis",
|
|
722
|
-
marginTop: 1
|
|
806
|
+
marginTop: 1,
|
|
807
|
+
paddingLeft: 16
|
|
723
808
|
},
|
|
724
809
|
children: event.subtitle
|
|
725
810
|
}
|
|
@@ -1404,6 +1489,273 @@ const ScatterView = memo(function ScatterView2({
|
|
|
1404
1489
|
` })
|
|
1405
1490
|
] });
|
|
1406
1491
|
});
|
|
1492
|
+
const TimelineFiltersToolbar = memo(function TimelineFiltersToolbar2({
|
|
1493
|
+
filter,
|
|
1494
|
+
onFilterChange,
|
|
1495
|
+
trackOptions,
|
|
1496
|
+
defaultExpanded
|
|
1497
|
+
}) {
|
|
1498
|
+
const { tokens, theme } = useTheme();
|
|
1499
|
+
const isTransparentTheme = theme === "transparent" || theme === "transparent-bold" || theme === "transparent-minimal";
|
|
1500
|
+
const [expanded, setExpanded] = useState(defaultExpanded);
|
|
1501
|
+
const chipCount = countTimelineFilterChips(filter);
|
|
1502
|
+
const patch = useCallback(
|
|
1503
|
+
(partial) => {
|
|
1504
|
+
onFilterChange(normalizeTimelineFilter({ ...filter, ...partial }));
|
|
1505
|
+
},
|
|
1506
|
+
[filter, onFilterChange]
|
|
1507
|
+
);
|
|
1508
|
+
const clearAll = useCallback(() => {
|
|
1509
|
+
onFilterChange({});
|
|
1510
|
+
}, [onFilterChange]);
|
|
1511
|
+
const toggleTrack = useCallback(
|
|
1512
|
+
(id) => {
|
|
1513
|
+
const cur = filter.tracks ?? [];
|
|
1514
|
+
const next = cur.includes(id) ? cur.filter((t) => t !== id) : [...cur, id];
|
|
1515
|
+
patch({ tracks: next.length ? next : void 0 });
|
|
1516
|
+
},
|
|
1517
|
+
[filter.tracks, patch]
|
|
1518
|
+
);
|
|
1519
|
+
const toggleStatus = useCallback(
|
|
1520
|
+
(st) => {
|
|
1521
|
+
const cur = filter.status ?? [];
|
|
1522
|
+
const next = cur.includes(st) ? cur.filter((s) => s !== st) : [...cur, st];
|
|
1523
|
+
patch({ status: next.length ? next : void 0 });
|
|
1524
|
+
},
|
|
1525
|
+
[filter.status, patch]
|
|
1526
|
+
);
|
|
1527
|
+
const pillBase = (active) => ({
|
|
1528
|
+
padding: "4px 10px",
|
|
1529
|
+
borderRadius: tokens.borderRadius.full ?? 999,
|
|
1530
|
+
fontSize: "0.6875rem",
|
|
1531
|
+
fontWeight: 500,
|
|
1532
|
+
border: `1px solid ${active ? tokens.colors.accent.primary : tokens.colors.border.muted}`,
|
|
1533
|
+
backgroundColor: active ? `${tokens.colors.accent.primary}22` : tokens.colors.background.elevated,
|
|
1534
|
+
color: active ? tokens.colors.accent.primary : tokens.colors.text.secondary,
|
|
1535
|
+
cursor: "pointer",
|
|
1536
|
+
transition: "background-color 150ms ease, border-color 150ms ease, color 150ms ease"
|
|
1537
|
+
});
|
|
1538
|
+
return /* @__PURE__ */ jsxs(
|
|
1539
|
+
"div",
|
|
1540
|
+
{
|
|
1541
|
+
style: {
|
|
1542
|
+
padding: "12px 20px",
|
|
1543
|
+
borderBottom: `1px solid ${tokens.colors.border.muted}`,
|
|
1544
|
+
backgroundColor: isTransparentTheme ? "transparent" : tokens.colors.background.elevated,
|
|
1545
|
+
...isTransparentTheme && { backdropFilter: "blur(8px)", WebkitBackdropFilter: "blur(8px)" }
|
|
1546
|
+
},
|
|
1547
|
+
children: [
|
|
1548
|
+
/* @__PURE__ */ jsxs(
|
|
1549
|
+
"div",
|
|
1550
|
+
{
|
|
1551
|
+
style: {
|
|
1552
|
+
display: "flex",
|
|
1553
|
+
flexWrap: "wrap",
|
|
1554
|
+
alignItems: "center",
|
|
1555
|
+
gap: 10
|
|
1556
|
+
},
|
|
1557
|
+
children: [
|
|
1558
|
+
/* @__PURE__ */ jsxs("div", { style: { flex: "1 1 220px", minWidth: 0, position: "relative" }, children: [
|
|
1559
|
+
/* @__PURE__ */ jsx(
|
|
1560
|
+
Icon,
|
|
1561
|
+
{
|
|
1562
|
+
name: "search",
|
|
1563
|
+
size: 16,
|
|
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
|
+
)
|
|
1597
|
+
] }),
|
|
1598
|
+
/* @__PURE__ */ jsxs(
|
|
1599
|
+
"button",
|
|
1600
|
+
{
|
|
1601
|
+
type: "button",
|
|
1602
|
+
onClick: () => setExpanded((v) => !v),
|
|
1603
|
+
"aria-expanded": expanded,
|
|
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(
|
|
1678
|
+
"button",
|
|
1679
|
+
{
|
|
1680
|
+
type: "button",
|
|
1681
|
+
onClick: () => toggleTrack(t.id),
|
|
1682
|
+
style: pillBase(active),
|
|
1683
|
+
children: t.label
|
|
1684
|
+
},
|
|
1685
|
+
t.id
|
|
1686
|
+
);
|
|
1687
|
+
}) })
|
|
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
|
+
)
|
|
1752
|
+
]
|
|
1753
|
+
}
|
|
1754
|
+
) : null
|
|
1755
|
+
]
|
|
1756
|
+
}
|
|
1757
|
+
);
|
|
1758
|
+
});
|
|
1407
1759
|
const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
1408
1760
|
title = "Timeline",
|
|
1409
1761
|
events,
|
|
@@ -1422,6 +1774,8 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1422
1774
|
zoomable = false,
|
|
1423
1775
|
initialZoom = 1,
|
|
1424
1776
|
showFilters: _showFilters = false,
|
|
1777
|
+
filtersDefaultExpanded = false,
|
|
1778
|
+
hideEmptyTracksWhenFiltered = true,
|
|
1425
1779
|
filter: _filter,
|
|
1426
1780
|
onFilterChange: _onFilterChange,
|
|
1427
1781
|
showCount: _showCount = true,
|
|
@@ -1437,6 +1791,15 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1437
1791
|
const [internalViewMode, setInternalViewMode] = useState(defaultView);
|
|
1438
1792
|
const [zoom, setZoom] = useState(initialZoom);
|
|
1439
1793
|
const [_internalFilter, _setInternalFilter] = useState({});
|
|
1794
|
+
const filter = _filter !== void 0 ? _filter : _internalFilter;
|
|
1795
|
+
const setFilter = useCallback(
|
|
1796
|
+
(next) => {
|
|
1797
|
+
const n = normalizeTimelineFilter(next);
|
|
1798
|
+
if (_filter === void 0) _setInternalFilter(n);
|
|
1799
|
+
_onFilterChange == null ? void 0 : _onFilterChange(n);
|
|
1800
|
+
},
|
|
1801
|
+
[_filter, _onFilterChange]
|
|
1802
|
+
);
|
|
1440
1803
|
const viewMode = controlledViewMode ?? internalViewMode;
|
|
1441
1804
|
const handleViewModeChange = useCallback((mode) => {
|
|
1442
1805
|
setInternalViewMode(mode);
|
|
@@ -1481,9 +1844,28 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1481
1844
|
height: trackHeight
|
|
1482
1845
|
}));
|
|
1483
1846
|
}, [events, tracks, trackHeight]);
|
|
1847
|
+
const filteredEvents = useMemo(
|
|
1848
|
+
() => events.filter((e) => matchesTimelineFilter(e, filter)),
|
|
1849
|
+
[events, filter]
|
|
1850
|
+
);
|
|
1851
|
+
const effectiveTracksForViews = useMemo(() => {
|
|
1852
|
+
if (!hideEmptyTracksWhenFiltered || !isTimelineFilterActive(filter)) return effectiveTracks;
|
|
1853
|
+
const ids = new Set(filteredEvents.map((e) => e.track || "default"));
|
|
1854
|
+
return effectiveTracks.filter((t) => ids.has(t.id));
|
|
1855
|
+
}, [effectiveTracks, filteredEvents, filter, hideEmptyTracksWhenFiltered]);
|
|
1856
|
+
const trackOptionsForToolbar = useMemo(() => {
|
|
1857
|
+
if (tracks.length > 0) return tracks.map((t) => ({ id: t.id, label: t.label }));
|
|
1858
|
+
const u = /* @__PURE__ */ new Set();
|
|
1859
|
+
events.forEach((e) => {
|
|
1860
|
+
if (e.track) u.add(e.track);
|
|
1861
|
+
});
|
|
1862
|
+
if (u.size === 0) return [{ id: "default", label: "Events" }];
|
|
1863
|
+
return [...u].sort().map((id) => ({ id, label: id }));
|
|
1864
|
+
}, [events, tracks]);
|
|
1484
1865
|
const sortedEvents = useMemo(() => {
|
|
1485
|
-
return [...
|
|
1486
|
-
}, [
|
|
1866
|
+
return [...filteredEvents].sort((a, b) => b.start.getTime() - a.start.getTime());
|
|
1867
|
+
}, [filteredEvents]);
|
|
1868
|
+
const countLabel = !_showCount ? title : `${title} (${filteredEvents.length}${filteredEvents.length !== events.length ? ` / ${events.length}` : ""})`;
|
|
1487
1869
|
return /* @__PURE__ */ jsxs(
|
|
1488
1870
|
"div",
|
|
1489
1871
|
{
|
|
@@ -1507,7 +1889,7 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1507
1889
|
borderBottom: `1px solid ${tokens.colors.border.muted}`
|
|
1508
1890
|
},
|
|
1509
1891
|
children: [
|
|
1510
|
-
/* @__PURE__ */
|
|
1892
|
+
/* @__PURE__ */ jsx(
|
|
1511
1893
|
"h3",
|
|
1512
1894
|
{
|
|
1513
1895
|
style: {
|
|
@@ -1517,12 +1899,7 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1517
1899
|
// AstroUXDS medium (was 600)
|
|
1518
1900
|
color: tokens.colors.text.primary
|
|
1519
1901
|
},
|
|
1520
|
-
children:
|
|
1521
|
-
title,
|
|
1522
|
-
" (",
|
|
1523
|
-
events.length,
|
|
1524
|
-
")"
|
|
1525
|
-
]
|
|
1902
|
+
children: countLabel
|
|
1526
1903
|
}
|
|
1527
1904
|
),
|
|
1528
1905
|
/* @__PURE__ */ jsxs("div", { style: { display: "flex", alignItems: "center", gap: 12 }, children: [
|
|
@@ -1697,6 +2074,15 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1697
2074
|
]
|
|
1698
2075
|
}
|
|
1699
2076
|
),
|
|
2077
|
+
_showFilters ? /* @__PURE__ */ jsx(
|
|
2078
|
+
TimelineFiltersToolbar,
|
|
2079
|
+
{
|
|
2080
|
+
filter,
|
|
2081
|
+
onFilterChange: setFilter,
|
|
2082
|
+
trackOptions: trackOptionsForToolbar,
|
|
2083
|
+
defaultExpanded: filtersDefaultExpanded
|
|
2084
|
+
}
|
|
2085
|
+
) : null,
|
|
1700
2086
|
loading && /* @__PURE__ */ jsx(
|
|
1701
2087
|
"div",
|
|
1702
2088
|
{
|
|
@@ -1751,6 +2137,43 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1751
2137
|
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem" }, children: "No events to display" })
|
|
1752
2138
|
]
|
|
1753
2139
|
}
|
|
2140
|
+
) : filteredEvents.length === 0 ? /* @__PURE__ */ jsxs(
|
|
2141
|
+
"div",
|
|
2142
|
+
{
|
|
2143
|
+
style: {
|
|
2144
|
+
display: "flex",
|
|
2145
|
+
flexDirection: "column",
|
|
2146
|
+
alignItems: "center",
|
|
2147
|
+
justifyContent: "center",
|
|
2148
|
+
padding: "48px 24px",
|
|
2149
|
+
color: tokens.colors.text.tertiary,
|
|
2150
|
+
gap: 12,
|
|
2151
|
+
textAlign: "center"
|
|
2152
|
+
},
|
|
2153
|
+
children: [
|
|
2154
|
+
/* @__PURE__ */ jsx(Icon, { name: "search", size: 32 }),
|
|
2155
|
+
/* @__PURE__ */ jsx("span", { style: { fontSize: "0.875rem", color: tokens.colors.text.secondary }, children: "No events match the current filters." }),
|
|
2156
|
+
_showFilters && isTimelineFilterActive(filter) ? /* @__PURE__ */ jsx(
|
|
2157
|
+
"button",
|
|
2158
|
+
{
|
|
2159
|
+
type: "button",
|
|
2160
|
+
onClick: () => setFilter({}),
|
|
2161
|
+
style: {
|
|
2162
|
+
marginTop: 4,
|
|
2163
|
+
padding: "8px 16px",
|
|
2164
|
+
borderRadius: tokens.borderRadius.md,
|
|
2165
|
+
border: `1px solid ${tokens.colors.accent.primary}`,
|
|
2166
|
+
backgroundColor: `${tokens.colors.accent.primary}18`,
|
|
2167
|
+
color: tokens.colors.accent.primary,
|
|
2168
|
+
cursor: "pointer",
|
|
2169
|
+
fontSize: "0.8125rem",
|
|
2170
|
+
fontWeight: 500
|
|
2171
|
+
},
|
|
2172
|
+
children: "Clear filters"
|
|
2173
|
+
}
|
|
2174
|
+
) : null
|
|
2175
|
+
]
|
|
2176
|
+
}
|
|
1754
2177
|
) : viewMode === "list" ? (
|
|
1755
2178
|
// List View
|
|
1756
2179
|
sortedEvents.map((event, index) => /* @__PURE__ */ jsx(
|
|
@@ -1767,8 +2190,8 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1767
2190
|
/* @__PURE__ */ jsx(
|
|
1768
2191
|
ScatterView,
|
|
1769
2192
|
{
|
|
1770
|
-
events,
|
|
1771
|
-
tracks:
|
|
2193
|
+
events: filteredEvents,
|
|
2194
|
+
tracks: effectiveTracksForViews,
|
|
1772
2195
|
start,
|
|
1773
2196
|
end,
|
|
1774
2197
|
trackHeight,
|
|
@@ -1783,8 +2206,8 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1783
2206
|
/* @__PURE__ */ jsx(
|
|
1784
2207
|
ChartView,
|
|
1785
2208
|
{
|
|
1786
|
-
events,
|
|
1787
|
-
tracks:
|
|
2209
|
+
events: filteredEvents,
|
|
2210
|
+
tracks: effectiveTracksForViews,
|
|
1788
2211
|
start,
|
|
1789
2212
|
end,
|
|
1790
2213
|
trackHeight,
|
|
@@ -1810,6 +2233,9 @@ const UnifiedTimeline = memo(function UnifiedTimeline2({
|
|
|
1810
2233
|
);
|
|
1811
2234
|
});
|
|
1812
2235
|
export {
|
|
1813
|
-
UnifiedTimeline
|
|
2236
|
+
UnifiedTimeline,
|
|
2237
|
+
getTimelineEventDisplayStatus,
|
|
2238
|
+
isTimelineFilterActive,
|
|
2239
|
+
matchesTimelineFilter
|
|
1814
2240
|
};
|
|
1815
2241
|
//# sourceMappingURL=UnifiedTimeline.js.map
|