epiq 1.7.0 → 1.7.2
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/LICENSE +21 -0
- package/dist/gui/main.js +252 -168
- package/dist/index.js +75 -71
- package/dist/mcp.js +60 -56
- package/package.json +1 -1
package/dist/gui/main.js
CHANGED
|
@@ -52557,7 +52557,7 @@ var User = ({
|
|
|
52557
52557
|
);
|
|
52558
52558
|
|
|
52559
52559
|
// source/version.ts
|
|
52560
|
-
var EPIQ_VERSION = "1.7.
|
|
52560
|
+
var EPIQ_VERSION = "1.7.2";
|
|
52561
52561
|
|
|
52562
52562
|
// source/gui/client/components/Header.tsx
|
|
52563
52563
|
var import_jsx_runtime32 = __toESM(require_jsx_runtime(), 1);
|
|
@@ -52906,7 +52906,12 @@ var ManageContributorsModal = ({
|
|
|
52906
52906
|
alignItems: "center",
|
|
52907
52907
|
gap: 6,
|
|
52908
52908
|
color: armed ? GUI_THEME.red : GUI_THEME.dim,
|
|
52909
|
-
|
|
52909
|
+
// The whole shorthand, and only when armed: Button sets
|
|
52910
|
+
// `border` itself, and React warns that an element given
|
|
52911
|
+
// both it and `borderColor` can drop whichever loses the
|
|
52912
|
+
// race. Spreading `border: undefined` is not the other
|
|
52913
|
+
// branch — that reads as "remove this style".
|
|
52914
|
+
...armed ? { border: `1px solid ${GUI_THEME.red}` } : {}
|
|
52910
52915
|
},
|
|
52911
52916
|
children: [
|
|
52912
52917
|
armed && /* @__PURE__ */ (0, import_jsx_runtime35.jsx)("span", { style: { fontSize: 10 }, children: "confirm" }),
|
|
@@ -53017,7 +53022,12 @@ var ManageTagsModal = ({ tags, onDelete, onClose }) => {
|
|
|
53017
53022
|
alignItems: "center",
|
|
53018
53023
|
gap: 6,
|
|
53019
53024
|
color: armed ? GUI_THEME.red : GUI_THEME.dim,
|
|
53020
|
-
|
|
53025
|
+
// The whole shorthand, and only when armed: Button sets
|
|
53026
|
+
// `border` itself, and React warns that an element given
|
|
53027
|
+
// both it and `borderColor` can drop whichever loses the
|
|
53028
|
+
// race. Spreading `border: undefined` is not the other
|
|
53029
|
+
// branch — that reads as "remove this style".
|
|
53030
|
+
...armed ? { border: `1px solid ${GUI_THEME.red}` } : {}
|
|
53021
53031
|
},
|
|
53022
53032
|
children: [
|
|
53023
53033
|
armed && /* @__PURE__ */ (0, import_jsx_runtime36.jsx)("span", { style: { fontSize: 10 }, children: "confirm" }),
|
|
@@ -66837,6 +66847,7 @@ var HOVER_HINT_WIDTH = 220;
|
|
|
66837
66847
|
var SEGMENT_HIGHLIGHT_COLOR = "rgba(122, 157, 214, 0.14)";
|
|
66838
66848
|
var BUCKET_HIGHLIGHT_COLOR = "rgba(255, 255, 255, 0.06)";
|
|
66839
66849
|
var NEEDLE_COLOR = "rgba(255, 255, 255, 0.62)";
|
|
66850
|
+
var SCOPED_OUTLINE_COLOR = "rgba(118, 212, 255, 0.45)";
|
|
66840
66851
|
var RANGE_SELECTION_COLOR = "rgba(122, 157, 214, 0.22)";
|
|
66841
66852
|
var RANGE_SELECTION_EDGE = "rgba(160, 195, 250, 0.75)";
|
|
66842
66853
|
var NEEDLE_GRIP_WIDTH = 11;
|
|
@@ -67112,6 +67123,7 @@ var SCOPE_RECENT_LABELS = {
|
|
|
67112
67123
|
year: "Last 365 days"
|
|
67113
67124
|
};
|
|
67114
67125
|
var isScope = (value) => SCOPES.includes(value ?? "");
|
|
67126
|
+
var isPeriodWindow = (scope, zoomed) => scope !== "all" || zoomed;
|
|
67115
67127
|
var getPeriodRange = (scope, offset) => {
|
|
67116
67128
|
if (scope === "all") return null;
|
|
67117
67129
|
const durationMs = SCOPE_DURATION_MS[scope];
|
|
@@ -67249,6 +67261,15 @@ var buildBoardFilter = (view, only) => {
|
|
|
67249
67261
|
if (axis === null || only === null) return null;
|
|
67250
67262
|
return { axis, visibleIds: new Set(only) };
|
|
67251
67263
|
};
|
|
67264
|
+
var windowNamesIssues = (timeline) => timeline === null || timeline.events.length > 0 || timeline.buckets.length === 0;
|
|
67265
|
+
var windowIssueIds = (timeline) => {
|
|
67266
|
+
if (timeline === null || !windowNamesIssues(timeline)) return null;
|
|
67267
|
+
const ids = /* @__PURE__ */ new Set();
|
|
67268
|
+
for (const entry of timeline.events) {
|
|
67269
|
+
if (entry.issue !== null) ids.add(entry.issue);
|
|
67270
|
+
}
|
|
67271
|
+
return ids;
|
|
67272
|
+
};
|
|
67252
67273
|
var issuePassesBoardFilter = (issue, commentAuthorIds, filter) => {
|
|
67253
67274
|
if (!filter) return true;
|
|
67254
67275
|
const ids = filter.axis === "tag" ? issue.tags.map((tag) => tag.id) : filter.axis === "assignee" ? issue.assignees.map((assignee) => assignee.id) : commentAuthorIds;
|
|
@@ -68930,7 +68951,8 @@ var DEFAULT_SELECTION = {
|
|
|
68930
68951
|
zoom: null,
|
|
68931
68952
|
layout: "even",
|
|
68932
68953
|
view: "all",
|
|
68933
|
-
only: null
|
|
68954
|
+
only: null,
|
|
68955
|
+
windowOnly: false
|
|
68934
68956
|
};
|
|
68935
68957
|
var PARAM_KEYS = [
|
|
68936
68958
|
"scope",
|
|
@@ -68939,7 +68961,8 @@ var PARAM_KEYS = [
|
|
|
68939
68961
|
"to",
|
|
68940
68962
|
"layout",
|
|
68941
68963
|
"view",
|
|
68942
|
-
"only"
|
|
68964
|
+
"only",
|
|
68965
|
+
"window"
|
|
68943
68966
|
];
|
|
68944
68967
|
var STORAGE_KEY = "epiq.board.selection";
|
|
68945
68968
|
var unique = (ids) => [...new Set(ids)];
|
|
@@ -68954,7 +68977,7 @@ var normalize3 = (selection) => {
|
|
|
68954
68977
|
only: selection.only === null ? null : unique(selection.only)
|
|
68955
68978
|
};
|
|
68956
68979
|
};
|
|
68957
|
-
var isDefaultSelection = (selection) => selection.scope === DEFAULT_SELECTION.scope && selection.offset === DEFAULT_SELECTION.offset && selection.zoom === null && selection.layout === DEFAULT_SELECTION.layout && selection.view === DEFAULT_SELECTION.view && selection.only === null;
|
|
68980
|
+
var isDefaultSelection = (selection) => selection.scope === DEFAULT_SELECTION.scope && selection.offset === DEFAULT_SELECTION.offset && selection.zoom === null && selection.layout === DEFAULT_SELECTION.layout && selection.view === DEFAULT_SELECTION.view && selection.only === null && selection.windowOnly === DEFAULT_SELECTION.windowOnly;
|
|
68958
68981
|
var applySelectionPatch = (current, patch2) => {
|
|
68959
68982
|
const scopeChanged = patch2.scope !== void 0 && patch2.scope !== current.scope;
|
|
68960
68983
|
const viewChanged = patch2.view !== void 0 && patch2.view !== current.view;
|
|
@@ -68982,7 +69005,8 @@ var readSelectionParams = (params) => {
|
|
|
68982
69005
|
zoom: from === null || to === null ? null : { start: Number(from), end: Number(to) },
|
|
68983
69006
|
layout: isLayoutMode(layout) ? layout : DEFAULT_SELECTION.layout,
|
|
68984
69007
|
view: isBoardView(view) ? view : DEFAULT_SELECTION.view,
|
|
68985
|
-
only: only === null ? null : only.split(",").filter(Boolean)
|
|
69008
|
+
only: only === null ? null : only.split(",").filter(Boolean),
|
|
69009
|
+
windowOnly: params.get("window") === "1"
|
|
68986
69010
|
});
|
|
68987
69011
|
};
|
|
68988
69012
|
var writeSelectionParams = (params, selection) => {
|
|
@@ -69001,6 +69025,7 @@ var writeSelectionParams = (params, selection) => {
|
|
|
69001
69025
|
put("layout", next.layout === DEFAULT_SELECTION.layout ? null : next.layout);
|
|
69002
69026
|
put("view", next.view === DEFAULT_SELECTION.view ? null : next.view);
|
|
69003
69027
|
put("only", next.only === null ? null : next.only.join(","));
|
|
69028
|
+
put("window", next.windowOnly ? "1" : null);
|
|
69004
69029
|
};
|
|
69005
69030
|
var readStoredSelection = () => {
|
|
69006
69031
|
try {
|
|
@@ -69015,7 +69040,8 @@ var readStoredSelection = () => {
|
|
|
69015
69040
|
zoom: null,
|
|
69016
69041
|
layout: isLayoutMode(String(layout)) ? layout : DEFAULT_SELECTION.layout,
|
|
69017
69042
|
view: isBoardView(view) ? view : DEFAULT_SELECTION.view,
|
|
69018
|
-
only: Array.isArray(only) ? only.map(String) : null
|
|
69043
|
+
only: Array.isArray(only) ? only.map(String) : null,
|
|
69044
|
+
windowOnly: DEFAULT_SELECTION.windowOnly
|
|
69019
69045
|
});
|
|
69020
69046
|
} catch {
|
|
69021
69047
|
return DEFAULT_SELECTION;
|
|
@@ -69081,7 +69107,10 @@ var Checkbox = ({
|
|
|
69081
69107
|
fontSize: 10,
|
|
69082
69108
|
color: color2,
|
|
69083
69109
|
cursor: disabled ? "not-allowed" : "pointer",
|
|
69084
|
-
opacity: disabled ? 0.4 : 1
|
|
69110
|
+
opacity: disabled ? 0.4 : 1,
|
|
69111
|
+
// A label that wraps takes the row's height with it.
|
|
69112
|
+
whiteSpace: "nowrap",
|
|
69113
|
+
flexShrink: 0
|
|
69085
69114
|
},
|
|
69086
69115
|
children: [
|
|
69087
69116
|
/* @__PURE__ */ (0, import_jsx_runtime62.jsxs)(
|
|
@@ -69185,6 +69214,7 @@ var IconScatter = ({ size = 16 }) => /* @__PURE__ */ (0, import_jsx_runtime64.js
|
|
|
69185
69214
|
|
|
69186
69215
|
// source/gui/client/components/ScrubberParts.tsx
|
|
69187
69216
|
var import_jsx_runtime65 = __toESM(require_jsx_runtime(), 1);
|
|
69217
|
+
var SCOPE_ONLY_LABEL = "Scope only";
|
|
69188
69218
|
var toggleButtonStyle = (active) => ({
|
|
69189
69219
|
background: "transparent",
|
|
69190
69220
|
border: `1px solid ${active ? GUI_THEME.accent : GUI_THEME.dim}`,
|
|
@@ -69554,6 +69584,8 @@ var ScrubberControls = ({
|
|
|
69554
69584
|
periodRange,
|
|
69555
69585
|
zoomed,
|
|
69556
69586
|
atLatest,
|
|
69587
|
+
windowOnly,
|
|
69588
|
+
windowFilterable,
|
|
69557
69589
|
layoutMode,
|
|
69558
69590
|
showIssues,
|
|
69559
69591
|
showCommits,
|
|
@@ -69568,6 +69600,7 @@ var ScrubberControls = ({
|
|
|
69568
69600
|
onReturnToLive,
|
|
69569
69601
|
onChangeScope,
|
|
69570
69602
|
onChangeOffset,
|
|
69603
|
+
onChangeWindowOnly,
|
|
69571
69604
|
onChangeLayoutMode,
|
|
69572
69605
|
onChangeShowIssues,
|
|
69573
69606
|
onChangeShowCommits,
|
|
@@ -69577,182 +69610,195 @@ var ScrubberControls = ({
|
|
|
69577
69610
|
onOnlyIdentity,
|
|
69578
69611
|
onToggleCategoriesExpanded,
|
|
69579
69612
|
onSetIdentitiesExpanded
|
|
69580
|
-
}) =>
|
|
69581
|
-
|
|
69582
|
-
|
|
69583
|
-
|
|
69584
|
-
|
|
69585
|
-
|
|
69586
|
-
|
|
69587
|
-
|
|
69588
|
-
|
|
69589
|
-
|
|
69590
|
-
|
|
69591
|
-
|
|
69613
|
+
}) => {
|
|
69614
|
+
const everythingInScope = !isPeriodWindow(scope, zoomed);
|
|
69615
|
+
return /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)(
|
|
69616
|
+
"div",
|
|
69617
|
+
{
|
|
69618
|
+
style: {
|
|
69619
|
+
display: "flex",
|
|
69620
|
+
alignItems: "center",
|
|
69621
|
+
justifyContent: "flex-end",
|
|
69622
|
+
gap: 12
|
|
69623
|
+
},
|
|
69624
|
+
children: [
|
|
69625
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 6 }, children: [
|
|
69626
|
+
(scope !== "all" || zoomed) && /* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", alignItems: "center", gap: 2 }, children: [
|
|
69627
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69628
|
+
"button",
|
|
69629
|
+
{
|
|
69630
|
+
title: "Earlier",
|
|
69631
|
+
disabled: !connected,
|
|
69632
|
+
onClick: () => onChangeOffset(offset + 1),
|
|
69633
|
+
style: { ...navButtonStyle, ...connected ? {} : mutedStyle },
|
|
69634
|
+
children: "\u25C0"
|
|
69635
|
+
}
|
|
69636
|
+
),
|
|
69637
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69638
|
+
"span",
|
|
69639
|
+
{
|
|
69640
|
+
style: {
|
|
69641
|
+
fontSize: 10,
|
|
69642
|
+
color: GUI_THEME.dim,
|
|
69643
|
+
whiteSpace: "nowrap",
|
|
69644
|
+
overflow: "hidden",
|
|
69645
|
+
// Fixed, not min, so the changing label never shifts the
|
|
69646
|
+
// buttons around it.
|
|
69647
|
+
width: 88,
|
|
69648
|
+
flexShrink: 0,
|
|
69649
|
+
textAlign: "center"
|
|
69650
|
+
},
|
|
69651
|
+
children: formatPeriodLabel(scope, offset, periodRange, zoomed)
|
|
69652
|
+
}
|
|
69653
|
+
),
|
|
69654
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69655
|
+
"button",
|
|
69656
|
+
{
|
|
69657
|
+
title: "Later",
|
|
69658
|
+
disabled: atLatest || !connected,
|
|
69659
|
+
onClick: () => onChangeOffset(offset - 1),
|
|
69660
|
+
style: {
|
|
69661
|
+
...navButtonStyle,
|
|
69662
|
+
opacity: atLatest ? 0.35 : 1,
|
|
69663
|
+
cursor: atLatest ? "default" : "pointer"
|
|
69664
|
+
},
|
|
69665
|
+
children: "\u25B6"
|
|
69666
|
+
}
|
|
69667
|
+
)
|
|
69668
|
+
] }),
|
|
69669
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
|
|
69670
|
+
SCOPES.map((option2) => /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69671
|
+
"button",
|
|
69672
|
+
{
|
|
69673
|
+
"aria-pressed": !zoomed && scope === option2,
|
|
69674
|
+
disabled: !connected,
|
|
69675
|
+
onClick: () => onChangeScope(option2),
|
|
69676
|
+
style: {
|
|
69677
|
+
...scopeButtonStyle(!zoomed && scope === option2),
|
|
69678
|
+
...connected ? {} : mutedStyle
|
|
69679
|
+
},
|
|
69680
|
+
children: scopeButtonLabel(option2)
|
|
69681
|
+
},
|
|
69682
|
+
option2
|
|
69683
|
+
)),
|
|
69684
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69685
|
+
"button",
|
|
69686
|
+
{
|
|
69687
|
+
title: zoomed ? "A window dragged out on the chart \u2014 pick a period to leave it" : "Drag across the chart to zoom the window to a stretch of it",
|
|
69688
|
+
"aria-pressed": zoomed,
|
|
69689
|
+
disabled: true,
|
|
69690
|
+
style: {
|
|
69691
|
+
...scopeButtonStyle(zoomed),
|
|
69692
|
+
opacity: zoomed ? 1 : 0.35,
|
|
69693
|
+
cursor: "default"
|
|
69694
|
+
},
|
|
69695
|
+
children: "Zoom"
|
|
69696
|
+
}
|
|
69697
|
+
)
|
|
69698
|
+
] })
|
|
69699
|
+
] }),
|
|
69700
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
|
|
69592
69701
|
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69593
69702
|
"button",
|
|
69594
69703
|
{
|
|
69595
|
-
title: "
|
|
69704
|
+
title: "Volume \u2014 how much happened, per equal-width period, with no empty gaps for quiet stretches",
|
|
69705
|
+
"aria-label": "Volume",
|
|
69706
|
+
"aria-pressed": layoutMode === "even",
|
|
69596
69707
|
disabled: !connected,
|
|
69597
|
-
onClick: () =>
|
|
69598
|
-
style: { ...navButtonStyle, ...connected ? {} : mutedStyle },
|
|
69599
|
-
children: "\u25C0"
|
|
69600
|
-
}
|
|
69601
|
-
),
|
|
69602
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69603
|
-
"span",
|
|
69604
|
-
{
|
|
69708
|
+
onClick: () => onChangeLayoutMode("even"),
|
|
69605
69709
|
style: {
|
|
69606
|
-
|
|
69607
|
-
|
|
69608
|
-
whiteSpace: "nowrap",
|
|
69609
|
-
overflow: "hidden",
|
|
69610
|
-
// Fixed, not min, so the changing label never shifts the
|
|
69611
|
-
// buttons around it.
|
|
69612
|
-
width: 88,
|
|
69613
|
-
flexShrink: 0,
|
|
69614
|
-
textAlign: "center"
|
|
69710
|
+
...iconToggleButtonStyle(layoutMode === "even"),
|
|
69711
|
+
...connected ? {} : mutedStyle
|
|
69615
69712
|
},
|
|
69616
|
-
children:
|
|
69713
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(IconBars, { size: 13 })
|
|
69617
69714
|
}
|
|
69618
69715
|
),
|
|
69619
69716
|
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69620
69717
|
"button",
|
|
69621
69718
|
{
|
|
69622
|
-
title: "
|
|
69623
|
-
|
|
69624
|
-
|
|
69719
|
+
title: "Events \u2014 individual events by exact moment, x is elapsed time and y is time of day",
|
|
69720
|
+
"aria-label": "Events",
|
|
69721
|
+
"aria-pressed": layoutMode === "real",
|
|
69722
|
+
disabled: !connected,
|
|
69723
|
+
onClick: () => onChangeLayoutMode("real"),
|
|
69625
69724
|
style: {
|
|
69626
|
-
...
|
|
69627
|
-
|
|
69628
|
-
cursor: atLatest ? "default" : "pointer"
|
|
69725
|
+
...iconToggleButtonStyle(layoutMode === "real"),
|
|
69726
|
+
...connected ? {} : mutedStyle
|
|
69629
69727
|
},
|
|
69630
|
-
children:
|
|
69728
|
+
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(IconScatter, { size: 13 })
|
|
69631
69729
|
}
|
|
69632
69730
|
)
|
|
69633
69731
|
] }),
|
|
69634
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", gap:
|
|
69635
|
-
|
|
69636
|
-
|
|
69732
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", gap: 12, alignItems: "center" }, children: [
|
|
69733
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69734
|
+
Checkbox,
|
|
69637
69735
|
{
|
|
69638
|
-
"
|
|
69736
|
+
label: "Code",
|
|
69737
|
+
checked: showCommits,
|
|
69738
|
+
activeColor: GUI_THEME.green,
|
|
69639
69739
|
disabled: !connected,
|
|
69640
|
-
|
|
69641
|
-
|
|
69642
|
-
|
|
69643
|
-
...connected ? {} : mutedStyle
|
|
69644
|
-
},
|
|
69645
|
-
children: scopeButtonLabel(option2)
|
|
69646
|
-
},
|
|
69647
|
-
option2
|
|
69648
|
-
)),
|
|
69740
|
+
onChange: onChangeShowCommits
|
|
69741
|
+
}
|
|
69742
|
+
),
|
|
69649
69743
|
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69650
|
-
|
|
69744
|
+
BoardSeriesGroup,
|
|
69651
69745
|
{
|
|
69652
|
-
|
|
69653
|
-
|
|
69654
|
-
|
|
69655
|
-
|
|
69656
|
-
|
|
69657
|
-
|
|
69658
|
-
|
|
69659
|
-
|
|
69660
|
-
|
|
69746
|
+
connected,
|
|
69747
|
+
showIssues,
|
|
69748
|
+
view: boardView,
|
|
69749
|
+
identities,
|
|
69750
|
+
hiddenIds: hiddenIdentityIds,
|
|
69751
|
+
expanded: categoriesExpanded,
|
|
69752
|
+
identitiesExpanded,
|
|
69753
|
+
filtered: categoriesFiltered,
|
|
69754
|
+
onChangeShowIssues,
|
|
69755
|
+
onChangeView: onChangeBoardView,
|
|
69756
|
+
onToggleIdentity,
|
|
69757
|
+
onOnlyIdentity,
|
|
69758
|
+
onToggleExpanded: onToggleCategoriesExpanded,
|
|
69759
|
+
onSetIdentitiesExpanded
|
|
69760
|
+
}
|
|
69761
|
+
),
|
|
69762
|
+
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69763
|
+
Checkbox,
|
|
69764
|
+
{
|
|
69765
|
+
label: SCOPE_ONLY_LABEL,
|
|
69766
|
+
title: everythingInScope ? "Every event is in scope \u2014 pick a period to narrow the board" : !windowFilterable ? "Too many events in this window to tell which tickets they belong to" : "Show only tickets with activity in the selected window",
|
|
69767
|
+
checked: windowOnly,
|
|
69768
|
+
disabled: everythingInScope || !windowFilterable || !connected && !windowOnly,
|
|
69769
|
+
onChange: onChangeWindowOnly
|
|
69661
69770
|
}
|
|
69662
69771
|
)
|
|
69663
|
-
] })
|
|
69664
|
-
] }),
|
|
69665
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsxs)("div", { style: { display: "flex", gap: 2 }, children: [
|
|
69666
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69667
|
-
"button",
|
|
69668
|
-
{
|
|
69669
|
-
title: "Volume \u2014 how much happened, per equal-width period, with no empty gaps for quiet stretches",
|
|
69670
|
-
"aria-label": "Volume",
|
|
69671
|
-
"aria-pressed": layoutMode === "even",
|
|
69672
|
-
disabled: !connected,
|
|
69673
|
-
onClick: () => onChangeLayoutMode("even"),
|
|
69674
|
-
style: {
|
|
69675
|
-
...iconToggleButtonStyle(layoutMode === "even"),
|
|
69676
|
-
...connected ? {} : mutedStyle
|
|
69677
|
-
},
|
|
69678
|
-
children: /* @__PURE__ */ (0, import_jsx_runtime65.jsx)(IconBars, { size: 13 })
|
|
69679
|
-
}
|
|
69680
|
-
),
|
|
69772
|
+
] }),
|
|
69681
69773
|
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69682
69774
|
"button",
|
|
69683
69775
|
{
|
|
69684
|
-
|
|
69685
|
-
|
|
69686
|
-
|
|
69687
|
-
disabled: !connected,
|
|
69688
|
-
onClick: () => onChangeLayoutMode("real"),
|
|
69776
|
+
onClick: onReturnToLive,
|
|
69777
|
+
disabled: !isScrubbing,
|
|
69778
|
+
title: isScrubbing ? "Leave history and follow the board again" : void 0,
|
|
69689
69779
|
style: {
|
|
69690
|
-
|
|
69691
|
-
|
|
69780
|
+
background: "transparent",
|
|
69781
|
+
border: `1px solid ${isScrubbing ? GUI_THEME.accent : GUI_THEME.transparent}`,
|
|
69782
|
+
color: isScrubbing ? GUI_THEME.accent : GUI_THEME.dim,
|
|
69783
|
+
borderRadius: 6,
|
|
69784
|
+
fontFamily: "inherit",
|
|
69785
|
+
width: 60,
|
|
69786
|
+
display: "inline-flex",
|
|
69787
|
+
alignItems: "center",
|
|
69788
|
+
justifyContent: isScrubbing ? "center" : "flex-end",
|
|
69789
|
+
fontSize: 10,
|
|
69790
|
+
padding: "2px 8px",
|
|
69791
|
+
cursor: isScrubbing ? "pointer" : "default",
|
|
69792
|
+
whiteSpace: "nowrap",
|
|
69793
|
+
flexShrink: 0
|
|
69692
69794
|
},
|
|
69693
|
-
children:
|
|
69795
|
+
children: isScrubbing ? "Resume" : atLatest ? "Now" : ""
|
|
69694
69796
|
}
|
|
69695
69797
|
)
|
|
69696
|
-
]
|
|
69697
|
-
|
|
69698
|
-
|
|
69699
|
-
|
|
69700
|
-
{
|
|
69701
|
-
label: "Code",
|
|
69702
|
-
checked: showCommits,
|
|
69703
|
-
activeColor: GUI_THEME.green,
|
|
69704
|
-
disabled: !connected,
|
|
69705
|
-
onChange: onChangeShowCommits
|
|
69706
|
-
}
|
|
69707
|
-
),
|
|
69708
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69709
|
-
BoardSeriesGroup,
|
|
69710
|
-
{
|
|
69711
|
-
connected,
|
|
69712
|
-
showIssues,
|
|
69713
|
-
view: boardView,
|
|
69714
|
-
identities,
|
|
69715
|
-
hiddenIds: hiddenIdentityIds,
|
|
69716
|
-
expanded: categoriesExpanded,
|
|
69717
|
-
identitiesExpanded,
|
|
69718
|
-
filtered: categoriesFiltered,
|
|
69719
|
-
onChangeShowIssues,
|
|
69720
|
-
onChangeView: onChangeBoardView,
|
|
69721
|
-
onToggleIdentity,
|
|
69722
|
-
onOnlyIdentity,
|
|
69723
|
-
onToggleExpanded: onToggleCategoriesExpanded,
|
|
69724
|
-
onSetIdentitiesExpanded
|
|
69725
|
-
}
|
|
69726
|
-
)
|
|
69727
|
-
] }),
|
|
69728
|
-
/* @__PURE__ */ (0, import_jsx_runtime65.jsx)(
|
|
69729
|
-
"button",
|
|
69730
|
-
{
|
|
69731
|
-
onClick: onReturnToLive,
|
|
69732
|
-
disabled: !isScrubbing,
|
|
69733
|
-
title: isScrubbing ? "Leave history and follow the board again" : void 0,
|
|
69734
|
-
style: {
|
|
69735
|
-
background: "transparent",
|
|
69736
|
-
border: `1px solid ${isScrubbing ? GUI_THEME.accent : GUI_THEME.transparent}`,
|
|
69737
|
-
color: isScrubbing ? GUI_THEME.accent : GUI_THEME.dim,
|
|
69738
|
-
borderRadius: 6,
|
|
69739
|
-
fontFamily: "inherit",
|
|
69740
|
-
width: 60,
|
|
69741
|
-
display: "inline-flex",
|
|
69742
|
-
alignItems: "center",
|
|
69743
|
-
justifyContent: isScrubbing ? "center" : "flex-end",
|
|
69744
|
-
fontSize: 10,
|
|
69745
|
-
padding: "2px 8px",
|
|
69746
|
-
cursor: isScrubbing ? "pointer" : "default",
|
|
69747
|
-
whiteSpace: "nowrap",
|
|
69748
|
-
flexShrink: 0
|
|
69749
|
-
},
|
|
69750
|
-
children: isScrubbing ? "Resume" : atLatest ? "Now" : ""
|
|
69751
|
-
}
|
|
69752
|
-
)
|
|
69753
|
-
]
|
|
69754
|
-
}
|
|
69755
|
-
);
|
|
69798
|
+
]
|
|
69799
|
+
}
|
|
69800
|
+
);
|
|
69801
|
+
};
|
|
69756
69802
|
var ScrubberHeader = ({
|
|
69757
69803
|
collapsed,
|
|
69758
69804
|
onToggleCollapsed
|
|
@@ -70334,7 +70380,21 @@ var ScrubberLayout = ({
|
|
|
70334
70380
|
onToggleCollapsed
|
|
70335
70381
|
}
|
|
70336
70382
|
),
|
|
70337
|
-
|
|
70383
|
+
collapsed ? (
|
|
70384
|
+
// The narrowing outlives the chart it belongs to — a link can
|
|
70385
|
+
// arrive with the scrubber shut, and collapsing it is remembered
|
|
70386
|
+
// — so its box comes up here rather than leaving the board
|
|
70387
|
+
// hiding tickets behind a control nobody can see.
|
|
70388
|
+
controls.windowOnly && /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(
|
|
70389
|
+
Checkbox,
|
|
70390
|
+
{
|
|
70391
|
+
label: SCOPE_ONLY_LABEL,
|
|
70392
|
+
title: "Show every ticket again",
|
|
70393
|
+
checked: true,
|
|
70394
|
+
onChange: controls.onChangeWindowOnly
|
|
70395
|
+
}
|
|
70396
|
+
)
|
|
70397
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime66.jsx)(ScrubberControls, { ...controls })
|
|
70338
70398
|
]
|
|
70339
70399
|
}
|
|
70340
70400
|
),
|
|
@@ -70360,6 +70420,12 @@ var ScrubberLayout = ({
|
|
|
70360
70420
|
// Crosshair, not a hand: a press picks a moment but a drag picks
|
|
70361
70421
|
// out a range, and the pointer has to say the second is on offer.
|
|
70362
70422
|
cursor: chart.connected ? "crosshair" : "default",
|
|
70423
|
+
// Outline rather than a border: it takes up no space, so
|
|
70424
|
+
// narrowing the board cannot reflow the charts under the
|
|
70425
|
+
// pointer that just clicked.
|
|
70426
|
+
outline: chart.scoped ? `1px solid ${SCOPED_OUTLINE_COLOR}` : void 0,
|
|
70427
|
+
outlineOffset: 5,
|
|
70428
|
+
borderRadius: 4,
|
|
70363
70429
|
// A drag must never turn into a native text selection or a drag
|
|
70364
70430
|
// of the axis labels underneath the pointer.
|
|
70365
70431
|
userSelect: "none",
|
|
@@ -70530,7 +70596,8 @@ var TimeScrubber = ({
|
|
|
70530
70596
|
onInspectCommit,
|
|
70531
70597
|
selection,
|
|
70532
70598
|
onChangeSelection,
|
|
70533
|
-
knownIdentities
|
|
70599
|
+
knownIdentities,
|
|
70600
|
+
refreshOn
|
|
70534
70601
|
}) => {
|
|
70535
70602
|
const {
|
|
70536
70603
|
scope,
|
|
@@ -70538,7 +70605,8 @@ var TimeScrubber = ({
|
|
|
70538
70605
|
zoom,
|
|
70539
70606
|
layout: layoutMode,
|
|
70540
70607
|
view: boardView,
|
|
70541
|
-
only
|
|
70608
|
+
only,
|
|
70609
|
+
windowOnly
|
|
70542
70610
|
} = selection;
|
|
70543
70611
|
const animate = !usePrefersReducedMotion();
|
|
70544
70612
|
const trackRef = (0, import_react36.useRef)(null);
|
|
@@ -70598,7 +70666,8 @@ var TimeScrubber = ({
|
|
|
70598
70666
|
boardId,
|
|
70599
70667
|
allBoards,
|
|
70600
70668
|
connected,
|
|
70601
|
-
socketEpoch
|
|
70669
|
+
socketEpoch,
|
|
70670
|
+
refreshOn
|
|
70602
70671
|
]);
|
|
70603
70672
|
const changeLayoutMode = (next) => onChangeSelection({ layout: next });
|
|
70604
70673
|
const changeScope = (nextScope) => {
|
|
@@ -70901,12 +70970,15 @@ var TimeScrubber = ({
|
|
|
70901
70970
|
periodRange,
|
|
70902
70971
|
zoomed: zoom !== null,
|
|
70903
70972
|
atLatest,
|
|
70973
|
+
windowOnly,
|
|
70974
|
+
windowFilterable: windowNamesIssues(timeline),
|
|
70904
70975
|
layoutMode,
|
|
70905
70976
|
showIssues,
|
|
70906
70977
|
showCommits,
|
|
70907
70978
|
allBoards,
|
|
70908
70979
|
onChangeScope: changeScope,
|
|
70909
70980
|
onChangeOffset: changeOffset,
|
|
70981
|
+
onChangeWindowOnly: (next) => onChangeSelection({ windowOnly: next }),
|
|
70910
70982
|
onChangeLayoutMode: changeLayoutMode,
|
|
70911
70983
|
onChangeShowIssues: setShowIssues,
|
|
70912
70984
|
onChangeShowCommits: setShowCommits,
|
|
@@ -70926,6 +70998,10 @@ var TimeScrubber = ({
|
|
|
70926
70998
|
onSetIdentitiesExpanded: setIdentitiesExpanded
|
|
70927
70999
|
},
|
|
70928
71000
|
chart: {
|
|
71001
|
+
// Only where it is actually hiding something: ticked over a window
|
|
71002
|
+
// that narrows nothing draws no outline, the way the box itself goes
|
|
71003
|
+
// flat there.
|
|
71004
|
+
scoped: windowOnly && isPeriodWindow(scope, zoom !== null) && windowNamesIssues(timeline),
|
|
70929
71005
|
trackRef,
|
|
70930
71006
|
axis,
|
|
70931
71007
|
layoutMode,
|
|
@@ -71175,10 +71251,12 @@ var import_react38 = __toESM(require_react(), 1);
|
|
|
71175
71251
|
var useBoardSelection = () => {
|
|
71176
71252
|
const [searchParams, setSearchParams] = useSearchParams();
|
|
71177
71253
|
const fromUrl = hasSelectionParams(searchParams);
|
|
71178
|
-
const
|
|
71179
|
-
|
|
71180
|
-
|
|
71181
|
-
|
|
71254
|
+
const windowOnly = (0, import_react38.useRef)(false);
|
|
71255
|
+
const selection = (0, import_react38.useMemo)(() => {
|
|
71256
|
+
const fromParams = readSelectionParams(searchParams);
|
|
71257
|
+
return fromParams ?? { ...readStoredSelection(), windowOnly: windowOnly.current };
|
|
71258
|
+
}, [searchParams]);
|
|
71259
|
+
windowOnly.current = selection.windowOnly;
|
|
71182
71260
|
(0, import_react38.useEffect)(() => {
|
|
71183
71261
|
if (fromUrl) {
|
|
71184
71262
|
storeSelection(selection);
|
|
@@ -71483,6 +71561,11 @@ var App = () => {
|
|
|
71483
71561
|
() => buildBoardFilter(selection.view, selection.only),
|
|
71484
71562
|
[selection.view, selection.only]
|
|
71485
71563
|
);
|
|
71564
|
+
const zoomed = selection.zoom !== null;
|
|
71565
|
+
const windowIds = (0, import_react39.useMemo)(
|
|
71566
|
+
() => selection.windowOnly && isPeriodWindow(selection.scope, zoomed) ? windowIssueIds(history.timeline) : null,
|
|
71567
|
+
[selection.windowOnly, selection.scope, zoomed, history.timeline]
|
|
71568
|
+
);
|
|
71486
71569
|
const isolatedTagId = selection.view === "tagging" && selection.only?.length === 1 ? selection.only[0] ?? null : null;
|
|
71487
71570
|
const filterByTag = (tagId) => changeSelection(
|
|
71488
71571
|
isolatedTagId === tagId ? { only: null } : { view: "tagging", only: [tagId] }
|
|
@@ -71498,7 +71581,7 @@ var App = () => {
|
|
|
71498
71581
|
const { visibleSwimlanes, hiddenIssueCount } = (0, import_react39.useMemo)(() => {
|
|
71499
71582
|
const swimlanes = selectedBoard?.swimlanes ?? [];
|
|
71500
71583
|
const query = textFilter.trim();
|
|
71501
|
-
if (!boardFilter && !query)
|
|
71584
|
+
if (!boardFilter && !query && windowIds === null)
|
|
71502
71585
|
return { visibleSwimlanes: swimlanes, hiddenIssueCount: 0 };
|
|
71503
71586
|
let hidden = 0;
|
|
71504
71587
|
const visible = swimlanes.map((swimlane) => {
|
|
@@ -71509,13 +71592,13 @@ var App = () => {
|
|
|
71509
71592
|
(comment2) => comment2.author.id
|
|
71510
71593
|
),
|
|
71511
71594
|
boardFilter
|
|
71512
|
-
) && issueMatchesText(issue, query)
|
|
71595
|
+
) && issueMatchesText(issue, query) && (windowIds === null || windowIds.has(issue.id))
|
|
71513
71596
|
);
|
|
71514
71597
|
hidden += swimlane.issues.length - issues.length;
|
|
71515
71598
|
return { ...swimlane, issues };
|
|
71516
71599
|
});
|
|
71517
71600
|
return { visibleSwimlanes: visible, hiddenIssueCount: hidden };
|
|
71518
|
-
}, [selectedBoard, boardFilter, textFilter, commentsByIssueId]);
|
|
71601
|
+
}, [selectedBoard, boardFilter, textFilter, commentsByIssueId, windowIds]);
|
|
71519
71602
|
const attachmentsByIssueId = state?.attachmentsByIssueId ?? {};
|
|
71520
71603
|
const [attachmentUploadStatus, setAttachmentUploadStatus] = (0, import_react39.useState)({ state: "idle" });
|
|
71521
71604
|
(0, import_react39.useEffect)(() => {
|
|
@@ -72337,7 +72420,8 @@ var App = () => {
|
|
|
72337
72420
|
onReturnToLive: returnToLive,
|
|
72338
72421
|
selection,
|
|
72339
72422
|
onChangeSelection: changeSelection,
|
|
72340
|
-
knownIdentities
|
|
72423
|
+
knownIdentities,
|
|
72424
|
+
refreshOn: selection.windowOnly ? state : null
|
|
72341
72425
|
}
|
|
72342
72426
|
),
|
|
72343
72427
|
/* @__PURE__ */ (0, import_jsx_runtime68.jsxs)(
|