glitchgrab 1.46.0 → 1.48.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/dist/index.js +332 -74
- package/dist/index.js.map +1 -1
- package/dist/index.mjs +332 -74
- package/dist/index.mjs.map +1 -1
- package/dist/server.js.map +1 -1
- package/dist/server.mjs.map +1 -1
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -73,6 +73,37 @@ var import_react6 = require("react");
|
|
|
73
73
|
// src/error-boundary.tsx
|
|
74
74
|
var React = __toESM(require("react"));
|
|
75
75
|
|
|
76
|
+
// ../report-ui/dist/assist-response.mjs
|
|
77
|
+
var ASSIST_OFFLINE_MESSAGE = "The assistant is unavailable \u2014 write your report below and send it as normal.";
|
|
78
|
+
function assistOffline() {
|
|
79
|
+
return { conversationId: null, question: null, report: null, degraded: ASSIST_OFFLINE_MESSAGE };
|
|
80
|
+
}
|
|
81
|
+
function toAssistTurnResult(ok, body) {
|
|
82
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
83
|
+
const envelope = body != null ? body : null;
|
|
84
|
+
if (!ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
85
|
+
return {
|
|
86
|
+
...assistOffline(),
|
|
87
|
+
// The server words why (cap, rate limit, switched off). An hourly limit
|
|
88
|
+
// keeps the assistant button for this report.
|
|
89
|
+
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : ASSIST_OFFLINE_MESSAGE,
|
|
90
|
+
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
const d = (_b = envelope.data) != null ? _b : {};
|
|
94
|
+
return {
|
|
95
|
+
conversationId: (_c = d.conversationId) != null ? _c : null,
|
|
96
|
+
question: (_d = d.question) != null ? _d : null,
|
|
97
|
+
options: Array.isArray(d.options) ? d.options.filter((o) => typeof o === "string") : [],
|
|
98
|
+
report: (_e = d.report) != null ? _e : null,
|
|
99
|
+
duplicate: (_f = d.duplicate) != null ? _f : null,
|
|
100
|
+
related: (_g = d.related) != null ? _g : null,
|
|
101
|
+
solved: (_h = d.solved) != null ? _h : null,
|
|
102
|
+
aboutGlitchgrab: d.aboutGlitchgrab === true,
|
|
103
|
+
degraded: null
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
|
|
76
107
|
// src/redact.ts
|
|
77
108
|
var SENSITIVE_KEY_RE = /(pass|pwd|secret|token|auth|session|cookie|credential|apikey|api_key|access_key|private|signature|otp|pin|cvv|card|ssn|aadhaar|pan)/i;
|
|
78
109
|
var EMAIL_RE = /[\w.+-]+@[\w-]+\.[\w.-]+/g;
|
|
@@ -747,13 +778,7 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
747
778
|
}
|
|
748
779
|
}
|
|
749
780
|
async function assistTurn(params, token, baseUrl) {
|
|
750
|
-
|
|
751
|
-
const offline = {
|
|
752
|
-
conversationId: null,
|
|
753
|
-
question: null,
|
|
754
|
-
report: null,
|
|
755
|
-
degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
|
|
756
|
-
};
|
|
781
|
+
const offline = assistOffline();
|
|
757
782
|
try {
|
|
758
783
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
|
|
759
784
|
const response = await fetch(url, {
|
|
@@ -764,27 +789,7 @@ async function assistTurn(params, token, baseUrl) {
|
|
|
764
789
|
},
|
|
765
790
|
body: JSON.stringify(params)
|
|
766
791
|
});
|
|
767
|
-
|
|
768
|
-
if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
769
|
-
return {
|
|
770
|
-
conversationId: null,
|
|
771
|
-
question: null,
|
|
772
|
-
report: null,
|
|
773
|
-
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded,
|
|
774
|
-
// An hourly limit, not a cap: the dialog keeps the assistant button.
|
|
775
|
-
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
776
|
-
};
|
|
777
|
-
}
|
|
778
|
-
return {
|
|
779
|
-
conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
|
|
780
|
-
question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
|
|
781
|
-
options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
|
|
782
|
-
report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
|
|
783
|
-
duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
|
|
784
|
-
solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
|
|
785
|
-
aboutGlitchgrab: ((_n = envelope.data) == null ? void 0 : _n.aboutGlitchgrab) === true,
|
|
786
|
-
degraded: null
|
|
787
|
-
};
|
|
792
|
+
return toAssistTurnResult(response.ok, await response.json().catch(() => null));
|
|
788
793
|
} catch (e) {
|
|
789
794
|
return offline;
|
|
790
795
|
}
|
|
@@ -1474,6 +1479,17 @@ var STARTERS = [
|
|
|
1474
1479
|
"It did the wrong thing",
|
|
1475
1480
|
"I wish it could\u2026"
|
|
1476
1481
|
];
|
|
1482
|
+
var CONFIRM_OPTION = "Yes, that's it";
|
|
1483
|
+
function isCheckBackQuestion(text) {
|
|
1484
|
+
const t2 = text.trim();
|
|
1485
|
+
return /^so,? you['’]?re saying\b/i.test(t2) || /\b(is that right|is that correct|did i get (that|it) right|have i got (that|it) right)\s*\??\s*$/i.test(t2);
|
|
1486
|
+
}
|
|
1487
|
+
function isAffirmativeReply(text) {
|
|
1488
|
+
return /^(y|ya|yah|yes|yess|yeah|yep|yup|ok|okay|sure|correct|right|exactly|confirm(ed)?|that['’]?s (it|right|correct)|yes,? that['’]?s (it|right)|haan|han|ha|ho|hmm yes|👍)[\s.!👍]*$/i.test(
|
|
1489
|
+
text.trim()
|
|
1490
|
+
);
|
|
1491
|
+
}
|
|
1492
|
+
var AUTO_FILE_SECONDS = 4;
|
|
1477
1493
|
var NARROW_QUERY = "(max-width: 640px)";
|
|
1478
1494
|
function useIsNarrow() {
|
|
1479
1495
|
const [narrow, setNarrow] = (0, import_react3.useState)(false);
|
|
@@ -1588,12 +1604,15 @@ function AssistSheet({
|
|
|
1588
1604
|
const [duplicate, setDuplicate] = (0, import_react3.useState)(null);
|
|
1589
1605
|
const [glitchgrabOffer, setGlitchgrabOffer] = (0, import_react3.useState)(false);
|
|
1590
1606
|
const [solved, setSolved] = (0, import_react3.useState)(null);
|
|
1607
|
+
const needsSeverity = (tile) => showSeverity && tile === "BUG" && !severity;
|
|
1591
1608
|
const [phase, setPhase] = (0, import_react3.useState)(
|
|
1592
|
-
!typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
|
|
1609
|
+
() => !typePicked ? "type" : currentTile === "RATING" ? "rating" : needsSeverity(currentTile) ? "severity" : "chat"
|
|
1593
1610
|
);
|
|
1611
|
+
const [autoFileLeft, setAutoFileLeft] = (0, import_react3.useState)(null);
|
|
1594
1612
|
const scrollRef = (0, import_react3.useRef)(null);
|
|
1595
1613
|
const draftRef = (0, import_react3.useRef)(null);
|
|
1596
1614
|
const seededRef = (0, import_react3.useRef)(false);
|
|
1615
|
+
const seedPendingRef = (0, import_react3.useRef)(false);
|
|
1597
1616
|
const eventsRef = (0, import_react3.useRef)([]);
|
|
1598
1617
|
const aiDraftRef = (0, import_react3.useRef)(null);
|
|
1599
1618
|
function logEvent(type, detail) {
|
|
@@ -1633,14 +1652,33 @@ function AssistSheet({
|
|
|
1633
1652
|
var _a;
|
|
1634
1653
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
1635
1654
|
}, [phase]);
|
|
1655
|
+
(0, import_react3.useEffect)(() => {
|
|
1656
|
+
if (autoFileLeft === null) return;
|
|
1657
|
+
if (isSubmitting || submitted || phase !== "draft") {
|
|
1658
|
+
setAutoFileLeft(null);
|
|
1659
|
+
return;
|
|
1660
|
+
}
|
|
1661
|
+
if (autoFileLeft <= 0) {
|
|
1662
|
+
sendDraft(true);
|
|
1663
|
+
return;
|
|
1664
|
+
}
|
|
1665
|
+
const id = setTimeout(() => setAutoFileLeft((n) => n === null ? null : n - 1), 1e3);
|
|
1666
|
+
return () => clearTimeout(id);
|
|
1667
|
+
}, [autoFileLeft, isSubmitting, submitted, phase]);
|
|
1668
|
+
function stopAutoFile(reason) {
|
|
1669
|
+
if (autoFileLeft === null) return;
|
|
1670
|
+
setAutoFileLeft(null);
|
|
1671
|
+
logEvent("auto_file_stopped", reason);
|
|
1672
|
+
}
|
|
1636
1673
|
function degradeKeepingEvents(events, message, retryable) {
|
|
1637
1674
|
if (events) eventsRef.current = [...events, ...eventsRef.current];
|
|
1638
1675
|
flushEvents();
|
|
1639
1676
|
onDegrade(message, retryable);
|
|
1640
1677
|
}
|
|
1641
|
-
async function runTurn(history2) {
|
|
1642
|
-
var _a, _b
|
|
1678
|
+
async function runTurn(history2, autoFile = false) {
|
|
1679
|
+
var _a, _b;
|
|
1643
1680
|
setBusy(true);
|
|
1681
|
+
setAutoFileLeft(null);
|
|
1644
1682
|
let result;
|
|
1645
1683
|
const events = takeEvents();
|
|
1646
1684
|
try {
|
|
@@ -1683,8 +1721,9 @@ function AssistSheet({
|
|
|
1683
1721
|
setConversationId(result.conversationId);
|
|
1684
1722
|
onConversationChange == null ? void 0 : onConversationChange(result.conversationId);
|
|
1685
1723
|
}
|
|
1686
|
-
|
|
1687
|
-
|
|
1724
|
+
const attach = result.duplicate ? { ...result.duplicate, kind: "duplicate" } : result.related ? { ...result.related, kind: "related" } : null;
|
|
1725
|
+
setDuplicate(attach);
|
|
1726
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange((_a = attach == null ? void 0 : attach.number) != null ? _a : null, attach == null ? void 0 : attach.kind);
|
|
1688
1727
|
setGlitchgrabOffer(!!result.aboutGlitchgrab && !!onReportGlitchgrabProblem && !!result.question);
|
|
1689
1728
|
if (result.solved) {
|
|
1690
1729
|
setSolved(result.solved);
|
|
@@ -1699,11 +1738,14 @@ function AssistSheet({
|
|
|
1699
1738
|
setMessages([...history2, { role: "assistant", content: result.report, kind: "report" }]);
|
|
1700
1739
|
setOptions([]);
|
|
1701
1740
|
setPhase("draft");
|
|
1741
|
+
if (autoFile && !attach && !(severityAsked && !severity)) {
|
|
1742
|
+
setAutoFileLeft(AUTO_FILE_SECONDS);
|
|
1743
|
+
}
|
|
1702
1744
|
return;
|
|
1703
1745
|
}
|
|
1704
1746
|
if (result.question) {
|
|
1705
1747
|
setMessages([...history2, { role: "assistant", content: result.question }]);
|
|
1706
|
-
setOptions((
|
|
1748
|
+
setOptions((_b = result.options) != null ? _b : []);
|
|
1707
1749
|
return;
|
|
1708
1750
|
}
|
|
1709
1751
|
onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
|
|
@@ -1712,13 +1754,34 @@ function AssistSheet({
|
|
|
1712
1754
|
if (seededRef.current) return;
|
|
1713
1755
|
seededRef.current = true;
|
|
1714
1756
|
if (!typePicked || currentTile === "RATING") return;
|
|
1757
|
+
if (phase === "severity") {
|
|
1758
|
+
seedPendingRef.current = true;
|
|
1759
|
+
return;
|
|
1760
|
+
}
|
|
1761
|
+
seedFromDescription();
|
|
1762
|
+
}, []);
|
|
1763
|
+
function seedFromDescription() {
|
|
1715
1764
|
const seed = description.trim();
|
|
1716
1765
|
if (!seed) return;
|
|
1717
1766
|
const history2 = [{ role: "user", content: seed }];
|
|
1718
1767
|
setMessages(history2);
|
|
1719
1768
|
void runTurn(history2);
|
|
1720
|
-
}
|
|
1721
|
-
function
|
|
1769
|
+
}
|
|
1770
|
+
function answerSeverity(value) {
|
|
1771
|
+
onSeverityChange(value);
|
|
1772
|
+
setPhase("chat");
|
|
1773
|
+
if (seedPendingRef.current) {
|
|
1774
|
+
seedPendingRef.current = false;
|
|
1775
|
+
seedFromDescription();
|
|
1776
|
+
}
|
|
1777
|
+
}
|
|
1778
|
+
function sendTyped(text) {
|
|
1779
|
+
var _a;
|
|
1780
|
+
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
1781
|
+
const checkingBack = options.includes(CONFIRM_OPTION) || (lastAssistant == null ? void 0 : lastAssistant.kind) !== "report" && isCheckBackQuestion((_a = lastAssistant == null ? void 0 : lastAssistant.content) != null ? _a : "");
|
|
1782
|
+
send(text, checkingBack && isAffirmativeReply(text));
|
|
1783
|
+
}
|
|
1784
|
+
function send(text, autoFile = false) {
|
|
1722
1785
|
const value = text.trim();
|
|
1723
1786
|
if (!value || busy) return;
|
|
1724
1787
|
setOptions([]);
|
|
@@ -1733,11 +1796,11 @@ function AssistSheet({
|
|
|
1733
1796
|
const history2 = [...base, { role: "user", content: value }];
|
|
1734
1797
|
setMessages(history2);
|
|
1735
1798
|
setInput("");
|
|
1736
|
-
void runTurn(history2);
|
|
1799
|
+
void runTurn(history2, autoFile);
|
|
1737
1800
|
}
|
|
1738
1801
|
function pickType(tile) {
|
|
1739
1802
|
onPickType(tile);
|
|
1740
|
-
setPhase(tile === "RATING" ? "rating" : "chat");
|
|
1803
|
+
setPhase(tile === "RATING" ? "rating" : needsSeverity(tile) ? "severity" : "chat");
|
|
1741
1804
|
}
|
|
1742
1805
|
function withCurrentDraft(history2) {
|
|
1743
1806
|
const current = description.trim();
|
|
@@ -1750,9 +1813,10 @@ function AssistSheet({
|
|
|
1750
1813
|
}
|
|
1751
1814
|
return next;
|
|
1752
1815
|
}
|
|
1753
|
-
function sendDraft() {
|
|
1816
|
+
function sendDraft(auto = false) {
|
|
1817
|
+
setAutoFileLeft(null);
|
|
1754
1818
|
const edited = aiDraftRef.current !== null && description.trim() !== aiDraftRef.current.trim();
|
|
1755
|
-
logEvent("draft_sent", edited ? "edited" : "as drafted");
|
|
1819
|
+
logEvent("draft_sent", auto ? "auto-filed" : edited ? "edited" : "as drafted");
|
|
1756
1820
|
flushEvents();
|
|
1757
1821
|
onSend();
|
|
1758
1822
|
}
|
|
@@ -1776,15 +1840,15 @@ function AssistSheet({
|
|
|
1776
1840
|
minWidth: 0
|
|
1777
1841
|
},
|
|
1778
1842
|
children: [
|
|
1779
|
-
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.text, fontWeight: 600 }, children: title ? "Our team is already on this" : `Our team is already on #${duplicate.number}` }),
|
|
1843
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.text, fontWeight: 600 }, children: duplicate.kind === "related" ? title ? "Your request goes onto this issue" : `Connected to #${duplicate.number}` : title ? "Our team is already on this" : `Our team is already on #${duplicate.number}` }),
|
|
1780
1844
|
title && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
|
|
1781
1845
|
"#",
|
|
1782
1846
|
duplicate.number,
|
|
1783
1847
|
" ",
|
|
1784
1848
|
duplicate.title
|
|
1785
1849
|
] }),
|
|
1786
|
-
duplicate.status && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.text, fontWeight: 600 }, children: duplicate.status }),
|
|
1787
|
-
footer && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted }, children: footer })
|
|
1850
|
+
duplicate.status && duplicate.kind !== "related" && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.text, fontWeight: 600 }, children: duplicate.status }),
|
|
1851
|
+
footer && /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { color: t2.textMuted }, children: duplicate.kind === "related" ? "Added as a separate request on it, not a repeat \u2014 the team sees both." : footer })
|
|
1788
1852
|
]
|
|
1789
1853
|
}
|
|
1790
1854
|
);
|
|
@@ -1812,6 +1876,7 @@ function AssistSheet({
|
|
|
1812
1876
|
@keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
|
|
1813
1877
|
@keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
1814
1878
|
@keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
|
|
1879
|
+
@keyframes gg-autofile{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
1815
1880
|
@keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
|
|
1816
1881
|
[data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible,[data-gg-assist-remove]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
1817
1882
|
` }),
|
|
@@ -1906,6 +1971,7 @@ function AssistSheet({
|
|
|
1906
1971
|
),
|
|
1907
1972
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
|
|
1908
1973
|
phase === "type" ? null : reportTypeLabel,
|
|
1974
|
+
phase !== "type" && severityAsked && severity ? ` \xB7 ${SEVERITY_LABELS[severity]}` : null,
|
|
1909
1975
|
projectSlot ? /* @__PURE__ */ (0, import_jsx_runtime2.jsx)("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
1910
1976
|
] })
|
|
1911
1977
|
] }),
|
|
@@ -2024,6 +2090,62 @@ function AssistSheet({
|
|
|
2024
2090
|
}
|
|
2025
2091
|
)
|
|
2026
2092
|
] }),
|
|
2093
|
+
phase === "severity" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2094
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2095
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
2096
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2097
|
+
"div",
|
|
2098
|
+
{
|
|
2099
|
+
style: {
|
|
2100
|
+
padding: "9px 12px",
|
|
2101
|
+
borderRadius: "12px 12px 12px 4px",
|
|
2102
|
+
backgroundColor: t2.bgSecondary,
|
|
2103
|
+
fontSize: "13px",
|
|
2104
|
+
lineHeight: 1.55,
|
|
2105
|
+
maxWidth: "88%"
|
|
2106
|
+
},
|
|
2107
|
+
children: "How bad is it?"
|
|
2108
|
+
}
|
|
2109
|
+
)
|
|
2110
|
+
] }),
|
|
2111
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2112
|
+
"div",
|
|
2113
|
+
{
|
|
2114
|
+
role: "radiogroup",
|
|
2115
|
+
"aria-label": "Severity",
|
|
2116
|
+
style: {
|
|
2117
|
+
display: "flex",
|
|
2118
|
+
flexWrap: "wrap",
|
|
2119
|
+
gap: "6px",
|
|
2120
|
+
paddingLeft: "32px"
|
|
2121
|
+
},
|
|
2122
|
+
children: SEVERITY_LEVELS.map((s) => /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2123
|
+
"button",
|
|
2124
|
+
{
|
|
2125
|
+
type: "button",
|
|
2126
|
+
role: "radio",
|
|
2127
|
+
"aria-checked": severity === s,
|
|
2128
|
+
"data-gg-chip": "",
|
|
2129
|
+
"data-gg-severity": s,
|
|
2130
|
+
onClick: () => answerSeverity(s),
|
|
2131
|
+
style: {
|
|
2132
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
2133
|
+
background: "transparent",
|
|
2134
|
+
color: t2.textMuted,
|
|
2135
|
+
borderRadius: "999px",
|
|
2136
|
+
// Same as the picker and option chips — one chip size.
|
|
2137
|
+
padding: "8px 12px",
|
|
2138
|
+
fontSize: "12px",
|
|
2139
|
+
fontFamily: "inherit",
|
|
2140
|
+
cursor: "pointer"
|
|
2141
|
+
},
|
|
2142
|
+
children: SEVERITY_LABELS[s]
|
|
2143
|
+
},
|
|
2144
|
+
s
|
|
2145
|
+
))
|
|
2146
|
+
}
|
|
2147
|
+
)
|
|
2148
|
+
] }),
|
|
2027
2149
|
phase === "rating" && !submitted && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2028
2150
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2029
2151
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(Avatar, { who: "assistant", theme: t2 }),
|
|
@@ -2212,7 +2334,11 @@ function AssistSheet({
|
|
|
2212
2334
|
color: t2.text,
|
|
2213
2335
|
border: live ? "none" : `1px solid ${t2.accent}66`
|
|
2214
2336
|
},
|
|
2215
|
-
children: live ?
|
|
2337
|
+
children: live ? (
|
|
2338
|
+
// #402: "have a read" beside a countdown reads as a
|
|
2339
|
+
// contradiction. Say what is about to happen instead.
|
|
2340
|
+
autoFileLeft !== null ? "Here's your report \u2014 I'll file it unless you want to change something." : "Here's your report \u2014 have a read."
|
|
2341
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(import_jsx_runtime2.Fragment, { children: [
|
|
2216
2342
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
2217
2343
|
"span",
|
|
2218
2344
|
{
|
|
@@ -2379,7 +2505,7 @@ function AssistSheet({
|
|
|
2379
2505
|
"data-gg-option": "",
|
|
2380
2506
|
onClick: () => {
|
|
2381
2507
|
logEvent("option_tap", option);
|
|
2382
|
-
send(option);
|
|
2508
|
+
send(option, option === CONFIRM_OPTION);
|
|
2383
2509
|
},
|
|
2384
2510
|
style: {
|
|
2385
2511
|
border: `1px solid ${t2.inputBorder}`,
|
|
@@ -2454,7 +2580,7 @@ function AssistSheet({
|
|
|
2454
2580
|
textTransform: "uppercase",
|
|
2455
2581
|
color: t2.accent
|
|
2456
2582
|
},
|
|
2457
|
-
children: duplicate ? `What we'll add to #${duplicate.number} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
2583
|
+
children: duplicate ? `What we'll add to #${duplicate.number}${duplicate.kind === "related" ? " as a related request" : ""} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
2458
2584
|
}
|
|
2459
2585
|
),
|
|
2460
2586
|
renderKnownIssue({
|
|
@@ -2466,7 +2592,10 @@ function AssistSheet({
|
|
|
2466
2592
|
{
|
|
2467
2593
|
ref: draftRef,
|
|
2468
2594
|
value: description,
|
|
2469
|
-
onChange: (e) =>
|
|
2595
|
+
onChange: (e) => {
|
|
2596
|
+
stopAutoFile("edited the draft");
|
|
2597
|
+
onDescriptionChange(e.target.value);
|
|
2598
|
+
},
|
|
2470
2599
|
rows: 6,
|
|
2471
2600
|
style: {
|
|
2472
2601
|
width: "100%",
|
|
@@ -2485,7 +2614,7 @@ function AssistSheet({
|
|
|
2485
2614
|
}
|
|
2486
2615
|
}
|
|
2487
2616
|
),
|
|
2488
|
-
severityAsked && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
2617
|
+
severityAsked && autoFileLeft === null && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { children: [
|
|
2489
2618
|
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2490
2619
|
"span",
|
|
2491
2620
|
{
|
|
@@ -2607,7 +2736,7 @@ function AssistSheet({
|
|
|
2607
2736
|
)
|
|
2608
2737
|
}
|
|
2609
2738
|
),
|
|
2610
|
-
!submitted && phase !== "type" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2739
|
+
!submitted && phase !== "type" && phase !== "severity" && /* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
2611
2740
|
"div",
|
|
2612
2741
|
{
|
|
2613
2742
|
style: {
|
|
@@ -2714,6 +2843,7 @@ function AssistSheet({
|
|
|
2714
2843
|
"aria-label": `Remove image ${i + 1}`,
|
|
2715
2844
|
title: "Remove this image",
|
|
2716
2845
|
onClick: () => {
|
|
2846
|
+
stopAutoFile("changed attachments");
|
|
2717
2847
|
logEvent(
|
|
2718
2848
|
"image_removed",
|
|
2719
2849
|
pageShot && shot === pageShot ? "page capture" : "attached"
|
|
@@ -2824,6 +2954,7 @@ function AssistSheet({
|
|
|
2824
2954
|
"aria-label": `Remove file ${file.name}`,
|
|
2825
2955
|
title: "Remove this file",
|
|
2826
2956
|
onClick: () => {
|
|
2957
|
+
stopAutoFile("changed attachments");
|
|
2827
2958
|
logEvent("file_removed", read ? "read" : "not read");
|
|
2828
2959
|
onRemoveFile(i);
|
|
2829
2960
|
},
|
|
@@ -2906,6 +3037,7 @@ function AssistSheet({
|
|
|
2906
3037
|
var _a;
|
|
2907
3038
|
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
2908
3039
|
if (picked.length) {
|
|
3040
|
+
stopAutoFile("changed attachments");
|
|
2909
3041
|
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
2910
3042
|
if (images) logEvent("image_added", String(images));
|
|
2911
3043
|
if (picked.length > images) {
|
|
@@ -2935,11 +3067,14 @@ function AssistSheet({
|
|
|
2935
3067
|
"textarea",
|
|
2936
3068
|
{
|
|
2937
3069
|
value: input,
|
|
2938
|
-
onChange: (e) =>
|
|
3070
|
+
onChange: (e) => {
|
|
3071
|
+
stopAutoFile("typing a change");
|
|
3072
|
+
setInput(e.target.value);
|
|
3073
|
+
},
|
|
2939
3074
|
onKeyDown: (e) => {
|
|
2940
3075
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2941
3076
|
e.preventDefault();
|
|
2942
|
-
|
|
3077
|
+
sendTyped(input);
|
|
2943
3078
|
}
|
|
2944
3079
|
},
|
|
2945
3080
|
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
@@ -2969,7 +3104,7 @@ function AssistSheet({
|
|
|
2969
3104
|
{
|
|
2970
3105
|
type: "button",
|
|
2971
3106
|
"data-gg-sheet-send": "",
|
|
2972
|
-
onClick: () =>
|
|
3107
|
+
onClick: () => sendTyped(input),
|
|
2973
3108
|
disabled: busy || !input.trim(),
|
|
2974
3109
|
"aria-label": "Send message",
|
|
2975
3110
|
"data-gg-send-message": "",
|
|
@@ -3008,12 +3143,87 @@ function AssistSheet({
|
|
|
3008
3143
|
children: validationError
|
|
3009
3144
|
}
|
|
3010
3145
|
),
|
|
3011
|
-
|
|
3146
|
+
autoFileLeft !== null ? (
|
|
3147
|
+
// #402: "Yes, that's it" was the confirmation. The draft
|
|
3148
|
+
// files itself unless they stop it — the bar shows how
|
|
3149
|
+
// long is left, the button sends now.
|
|
3150
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [
|
|
3151
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)(
|
|
3152
|
+
"button",
|
|
3153
|
+
{
|
|
3154
|
+
type: "button",
|
|
3155
|
+
"data-gg-sheet-send": "",
|
|
3156
|
+
"data-gg-auto-file": "",
|
|
3157
|
+
onClick: () => sendDraft(),
|
|
3158
|
+
style: {
|
|
3159
|
+
flex: 1,
|
|
3160
|
+
minWidth: 0,
|
|
3161
|
+
position: "relative",
|
|
3162
|
+
overflow: "hidden",
|
|
3163
|
+
padding: "12px",
|
|
3164
|
+
borderRadius: "10px",
|
|
3165
|
+
border: "none",
|
|
3166
|
+
backgroundColor: t2.accent,
|
|
3167
|
+
color: t2.accentText,
|
|
3168
|
+
fontSize: "14px",
|
|
3169
|
+
fontWeight: 700,
|
|
3170
|
+
fontFamily: "inherit",
|
|
3171
|
+
cursor: "pointer"
|
|
3172
|
+
},
|
|
3173
|
+
children: [
|
|
3174
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3175
|
+
"span",
|
|
3176
|
+
{
|
|
3177
|
+
"aria-hidden": "true",
|
|
3178
|
+
style: {
|
|
3179
|
+
position: "absolute",
|
|
3180
|
+
inset: 0,
|
|
3181
|
+
backgroundColor: "rgba(255,255,255,0.22)",
|
|
3182
|
+
transformOrigin: "left",
|
|
3183
|
+
animation: `gg-autofile ${AUTO_FILE_SECONDS}s linear forwards`
|
|
3184
|
+
}
|
|
3185
|
+
}
|
|
3186
|
+
),
|
|
3187
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsxs)("span", { style: { position: "relative" }, children: [
|
|
3188
|
+
"Filing in ",
|
|
3189
|
+
autoFileLeft,
|
|
3190
|
+
"s\u2026"
|
|
3191
|
+
] })
|
|
3192
|
+
]
|
|
3193
|
+
}
|
|
3194
|
+
),
|
|
3195
|
+
/* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3196
|
+
"button",
|
|
3197
|
+
{
|
|
3198
|
+
type: "button",
|
|
3199
|
+
"data-gg-edit-first": "",
|
|
3200
|
+
onClick: () => {
|
|
3201
|
+
var _a;
|
|
3202
|
+
stopAutoFile("edit first");
|
|
3203
|
+
(_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
3204
|
+
},
|
|
3205
|
+
style: {
|
|
3206
|
+
flexShrink: 0,
|
|
3207
|
+
padding: "12px 14px",
|
|
3208
|
+
borderRadius: "10px",
|
|
3209
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
3210
|
+
background: "transparent",
|
|
3211
|
+
color: t2.text,
|
|
3212
|
+
fontSize: "13px",
|
|
3213
|
+
fontWeight: 600,
|
|
3214
|
+
fontFamily: "inherit",
|
|
3215
|
+
cursor: "pointer"
|
|
3216
|
+
},
|
|
3217
|
+
children: "Edit first"
|
|
3218
|
+
}
|
|
3219
|
+
)
|
|
3220
|
+
] })
|
|
3221
|
+
) : /* @__PURE__ */ (0, import_jsx_runtime2.jsx)(
|
|
3012
3222
|
"button",
|
|
3013
3223
|
{
|
|
3014
3224
|
type: "button",
|
|
3015
3225
|
"data-gg-sheet-send": "",
|
|
3016
|
-
onClick: sendDraft,
|
|
3226
|
+
onClick: () => sendDraft(),
|
|
3017
3227
|
disabled: isSubmitting || !description.trim(),
|
|
3018
3228
|
style: {
|
|
3019
3229
|
width: "100%",
|
|
@@ -3989,9 +4199,11 @@ function ReportDialog({
|
|
|
3989
4199
|
reporter,
|
|
3990
4200
|
onClose,
|
|
3991
4201
|
headerSlot,
|
|
3992
|
-
reportGlitchgrabProblem
|
|
4202
|
+
reportGlitchgrabProblem,
|
|
4203
|
+
layout = "modal"
|
|
3993
4204
|
}) {
|
|
3994
4205
|
var _a;
|
|
4206
|
+
const sheet = layout === "sheet";
|
|
3995
4207
|
const [isEnhancing, setIsEnhancing] = (0, import_react.useState)(false);
|
|
3996
4208
|
const [assistOpen, setAssistOpen] = (0, import_react.useState)(false);
|
|
3997
4209
|
const [assistNotice, setAssistNotice] = (0, import_react.useState)(null);
|
|
@@ -4000,6 +4212,8 @@ function ReportDialog({
|
|
|
4000
4212
|
const [selfReportPrefill, setSelfReportPrefill] = (0, import_react.useState)("");
|
|
4001
4213
|
const [typeChosen, setTypeChosen] = (0, import_react.useState)(false);
|
|
4002
4214
|
const [duplicateIssueNumber, setDuplicateIssueNumber] = (0, import_react.useState)(null);
|
|
4215
|
+
const [duplicateKind, setDuplicateKind] = (0, import_react.useState)("duplicate");
|
|
4216
|
+
const [addedAsRelated, setAddedAsRelated] = (0, import_react.useState)(false);
|
|
4003
4217
|
const [similarIssues, setSimilarIssues] = (0, import_react.useState)(null);
|
|
4004
4218
|
const [checkingSimilar, setCheckingSimilar] = (0, import_react.useState)(false);
|
|
4005
4219
|
const [attachingTo, setAttachingTo] = (0, import_react.useState)(null);
|
|
@@ -4436,6 +4650,7 @@ function ReportDialog({
|
|
|
4436
4650
|
setReportType("BUG");
|
|
4437
4651
|
setTypeChosen(false);
|
|
4438
4652
|
setDuplicateIssueNumber(null);
|
|
4653
|
+
setDuplicateKind("duplicate");
|
|
4439
4654
|
setSimilarIssues(null);
|
|
4440
4655
|
setPickedSimilar(null);
|
|
4441
4656
|
setCheckingSimilar(false);
|
|
@@ -4628,7 +4843,7 @@ function ReportDialog({
|
|
|
4628
4843
|
}
|
|
4629
4844
|
};
|
|
4630
4845
|
const handleSubmit = async (opts) => {
|
|
4631
|
-
var _a2, _b;
|
|
4846
|
+
var _a2, _b, _c;
|
|
4632
4847
|
try {
|
|
4633
4848
|
if (isSubmitting) return;
|
|
4634
4849
|
if (isRating) {
|
|
@@ -4666,6 +4881,7 @@ function ReportDialog({
|
|
|
4666
4881
|
return;
|
|
4667
4882
|
}
|
|
4668
4883
|
const duplicateOf = (_a2 = opts == null ? void 0 : opts.duplicateOf) != null ? _a2 : duplicateIssueNumber;
|
|
4884
|
+
const attachKind = (opts == null ? void 0 : opts.duplicateOf) ? (_b = opts.kind) != null ? _b : "duplicate" : duplicateKind;
|
|
4669
4885
|
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf && !aiConversationId) {
|
|
4670
4886
|
setIsSubmitting(true);
|
|
4671
4887
|
setCheckingSimilar(true);
|
|
@@ -4701,6 +4917,7 @@ function ReportDialog({
|
|
|
4701
4917
|
}
|
|
4702
4918
|
if (duplicateOf) {
|
|
4703
4919
|
metadata.duplicateIssueNumber = String(duplicateOf);
|
|
4920
|
+
if (attachKind === "related") metadata.duplicateKind = "related";
|
|
4704
4921
|
}
|
|
4705
4922
|
if (aiConversationId) {
|
|
4706
4923
|
metadata.aiConversationId = aiConversationId;
|
|
@@ -4714,14 +4931,16 @@ function ReportDialog({
|
|
|
4714
4931
|
);
|
|
4715
4932
|
if (result) {
|
|
4716
4933
|
setAddedToIssue(duplicateOf && result.issueNumber === duplicateOf ? duplicateOf : null);
|
|
4934
|
+
setAddedAsRelated(!!duplicateOf && result.issueNumber === duplicateOf && attachKind === "related");
|
|
4717
4935
|
const queued = result.status === "QUEUED" && !!result.message;
|
|
4718
|
-
setQueuedMessage(queued ? (
|
|
4936
|
+
setQueuedMessage(queued ? (_c = result.message) != null ? _c : null : null);
|
|
4719
4937
|
setSubmitted(true);
|
|
4720
4938
|
setDescription("");
|
|
4721
4939
|
setScreenshots([]);
|
|
4722
4940
|
setAttachments([]);
|
|
4723
4941
|
setAiConversationId(null);
|
|
4724
4942
|
setDuplicateIssueNumber(null);
|
|
4943
|
+
setDuplicateKind("duplicate");
|
|
4725
4944
|
setSimilarIssues(null);
|
|
4726
4945
|
setPickedSimilar(null);
|
|
4727
4946
|
setTimeout(() => {
|
|
@@ -4792,8 +5011,8 @@ function ReportDialog({
|
|
|
4792
5011
|
// dialog's state IS the report, and unmounting would drop the
|
|
4793
5012
|
// screenshots, attachments and step the reporter is on.
|
|
4794
5013
|
display: sheetUp ? "none" : "flex",
|
|
4795
|
-
alignItems: "center",
|
|
4796
|
-
justifyContent: "center",
|
|
5014
|
+
alignItems: sheet ? "stretch" : "center",
|
|
5015
|
+
justifyContent: sheet ? "flex-end" : "center",
|
|
4797
5016
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
4798
5017
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
4799
5018
|
},
|
|
@@ -4813,14 +5032,15 @@ function ReportDialog({
|
|
|
4813
5032
|
style: {
|
|
4814
5033
|
position: "relative",
|
|
4815
5034
|
zIndex: 2147483647,
|
|
4816
|
-
width: "420px",
|
|
4817
|
-
maxWidth: "calc(100% - 32px)",
|
|
4818
|
-
maxHeight: "calc(100dvh - 32px)",
|
|
5035
|
+
width: sheet ? "440px" : "420px",
|
|
5036
|
+
maxWidth: sheet ? "100%" : "calc(100% - 32px)",
|
|
5037
|
+
maxHeight: sheet ? "100dvh" : "calc(100dvh - 32px)",
|
|
5038
|
+
...sheet ? { height: "100dvh", borderLeft: `1px solid ${t2.inputBorder}` } : {},
|
|
4819
5039
|
display: "flex",
|
|
4820
5040
|
flexDirection: "column",
|
|
4821
5041
|
backgroundColor: t2.bg,
|
|
4822
|
-
borderRadius: "12px",
|
|
4823
|
-
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
5042
|
+
borderRadius: sheet ? 0 : "12px",
|
|
5043
|
+
boxShadow: sheet ? "0 20px 60px rgba(0, 0, 0, 0.35)" : "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
4824
5044
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
4825
5045
|
overflow: "hidden",
|
|
4826
5046
|
color: t2.text,
|
|
@@ -4854,7 +5074,7 @@ function ReportDialog({
|
|
|
4854
5074
|
gap: "8px"
|
|
4855
5075
|
},
|
|
4856
5076
|
children: [
|
|
4857
|
-
step > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
5077
|
+
step > 1 && availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4858
5078
|
"button",
|
|
4859
5079
|
{
|
|
4860
5080
|
type: "button",
|
|
@@ -4972,7 +5192,7 @@ function ReportDialog({
|
|
|
4972
5192
|
]
|
|
4973
5193
|
}
|
|
4974
5194
|
),
|
|
4975
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
5195
|
+
availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
4976
5196
|
"div",
|
|
4977
5197
|
{
|
|
4978
5198
|
style: {
|
|
@@ -5049,7 +5269,7 @@ function ReportDialog({
|
|
|
5049
5269
|
},
|
|
5050
5270
|
children: queuedMessage
|
|
5051
5271
|
}
|
|
5052
|
-
) : addedToIssue ? `Added to #${addedToIssue}. Thank you!` : `${getTypeLabel(reportType)} sent. Thank you!`
|
|
5272
|
+
) : addedToIssue ? `Added to #${addedToIssue}${addedAsRelated ? " as a related request" : ""}. Thank you!` : `${getTypeLabel(reportType)} sent. Thank you!`
|
|
5053
5273
|
}
|
|
5054
5274
|
) : /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
5055
5275
|
step === 1 && headerSlot ? /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
|
|
@@ -5248,6 +5468,7 @@ function ReportDialog({
|
|
|
5248
5468
|
"button",
|
|
5249
5469
|
{
|
|
5250
5470
|
type: "button",
|
|
5471
|
+
disabled: availableTypes.length === 1,
|
|
5251
5472
|
onClick: () => setStep(1),
|
|
5252
5473
|
style: {
|
|
5253
5474
|
display: "inline-flex",
|
|
@@ -5262,12 +5483,12 @@ function ReportDialog({
|
|
|
5262
5483
|
fontSize: "11px",
|
|
5263
5484
|
fontWeight: 600,
|
|
5264
5485
|
fontFamily: "inherit",
|
|
5265
|
-
cursor: "pointer"
|
|
5486
|
+
cursor: availableTypes.length === 1 ? "default" : "pointer"
|
|
5266
5487
|
},
|
|
5267
5488
|
children: [
|
|
5268
5489
|
getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
|
|
5269
5490
|
getTypeLabel(reportType),
|
|
5270
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5491
|
+
availableTypes.length > 1 && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5271
5492
|
]
|
|
5272
5493
|
}
|
|
5273
5494
|
),
|
|
@@ -6294,8 +6515,8 @@ function ReportDialog({
|
|
|
6294
6515
|
},
|
|
6295
6516
|
children: [
|
|
6296
6517
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsxs)("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
6297
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this" }),
|
|
6298
|
-
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches \u2014
|
|
6518
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
6519
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)("span", { style: { color: t2.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches. Same problem, or a different request for the same feature \u2014 it's added to that issue, so the team has it in one place." : "Same problem, or a different request for the same feature? Pick it \u2014 it's added to that issue, so the team has it in one place." })
|
|
6299
6520
|
] }),
|
|
6300
6521
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
6301
6522
|
"div",
|
|
@@ -6400,7 +6621,8 @@ function ReportDialog({
|
|
|
6400
6621
|
if (!pickedSimilar) return;
|
|
6401
6622
|
setAttachingTo(pickedSimilar);
|
|
6402
6623
|
setDuplicateIssueNumber(pickedSimilar);
|
|
6403
|
-
|
|
6624
|
+
setDuplicateKind("duplicate");
|
|
6625
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
6404
6626
|
},
|
|
6405
6627
|
style: {
|
|
6406
6628
|
width: "100%",
|
|
@@ -6415,7 +6637,7 @@ function ReportDialog({
|
|
|
6415
6637
|
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
6416
6638
|
fontFamily: "inherit"
|
|
6417
6639
|
},
|
|
6418
|
-
children: typeof attachingTo === "number" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
6640
|
+
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
6419
6641
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ButtonSpinner, {}),
|
|
6420
6642
|
"Adding to #",
|
|
6421
6643
|
attachingTo,
|
|
@@ -6423,6 +6645,39 @@ function ReportDialog({
|
|
|
6423
6645
|
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
6424
6646
|
}
|
|
6425
6647
|
),
|
|
6648
|
+
pickedSimilar && /* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
6649
|
+
"button",
|
|
6650
|
+
{
|
|
6651
|
+
type: "button",
|
|
6652
|
+
disabled: isSubmitting,
|
|
6653
|
+
onClick: () => {
|
|
6654
|
+
setAttachingTo(pickedSimilar);
|
|
6655
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
6656
|
+
setDuplicateKind("related");
|
|
6657
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
6658
|
+
},
|
|
6659
|
+
style: {
|
|
6660
|
+
width: "100%",
|
|
6661
|
+
minHeight: "40px",
|
|
6662
|
+
marginTop: "-4px",
|
|
6663
|
+
padding: "9px 10px",
|
|
6664
|
+
borderRadius: "8px",
|
|
6665
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
6666
|
+
backgroundColor: "transparent",
|
|
6667
|
+
color: isSubmitting ? t2.textMuted : t2.text,
|
|
6668
|
+
fontSize: "13px",
|
|
6669
|
+
fontWeight: 600,
|
|
6670
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6671
|
+
fontFamily: "inherit"
|
|
6672
|
+
},
|
|
6673
|
+
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ (0, import_jsx_runtime4.jsxs)(import_jsx_runtime4.Fragment, { children: [
|
|
6674
|
+
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(ButtonSpinner, {}),
|
|
6675
|
+
"Adding to #",
|
|
6676
|
+
attachingTo,
|
|
6677
|
+
"\u2026"
|
|
6678
|
+
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
6679
|
+
}
|
|
6680
|
+
),
|
|
6426
6681
|
/* @__PURE__ */ (0, import_jsx_runtime4.jsx)(
|
|
6427
6682
|
"button",
|
|
6428
6683
|
{
|
|
@@ -6769,7 +7024,10 @@ function ReportDialog({
|
|
|
6769
7024
|
setTypeChosen(true);
|
|
6770
7025
|
setStep(2);
|
|
6771
7026
|
},
|
|
6772
|
-
onDuplicateChange:
|
|
7027
|
+
onDuplicateChange: (issueNumber, kind) => {
|
|
7028
|
+
setDuplicateIssueNumber(issueNumber);
|
|
7029
|
+
setDuplicateKind(issueNumber && kind === "related" ? "related" : "duplicate");
|
|
7030
|
+
},
|
|
6773
7031
|
onConversationChange: setAiConversationId,
|
|
6774
7032
|
onFinish: handleClose,
|
|
6775
7033
|
rating,
|