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.mjs
CHANGED
|
@@ -14,6 +14,37 @@ import {
|
|
|
14
14
|
// src/error-boundary.tsx
|
|
15
15
|
import * as React from "react";
|
|
16
16
|
|
|
17
|
+
// ../report-ui/dist/assist-response.mjs
|
|
18
|
+
var ASSIST_OFFLINE_MESSAGE = "The assistant is unavailable \u2014 write your report below and send it as normal.";
|
|
19
|
+
function assistOffline() {
|
|
20
|
+
return { conversationId: null, question: null, report: null, degraded: ASSIST_OFFLINE_MESSAGE };
|
|
21
|
+
}
|
|
22
|
+
function toAssistTurnResult(ok, body) {
|
|
23
|
+
var _a, _b, _c, _d, _e, _f, _g, _h;
|
|
24
|
+
const envelope = body != null ? body : null;
|
|
25
|
+
if (!ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
26
|
+
return {
|
|
27
|
+
...assistOffline(),
|
|
28
|
+
// The server words why (cap, rate limit, switched off). An hourly limit
|
|
29
|
+
// keeps the assistant button for this report.
|
|
30
|
+
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : ASSIST_OFFLINE_MESSAGE,
|
|
31
|
+
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
32
|
+
};
|
|
33
|
+
}
|
|
34
|
+
const d = (_b = envelope.data) != null ? _b : {};
|
|
35
|
+
return {
|
|
36
|
+
conversationId: (_c = d.conversationId) != null ? _c : null,
|
|
37
|
+
question: (_d = d.question) != null ? _d : null,
|
|
38
|
+
options: Array.isArray(d.options) ? d.options.filter((o) => typeof o === "string") : [],
|
|
39
|
+
report: (_e = d.report) != null ? _e : null,
|
|
40
|
+
duplicate: (_f = d.duplicate) != null ? _f : null,
|
|
41
|
+
related: (_g = d.related) != null ? _g : null,
|
|
42
|
+
solved: (_h = d.solved) != null ? _h : null,
|
|
43
|
+
aboutGlitchgrab: d.aboutGlitchgrab === true,
|
|
44
|
+
degraded: null
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
17
48
|
// src/redact.ts
|
|
18
49
|
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;
|
|
19
50
|
var EMAIL_RE = /[\w.+-]+@[\w-]+\.[\w.-]+/g;
|
|
@@ -688,13 +719,7 @@ async function findSimilarIssues(description, token, baseUrl, identity) {
|
|
|
688
719
|
}
|
|
689
720
|
}
|
|
690
721
|
async function assistTurn(params, token, baseUrl) {
|
|
691
|
-
|
|
692
|
-
const offline = {
|
|
693
|
-
conversationId: null,
|
|
694
|
-
question: null,
|
|
695
|
-
report: null,
|
|
696
|
-
degraded: "The assistant is unavailable \u2014 write your report below and send it as normal."
|
|
697
|
-
};
|
|
722
|
+
const offline = assistOffline();
|
|
698
723
|
try {
|
|
699
724
|
const url = `${baseUrl != null ? baseUrl : DEFAULT_BASE_URL}/api/v1/ai/report-chat`;
|
|
700
725
|
const response = await fetch(url, {
|
|
@@ -705,27 +730,7 @@ async function assistTurn(params, token, baseUrl) {
|
|
|
705
730
|
},
|
|
706
731
|
body: JSON.stringify(params)
|
|
707
732
|
});
|
|
708
|
-
|
|
709
|
-
if (!response.ok || !(envelope == null ? void 0 : envelope.success)) {
|
|
710
|
-
return {
|
|
711
|
-
conversationId: null,
|
|
712
|
-
question: null,
|
|
713
|
-
report: null,
|
|
714
|
-
degraded: (_a = envelope == null ? void 0 : envelope.error) != null ? _a : offline.degraded,
|
|
715
|
-
// An hourly limit, not a cap: the dialog keeps the assistant button.
|
|
716
|
-
retryable: (envelope == null ? void 0 : envelope.retryable) === true
|
|
717
|
-
};
|
|
718
|
-
}
|
|
719
|
-
return {
|
|
720
|
-
conversationId: (_c = (_b = envelope.data) == null ? void 0 : _b.conversationId) != null ? _c : null,
|
|
721
|
-
question: (_e = (_d = envelope.data) == null ? void 0 : _d.question) != null ? _e : null,
|
|
722
|
-
options: (_g = (_f = envelope.data) == null ? void 0 : _f.options) != null ? _g : [],
|
|
723
|
-
report: (_i = (_h = envelope.data) == null ? void 0 : _h.report) != null ? _i : null,
|
|
724
|
-
duplicate: (_k = (_j = envelope.data) == null ? void 0 : _j.duplicate) != null ? _k : null,
|
|
725
|
-
solved: (_m = (_l = envelope.data) == null ? void 0 : _l.solved) != null ? _m : null,
|
|
726
|
-
aboutGlitchgrab: ((_n = envelope.data) == null ? void 0 : _n.aboutGlitchgrab) === true,
|
|
727
|
-
degraded: null
|
|
728
|
-
};
|
|
733
|
+
return toAssistTurnResult(response.ok, await response.json().catch(() => null));
|
|
729
734
|
} catch (e) {
|
|
730
735
|
return offline;
|
|
731
736
|
}
|
|
@@ -1420,6 +1425,17 @@ var STARTERS = [
|
|
|
1420
1425
|
"It did the wrong thing",
|
|
1421
1426
|
"I wish it could\u2026"
|
|
1422
1427
|
];
|
|
1428
|
+
var CONFIRM_OPTION = "Yes, that's it";
|
|
1429
|
+
function isCheckBackQuestion(text) {
|
|
1430
|
+
const t2 = text.trim();
|
|
1431
|
+
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);
|
|
1432
|
+
}
|
|
1433
|
+
function isAffirmativeReply(text) {
|
|
1434
|
+
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(
|
|
1435
|
+
text.trim()
|
|
1436
|
+
);
|
|
1437
|
+
}
|
|
1438
|
+
var AUTO_FILE_SECONDS = 4;
|
|
1423
1439
|
var NARROW_QUERY = "(max-width: 640px)";
|
|
1424
1440
|
function useIsNarrow() {
|
|
1425
1441
|
const [narrow, setNarrow] = useState2(false);
|
|
@@ -1534,12 +1550,15 @@ function AssistSheet({
|
|
|
1534
1550
|
const [duplicate, setDuplicate] = useState2(null);
|
|
1535
1551
|
const [glitchgrabOffer, setGlitchgrabOffer] = useState2(false);
|
|
1536
1552
|
const [solved, setSolved] = useState2(null);
|
|
1553
|
+
const needsSeverity = (tile) => showSeverity && tile === "BUG" && !severity;
|
|
1537
1554
|
const [phase, setPhase] = useState2(
|
|
1538
|
-
!typePicked ? "type" : currentTile === "RATING" ? "rating" : "chat"
|
|
1555
|
+
() => !typePicked ? "type" : currentTile === "RATING" ? "rating" : needsSeverity(currentTile) ? "severity" : "chat"
|
|
1539
1556
|
);
|
|
1557
|
+
const [autoFileLeft, setAutoFileLeft] = useState2(null);
|
|
1540
1558
|
const scrollRef = useRef2(null);
|
|
1541
1559
|
const draftRef = useRef2(null);
|
|
1542
1560
|
const seededRef = useRef2(false);
|
|
1561
|
+
const seedPendingRef = useRef2(false);
|
|
1543
1562
|
const eventsRef = useRef2([]);
|
|
1544
1563
|
const aiDraftRef = useRef2(null);
|
|
1545
1564
|
function logEvent(type, detail) {
|
|
@@ -1579,14 +1598,33 @@ function AssistSheet({
|
|
|
1579
1598
|
var _a;
|
|
1580
1599
|
if (phase === "draft") (_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
1581
1600
|
}, [phase]);
|
|
1601
|
+
useEffect2(() => {
|
|
1602
|
+
if (autoFileLeft === null) return;
|
|
1603
|
+
if (isSubmitting || submitted || phase !== "draft") {
|
|
1604
|
+
setAutoFileLeft(null);
|
|
1605
|
+
return;
|
|
1606
|
+
}
|
|
1607
|
+
if (autoFileLeft <= 0) {
|
|
1608
|
+
sendDraft(true);
|
|
1609
|
+
return;
|
|
1610
|
+
}
|
|
1611
|
+
const id = setTimeout(() => setAutoFileLeft((n) => n === null ? null : n - 1), 1e3);
|
|
1612
|
+
return () => clearTimeout(id);
|
|
1613
|
+
}, [autoFileLeft, isSubmitting, submitted, phase]);
|
|
1614
|
+
function stopAutoFile(reason) {
|
|
1615
|
+
if (autoFileLeft === null) return;
|
|
1616
|
+
setAutoFileLeft(null);
|
|
1617
|
+
logEvent("auto_file_stopped", reason);
|
|
1618
|
+
}
|
|
1582
1619
|
function degradeKeepingEvents(events, message, retryable) {
|
|
1583
1620
|
if (events) eventsRef.current = [...events, ...eventsRef.current];
|
|
1584
1621
|
flushEvents();
|
|
1585
1622
|
onDegrade(message, retryable);
|
|
1586
1623
|
}
|
|
1587
|
-
async function runTurn(history2) {
|
|
1588
|
-
var _a, _b
|
|
1624
|
+
async function runTurn(history2, autoFile = false) {
|
|
1625
|
+
var _a, _b;
|
|
1589
1626
|
setBusy(true);
|
|
1627
|
+
setAutoFileLeft(null);
|
|
1590
1628
|
let result;
|
|
1591
1629
|
const events = takeEvents();
|
|
1592
1630
|
try {
|
|
@@ -1629,8 +1667,9 @@ function AssistSheet({
|
|
|
1629
1667
|
setConversationId(result.conversationId);
|
|
1630
1668
|
onConversationChange == null ? void 0 : onConversationChange(result.conversationId);
|
|
1631
1669
|
}
|
|
1632
|
-
|
|
1633
|
-
|
|
1670
|
+
const attach = result.duplicate ? { ...result.duplicate, kind: "duplicate" } : result.related ? { ...result.related, kind: "related" } : null;
|
|
1671
|
+
setDuplicate(attach);
|
|
1672
|
+
onDuplicateChange == null ? void 0 : onDuplicateChange((_a = attach == null ? void 0 : attach.number) != null ? _a : null, attach == null ? void 0 : attach.kind);
|
|
1634
1673
|
setGlitchgrabOffer(!!result.aboutGlitchgrab && !!onReportGlitchgrabProblem && !!result.question);
|
|
1635
1674
|
if (result.solved) {
|
|
1636
1675
|
setSolved(result.solved);
|
|
@@ -1645,11 +1684,14 @@ function AssistSheet({
|
|
|
1645
1684
|
setMessages([...history2, { role: "assistant", content: result.report, kind: "report" }]);
|
|
1646
1685
|
setOptions([]);
|
|
1647
1686
|
setPhase("draft");
|
|
1687
|
+
if (autoFile && !attach && !(severityAsked && !severity)) {
|
|
1688
|
+
setAutoFileLeft(AUTO_FILE_SECONDS);
|
|
1689
|
+
}
|
|
1648
1690
|
return;
|
|
1649
1691
|
}
|
|
1650
1692
|
if (result.question) {
|
|
1651
1693
|
setMessages([...history2, { role: "assistant", content: result.question }]);
|
|
1652
|
-
setOptions((
|
|
1694
|
+
setOptions((_b = result.options) != null ? _b : []);
|
|
1653
1695
|
return;
|
|
1654
1696
|
}
|
|
1655
1697
|
onDegrade("The assistant had nothing to add \u2014 write your report below and send it as normal.");
|
|
@@ -1658,13 +1700,34 @@ function AssistSheet({
|
|
|
1658
1700
|
if (seededRef.current) return;
|
|
1659
1701
|
seededRef.current = true;
|
|
1660
1702
|
if (!typePicked || currentTile === "RATING") return;
|
|
1703
|
+
if (phase === "severity") {
|
|
1704
|
+
seedPendingRef.current = true;
|
|
1705
|
+
return;
|
|
1706
|
+
}
|
|
1707
|
+
seedFromDescription();
|
|
1708
|
+
}, []);
|
|
1709
|
+
function seedFromDescription() {
|
|
1661
1710
|
const seed = description.trim();
|
|
1662
1711
|
if (!seed) return;
|
|
1663
1712
|
const history2 = [{ role: "user", content: seed }];
|
|
1664
1713
|
setMessages(history2);
|
|
1665
1714
|
void runTurn(history2);
|
|
1666
|
-
}
|
|
1667
|
-
function
|
|
1715
|
+
}
|
|
1716
|
+
function answerSeverity(value) {
|
|
1717
|
+
onSeverityChange(value);
|
|
1718
|
+
setPhase("chat");
|
|
1719
|
+
if (seedPendingRef.current) {
|
|
1720
|
+
seedPendingRef.current = false;
|
|
1721
|
+
seedFromDescription();
|
|
1722
|
+
}
|
|
1723
|
+
}
|
|
1724
|
+
function sendTyped(text) {
|
|
1725
|
+
var _a;
|
|
1726
|
+
const lastAssistant = [...messages].reverse().find((m) => m.role === "assistant");
|
|
1727
|
+
const checkingBack = options.includes(CONFIRM_OPTION) || (lastAssistant == null ? void 0 : lastAssistant.kind) !== "report" && isCheckBackQuestion((_a = lastAssistant == null ? void 0 : lastAssistant.content) != null ? _a : "");
|
|
1728
|
+
send(text, checkingBack && isAffirmativeReply(text));
|
|
1729
|
+
}
|
|
1730
|
+
function send(text, autoFile = false) {
|
|
1668
1731
|
const value = text.trim();
|
|
1669
1732
|
if (!value || busy) return;
|
|
1670
1733
|
setOptions([]);
|
|
@@ -1679,11 +1742,11 @@ function AssistSheet({
|
|
|
1679
1742
|
const history2 = [...base, { role: "user", content: value }];
|
|
1680
1743
|
setMessages(history2);
|
|
1681
1744
|
setInput("");
|
|
1682
|
-
void runTurn(history2);
|
|
1745
|
+
void runTurn(history2, autoFile);
|
|
1683
1746
|
}
|
|
1684
1747
|
function pickType(tile) {
|
|
1685
1748
|
onPickType(tile);
|
|
1686
|
-
setPhase(tile === "RATING" ? "rating" : "chat");
|
|
1749
|
+
setPhase(tile === "RATING" ? "rating" : needsSeverity(tile) ? "severity" : "chat");
|
|
1687
1750
|
}
|
|
1688
1751
|
function withCurrentDraft(history2) {
|
|
1689
1752
|
const current = description.trim();
|
|
@@ -1696,9 +1759,10 @@ function AssistSheet({
|
|
|
1696
1759
|
}
|
|
1697
1760
|
return next;
|
|
1698
1761
|
}
|
|
1699
|
-
function sendDraft() {
|
|
1762
|
+
function sendDraft(auto = false) {
|
|
1763
|
+
setAutoFileLeft(null);
|
|
1700
1764
|
const edited = aiDraftRef.current !== null && description.trim() !== aiDraftRef.current.trim();
|
|
1701
|
-
logEvent("draft_sent", edited ? "edited" : "as drafted");
|
|
1765
|
+
logEvent("draft_sent", auto ? "auto-filed" : edited ? "edited" : "as drafted");
|
|
1702
1766
|
flushEvents();
|
|
1703
1767
|
onSend();
|
|
1704
1768
|
}
|
|
@@ -1722,15 +1786,15 @@ function AssistSheet({
|
|
|
1722
1786
|
minWidth: 0
|
|
1723
1787
|
},
|
|
1724
1788
|
children: [
|
|
1725
|
-
/* @__PURE__ */ jsx2("span", { style: { color: t2.text, fontWeight: 600 }, children: title ? "Our team is already on this" : `Our team is already on #${duplicate.number}` }),
|
|
1789
|
+
/* @__PURE__ */ jsx2("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}` }),
|
|
1726
1790
|
title && /* @__PURE__ */ jsxs2("span", { style: { color: t2.textMuted, wordBreak: "break-word" }, children: [
|
|
1727
1791
|
"#",
|
|
1728
1792
|
duplicate.number,
|
|
1729
1793
|
" ",
|
|
1730
1794
|
duplicate.title
|
|
1731
1795
|
] }),
|
|
1732
|
-
duplicate.status && /* @__PURE__ */ jsx2("span", { style: { color: t2.text, fontWeight: 600 }, children: duplicate.status }),
|
|
1733
|
-
footer && /* @__PURE__ */ jsx2("span", { style: { color: t2.textMuted }, children: footer })
|
|
1796
|
+
duplicate.status && duplicate.kind !== "related" && /* @__PURE__ */ jsx2("span", { style: { color: t2.text, fontWeight: 600 }, children: duplicate.status }),
|
|
1797
|
+
footer && /* @__PURE__ */ jsx2("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 })
|
|
1734
1798
|
]
|
|
1735
1799
|
}
|
|
1736
1800
|
);
|
|
@@ -1758,6 +1822,7 @@ function AssistSheet({
|
|
|
1758
1822
|
@keyframes gg-sheet-in{from{transform:translateX(24px);opacity:0}to{transform:translateX(0);opacity:1}}
|
|
1759
1823
|
@keyframes gg-sheet-up{from{transform:translateY(24px);opacity:0}to{transform:translateY(0);opacity:1}}
|
|
1760
1824
|
@keyframes gg-sheet-fade{from{opacity:0}to{opacity:1}}
|
|
1825
|
+
@keyframes gg-autofile{from{transform:scaleX(0)}to{transform:scaleX(1)}}
|
|
1761
1826
|
@keyframes gg-dot{0%,80%,100%{transform:translateY(0);opacity:.4}40%{transform:translateY(-3px);opacity:1}}
|
|
1762
1827
|
[data-gg-sheet-send]:focus-visible,[data-gg-chip]:focus-visible,[data-gg-assist-remove]:focus-visible{outline:2px solid currentColor;outline-offset:2px}
|
|
1763
1828
|
` }),
|
|
@@ -1852,6 +1917,7 @@ function AssistSheet({
|
|
|
1852
1917
|
),
|
|
1853
1918
|
/* @__PURE__ */ jsxs2("div", { style: { fontSize: "11.5px", color: t2.textMuted, marginTop: "3px" }, children: [
|
|
1854
1919
|
phase === "type" ? null : reportTypeLabel,
|
|
1920
|
+
phase !== "type" && severityAsked && severity ? ` \xB7 ${SEVERITY_LABELS[severity]}` : null,
|
|
1855
1921
|
projectSlot ? /* @__PURE__ */ jsx2("span", { style: { marginLeft: "6px" }, children: projectSlot }) : null
|
|
1856
1922
|
] })
|
|
1857
1923
|
] }),
|
|
@@ -1970,6 +2036,62 @@ function AssistSheet({
|
|
|
1970
2036
|
}
|
|
1971
2037
|
)
|
|
1972
2038
|
] }),
|
|
2039
|
+
phase === "severity" && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
2040
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
2041
|
+
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
2042
|
+
/* @__PURE__ */ jsx2(
|
|
2043
|
+
"div",
|
|
2044
|
+
{
|
|
2045
|
+
style: {
|
|
2046
|
+
padding: "9px 12px",
|
|
2047
|
+
borderRadius: "12px 12px 12px 4px",
|
|
2048
|
+
backgroundColor: t2.bgSecondary,
|
|
2049
|
+
fontSize: "13px",
|
|
2050
|
+
lineHeight: 1.55,
|
|
2051
|
+
maxWidth: "88%"
|
|
2052
|
+
},
|
|
2053
|
+
children: "How bad is it?"
|
|
2054
|
+
}
|
|
2055
|
+
)
|
|
2056
|
+
] }),
|
|
2057
|
+
/* @__PURE__ */ jsx2(
|
|
2058
|
+
"div",
|
|
2059
|
+
{
|
|
2060
|
+
role: "radiogroup",
|
|
2061
|
+
"aria-label": "Severity",
|
|
2062
|
+
style: {
|
|
2063
|
+
display: "flex",
|
|
2064
|
+
flexWrap: "wrap",
|
|
2065
|
+
gap: "6px",
|
|
2066
|
+
paddingLeft: "32px"
|
|
2067
|
+
},
|
|
2068
|
+
children: SEVERITY_LEVELS.map((s) => /* @__PURE__ */ jsx2(
|
|
2069
|
+
"button",
|
|
2070
|
+
{
|
|
2071
|
+
type: "button",
|
|
2072
|
+
role: "radio",
|
|
2073
|
+
"aria-checked": severity === s,
|
|
2074
|
+
"data-gg-chip": "",
|
|
2075
|
+
"data-gg-severity": s,
|
|
2076
|
+
onClick: () => answerSeverity(s),
|
|
2077
|
+
style: {
|
|
2078
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
2079
|
+
background: "transparent",
|
|
2080
|
+
color: t2.textMuted,
|
|
2081
|
+
borderRadius: "999px",
|
|
2082
|
+
// Same as the picker and option chips — one chip size.
|
|
2083
|
+
padding: "8px 12px",
|
|
2084
|
+
fontSize: "12px",
|
|
2085
|
+
fontFamily: "inherit",
|
|
2086
|
+
cursor: "pointer"
|
|
2087
|
+
},
|
|
2088
|
+
children: SEVERITY_LABELS[s]
|
|
2089
|
+
},
|
|
2090
|
+
s
|
|
2091
|
+
))
|
|
2092
|
+
}
|
|
2093
|
+
)
|
|
2094
|
+
] }),
|
|
1973
2095
|
phase === "rating" && !submitted && /* @__PURE__ */ jsxs2("div", { style: { display: "flex", flexDirection: "column", gap: "12px" }, children: [
|
|
1974
2096
|
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px" }, children: [
|
|
1975
2097
|
/* @__PURE__ */ jsx2(Avatar, { who: "assistant", theme: t2 }),
|
|
@@ -2158,7 +2280,11 @@ function AssistSheet({
|
|
|
2158
2280
|
color: t2.text,
|
|
2159
2281
|
border: live ? "none" : `1px solid ${t2.accent}66`
|
|
2160
2282
|
},
|
|
2161
|
-
children: live ?
|
|
2283
|
+
children: live ? (
|
|
2284
|
+
// #402: "have a read" beside a countdown reads as a
|
|
2285
|
+
// contradiction. Say what is about to happen instead.
|
|
2286
|
+
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."
|
|
2287
|
+
) : /* @__PURE__ */ jsxs2(Fragment, { children: [
|
|
2162
2288
|
/* @__PURE__ */ jsx2(
|
|
2163
2289
|
"span",
|
|
2164
2290
|
{
|
|
@@ -2325,7 +2451,7 @@ function AssistSheet({
|
|
|
2325
2451
|
"data-gg-option": "",
|
|
2326
2452
|
onClick: () => {
|
|
2327
2453
|
logEvent("option_tap", option);
|
|
2328
|
-
send(option);
|
|
2454
|
+
send(option, option === CONFIRM_OPTION);
|
|
2329
2455
|
},
|
|
2330
2456
|
style: {
|
|
2331
2457
|
border: `1px solid ${t2.inputBorder}`,
|
|
@@ -2400,7 +2526,7 @@ function AssistSheet({
|
|
|
2400
2526
|
textTransform: "uppercase",
|
|
2401
2527
|
color: t2.accent
|
|
2402
2528
|
},
|
|
2403
|
-
children: duplicate ? `What we'll add to #${duplicate.number} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
2529
|
+
children: duplicate ? `What we'll add to #${duplicate.number}${duplicate.kind === "related" ? " as a related request" : ""} \xB7 edit anything` : "Your report \xB7 edit anything"
|
|
2404
2530
|
}
|
|
2405
2531
|
),
|
|
2406
2532
|
renderKnownIssue({
|
|
@@ -2412,7 +2538,10 @@ function AssistSheet({
|
|
|
2412
2538
|
{
|
|
2413
2539
|
ref: draftRef,
|
|
2414
2540
|
value: description,
|
|
2415
|
-
onChange: (e) =>
|
|
2541
|
+
onChange: (e) => {
|
|
2542
|
+
stopAutoFile("edited the draft");
|
|
2543
|
+
onDescriptionChange(e.target.value);
|
|
2544
|
+
},
|
|
2416
2545
|
rows: 6,
|
|
2417
2546
|
style: {
|
|
2418
2547
|
width: "100%",
|
|
@@ -2431,7 +2560,7 @@ function AssistSheet({
|
|
|
2431
2560
|
}
|
|
2432
2561
|
}
|
|
2433
2562
|
),
|
|
2434
|
-
severityAsked && /* @__PURE__ */ jsxs2("div", { children: [
|
|
2563
|
+
severityAsked && autoFileLeft === null && /* @__PURE__ */ jsxs2("div", { children: [
|
|
2435
2564
|
/* @__PURE__ */ jsxs2(
|
|
2436
2565
|
"span",
|
|
2437
2566
|
{
|
|
@@ -2553,7 +2682,7 @@ function AssistSheet({
|
|
|
2553
2682
|
)
|
|
2554
2683
|
}
|
|
2555
2684
|
),
|
|
2556
|
-
!submitted && phase !== "type" && /* @__PURE__ */ jsxs2(
|
|
2685
|
+
!submitted && phase !== "type" && phase !== "severity" && /* @__PURE__ */ jsxs2(
|
|
2557
2686
|
"div",
|
|
2558
2687
|
{
|
|
2559
2688
|
style: {
|
|
@@ -2660,6 +2789,7 @@ function AssistSheet({
|
|
|
2660
2789
|
"aria-label": `Remove image ${i + 1}`,
|
|
2661
2790
|
title: "Remove this image",
|
|
2662
2791
|
onClick: () => {
|
|
2792
|
+
stopAutoFile("changed attachments");
|
|
2663
2793
|
logEvent(
|
|
2664
2794
|
"image_removed",
|
|
2665
2795
|
pageShot && shot === pageShot ? "page capture" : "attached"
|
|
@@ -2770,6 +2900,7 @@ function AssistSheet({
|
|
|
2770
2900
|
"aria-label": `Remove file ${file.name}`,
|
|
2771
2901
|
title: "Remove this file",
|
|
2772
2902
|
onClick: () => {
|
|
2903
|
+
stopAutoFile("changed attachments");
|
|
2773
2904
|
logEvent("file_removed", read ? "read" : "not read");
|
|
2774
2905
|
onRemoveFile(i);
|
|
2775
2906
|
},
|
|
@@ -2852,6 +2983,7 @@ function AssistSheet({
|
|
|
2852
2983
|
var _a;
|
|
2853
2984
|
const picked = Array.from((_a = e.target.files) != null ? _a : []);
|
|
2854
2985
|
if (picked.length) {
|
|
2986
|
+
stopAutoFile("changed attachments");
|
|
2855
2987
|
const images = picked.filter((f) => f.type.startsWith("image/")).length;
|
|
2856
2988
|
if (images) logEvent("image_added", String(images));
|
|
2857
2989
|
if (picked.length > images) {
|
|
@@ -2881,11 +3013,14 @@ function AssistSheet({
|
|
|
2881
3013
|
"textarea",
|
|
2882
3014
|
{
|
|
2883
3015
|
value: input,
|
|
2884
|
-
onChange: (e) =>
|
|
3016
|
+
onChange: (e) => {
|
|
3017
|
+
stopAutoFile("typing a change");
|
|
3018
|
+
setInput(e.target.value);
|
|
3019
|
+
},
|
|
2885
3020
|
onKeyDown: (e) => {
|
|
2886
3021
|
if (e.key === "Enter" && !e.shiftKey) {
|
|
2887
3022
|
e.preventDefault();
|
|
2888
|
-
|
|
3023
|
+
sendTyped(input);
|
|
2889
3024
|
}
|
|
2890
3025
|
},
|
|
2891
3026
|
placeholder: phase === "draft" ? "Anything to change? Tell me here\u2026" : "Type your answer\u2026",
|
|
@@ -2915,7 +3050,7 @@ function AssistSheet({
|
|
|
2915
3050
|
{
|
|
2916
3051
|
type: "button",
|
|
2917
3052
|
"data-gg-sheet-send": "",
|
|
2918
|
-
onClick: () =>
|
|
3053
|
+
onClick: () => sendTyped(input),
|
|
2919
3054
|
disabled: busy || !input.trim(),
|
|
2920
3055
|
"aria-label": "Send message",
|
|
2921
3056
|
"data-gg-send-message": "",
|
|
@@ -2954,12 +3089,87 @@ function AssistSheet({
|
|
|
2954
3089
|
children: validationError
|
|
2955
3090
|
}
|
|
2956
3091
|
),
|
|
2957
|
-
|
|
3092
|
+
autoFileLeft !== null ? (
|
|
3093
|
+
// #402: "Yes, that's it" was the confirmation. The draft
|
|
3094
|
+
// files itself unless they stop it — the bar shows how
|
|
3095
|
+
// long is left, the button sends now.
|
|
3096
|
+
/* @__PURE__ */ jsxs2("div", { style: { display: "flex", gap: "8px", marginTop: "8px" }, children: [
|
|
3097
|
+
/* @__PURE__ */ jsxs2(
|
|
3098
|
+
"button",
|
|
3099
|
+
{
|
|
3100
|
+
type: "button",
|
|
3101
|
+
"data-gg-sheet-send": "",
|
|
3102
|
+
"data-gg-auto-file": "",
|
|
3103
|
+
onClick: () => sendDraft(),
|
|
3104
|
+
style: {
|
|
3105
|
+
flex: 1,
|
|
3106
|
+
minWidth: 0,
|
|
3107
|
+
position: "relative",
|
|
3108
|
+
overflow: "hidden",
|
|
3109
|
+
padding: "12px",
|
|
3110
|
+
borderRadius: "10px",
|
|
3111
|
+
border: "none",
|
|
3112
|
+
backgroundColor: t2.accent,
|
|
3113
|
+
color: t2.accentText,
|
|
3114
|
+
fontSize: "14px",
|
|
3115
|
+
fontWeight: 700,
|
|
3116
|
+
fontFamily: "inherit",
|
|
3117
|
+
cursor: "pointer"
|
|
3118
|
+
},
|
|
3119
|
+
children: [
|
|
3120
|
+
/* @__PURE__ */ jsx2(
|
|
3121
|
+
"span",
|
|
3122
|
+
{
|
|
3123
|
+
"aria-hidden": "true",
|
|
3124
|
+
style: {
|
|
3125
|
+
position: "absolute",
|
|
3126
|
+
inset: 0,
|
|
3127
|
+
backgroundColor: "rgba(255,255,255,0.22)",
|
|
3128
|
+
transformOrigin: "left",
|
|
3129
|
+
animation: `gg-autofile ${AUTO_FILE_SECONDS}s linear forwards`
|
|
3130
|
+
}
|
|
3131
|
+
}
|
|
3132
|
+
),
|
|
3133
|
+
/* @__PURE__ */ jsxs2("span", { style: { position: "relative" }, children: [
|
|
3134
|
+
"Filing in ",
|
|
3135
|
+
autoFileLeft,
|
|
3136
|
+
"s\u2026"
|
|
3137
|
+
] })
|
|
3138
|
+
]
|
|
3139
|
+
}
|
|
3140
|
+
),
|
|
3141
|
+
/* @__PURE__ */ jsx2(
|
|
3142
|
+
"button",
|
|
3143
|
+
{
|
|
3144
|
+
type: "button",
|
|
3145
|
+
"data-gg-edit-first": "",
|
|
3146
|
+
onClick: () => {
|
|
3147
|
+
var _a;
|
|
3148
|
+
stopAutoFile("edit first");
|
|
3149
|
+
(_a = draftRef.current) == null ? void 0 : _a.focus();
|
|
3150
|
+
},
|
|
3151
|
+
style: {
|
|
3152
|
+
flexShrink: 0,
|
|
3153
|
+
padding: "12px 14px",
|
|
3154
|
+
borderRadius: "10px",
|
|
3155
|
+
border: `1px solid ${t2.inputBorder}`,
|
|
3156
|
+
background: "transparent",
|
|
3157
|
+
color: t2.text,
|
|
3158
|
+
fontSize: "13px",
|
|
3159
|
+
fontWeight: 600,
|
|
3160
|
+
fontFamily: "inherit",
|
|
3161
|
+
cursor: "pointer"
|
|
3162
|
+
},
|
|
3163
|
+
children: "Edit first"
|
|
3164
|
+
}
|
|
3165
|
+
)
|
|
3166
|
+
] })
|
|
3167
|
+
) : /* @__PURE__ */ jsx2(
|
|
2958
3168
|
"button",
|
|
2959
3169
|
{
|
|
2960
3170
|
type: "button",
|
|
2961
3171
|
"data-gg-sheet-send": "",
|
|
2962
|
-
onClick: sendDraft,
|
|
3172
|
+
onClick: () => sendDraft(),
|
|
2963
3173
|
disabled: isSubmitting || !description.trim(),
|
|
2964
3174
|
style: {
|
|
2965
3175
|
width: "100%",
|
|
@@ -3935,9 +4145,11 @@ function ReportDialog({
|
|
|
3935
4145
|
reporter,
|
|
3936
4146
|
onClose,
|
|
3937
4147
|
headerSlot,
|
|
3938
|
-
reportGlitchgrabProblem
|
|
4148
|
+
reportGlitchgrabProblem,
|
|
4149
|
+
layout = "modal"
|
|
3939
4150
|
}) {
|
|
3940
4151
|
var _a;
|
|
4152
|
+
const sheet = layout === "sheet";
|
|
3941
4153
|
const [isEnhancing, setIsEnhancing] = useState4(false);
|
|
3942
4154
|
const [assistOpen, setAssistOpen] = useState4(false);
|
|
3943
4155
|
const [assistNotice, setAssistNotice] = useState4(null);
|
|
@@ -3946,6 +4158,8 @@ function ReportDialog({
|
|
|
3946
4158
|
const [selfReportPrefill, setSelfReportPrefill] = useState4("");
|
|
3947
4159
|
const [typeChosen, setTypeChosen] = useState4(false);
|
|
3948
4160
|
const [duplicateIssueNumber, setDuplicateIssueNumber] = useState4(null);
|
|
4161
|
+
const [duplicateKind, setDuplicateKind] = useState4("duplicate");
|
|
4162
|
+
const [addedAsRelated, setAddedAsRelated] = useState4(false);
|
|
3949
4163
|
const [similarIssues, setSimilarIssues] = useState4(null);
|
|
3950
4164
|
const [checkingSimilar, setCheckingSimilar] = useState4(false);
|
|
3951
4165
|
const [attachingTo, setAttachingTo] = useState4(null);
|
|
@@ -4382,6 +4596,7 @@ function ReportDialog({
|
|
|
4382
4596
|
setReportType("BUG");
|
|
4383
4597
|
setTypeChosen(false);
|
|
4384
4598
|
setDuplicateIssueNumber(null);
|
|
4599
|
+
setDuplicateKind("duplicate");
|
|
4385
4600
|
setSimilarIssues(null);
|
|
4386
4601
|
setPickedSimilar(null);
|
|
4387
4602
|
setCheckingSimilar(false);
|
|
@@ -4574,7 +4789,7 @@ function ReportDialog({
|
|
|
4574
4789
|
}
|
|
4575
4790
|
};
|
|
4576
4791
|
const handleSubmit = async (opts) => {
|
|
4577
|
-
var _a2, _b;
|
|
4792
|
+
var _a2, _b, _c;
|
|
4578
4793
|
try {
|
|
4579
4794
|
if (isSubmitting) return;
|
|
4580
4795
|
if (isRating) {
|
|
@@ -4612,6 +4827,7 @@ function ReportDialog({
|
|
|
4612
4827
|
return;
|
|
4613
4828
|
}
|
|
4614
4829
|
const duplicateOf = (_a2 = opts == null ? void 0 : opts.duplicateOf) != null ? _a2 : duplicateIssueNumber;
|
|
4830
|
+
const attachKind = (opts == null ? void 0 : opts.duplicateOf) ? (_b = opts.kind) != null ? _b : "duplicate" : duplicateKind;
|
|
4615
4831
|
if (findSimilarIssues2 && !(opts == null ? void 0 : opts.skipSimilar) && !duplicateOf && !aiConversationId) {
|
|
4616
4832
|
setIsSubmitting(true);
|
|
4617
4833
|
setCheckingSimilar(true);
|
|
@@ -4647,6 +4863,7 @@ function ReportDialog({
|
|
|
4647
4863
|
}
|
|
4648
4864
|
if (duplicateOf) {
|
|
4649
4865
|
metadata.duplicateIssueNumber = String(duplicateOf);
|
|
4866
|
+
if (attachKind === "related") metadata.duplicateKind = "related";
|
|
4650
4867
|
}
|
|
4651
4868
|
if (aiConversationId) {
|
|
4652
4869
|
metadata.aiConversationId = aiConversationId;
|
|
@@ -4660,14 +4877,16 @@ function ReportDialog({
|
|
|
4660
4877
|
);
|
|
4661
4878
|
if (result) {
|
|
4662
4879
|
setAddedToIssue(duplicateOf && result.issueNumber === duplicateOf ? duplicateOf : null);
|
|
4880
|
+
setAddedAsRelated(!!duplicateOf && result.issueNumber === duplicateOf && attachKind === "related");
|
|
4663
4881
|
const queued = result.status === "QUEUED" && !!result.message;
|
|
4664
|
-
setQueuedMessage(queued ? (
|
|
4882
|
+
setQueuedMessage(queued ? (_c = result.message) != null ? _c : null : null);
|
|
4665
4883
|
setSubmitted(true);
|
|
4666
4884
|
setDescription("");
|
|
4667
4885
|
setScreenshots([]);
|
|
4668
4886
|
setAttachments([]);
|
|
4669
4887
|
setAiConversationId(null);
|
|
4670
4888
|
setDuplicateIssueNumber(null);
|
|
4889
|
+
setDuplicateKind("duplicate");
|
|
4671
4890
|
setSimilarIssues(null);
|
|
4672
4891
|
setPickedSimilar(null);
|
|
4673
4892
|
setTimeout(() => {
|
|
@@ -4738,8 +4957,8 @@ function ReportDialog({
|
|
|
4738
4957
|
// dialog's state IS the report, and unmounting would drop the
|
|
4739
4958
|
// screenshots, attachments and step the reporter is on.
|
|
4740
4959
|
display: sheetUp ? "none" : "flex",
|
|
4741
|
-
alignItems: "center",
|
|
4742
|
-
justifyContent: "center",
|
|
4960
|
+
alignItems: sheet ? "stretch" : "center",
|
|
4961
|
+
justifyContent: sheet ? "flex-end" : "center",
|
|
4743
4962
|
backgroundColor: "rgba(0,0,0,0.5)",
|
|
4744
4963
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif'
|
|
4745
4964
|
},
|
|
@@ -4759,14 +4978,15 @@ function ReportDialog({
|
|
|
4759
4978
|
style: {
|
|
4760
4979
|
position: "relative",
|
|
4761
4980
|
zIndex: 2147483647,
|
|
4762
|
-
width: "420px",
|
|
4763
|
-
maxWidth: "calc(100% - 32px)",
|
|
4764
|
-
maxHeight: "calc(100dvh - 32px)",
|
|
4981
|
+
width: sheet ? "440px" : "420px",
|
|
4982
|
+
maxWidth: sheet ? "100%" : "calc(100% - 32px)",
|
|
4983
|
+
maxHeight: sheet ? "100dvh" : "calc(100dvh - 32px)",
|
|
4984
|
+
...sheet ? { height: "100dvh", borderLeft: `1px solid ${t2.inputBorder}` } : {},
|
|
4765
4985
|
display: "flex",
|
|
4766
4986
|
flexDirection: "column",
|
|
4767
4987
|
backgroundColor: t2.bg,
|
|
4768
|
-
borderRadius: "12px",
|
|
4769
|
-
boxShadow: "0 20px 60px rgba(0, 0, 0, 0.2), 0 4px 16px rgba(0, 0, 0, 0.1)",
|
|
4988
|
+
borderRadius: sheet ? 0 : "12px",
|
|
4989
|
+
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)",
|
|
4770
4990
|
fontFamily: '-apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
|
4771
4991
|
overflow: "hidden",
|
|
4772
4992
|
color: t2.text,
|
|
@@ -4800,7 +5020,7 @@ function ReportDialog({
|
|
|
4800
5020
|
gap: "8px"
|
|
4801
5021
|
},
|
|
4802
5022
|
children: [
|
|
4803
|
-
step > 1 && /* @__PURE__ */ jsx4(
|
|
5023
|
+
step > 1 && availableTypes.length > 1 && /* @__PURE__ */ jsx4(
|
|
4804
5024
|
"button",
|
|
4805
5025
|
{
|
|
4806
5026
|
type: "button",
|
|
@@ -4918,7 +5138,7 @@ function ReportDialog({
|
|
|
4918
5138
|
]
|
|
4919
5139
|
}
|
|
4920
5140
|
),
|
|
4921
|
-
/* @__PURE__ */ jsx4(
|
|
5141
|
+
availableTypes.length > 1 && /* @__PURE__ */ jsx4(
|
|
4922
5142
|
"div",
|
|
4923
5143
|
{
|
|
4924
5144
|
style: {
|
|
@@ -4995,7 +5215,7 @@ function ReportDialog({
|
|
|
4995
5215
|
},
|
|
4996
5216
|
children: queuedMessage
|
|
4997
5217
|
}
|
|
4998
|
-
) : addedToIssue ? `Added to #${addedToIssue}. Thank you!` : `${getTypeLabel(reportType)} sent. Thank you!`
|
|
5218
|
+
) : addedToIssue ? `Added to #${addedToIssue}${addedAsRelated ? " as a related request" : ""}. Thank you!` : `${getTypeLabel(reportType)} sent. Thank you!`
|
|
4999
5219
|
}
|
|
5000
5220
|
) : /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
5001
5221
|
step === 1 && headerSlot ? /* @__PURE__ */ jsx4("div", { style: { marginBottom: "14px" }, children: headerSlot }) : null,
|
|
@@ -5194,6 +5414,7 @@ function ReportDialog({
|
|
|
5194
5414
|
"button",
|
|
5195
5415
|
{
|
|
5196
5416
|
type: "button",
|
|
5417
|
+
disabled: availableTypes.length === 1,
|
|
5197
5418
|
onClick: () => setStep(1),
|
|
5198
5419
|
style: {
|
|
5199
5420
|
display: "inline-flex",
|
|
@@ -5208,12 +5429,12 @@ function ReportDialog({
|
|
|
5208
5429
|
fontSize: "11px",
|
|
5209
5430
|
fontWeight: 600,
|
|
5210
5431
|
fontFamily: "inherit",
|
|
5211
|
-
cursor: "pointer"
|
|
5432
|
+
cursor: availableTypes.length === 1 ? "default" : "pointer"
|
|
5212
5433
|
},
|
|
5213
5434
|
children: [
|
|
5214
5435
|
getTypeIcon(reportType, isRating ? "#f59e0b" : t2.accent, 13),
|
|
5215
5436
|
getTypeLabel(reportType),
|
|
5216
|
-
/* @__PURE__ */ jsx4("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5437
|
+
availableTypes.length > 1 && /* @__PURE__ */ jsx4("span", { style: { color: t2.textMuted, fontWeight: 400 }, children: "\xB7 change" })
|
|
5217
5438
|
]
|
|
5218
5439
|
}
|
|
5219
5440
|
),
|
|
@@ -6240,8 +6461,8 @@ function ReportDialog({
|
|
|
6240
6461
|
},
|
|
6241
6462
|
children: [
|
|
6242
6463
|
/* @__PURE__ */ jsxs4("div", { style: { display: "flex", flexDirection: "column", gap: "2px" }, children: [
|
|
6243
|
-
/* @__PURE__ */ jsx4("span", { style: { color: t2.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this" }),
|
|
6244
|
-
/* @__PURE__ */ jsx4("span", { style: { color: t2.textMuted, fontSize: "12px", lineHeight: 1.5 }, children: similarIssues.length > 1 ? "Pick the one that matches \u2014
|
|
6464
|
+
/* @__PURE__ */ jsx4("span", { style: { color: t2.text, fontWeight: 600, fontSize: "13px" }, children: "Our team may already have this, or something close" }),
|
|
6465
|
+
/* @__PURE__ */ jsx4("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." })
|
|
6245
6466
|
] }),
|
|
6246
6467
|
/* @__PURE__ */ jsx4(
|
|
6247
6468
|
"div",
|
|
@@ -6346,7 +6567,8 @@ function ReportDialog({
|
|
|
6346
6567
|
if (!pickedSimilar) return;
|
|
6347
6568
|
setAttachingTo(pickedSimilar);
|
|
6348
6569
|
setDuplicateIssueNumber(pickedSimilar);
|
|
6349
|
-
|
|
6570
|
+
setDuplicateKind("duplicate");
|
|
6571
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "duplicate" });
|
|
6350
6572
|
},
|
|
6351
6573
|
style: {
|
|
6352
6574
|
width: "100%",
|
|
@@ -6361,7 +6583,7 @@ function ReportDialog({
|
|
|
6361
6583
|
cursor: isSubmitting || !pickedSimilar ? "not-allowed" : "pointer",
|
|
6362
6584
|
fontFamily: "inherit"
|
|
6363
6585
|
},
|
|
6364
|
-
children: typeof attachingTo === "number" ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
6586
|
+
children: typeof attachingTo === "number" && duplicateKind !== "related" ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
6365
6587
|
/* @__PURE__ */ jsx4(ButtonSpinner, {}),
|
|
6366
6588
|
"Adding to #",
|
|
6367
6589
|
attachingTo,
|
|
@@ -6369,6 +6591,39 @@ function ReportDialog({
|
|
|
6369
6591
|
] }) : pickedSimilar ? `Add to #${pickedSimilar}` : "Pick the matching issue"
|
|
6370
6592
|
}
|
|
6371
6593
|
),
|
|
6594
|
+
pickedSimilar && /* @__PURE__ */ jsx4(
|
|
6595
|
+
"button",
|
|
6596
|
+
{
|
|
6597
|
+
type: "button",
|
|
6598
|
+
disabled: isSubmitting,
|
|
6599
|
+
onClick: () => {
|
|
6600
|
+
setAttachingTo(pickedSimilar);
|
|
6601
|
+
setDuplicateIssueNumber(pickedSimilar);
|
|
6602
|
+
setDuplicateKind("related");
|
|
6603
|
+
void handleSubmit({ duplicateOf: pickedSimilar, kind: "related" });
|
|
6604
|
+
},
|
|
6605
|
+
style: {
|
|
6606
|
+
width: "100%",
|
|
6607
|
+
minHeight: "40px",
|
|
6608
|
+
marginTop: "-4px",
|
|
6609
|
+
padding: "9px 10px",
|
|
6610
|
+
borderRadius: "8px",
|
|
6611
|
+
border: "1px solid rgba(245,158,11,0.4)",
|
|
6612
|
+
backgroundColor: "transparent",
|
|
6613
|
+
color: isSubmitting ? t2.textMuted : t2.text,
|
|
6614
|
+
fontSize: "13px",
|
|
6615
|
+
fontWeight: 600,
|
|
6616
|
+
cursor: isSubmitting ? "not-allowed" : "pointer",
|
|
6617
|
+
fontFamily: "inherit"
|
|
6618
|
+
},
|
|
6619
|
+
children: typeof attachingTo === "number" && duplicateKind === "related" ? /* @__PURE__ */ jsxs4(Fragment3, { children: [
|
|
6620
|
+
/* @__PURE__ */ jsx4(ButtonSpinner, {}),
|
|
6621
|
+
"Adding to #",
|
|
6622
|
+
attachingTo,
|
|
6623
|
+
"\u2026"
|
|
6624
|
+
] }) : `Related request \u2014 add to #${pickedSimilar}`
|
|
6625
|
+
}
|
|
6626
|
+
),
|
|
6372
6627
|
/* @__PURE__ */ jsx4(
|
|
6373
6628
|
"button",
|
|
6374
6629
|
{
|
|
@@ -6715,7 +6970,10 @@ function ReportDialog({
|
|
|
6715
6970
|
setTypeChosen(true);
|
|
6716
6971
|
setStep(2);
|
|
6717
6972
|
},
|
|
6718
|
-
onDuplicateChange:
|
|
6973
|
+
onDuplicateChange: (issueNumber, kind) => {
|
|
6974
|
+
setDuplicateIssueNumber(issueNumber);
|
|
6975
|
+
setDuplicateKind(issueNumber && kind === "related" ? "related" : "duplicate");
|
|
6976
|
+
},
|
|
6719
6977
|
onConversationChange: setAiConversationId,
|
|
6720
6978
|
onFinish: handleClose,
|
|
6721
6979
|
rating,
|