@bbearai/react-native 0.4.0 → 0.4.1
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 +83 -26
- package/dist/index.mjs +83 -26
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11634,6 +11634,11 @@ function captureError(error, errorInfo) {
|
|
|
11634
11634
|
componentStack: errorInfo?.componentStack
|
|
11635
11635
|
};
|
|
11636
11636
|
}
|
|
11637
|
+
var formatPgError = (e) => {
|
|
11638
|
+
if (!e || typeof e !== "object") return { raw: e };
|
|
11639
|
+
const { message, code, details, hint } = e;
|
|
11640
|
+
return { message, code, details, hint };
|
|
11641
|
+
};
|
|
11637
11642
|
var DEFAULT_SUPABASE_URL = "https://kyxgzjnqgvapvlnvqawz.supabase.co";
|
|
11638
11643
|
var getEnvVar = (key) => {
|
|
11639
11644
|
try {
|
|
@@ -11803,7 +11808,7 @@ var BugBearClient = class {
|
|
|
11803
11808
|
)
|
|
11804
11809
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
11805
11810
|
if (error) {
|
|
11806
|
-
console.error("BugBear: Failed to fetch assignments", error);
|
|
11811
|
+
console.error("BugBear: Failed to fetch assignments", formatPgError(error));
|
|
11807
11812
|
return [];
|
|
11808
11813
|
}
|
|
11809
11814
|
const mapped = (data || []).map((item) => ({
|
|
@@ -12031,7 +12036,7 @@ var BugBearClient = class {
|
|
|
12031
12036
|
}
|
|
12032
12037
|
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
12033
12038
|
if (error) {
|
|
12034
|
-
console.error("BugBear: Failed to skip assignment", error);
|
|
12039
|
+
console.error("BugBear: Failed to skip assignment", formatPgError(error));
|
|
12035
12040
|
return { success: false, error: error.message };
|
|
12036
12041
|
}
|
|
12037
12042
|
return { success: true };
|
|
@@ -12210,7 +12215,7 @@ var BugBearClient = class {
|
|
|
12210
12215
|
p_tester_id: testerInfo.id
|
|
12211
12216
|
});
|
|
12212
12217
|
if (error) {
|
|
12213
|
-
console.error("BugBear: Failed to fetch tester stats", error);
|
|
12218
|
+
console.error("BugBear: Failed to fetch tester stats", formatPgError(error));
|
|
12214
12219
|
return null;
|
|
12215
12220
|
}
|
|
12216
12221
|
return data;
|
|
@@ -12361,7 +12366,7 @@ var BugBearClient = class {
|
|
|
12361
12366
|
if (updates.platforms !== void 0) updateData.platforms = updates.platforms;
|
|
12362
12367
|
const { error } = await this.supabase.from("testers").update(updateData).eq("id", testerInfo.id);
|
|
12363
12368
|
if (error) {
|
|
12364
|
-
console.error("BugBear: updateTesterProfile error", error);
|
|
12369
|
+
console.error("BugBear: updateTesterProfile error", formatPgError(error));
|
|
12365
12370
|
return { success: false, error: error.message };
|
|
12366
12371
|
}
|
|
12367
12372
|
return { success: true };
|
|
@@ -12383,14 +12388,14 @@ var BugBearClient = class {
|
|
|
12383
12388
|
*/
|
|
12384
12389
|
async isQAEnabled() {
|
|
12385
12390
|
try {
|
|
12386
|
-
const { data, error } = await this.supabase.
|
|
12391
|
+
const { data, error } = await this.supabase.rpc("check_qa_enabled", {
|
|
12392
|
+
p_project_id: this.config.projectId
|
|
12393
|
+
});
|
|
12387
12394
|
if (error) {
|
|
12388
|
-
|
|
12389
|
-
console.warn("BugBear: Could not check QA status", error.message || error.code || "Unknown error");
|
|
12390
|
-
}
|
|
12395
|
+
console.warn("BugBear: Could not check QA status", error.message || error.code || "Unknown error");
|
|
12391
12396
|
return true;
|
|
12392
12397
|
}
|
|
12393
|
-
return data
|
|
12398
|
+
return data ?? true;
|
|
12394
12399
|
} catch (err) {
|
|
12395
12400
|
return true;
|
|
12396
12401
|
}
|
|
@@ -12420,7 +12425,7 @@ var BugBearClient = class {
|
|
|
12420
12425
|
upsert: false
|
|
12421
12426
|
});
|
|
12422
12427
|
if (error) {
|
|
12423
|
-
console.error("BugBear: Failed to upload screenshot", error);
|
|
12428
|
+
console.error("BugBear: Failed to upload screenshot", formatPgError(error));
|
|
12424
12429
|
return null;
|
|
12425
12430
|
}
|
|
12426
12431
|
const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
|
|
@@ -12451,7 +12456,7 @@ var BugBearClient = class {
|
|
|
12451
12456
|
upsert: false
|
|
12452
12457
|
});
|
|
12453
12458
|
if (error) {
|
|
12454
|
-
console.error("BugBear: Failed to upload image from URI", error);
|
|
12459
|
+
console.error("BugBear: Failed to upload image from URI", formatPgError(error));
|
|
12455
12460
|
return null;
|
|
12456
12461
|
}
|
|
12457
12462
|
const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
|
|
@@ -12526,7 +12531,7 @@ var BugBearClient = class {
|
|
|
12526
12531
|
}
|
|
12527
12532
|
const { data, error } = await query;
|
|
12528
12533
|
if (error) {
|
|
12529
|
-
console.error("BugBear: Failed to fetch fix requests", error);
|
|
12534
|
+
console.error("BugBear: Failed to fetch fix requests", formatPgError(error));
|
|
12530
12535
|
return [];
|
|
12531
12536
|
}
|
|
12532
12537
|
return (data || []).map((fr) => ({
|
|
@@ -12557,7 +12562,7 @@ var BugBearClient = class {
|
|
|
12557
12562
|
p_tester_id: testerInfo.id
|
|
12558
12563
|
});
|
|
12559
12564
|
if (error) {
|
|
12560
|
-
console.error("BugBear: Failed to fetch threads via RPC", error);
|
|
12565
|
+
console.error("BugBear: Failed to fetch threads via RPC", formatPgError(error));
|
|
12561
12566
|
return [];
|
|
12562
12567
|
}
|
|
12563
12568
|
if (!data || data.length === 0) return [];
|
|
@@ -12601,7 +12606,7 @@ var BugBearClient = class {
|
|
|
12601
12606
|
attachments
|
|
12602
12607
|
`).eq("thread_id", threadId).order("created_at", { ascending: true }).limit(200);
|
|
12603
12608
|
if (error) {
|
|
12604
|
-
console.error("BugBear: Failed to fetch messages", error);
|
|
12609
|
+
console.error("BugBear: Failed to fetch messages", formatPgError(error));
|
|
12605
12610
|
return [];
|
|
12606
12611
|
}
|
|
12607
12612
|
return (data || []).map((msg) => ({
|
|
@@ -12645,7 +12650,7 @@ var BugBearClient = class {
|
|
|
12645
12650
|
}
|
|
12646
12651
|
const { error } = await this.supabase.from("discussion_messages").insert(insertData);
|
|
12647
12652
|
if (error) {
|
|
12648
|
-
console.error("BugBear: Failed to send message", error);
|
|
12653
|
+
console.error("BugBear: Failed to send message", formatPgError(error));
|
|
12649
12654
|
return false;
|
|
12650
12655
|
}
|
|
12651
12656
|
await this.markThreadAsRead(threadId);
|
|
@@ -12761,7 +12766,7 @@ var BugBearClient = class {
|
|
|
12761
12766
|
p_platform: options.platform || null
|
|
12762
12767
|
});
|
|
12763
12768
|
if (error) {
|
|
12764
|
-
console.error("BugBear: Failed to start session", error);
|
|
12769
|
+
console.error("BugBear: Failed to start session", formatPgError(error));
|
|
12765
12770
|
return { success: false, error: error.message };
|
|
12766
12771
|
}
|
|
12767
12772
|
const session = await this.getSession(data);
|
|
@@ -12786,7 +12791,7 @@ var BugBearClient = class {
|
|
|
12786
12791
|
p_routes_covered: options.routesCovered || null
|
|
12787
12792
|
});
|
|
12788
12793
|
if (error) {
|
|
12789
|
-
console.error("BugBear: Failed to end session", error);
|
|
12794
|
+
console.error("BugBear: Failed to end session", formatPgError(error));
|
|
12790
12795
|
return { success: false, error: error.message };
|
|
12791
12796
|
}
|
|
12792
12797
|
const session = this.transformSession(data);
|
|
@@ -12834,7 +12839,7 @@ var BugBearClient = class {
|
|
|
12834
12839
|
if (!testerInfo) return [];
|
|
12835
12840
|
const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).order("started_at", { ascending: false }).limit(limit);
|
|
12836
12841
|
if (error) {
|
|
12837
|
-
console.error("BugBear: Failed to fetch session history", error);
|
|
12842
|
+
console.error("BugBear: Failed to fetch session history", formatPgError(error));
|
|
12838
12843
|
return [];
|
|
12839
12844
|
}
|
|
12840
12845
|
return (data || []).map((s) => this.transformSession(s));
|
|
@@ -12862,7 +12867,7 @@ var BugBearClient = class {
|
|
|
12862
12867
|
p_app_context: options.appContext || null
|
|
12863
12868
|
});
|
|
12864
12869
|
if (error) {
|
|
12865
|
-
console.error("BugBear: Failed to add finding", error);
|
|
12870
|
+
console.error("BugBear: Failed to add finding", formatPgError(error));
|
|
12866
12871
|
return { success: false, error: error.message };
|
|
12867
12872
|
}
|
|
12868
12873
|
const finding = this.transformFinding(data);
|
|
@@ -12880,7 +12885,7 @@ var BugBearClient = class {
|
|
|
12880
12885
|
try {
|
|
12881
12886
|
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true }).limit(100);
|
|
12882
12887
|
if (error) {
|
|
12883
|
-
console.error("BugBear: Failed to fetch findings", error);
|
|
12888
|
+
console.error("BugBear: Failed to fetch findings", formatPgError(error));
|
|
12884
12889
|
return [];
|
|
12885
12890
|
}
|
|
12886
12891
|
return (data || []).map((f) => this.transformFinding(f));
|
|
@@ -12898,7 +12903,7 @@ var BugBearClient = class {
|
|
|
12898
12903
|
p_finding_id: findingId
|
|
12899
12904
|
});
|
|
12900
12905
|
if (error) {
|
|
12901
|
-
console.error("BugBear: Failed to convert finding", error);
|
|
12906
|
+
console.error("BugBear: Failed to convert finding", formatPgError(error));
|
|
12902
12907
|
return { success: false, error: error.message };
|
|
12903
12908
|
}
|
|
12904
12909
|
return { success: true, bugId: data };
|
|
@@ -12919,7 +12924,7 @@ var BugBearClient = class {
|
|
|
12919
12924
|
dismissed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
12920
12925
|
}).eq("id", findingId);
|
|
12921
12926
|
if (error) {
|
|
12922
|
-
console.error("BugBear: Failed to dismiss finding", error);
|
|
12927
|
+
console.error("BugBear: Failed to dismiss finding", formatPgError(error));
|
|
12923
12928
|
return { success: false, error: error.message };
|
|
12924
12929
|
}
|
|
12925
12930
|
return { success: true };
|
|
@@ -13782,7 +13787,10 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
13782
13787
|
import_react_native4.Keyboard.dismiss();
|
|
13783
13788
|
setIsSubmitting(true);
|
|
13784
13789
|
try {
|
|
13785
|
-
await client.failAssignment(displayedAssignment.id);
|
|
13790
|
+
const result = await client.failAssignment(displayedAssignment.id);
|
|
13791
|
+
if (!result.success) {
|
|
13792
|
+
console.error("BugBear: Failed to mark assignment as failed", result.error);
|
|
13793
|
+
}
|
|
13786
13794
|
await refreshAssignments();
|
|
13787
13795
|
nav.replace({
|
|
13788
13796
|
name: "REPORT",
|
|
@@ -14446,6 +14454,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14446
14454
|
const [submitting, setSubmitting] = (0, import_react10.useState)(false);
|
|
14447
14455
|
const [error, setError] = (0, import_react10.useState)(null);
|
|
14448
14456
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14457
|
+
const isRetestFailure = prefill?.type === "test_fail";
|
|
14449
14458
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14450
14459
|
const handleSubmit = async () => {
|
|
14451
14460
|
if (!client || !description.trim()) return;
|
|
@@ -14485,7 +14494,50 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14485
14494
|
setSubmitting(false);
|
|
14486
14495
|
}
|
|
14487
14496
|
};
|
|
14488
|
-
return /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style:
|
|
14497
|
+
return /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, null, isRetestFailure ? /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.retestBanner }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.section }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.label }, "Severity"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.severityRow }, [
|
|
14498
|
+
{ sev: "critical", color: "#ef4444" },
|
|
14499
|
+
{ sev: "high", color: "#f97316" },
|
|
14500
|
+
{ sev: "medium", color: "#eab308" },
|
|
14501
|
+
{ sev: "low", color: "#6b7280" }
|
|
14502
|
+
].map(({ sev, color }) => /* @__PURE__ */ import_react10.default.createElement(
|
|
14503
|
+
import_react_native9.TouchableOpacity,
|
|
14504
|
+
{
|
|
14505
|
+
key: sev,
|
|
14506
|
+
style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
|
|
14507
|
+
onPress: () => setSeverity(sev)
|
|
14508
|
+
},
|
|
14509
|
+
/* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: [styles7.sevText, severity === sev && { color }] }, sev)
|
|
14510
|
+
)))), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.section }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.label }, "What went wrong?"), /* @__PURE__ */ import_react10.default.createElement(
|
|
14511
|
+
import_react_native9.TextInput,
|
|
14512
|
+
{
|
|
14513
|
+
style: styles7.descInput,
|
|
14514
|
+
value: description,
|
|
14515
|
+
onChangeText: setDescription,
|
|
14516
|
+
placeholder: "Describe what you observed. What still doesn't work?",
|
|
14517
|
+
placeholderTextColor: colors.textMuted,
|
|
14518
|
+
multiline: true,
|
|
14519
|
+
numberOfLines: 4,
|
|
14520
|
+
textAlignVertical: "top"
|
|
14521
|
+
}
|
|
14522
|
+
)), /* @__PURE__ */ import_react10.default.createElement(
|
|
14523
|
+
ImagePickerButtons,
|
|
14524
|
+
{
|
|
14525
|
+
images: images.images,
|
|
14526
|
+
maxImages: 5,
|
|
14527
|
+
onPickGallery: images.pickFromGallery,
|
|
14528
|
+
onPickCamera: images.pickFromCamera,
|
|
14529
|
+
onRemove: images.removeImage,
|
|
14530
|
+
label: "Attachments (optional)"
|
|
14531
|
+
}
|
|
14532
|
+
), error && /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.errorBanner }, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: styles7.errorText }, error)), /* @__PURE__ */ import_react10.default.createElement(
|
|
14533
|
+
import_react_native9.TouchableOpacity,
|
|
14534
|
+
{
|
|
14535
|
+
style: [shared.primaryButton, styles7.retestSubmitButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
|
|
14536
|
+
onPress: handleSubmit,
|
|
14537
|
+
disabled: !description.trim() || submitting || images.isUploading
|
|
14538
|
+
},
|
|
14539
|
+
/* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Failed Retest")
|
|
14540
|
+
)) : /* @__PURE__ */ import_react10.default.createElement(import_react10.default.Fragment, null, /* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ import_react10.default.createElement(import_react_native9.View, { style: styles7.typeRow }, [
|
|
14489
14541
|
{ type: "bug", label: "Bug", icon: "\u{1F41B}" },
|
|
14490
14542
|
{ type: "feedback", label: "Feedback", icon: "\u{1F4A1}" },
|
|
14491
14543
|
{ type: "suggestion", label: "Idea", icon: "\u2728" }
|
|
@@ -14550,7 +14602,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14550
14602
|
disabled: !description.trim() || submitting || images.isUploading
|
|
14551
14603
|
},
|
|
14552
14604
|
/* @__PURE__ */ import_react10.default.createElement(import_react_native9.Text, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Report")
|
|
14553
|
-
));
|
|
14605
|
+
)));
|
|
14554
14606
|
}
|
|
14555
14607
|
var styles7 = import_react_native9.StyleSheet.create({
|
|
14556
14608
|
typeRow: { flexDirection: "row", gap: 10, marginBottom: 20 },
|
|
@@ -14567,7 +14619,12 @@ var styles7 = import_react_native9.StyleSheet.create({
|
|
|
14567
14619
|
screenInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 8, fontSize: 13, color: colors.textPrimary },
|
|
14568
14620
|
screenHint: { fontSize: 11, color: colors.textMuted, marginTop: 4 },
|
|
14569
14621
|
errorBanner: { backgroundColor: "#7f1d1d", borderWidth: 1, borderColor: "#991b1b", borderRadius: 8, padding: 12, marginTop: 16 },
|
|
14570
|
-
errorText: { fontSize: 13, color: "#fca5a5", lineHeight: 18 }
|
|
14622
|
+
errorText: { fontSize: 13, color: "#fca5a5", lineHeight: 18 },
|
|
14623
|
+
retestBanner: { flexDirection: "row", alignItems: "center", gap: 10, backgroundColor: "#422006", borderWidth: 1, borderColor: "#854d0e", borderRadius: 10, paddingVertical: 12, paddingHorizontal: 14, marginBottom: 20 },
|
|
14624
|
+
retestIcon: { fontSize: 16 },
|
|
14625
|
+
retestTitle: { fontSize: 15, fontWeight: "600", color: "#fbbf24", lineHeight: 20 },
|
|
14626
|
+
retestSubtitle: { fontSize: 12, color: "#d97706", lineHeight: 16 },
|
|
14627
|
+
retestSubmitButton: { backgroundColor: "#b45309" }
|
|
14571
14628
|
});
|
|
14572
14629
|
|
|
14573
14630
|
// src/widget/screens/ReportSuccessScreen.tsx
|
package/dist/index.mjs
CHANGED
|
@@ -11601,6 +11601,11 @@ function captureError(error, errorInfo) {
|
|
|
11601
11601
|
componentStack: errorInfo?.componentStack
|
|
11602
11602
|
};
|
|
11603
11603
|
}
|
|
11604
|
+
var formatPgError = (e) => {
|
|
11605
|
+
if (!e || typeof e !== "object") return { raw: e };
|
|
11606
|
+
const { message, code, details, hint } = e;
|
|
11607
|
+
return { message, code, details, hint };
|
|
11608
|
+
};
|
|
11604
11609
|
var DEFAULT_SUPABASE_URL = "https://kyxgzjnqgvapvlnvqawz.supabase.co";
|
|
11605
11610
|
var getEnvVar = (key) => {
|
|
11606
11611
|
try {
|
|
@@ -11770,7 +11775,7 @@ var BugBearClient = class {
|
|
|
11770
11775
|
)
|
|
11771
11776
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true }).limit(100);
|
|
11772
11777
|
if (error) {
|
|
11773
|
-
console.error("BugBear: Failed to fetch assignments", error);
|
|
11778
|
+
console.error("BugBear: Failed to fetch assignments", formatPgError(error));
|
|
11774
11779
|
return [];
|
|
11775
11780
|
}
|
|
11776
11781
|
const mapped = (data || []).map((item) => ({
|
|
@@ -11998,7 +12003,7 @@ var BugBearClient = class {
|
|
|
11998
12003
|
}
|
|
11999
12004
|
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
12000
12005
|
if (error) {
|
|
12001
|
-
console.error("BugBear: Failed to skip assignment", error);
|
|
12006
|
+
console.error("BugBear: Failed to skip assignment", formatPgError(error));
|
|
12002
12007
|
return { success: false, error: error.message };
|
|
12003
12008
|
}
|
|
12004
12009
|
return { success: true };
|
|
@@ -12177,7 +12182,7 @@ var BugBearClient = class {
|
|
|
12177
12182
|
p_tester_id: testerInfo.id
|
|
12178
12183
|
});
|
|
12179
12184
|
if (error) {
|
|
12180
|
-
console.error("BugBear: Failed to fetch tester stats", error);
|
|
12185
|
+
console.error("BugBear: Failed to fetch tester stats", formatPgError(error));
|
|
12181
12186
|
return null;
|
|
12182
12187
|
}
|
|
12183
12188
|
return data;
|
|
@@ -12328,7 +12333,7 @@ var BugBearClient = class {
|
|
|
12328
12333
|
if (updates.platforms !== void 0) updateData.platforms = updates.platforms;
|
|
12329
12334
|
const { error } = await this.supabase.from("testers").update(updateData).eq("id", testerInfo.id);
|
|
12330
12335
|
if (error) {
|
|
12331
|
-
console.error("BugBear: updateTesterProfile error", error);
|
|
12336
|
+
console.error("BugBear: updateTesterProfile error", formatPgError(error));
|
|
12332
12337
|
return { success: false, error: error.message };
|
|
12333
12338
|
}
|
|
12334
12339
|
return { success: true };
|
|
@@ -12350,14 +12355,14 @@ var BugBearClient = class {
|
|
|
12350
12355
|
*/
|
|
12351
12356
|
async isQAEnabled() {
|
|
12352
12357
|
try {
|
|
12353
|
-
const { data, error } = await this.supabase.
|
|
12358
|
+
const { data, error } = await this.supabase.rpc("check_qa_enabled", {
|
|
12359
|
+
p_project_id: this.config.projectId
|
|
12360
|
+
});
|
|
12354
12361
|
if (error) {
|
|
12355
|
-
|
|
12356
|
-
console.warn("BugBear: Could not check QA status", error.message || error.code || "Unknown error");
|
|
12357
|
-
}
|
|
12362
|
+
console.warn("BugBear: Could not check QA status", error.message || error.code || "Unknown error");
|
|
12358
12363
|
return true;
|
|
12359
12364
|
}
|
|
12360
|
-
return data
|
|
12365
|
+
return data ?? true;
|
|
12361
12366
|
} catch (err) {
|
|
12362
12367
|
return true;
|
|
12363
12368
|
}
|
|
@@ -12387,7 +12392,7 @@ var BugBearClient = class {
|
|
|
12387
12392
|
upsert: false
|
|
12388
12393
|
});
|
|
12389
12394
|
if (error) {
|
|
12390
|
-
console.error("BugBear: Failed to upload screenshot", error);
|
|
12395
|
+
console.error("BugBear: Failed to upload screenshot", formatPgError(error));
|
|
12391
12396
|
return null;
|
|
12392
12397
|
}
|
|
12393
12398
|
const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
|
|
@@ -12418,7 +12423,7 @@ var BugBearClient = class {
|
|
|
12418
12423
|
upsert: false
|
|
12419
12424
|
});
|
|
12420
12425
|
if (error) {
|
|
12421
|
-
console.error("BugBear: Failed to upload image from URI", error);
|
|
12426
|
+
console.error("BugBear: Failed to upload image from URI", formatPgError(error));
|
|
12422
12427
|
return null;
|
|
12423
12428
|
}
|
|
12424
12429
|
const { data: { publicUrl } } = this.supabase.storage.from(bucket).getPublicUrl(path);
|
|
@@ -12493,7 +12498,7 @@ var BugBearClient = class {
|
|
|
12493
12498
|
}
|
|
12494
12499
|
const { data, error } = await query;
|
|
12495
12500
|
if (error) {
|
|
12496
|
-
console.error("BugBear: Failed to fetch fix requests", error);
|
|
12501
|
+
console.error("BugBear: Failed to fetch fix requests", formatPgError(error));
|
|
12497
12502
|
return [];
|
|
12498
12503
|
}
|
|
12499
12504
|
return (data || []).map((fr) => ({
|
|
@@ -12524,7 +12529,7 @@ var BugBearClient = class {
|
|
|
12524
12529
|
p_tester_id: testerInfo.id
|
|
12525
12530
|
});
|
|
12526
12531
|
if (error) {
|
|
12527
|
-
console.error("BugBear: Failed to fetch threads via RPC", error);
|
|
12532
|
+
console.error("BugBear: Failed to fetch threads via RPC", formatPgError(error));
|
|
12528
12533
|
return [];
|
|
12529
12534
|
}
|
|
12530
12535
|
if (!data || data.length === 0) return [];
|
|
@@ -12568,7 +12573,7 @@ var BugBearClient = class {
|
|
|
12568
12573
|
attachments
|
|
12569
12574
|
`).eq("thread_id", threadId).order("created_at", { ascending: true }).limit(200);
|
|
12570
12575
|
if (error) {
|
|
12571
|
-
console.error("BugBear: Failed to fetch messages", error);
|
|
12576
|
+
console.error("BugBear: Failed to fetch messages", formatPgError(error));
|
|
12572
12577
|
return [];
|
|
12573
12578
|
}
|
|
12574
12579
|
return (data || []).map((msg) => ({
|
|
@@ -12612,7 +12617,7 @@ var BugBearClient = class {
|
|
|
12612
12617
|
}
|
|
12613
12618
|
const { error } = await this.supabase.from("discussion_messages").insert(insertData);
|
|
12614
12619
|
if (error) {
|
|
12615
|
-
console.error("BugBear: Failed to send message", error);
|
|
12620
|
+
console.error("BugBear: Failed to send message", formatPgError(error));
|
|
12616
12621
|
return false;
|
|
12617
12622
|
}
|
|
12618
12623
|
await this.markThreadAsRead(threadId);
|
|
@@ -12728,7 +12733,7 @@ var BugBearClient = class {
|
|
|
12728
12733
|
p_platform: options.platform || null
|
|
12729
12734
|
});
|
|
12730
12735
|
if (error) {
|
|
12731
|
-
console.error("BugBear: Failed to start session", error);
|
|
12736
|
+
console.error("BugBear: Failed to start session", formatPgError(error));
|
|
12732
12737
|
return { success: false, error: error.message };
|
|
12733
12738
|
}
|
|
12734
12739
|
const session = await this.getSession(data);
|
|
@@ -12753,7 +12758,7 @@ var BugBearClient = class {
|
|
|
12753
12758
|
p_routes_covered: options.routesCovered || null
|
|
12754
12759
|
});
|
|
12755
12760
|
if (error) {
|
|
12756
|
-
console.error("BugBear: Failed to end session", error);
|
|
12761
|
+
console.error("BugBear: Failed to end session", formatPgError(error));
|
|
12757
12762
|
return { success: false, error: error.message };
|
|
12758
12763
|
}
|
|
12759
12764
|
const session = this.transformSession(data);
|
|
@@ -12801,7 +12806,7 @@ var BugBearClient = class {
|
|
|
12801
12806
|
if (!testerInfo) return [];
|
|
12802
12807
|
const { data, error } = await this.supabase.from("qa_sessions").select("*").eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).order("started_at", { ascending: false }).limit(limit);
|
|
12803
12808
|
if (error) {
|
|
12804
|
-
console.error("BugBear: Failed to fetch session history", error);
|
|
12809
|
+
console.error("BugBear: Failed to fetch session history", formatPgError(error));
|
|
12805
12810
|
return [];
|
|
12806
12811
|
}
|
|
12807
12812
|
return (data || []).map((s) => this.transformSession(s));
|
|
@@ -12829,7 +12834,7 @@ var BugBearClient = class {
|
|
|
12829
12834
|
p_app_context: options.appContext || null
|
|
12830
12835
|
});
|
|
12831
12836
|
if (error) {
|
|
12832
|
-
console.error("BugBear: Failed to add finding", error);
|
|
12837
|
+
console.error("BugBear: Failed to add finding", formatPgError(error));
|
|
12833
12838
|
return { success: false, error: error.message };
|
|
12834
12839
|
}
|
|
12835
12840
|
const finding = this.transformFinding(data);
|
|
@@ -12847,7 +12852,7 @@ var BugBearClient = class {
|
|
|
12847
12852
|
try {
|
|
12848
12853
|
const { data, error } = await this.supabase.from("qa_findings").select("*").eq("session_id", sessionId).order("created_at", { ascending: true }).limit(100);
|
|
12849
12854
|
if (error) {
|
|
12850
|
-
console.error("BugBear: Failed to fetch findings", error);
|
|
12855
|
+
console.error("BugBear: Failed to fetch findings", formatPgError(error));
|
|
12851
12856
|
return [];
|
|
12852
12857
|
}
|
|
12853
12858
|
return (data || []).map((f) => this.transformFinding(f));
|
|
@@ -12865,7 +12870,7 @@ var BugBearClient = class {
|
|
|
12865
12870
|
p_finding_id: findingId
|
|
12866
12871
|
});
|
|
12867
12872
|
if (error) {
|
|
12868
|
-
console.error("BugBear: Failed to convert finding", error);
|
|
12873
|
+
console.error("BugBear: Failed to convert finding", formatPgError(error));
|
|
12869
12874
|
return { success: false, error: error.message };
|
|
12870
12875
|
}
|
|
12871
12876
|
return { success: true, bugId: data };
|
|
@@ -12886,7 +12891,7 @@ var BugBearClient = class {
|
|
|
12886
12891
|
dismissed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
12887
12892
|
}).eq("id", findingId);
|
|
12888
12893
|
if (error) {
|
|
12889
|
-
console.error("BugBear: Failed to dismiss finding", error);
|
|
12894
|
+
console.error("BugBear: Failed to dismiss finding", formatPgError(error));
|
|
12890
12895
|
return { success: false, error: error.message };
|
|
12891
12896
|
}
|
|
12892
12897
|
return { success: true };
|
|
@@ -13764,7 +13769,10 @@ function TestDetailScreen({ testId, nav }) {
|
|
|
13764
13769
|
Keyboard.dismiss();
|
|
13765
13770
|
setIsSubmitting(true);
|
|
13766
13771
|
try {
|
|
13767
|
-
await client.failAssignment(displayedAssignment.id);
|
|
13772
|
+
const result = await client.failAssignment(displayedAssignment.id);
|
|
13773
|
+
if (!result.success) {
|
|
13774
|
+
console.error("BugBear: Failed to mark assignment as failed", result.error);
|
|
13775
|
+
}
|
|
13768
13776
|
await refreshAssignments();
|
|
13769
13777
|
nav.replace({
|
|
13770
13778
|
name: "REPORT",
|
|
@@ -14428,6 +14436,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14428
14436
|
const [submitting, setSubmitting] = useState6(false);
|
|
14429
14437
|
const [error, setError] = useState6(null);
|
|
14430
14438
|
const images = useImageAttachments(uploadImage, 5, "screenshots");
|
|
14439
|
+
const isRetestFailure = prefill?.type === "test_fail";
|
|
14431
14440
|
const isBugType = reportType === "bug" || reportType === "test_fail";
|
|
14432
14441
|
const handleSubmit = async () => {
|
|
14433
14442
|
if (!client || !description.trim()) return;
|
|
@@ -14467,7 +14476,50 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14467
14476
|
setSubmitting(false);
|
|
14468
14477
|
}
|
|
14469
14478
|
};
|
|
14470
|
-
return /* @__PURE__ */ React8.createElement(View7, null, /* @__PURE__ */ React8.createElement(Text7, { style:
|
|
14479
|
+
return /* @__PURE__ */ React8.createElement(View7, null, isRetestFailure ? /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(View7, { style: styles7.retestBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestIcon }, "\u{1F504}"), /* @__PURE__ */ React8.createElement(View7, null, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestTitle }, "Bug Still Present"), /* @__PURE__ */ React8.createElement(Text7, { style: styles7.retestSubtitle }, "The fix did not resolve this issue"))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "Severity"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.severityRow }, [
|
|
14480
|
+
{ sev: "critical", color: "#ef4444" },
|
|
14481
|
+
{ sev: "high", color: "#f97316" },
|
|
14482
|
+
{ sev: "medium", color: "#eab308" },
|
|
14483
|
+
{ sev: "low", color: "#6b7280" }
|
|
14484
|
+
].map(({ sev, color }) => /* @__PURE__ */ React8.createElement(
|
|
14485
|
+
TouchableOpacity7,
|
|
14486
|
+
{
|
|
14487
|
+
key: sev,
|
|
14488
|
+
style: [styles7.sevButton, severity === sev && { backgroundColor: `${color}30`, borderColor: color }],
|
|
14489
|
+
onPress: () => setSeverity(sev)
|
|
14490
|
+
},
|
|
14491
|
+
/* @__PURE__ */ React8.createElement(Text7, { style: [styles7.sevText, severity === sev && { color }] }, sev)
|
|
14492
|
+
)))), /* @__PURE__ */ React8.createElement(View7, { style: styles7.section }, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "What went wrong?"), /* @__PURE__ */ React8.createElement(
|
|
14493
|
+
TextInput3,
|
|
14494
|
+
{
|
|
14495
|
+
style: styles7.descInput,
|
|
14496
|
+
value: description,
|
|
14497
|
+
onChangeText: setDescription,
|
|
14498
|
+
placeholder: "Describe what you observed. What still doesn't work?",
|
|
14499
|
+
placeholderTextColor: colors.textMuted,
|
|
14500
|
+
multiline: true,
|
|
14501
|
+
numberOfLines: 4,
|
|
14502
|
+
textAlignVertical: "top"
|
|
14503
|
+
}
|
|
14504
|
+
)), /* @__PURE__ */ React8.createElement(
|
|
14505
|
+
ImagePickerButtons,
|
|
14506
|
+
{
|
|
14507
|
+
images: images.images,
|
|
14508
|
+
maxImages: 5,
|
|
14509
|
+
onPickGallery: images.pickFromGallery,
|
|
14510
|
+
onPickCamera: images.pickFromCamera,
|
|
14511
|
+
onRemove: images.removeImage,
|
|
14512
|
+
label: "Attachments (optional)"
|
|
14513
|
+
}
|
|
14514
|
+
), error && /* @__PURE__ */ React8.createElement(View7, { style: styles7.errorBanner }, /* @__PURE__ */ React8.createElement(Text7, { style: styles7.errorText }, error)), /* @__PURE__ */ React8.createElement(
|
|
14515
|
+
TouchableOpacity7,
|
|
14516
|
+
{
|
|
14517
|
+
style: [shared.primaryButton, styles7.retestSubmitButton, (!description.trim() || submitting || images.isUploading) && shared.primaryButtonDisabled, { marginTop: 20 }],
|
|
14518
|
+
onPress: handleSubmit,
|
|
14519
|
+
disabled: !description.trim() || submitting || images.isUploading
|
|
14520
|
+
},
|
|
14521
|
+
/* @__PURE__ */ React8.createElement(Text7, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Failed Retest")
|
|
14522
|
+
)) : /* @__PURE__ */ React8.createElement(React8.Fragment, null, /* @__PURE__ */ React8.createElement(Text7, { style: shared.label }, "What are you reporting?"), /* @__PURE__ */ React8.createElement(View7, { style: styles7.typeRow }, [
|
|
14471
14523
|
{ type: "bug", label: "Bug", icon: "\u{1F41B}" },
|
|
14472
14524
|
{ type: "feedback", label: "Feedback", icon: "\u{1F4A1}" },
|
|
14473
14525
|
{ type: "suggestion", label: "Idea", icon: "\u2728" }
|
|
@@ -14532,7 +14584,7 @@ function ReportScreen({ nav, prefill }) {
|
|
|
14532
14584
|
disabled: !description.trim() || submitting || images.isUploading
|
|
14533
14585
|
},
|
|
14534
14586
|
/* @__PURE__ */ React8.createElement(Text7, { style: shared.primaryButtonText }, images.isUploading ? "Uploading images..." : submitting ? "Submitting..." : error ? "Retry" : "Submit Report")
|
|
14535
|
-
));
|
|
14587
|
+
)));
|
|
14536
14588
|
}
|
|
14537
14589
|
var styles7 = StyleSheet8.create({
|
|
14538
14590
|
typeRow: { flexDirection: "row", gap: 10, marginBottom: 20 },
|
|
@@ -14549,7 +14601,12 @@ var styles7 = StyleSheet8.create({
|
|
|
14549
14601
|
screenInput: { backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border, borderRadius: 8, paddingHorizontal: 12, paddingVertical: 8, fontSize: 13, color: colors.textPrimary },
|
|
14550
14602
|
screenHint: { fontSize: 11, color: colors.textMuted, marginTop: 4 },
|
|
14551
14603
|
errorBanner: { backgroundColor: "#7f1d1d", borderWidth: 1, borderColor: "#991b1b", borderRadius: 8, padding: 12, marginTop: 16 },
|
|
14552
|
-
errorText: { fontSize: 13, color: "#fca5a5", lineHeight: 18 }
|
|
14604
|
+
errorText: { fontSize: 13, color: "#fca5a5", lineHeight: 18 },
|
|
14605
|
+
retestBanner: { flexDirection: "row", alignItems: "center", gap: 10, backgroundColor: "#422006", borderWidth: 1, borderColor: "#854d0e", borderRadius: 10, paddingVertical: 12, paddingHorizontal: 14, marginBottom: 20 },
|
|
14606
|
+
retestIcon: { fontSize: 16 },
|
|
14607
|
+
retestTitle: { fontSize: 15, fontWeight: "600", color: "#fbbf24", lineHeight: 20 },
|
|
14608
|
+
retestSubtitle: { fontSize: 12, color: "#d97706", lineHeight: 16 },
|
|
14609
|
+
retestSubmitButton: { backgroundColor: "#b45309" }
|
|
14553
14610
|
});
|
|
14554
14611
|
|
|
14555
14612
|
// src/widget/screens/ReportSuccessScreen.tsx
|