@bbearai/react-native 0.1.9 → 0.2.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.d.mts +17 -1
- package/dist/index.d.ts +17 -1
- package/dist/index.js +1375 -45
- package/dist/index.mjs +1376 -46
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -11510,6 +11510,9 @@ var BugBearClient = class {
|
|
|
11510
11510
|
id,
|
|
11511
11511
|
status,
|
|
11512
11512
|
started_at,
|
|
11513
|
+
skip_reason,
|
|
11514
|
+
is_verification,
|
|
11515
|
+
original_report_id,
|
|
11513
11516
|
test_case:test_cases(
|
|
11514
11517
|
id,
|
|
11515
11518
|
title,
|
|
@@ -11527,6 +11530,12 @@ var BugBearClient = class {
|
|
|
11527
11530
|
test_template,
|
|
11528
11531
|
rubric_mode,
|
|
11529
11532
|
description
|
|
11533
|
+
),
|
|
11534
|
+
group:test_groups(
|
|
11535
|
+
id,
|
|
11536
|
+
name,
|
|
11537
|
+
description,
|
|
11538
|
+
sort_order
|
|
11530
11539
|
)
|
|
11531
11540
|
)
|
|
11532
11541
|
`).eq("project_id", this.config.projectId).eq("tester_id", testerInfo.id).in("status", ["pending", "in_progress"]).order("created_at", { ascending: true });
|
|
@@ -11538,6 +11547,9 @@ var BugBearClient = class {
|
|
|
11538
11547
|
id: item.id,
|
|
11539
11548
|
status: item.status,
|
|
11540
11549
|
startedAt: item.started_at,
|
|
11550
|
+
skipReason: item.skip_reason,
|
|
11551
|
+
isVerification: item.is_verification || false,
|
|
11552
|
+
originalReportId: item.original_report_id,
|
|
11541
11553
|
testCase: {
|
|
11542
11554
|
id: item.test_case.id,
|
|
11543
11555
|
title: item.test_case.title,
|
|
@@ -11555,6 +11567,12 @@ var BugBearClient = class {
|
|
|
11555
11567
|
testTemplate: item.test_case.track.test_template,
|
|
11556
11568
|
rubricMode: item.test_case.track.rubric_mode || "pass_fail",
|
|
11557
11569
|
description: item.test_case.track.description
|
|
11570
|
+
} : void 0,
|
|
11571
|
+
group: item.test_case.group ? {
|
|
11572
|
+
id: item.test_case.group.id,
|
|
11573
|
+
name: item.test_case.group.name,
|
|
11574
|
+
description: item.test_case.group.description,
|
|
11575
|
+
sortOrder: item.test_case.group.sort_order
|
|
11558
11576
|
} : void 0
|
|
11559
11577
|
}
|
|
11560
11578
|
}));
|
|
@@ -11691,6 +11709,32 @@ var BugBearClient = class {
|
|
|
11691
11709
|
return { success: false, error: message };
|
|
11692
11710
|
}
|
|
11693
11711
|
}
|
|
11712
|
+
/**
|
|
11713
|
+
* Skip a test assignment with a required reason
|
|
11714
|
+
* Marks the assignment as 'skipped' and records why it was skipped
|
|
11715
|
+
*/
|
|
11716
|
+
async skipAssignment(assignmentId, reason, notes) {
|
|
11717
|
+
try {
|
|
11718
|
+
const updateData = {
|
|
11719
|
+
status: "skipped",
|
|
11720
|
+
skip_reason: reason,
|
|
11721
|
+
completed_at: (/* @__PURE__ */ new Date()).toISOString()
|
|
11722
|
+
};
|
|
11723
|
+
if (notes) {
|
|
11724
|
+
updateData.notes = notes;
|
|
11725
|
+
}
|
|
11726
|
+
const { error } = await this.supabase.from("test_assignments").update(updateData).eq("id", assignmentId);
|
|
11727
|
+
if (error) {
|
|
11728
|
+
console.error("BugBear: Failed to skip assignment", error);
|
|
11729
|
+
return { success: false, error: error.message };
|
|
11730
|
+
}
|
|
11731
|
+
return { success: true };
|
|
11732
|
+
} catch (err) {
|
|
11733
|
+
const message = err instanceof Error ? err.message : "Unknown error";
|
|
11734
|
+
console.error("BugBear: Error skipping assignment", err);
|
|
11735
|
+
return { success: false, error: message };
|
|
11736
|
+
}
|
|
11737
|
+
}
|
|
11694
11738
|
/**
|
|
11695
11739
|
* Submit feedback on a test case to help improve test quality
|
|
11696
11740
|
* This empowers testers to shape better tests over time
|
|
@@ -12789,6 +12833,14 @@ var BugBearContext = (0, import_react.createContext)({
|
|
|
12789
12833
|
markAsRead: async () => {
|
|
12790
12834
|
},
|
|
12791
12835
|
createThread: async () => ({ success: false }),
|
|
12836
|
+
// QA Sessions
|
|
12837
|
+
activeSession: null,
|
|
12838
|
+
sessionFindings: [],
|
|
12839
|
+
startSession: async () => ({ success: false }),
|
|
12840
|
+
endSession: async () => ({ success: false }),
|
|
12841
|
+
addFinding: async () => ({ success: false }),
|
|
12842
|
+
refreshSession: async () => {
|
|
12843
|
+
},
|
|
12792
12844
|
refreshTesterStatus: async () => {
|
|
12793
12845
|
},
|
|
12794
12846
|
updateTesterProfile: async () => ({ success: false }),
|
|
@@ -12807,6 +12859,8 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12807
12859
|
const [isLoading, setIsLoading] = (0, import_react.useState)(true);
|
|
12808
12860
|
const [threads, setThreads] = (0, import_react.useState)([]);
|
|
12809
12861
|
const [unreadCount, setUnreadCount] = (0, import_react.useState)(0);
|
|
12862
|
+
const [activeSession, setActiveSession] = (0, import_react.useState)(null);
|
|
12863
|
+
const [sessionFindings, setSessionFindings] = (0, import_react.useState)([]);
|
|
12810
12864
|
const hasInitialized = (0, import_react.useRef)(false);
|
|
12811
12865
|
const getDeviceInfo = (0, import_react.useCallback)(() => {
|
|
12812
12866
|
const { width, height } = import_react_native.Dimensions.get("window");
|
|
@@ -12854,6 +12908,45 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12854
12908
|
}
|
|
12855
12909
|
return result;
|
|
12856
12910
|
}, [client, refreshThreads]);
|
|
12911
|
+
const refreshSession = (0, import_react.useCallback)(async () => {
|
|
12912
|
+
if (!client) return;
|
|
12913
|
+
const session = await client.getActiveSession();
|
|
12914
|
+
setActiveSession(session);
|
|
12915
|
+
if (session) {
|
|
12916
|
+
const findings = await client.getSessionFindings(session.id);
|
|
12917
|
+
setSessionFindings(findings);
|
|
12918
|
+
} else {
|
|
12919
|
+
setSessionFindings([]);
|
|
12920
|
+
}
|
|
12921
|
+
}, [client]);
|
|
12922
|
+
const startSession = (0, import_react.useCallback)(async (options = {}) => {
|
|
12923
|
+
if (!client) return { success: false, error: "Client not initialized" };
|
|
12924
|
+
const result = await client.startSession(options);
|
|
12925
|
+
if (result.success && result.session) {
|
|
12926
|
+
setActiveSession(result.session);
|
|
12927
|
+
setSessionFindings([]);
|
|
12928
|
+
}
|
|
12929
|
+
return { success: result.success, error: result.error };
|
|
12930
|
+
}, [client]);
|
|
12931
|
+
const endSession = (0, import_react.useCallback)(async (notes) => {
|
|
12932
|
+
if (!client || !activeSession) return { success: false, error: "No active session" };
|
|
12933
|
+
const routesCovered = client.getNavigationHistory();
|
|
12934
|
+
const result = await client.endSession(activeSession.id, { notes, routesCovered });
|
|
12935
|
+
if (result.success) {
|
|
12936
|
+
setActiveSession(null);
|
|
12937
|
+
setSessionFindings([]);
|
|
12938
|
+
}
|
|
12939
|
+
return { success: result.success, error: result.error };
|
|
12940
|
+
}, [client, activeSession]);
|
|
12941
|
+
const addFinding = (0, import_react.useCallback)(async (options) => {
|
|
12942
|
+
if (!client || !activeSession) return { success: false, error: "No active session" };
|
|
12943
|
+
const result = await client.addFinding(activeSession.id, options);
|
|
12944
|
+
if (result.success && result.finding) {
|
|
12945
|
+
setSessionFindings((prev) => [...prev, result.finding]);
|
|
12946
|
+
setActiveSession((prev) => prev ? { ...prev, findingsCount: prev.findingsCount + 1 } : null);
|
|
12947
|
+
}
|
|
12948
|
+
return result;
|
|
12949
|
+
}, [client, activeSession]);
|
|
12857
12950
|
const updateTesterProfile = (0, import_react.useCallback)(async (updates) => {
|
|
12858
12951
|
if (!client) return { success: false, error: "Client not initialized" };
|
|
12859
12952
|
const result = await client.updateTesterProfile(updates);
|
|
@@ -12880,14 +12973,20 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12880
12973
|
setTesterInfo(info);
|
|
12881
12974
|
setIsTester(!!info);
|
|
12882
12975
|
if (info && qaEnabled) {
|
|
12883
|
-
const [newAssignments, newThreads] = await Promise.all([
|
|
12976
|
+
const [newAssignments, newThreads, session] = await Promise.all([
|
|
12884
12977
|
bugBearClient.getAssignedTests(),
|
|
12885
|
-
bugBearClient.getThreadsForTester()
|
|
12978
|
+
bugBearClient.getThreadsForTester(),
|
|
12979
|
+
bugBearClient.getActiveSession()
|
|
12886
12980
|
]);
|
|
12887
12981
|
setAssignments(newAssignments);
|
|
12888
12982
|
setThreads(newThreads);
|
|
12889
12983
|
const totalUnread = newThreads.reduce((sum, t) => sum + t.unreadCount, 0);
|
|
12890
12984
|
setUnreadCount(totalUnread);
|
|
12985
|
+
setActiveSession(session);
|
|
12986
|
+
if (session) {
|
|
12987
|
+
const findings = await bugBearClient.getSessionFindings(session.id);
|
|
12988
|
+
setSessionFindings(findings);
|
|
12989
|
+
}
|
|
12891
12990
|
}
|
|
12892
12991
|
} catch (err) {
|
|
12893
12992
|
console.error("BugBear: Init error", err);
|
|
@@ -12934,6 +13033,13 @@ function BugBearProvider({ config, children, appVersion, enabled = true }) {
|
|
|
12934
13033
|
sendMessage,
|
|
12935
13034
|
markAsRead,
|
|
12936
13035
|
createThread,
|
|
13036
|
+
// QA Sessions
|
|
13037
|
+
activeSession,
|
|
13038
|
+
sessionFindings,
|
|
13039
|
+
startSession,
|
|
13040
|
+
endSession,
|
|
13041
|
+
addFinding,
|
|
13042
|
+
refreshSession,
|
|
12937
13043
|
refreshTesterStatus,
|
|
12938
13044
|
updateTesterProfile,
|
|
12939
13045
|
refreshTesterInfo
|
|
@@ -12981,7 +13087,13 @@ function BugBearButton({
|
|
|
12981
13087
|
markAsRead,
|
|
12982
13088
|
createThread,
|
|
12983
13089
|
updateTesterProfile,
|
|
12984
|
-
refreshTesterInfo
|
|
13090
|
+
refreshTesterInfo,
|
|
13091
|
+
activeSession,
|
|
13092
|
+
sessionFindings,
|
|
13093
|
+
startSession,
|
|
13094
|
+
endSession,
|
|
13095
|
+
addFinding,
|
|
13096
|
+
refreshSession
|
|
12985
13097
|
} = useBugBear();
|
|
12986
13098
|
const [modalVisible, setModalVisible] = (0, import_react2.useState)(false);
|
|
12987
13099
|
const [activeTab, setActiveTab] = (0, import_react2.useState)("tests");
|
|
@@ -13069,39 +13181,228 @@ function BugBearButton({
|
|
|
13069
13181
|
const [submitting, setSubmitting] = (0, import_react2.useState)(false);
|
|
13070
13182
|
const [submitted, setSubmitted] = (0, import_react2.useState)(false);
|
|
13071
13183
|
const [justPassed, setJustPassed] = (0, import_react2.useState)(false);
|
|
13184
|
+
const [showFeedbackPrompt, setShowFeedbackPrompt] = (0, import_react2.useState)(false);
|
|
13185
|
+
const [pendingFeedbackStatus, setPendingFeedbackStatus] = (0, import_react2.useState)(null);
|
|
13186
|
+
const [feedbackRating, setFeedbackRating] = (0, import_react2.useState)(5);
|
|
13187
|
+
const [feedbackNote, setFeedbackNote] = (0, import_react2.useState)("");
|
|
13188
|
+
const [feedbackFlags, setFeedbackFlags] = (0, import_react2.useState)({
|
|
13189
|
+
isOutdated: false,
|
|
13190
|
+
needsMoreDetail: false,
|
|
13191
|
+
stepsUnclear: false,
|
|
13192
|
+
expectedResultUnclear: false
|
|
13193
|
+
});
|
|
13072
13194
|
const [criteriaResults, setCriteriaResults] = (0, import_react2.useState)({});
|
|
13195
|
+
const [showSkipModal, setShowSkipModal] = (0, import_react2.useState)(false);
|
|
13196
|
+
const [selectedSkipReason, setSelectedSkipReason] = (0, import_react2.useState)(null);
|
|
13197
|
+
const [skipNotes, setSkipNotes] = (0, import_react2.useState)("");
|
|
13198
|
+
const [skipping, setSkipping] = (0, import_react2.useState)(false);
|
|
13199
|
+
const [collapsedFolders, setCollapsedFolders] = (0, import_react2.useState)(/* @__PURE__ */ new Set());
|
|
13200
|
+
const [startingSession, setStartingSession] = (0, import_react2.useState)(false);
|
|
13201
|
+
const [sessionFocusArea, setSessionFocusArea] = (0, import_react2.useState)("");
|
|
13202
|
+
const [sessionPlatform, setSessionPlatform] = (0, import_react2.useState)(import_react_native2.Platform.OS === "ios" ? "ios" : "android");
|
|
13203
|
+
const [showAddFinding, setShowAddFinding] = (0, import_react2.useState)(false);
|
|
13204
|
+
const [findingType, setFindingType] = (0, import_react2.useState)("bug");
|
|
13205
|
+
const [findingTitle, setFindingTitle] = (0, import_react2.useState)("");
|
|
13206
|
+
const [findingDescription, setFindingDescription] = (0, import_react2.useState)("");
|
|
13207
|
+
const [findingSeverity, setFindingSeverity] = (0, import_react2.useState)("medium");
|
|
13208
|
+
const [addingFinding, setAddingFinding] = (0, import_react2.useState)(false);
|
|
13209
|
+
const [endingSession, setEndingSession] = (0, import_react2.useState)(false);
|
|
13210
|
+
const [sessionNotes, setSessionNotes] = (0, import_react2.useState)("");
|
|
13211
|
+
const [showEndConfirm, setShowEndConfirm] = (0, import_react2.useState)(false);
|
|
13212
|
+
const [sessionElapsedTime, setSessionElapsedTime] = (0, import_react2.useState)(0);
|
|
13213
|
+
const [assignmentElapsedTime, setAssignmentElapsedTime] = (0, import_react2.useState)(0);
|
|
13214
|
+
(0, import_react2.useEffect)(() => {
|
|
13215
|
+
const activeAssignment = displayedAssignment?.status === "in_progress" ? displayedAssignment : null;
|
|
13216
|
+
if (!activeAssignment?.startedAt) {
|
|
13217
|
+
setAssignmentElapsedTime(0);
|
|
13218
|
+
return;
|
|
13219
|
+
}
|
|
13220
|
+
const startTime = new Date(activeAssignment.startedAt).getTime();
|
|
13221
|
+
setAssignmentElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13222
|
+
const interval = setInterval(() => {
|
|
13223
|
+
setAssignmentElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13224
|
+
}, 1e3);
|
|
13225
|
+
return () => clearInterval(interval);
|
|
13226
|
+
}, [displayedAssignment?.id, displayedAssignment?.status, displayedAssignment?.startedAt]);
|
|
13227
|
+
(0, import_react2.useEffect)(() => {
|
|
13228
|
+
if (!activeSession) {
|
|
13229
|
+
setSessionElapsedTime(0);
|
|
13230
|
+
return;
|
|
13231
|
+
}
|
|
13232
|
+
const startTime = new Date(activeSession.startedAt).getTime();
|
|
13233
|
+
setSessionElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13234
|
+
const interval = setInterval(() => {
|
|
13235
|
+
setSessionElapsedTime(Math.floor((Date.now() - startTime) / 1e3));
|
|
13236
|
+
}, 1e3);
|
|
13237
|
+
return () => clearInterval(interval);
|
|
13238
|
+
}, [activeSession]);
|
|
13239
|
+
const formatElapsedTime = (seconds) => {
|
|
13240
|
+
const h = Math.floor(seconds / 3600);
|
|
13241
|
+
const m = Math.floor(seconds % 3600 / 60);
|
|
13242
|
+
const s = seconds % 60;
|
|
13243
|
+
if (h > 0) return `${h}:${m.toString().padStart(2, "0")}:${s.toString().padStart(2, "0")}`;
|
|
13244
|
+
return `${m}:${s.toString().padStart(2, "0")}`;
|
|
13245
|
+
};
|
|
13073
13246
|
(0, import_react2.useEffect)(() => {
|
|
13074
13247
|
setCriteriaResults({});
|
|
13075
13248
|
setShowSteps(false);
|
|
13076
13249
|
}, [displayedAssignment?.id]);
|
|
13250
|
+
const groupedAssignments = (0, import_react2.useMemo)(() => {
|
|
13251
|
+
const groups = /* @__PURE__ */ new Map();
|
|
13252
|
+
for (const assignment of assignments) {
|
|
13253
|
+
const groupId = assignment.testCase.group?.id || "ungrouped";
|
|
13254
|
+
const group = assignment.testCase.group || null;
|
|
13255
|
+
if (!groups.has(groupId)) {
|
|
13256
|
+
groups.set(groupId, {
|
|
13257
|
+
group,
|
|
13258
|
+
assignments: [],
|
|
13259
|
+
stats: { total: 0, passed: 0, failed: 0, pending: 0, skipped: 0 }
|
|
13260
|
+
});
|
|
13261
|
+
}
|
|
13262
|
+
const folder = groups.get(groupId);
|
|
13263
|
+
folder.assignments.push(assignment);
|
|
13264
|
+
folder.stats.total++;
|
|
13265
|
+
if (assignment.status === "passed") folder.stats.passed++;
|
|
13266
|
+
else if (assignment.status === "failed") folder.stats.failed++;
|
|
13267
|
+
else if (assignment.status === "skipped") folder.stats.skipped++;
|
|
13268
|
+
else folder.stats.pending++;
|
|
13269
|
+
}
|
|
13270
|
+
const sortedGroups = Array.from(groups.values()).sort((a, b) => {
|
|
13271
|
+
if (!a.group && !b.group) return 0;
|
|
13272
|
+
if (!a.group) return 1;
|
|
13273
|
+
if (!b.group) return -1;
|
|
13274
|
+
return a.group.sortOrder - b.group.sortOrder;
|
|
13275
|
+
});
|
|
13276
|
+
return sortedGroups;
|
|
13277
|
+
}, [assignments]);
|
|
13278
|
+
const toggleFolderCollapse = (0, import_react2.useCallback)((groupId) => {
|
|
13279
|
+
setCollapsedFolders((prev) => {
|
|
13280
|
+
const next = new Set(prev);
|
|
13281
|
+
if (next.has(groupId)) {
|
|
13282
|
+
next.delete(groupId);
|
|
13283
|
+
} else {
|
|
13284
|
+
next.add(groupId);
|
|
13285
|
+
}
|
|
13286
|
+
return next;
|
|
13287
|
+
});
|
|
13288
|
+
}, []);
|
|
13289
|
+
const getStatusBadge = (status) => {
|
|
13290
|
+
switch (status) {
|
|
13291
|
+
case "passed":
|
|
13292
|
+
return { icon: "\u2705", label: "Passed", color: "#22c55e" };
|
|
13293
|
+
case "failed":
|
|
13294
|
+
return { icon: "\u274C", label: "Failed", color: "#ef4444" };
|
|
13295
|
+
case "skipped":
|
|
13296
|
+
return { icon: "\u23ED\uFE0F", label: "Skipped", color: "#eab308" };
|
|
13297
|
+
case "in_progress":
|
|
13298
|
+
return { icon: "\u{1F504}", label: "In Progress", color: "#3b82f6" };
|
|
13299
|
+
case "blocked":
|
|
13300
|
+
return { icon: "\u{1F6AB}", label: "Blocked", color: "#f97316" };
|
|
13301
|
+
case "pending":
|
|
13302
|
+
default:
|
|
13303
|
+
return { icon: "\u23F3", label: "Pending", color: "#71717a" };
|
|
13304
|
+
}
|
|
13305
|
+
};
|
|
13077
13306
|
if (isLoading || !shouldShowWidget) {
|
|
13078
13307
|
return null;
|
|
13079
13308
|
}
|
|
13080
13309
|
const pendingCount = assignments.filter((a) => a.status === "pending").length;
|
|
13081
13310
|
const inProgressCount = assignments.filter((a) => a.status === "in_progress").length;
|
|
13082
13311
|
const handlePass = async () => {
|
|
13312
|
+
if (!displayedAssignment) return;
|
|
13313
|
+
setPendingFeedbackStatus("passed");
|
|
13314
|
+
setShowFeedbackPrompt(true);
|
|
13315
|
+
setFeedbackRating(5);
|
|
13316
|
+
setFeedbackNote("");
|
|
13317
|
+
setFeedbackFlags({ isOutdated: false, needsMoreDetail: false, stepsUnclear: false, expectedResultUnclear: false });
|
|
13318
|
+
};
|
|
13319
|
+
const handleFail = () => {
|
|
13320
|
+
if (!displayedAssignment) return;
|
|
13321
|
+
setPendingFeedbackStatus("failed");
|
|
13322
|
+
setShowFeedbackPrompt(true);
|
|
13323
|
+
setFeedbackRating(3);
|
|
13324
|
+
setFeedbackNote("");
|
|
13325
|
+
setFeedbackFlags({ isOutdated: false, needsMoreDetail: false, stepsUnclear: false, expectedResultUnclear: false });
|
|
13326
|
+
};
|
|
13327
|
+
const handleSubmitFeedback = async (skipFeedback = false) => {
|
|
13083
13328
|
if (!client || !displayedAssignment) return;
|
|
13084
13329
|
setSubmitting(true);
|
|
13085
|
-
|
|
13086
|
-
|
|
13087
|
-
|
|
13088
|
-
|
|
13089
|
-
|
|
13090
|
-
|
|
13091
|
-
|
|
13092
|
-
}
|
|
13093
|
-
|
|
13094
|
-
|
|
13095
|
-
|
|
13096
|
-
|
|
13097
|
-
|
|
13330
|
+
const feedback = skipFeedback ? void 0 : {
|
|
13331
|
+
rating: feedbackRating,
|
|
13332
|
+
feedbackNote: feedbackNote.trim() || void 0,
|
|
13333
|
+
isOutdated: feedbackFlags.isOutdated,
|
|
13334
|
+
needsMoreDetail: feedbackFlags.needsMoreDetail,
|
|
13335
|
+
stepsUnclear: feedbackFlags.stepsUnclear,
|
|
13336
|
+
expectedResultUnclear: feedbackFlags.expectedResultUnclear
|
|
13337
|
+
};
|
|
13338
|
+
if (pendingFeedbackStatus === "passed") {
|
|
13339
|
+
await client.submitReport({
|
|
13340
|
+
type: "test_pass",
|
|
13341
|
+
description: `Test passed: ${displayedAssignment.testCase.title}`,
|
|
13342
|
+
assignmentId: displayedAssignment.id,
|
|
13343
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13344
|
+
appContext: getAppContext?.() || { currentRoute: "unknown" },
|
|
13345
|
+
deviceInfo: getDeviceInfo()
|
|
13346
|
+
});
|
|
13347
|
+
if (feedback) {
|
|
13348
|
+
await client.submitTestFeedback({
|
|
13349
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13350
|
+
assignmentId: displayedAssignment.id,
|
|
13351
|
+
feedback,
|
|
13352
|
+
timeToCompleteSeconds: assignmentElapsedTime || void 0
|
|
13353
|
+
});
|
|
13354
|
+
}
|
|
13355
|
+
await refreshAssignments();
|
|
13356
|
+
setSubmitting(false);
|
|
13357
|
+
setShowFeedbackPrompt(false);
|
|
13358
|
+
setPendingFeedbackStatus(null);
|
|
13359
|
+
setJustPassed(true);
|
|
13360
|
+
setTimeout(() => {
|
|
13361
|
+
setJustPassed(false);
|
|
13362
|
+
setSelectedTestId(null);
|
|
13363
|
+
setTestView("detail");
|
|
13364
|
+
}, 1200);
|
|
13365
|
+
} else if (pendingFeedbackStatus === "failed") {
|
|
13366
|
+
if (feedback) {
|
|
13367
|
+
await client.submitTestFeedback({
|
|
13368
|
+
testCaseId: displayedAssignment.testCase.id,
|
|
13369
|
+
assignmentId: displayedAssignment.id,
|
|
13370
|
+
feedback,
|
|
13371
|
+
timeToCompleteSeconds: assignmentElapsedTime || void 0
|
|
13372
|
+
});
|
|
13373
|
+
}
|
|
13374
|
+
setSubmitting(false);
|
|
13375
|
+
setShowFeedbackPrompt(false);
|
|
13376
|
+
setPendingFeedbackStatus(null);
|
|
13377
|
+
setActiveTab("report");
|
|
13378
|
+
setReportType("test_fail");
|
|
13379
|
+
}
|
|
13380
|
+
};
|
|
13381
|
+
const handleSkipFeedback = () => {
|
|
13382
|
+
handleSubmitFeedback(true);
|
|
13383
|
+
};
|
|
13384
|
+
const handleOpenSkipModal = () => {
|
|
13385
|
+
setShowSkipModal(true);
|
|
13386
|
+
setSelectedSkipReason(null);
|
|
13387
|
+
setSkipNotes("");
|
|
13388
|
+
};
|
|
13389
|
+
const handleSkip = async () => {
|
|
13390
|
+
if (!client || !displayedAssignment || !selectedSkipReason) return;
|
|
13391
|
+
setSkipping(true);
|
|
13392
|
+
const result = await client.skipAssignment(
|
|
13393
|
+
displayedAssignment.id,
|
|
13394
|
+
selectedSkipReason,
|
|
13395
|
+
skipNotes || void 0
|
|
13396
|
+
);
|
|
13397
|
+
if (result.success) {
|
|
13398
|
+
await refreshAssignments();
|
|
13399
|
+
setShowSkipModal(false);
|
|
13400
|
+
setSelectedSkipReason(null);
|
|
13401
|
+
setSkipNotes("");
|
|
13098
13402
|
setSelectedTestId(null);
|
|
13099
13403
|
setTestView("detail");
|
|
13100
|
-
}
|
|
13101
|
-
|
|
13102
|
-
const handleFail = () => {
|
|
13103
|
-
setActiveTab("report");
|
|
13104
|
-
setReportType("test_fail");
|
|
13404
|
+
}
|
|
13405
|
+
setSkipping(false);
|
|
13105
13406
|
};
|
|
13106
13407
|
const handleSubmitReport = async () => {
|
|
13107
13408
|
if (!client || !description.trim()) return;
|
|
@@ -13248,6 +13549,44 @@ function BugBearButton({
|
|
|
13248
13549
|
}
|
|
13249
13550
|
setSavingProfile(false);
|
|
13250
13551
|
};
|
|
13552
|
+
const handleStartSession = async () => {
|
|
13553
|
+
setStartingSession(true);
|
|
13554
|
+
const result = await startSession({
|
|
13555
|
+
focusArea: sessionFocusArea.trim() || void 0,
|
|
13556
|
+
platform: sessionPlatform
|
|
13557
|
+
});
|
|
13558
|
+
if (result.success) {
|
|
13559
|
+
setSessionFocusArea("");
|
|
13560
|
+
}
|
|
13561
|
+
setStartingSession(false);
|
|
13562
|
+
};
|
|
13563
|
+
const handleEndSession = async () => {
|
|
13564
|
+
setEndingSession(true);
|
|
13565
|
+
const result = await endSession(sessionNotes.trim() || void 0);
|
|
13566
|
+
if (result.success) {
|
|
13567
|
+
setSessionNotes("");
|
|
13568
|
+
setShowEndConfirm(false);
|
|
13569
|
+
}
|
|
13570
|
+
setEndingSession(false);
|
|
13571
|
+
};
|
|
13572
|
+
const handleAddFinding = async () => {
|
|
13573
|
+
if (!findingTitle.trim()) return;
|
|
13574
|
+
setAddingFinding(true);
|
|
13575
|
+
const result = await addFinding({
|
|
13576
|
+
type: findingType,
|
|
13577
|
+
title: findingTitle.trim(),
|
|
13578
|
+
description: findingDescription.trim() || void 0,
|
|
13579
|
+
severity: findingType === "bug" ? findingSeverity : void 0
|
|
13580
|
+
});
|
|
13581
|
+
if (result.success) {
|
|
13582
|
+
setFindingTitle("");
|
|
13583
|
+
setFindingDescription("");
|
|
13584
|
+
setFindingType("bug");
|
|
13585
|
+
setFindingSeverity("medium");
|
|
13586
|
+
setShowAddFinding(false);
|
|
13587
|
+
}
|
|
13588
|
+
setAddingFinding(false);
|
|
13589
|
+
};
|
|
13251
13590
|
const formatRelativeTime = (dateString) => {
|
|
13252
13591
|
const date = new Date(dateString);
|
|
13253
13592
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -13431,6 +13770,13 @@ function BugBearButton({
|
|
|
13431
13770
|
onPress: () => setActiveTab("messages")
|
|
13432
13771
|
},
|
|
13433
13772
|
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.tabWithBadge }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [styles.tabText, activeTab === "messages" && styles.activeTabText] }, "Messages"), unreadCount > 0 && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.tabBadge }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.tabBadgeText }, unreadCount)))
|
|
13773
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
13774
|
+
import_react_native2.TouchableOpacity,
|
|
13775
|
+
{
|
|
13776
|
+
style: [styles.tab, activeTab === "explore" && styles.activeTab],
|
|
13777
|
+
onPress: () => setActiveTab("explore")
|
|
13778
|
+
},
|
|
13779
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.tabWithBadge }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [styles.tabText, activeTab === "explore" && styles.activeTabText] }, "Explore"), activeSession && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.sessionDot }))
|
|
13434
13780
|
), /* @__PURE__ */ import_react2.default.createElement(
|
|
13435
13781
|
import_react_native2.TouchableOpacity,
|
|
13436
13782
|
{
|
|
@@ -13439,32 +13785,114 @@ function BugBearButton({
|
|
|
13439
13785
|
},
|
|
13440
13786
|
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [styles.tabText, activeTab === "report" && styles.activeTabText] }, "Report")
|
|
13441
13787
|
)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.ScrollView, { style: styles.content }, activeTab === "tests" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, assignments.length === 0 ? /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyEmoji }, "\u2705"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyTitle }, "All caught up!"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptySubtitle }, "No tests assigned")) : testView === "list" ? (
|
|
13442
|
-
/* List View - Show
|
|
13443
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.listHeader }, assignments.length, " test", assignments.length !== 1 ? "s" : "", " assigned"),
|
|
13788
|
+
/* List View - Show tests grouped by folder */
|
|
13789
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.listHeader }, assignments.length, " test", assignments.length !== 1 ? "s" : "", " assigned"), groupedAssignments.map((folder) => {
|
|
13790
|
+
const groupId = folder.group?.id || "ungrouped";
|
|
13791
|
+
const isCollapsed = collapsedFolders.has(groupId);
|
|
13792
|
+
const completedCount = folder.stats.passed + folder.stats.failed + folder.stats.skipped;
|
|
13793
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { key: groupId, style: styles.folderContainer }, /* @__PURE__ */ import_react2.default.createElement(
|
|
13794
|
+
import_react_native2.TouchableOpacity,
|
|
13795
|
+
{
|
|
13796
|
+
onPress: () => toggleFolderCollapse(groupId),
|
|
13797
|
+
style: styles.folderHeader
|
|
13798
|
+
},
|
|
13799
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.folderHeaderLeft }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.folderIcon }, isCollapsed ? "\u{1F4C1}" : "\u{1F4C2}"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.folderName }, folder.group?.name || "Ungrouped Tests")),
|
|
13800
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.folderStats }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.folderProgress }, completedCount, "/", folder.stats.total), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.folderChevron }, isCollapsed ? "\u25B6" : "\u25BC"))
|
|
13801
|
+
), !isCollapsed && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.folderProgressBar }, /* @__PURE__ */ import_react2.default.createElement(
|
|
13802
|
+
import_react_native2.View,
|
|
13803
|
+
{
|
|
13804
|
+
style: [
|
|
13805
|
+
styles.folderProgressFill,
|
|
13806
|
+
{ width: `${completedCount / folder.stats.total * 100}%` }
|
|
13807
|
+
]
|
|
13808
|
+
}
|
|
13809
|
+
)), !isCollapsed && folder.assignments.map((assignment) => {
|
|
13810
|
+
const statusBadge = getStatusBadge(assignment.status);
|
|
13811
|
+
return /* @__PURE__ */ import_react2.default.createElement(
|
|
13812
|
+
import_react_native2.TouchableOpacity,
|
|
13813
|
+
{
|
|
13814
|
+
key: assignment.id,
|
|
13815
|
+
onPress: () => {
|
|
13816
|
+
setSelectedTestId(assignment.id);
|
|
13817
|
+
setTestView("detail");
|
|
13818
|
+
setShowSteps(false);
|
|
13819
|
+
},
|
|
13820
|
+
style: [
|
|
13821
|
+
styles.listItem,
|
|
13822
|
+
styles.listItemInFolder,
|
|
13823
|
+
assignment.id === currentAssignment?.id && styles.listItemCurrent
|
|
13824
|
+
]
|
|
13825
|
+
},
|
|
13826
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.listItemHeader }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.listItemKeyWithStatus }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.listItemKey }, assignment.testCase.testKey), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: [styles.statusBadge, { backgroundColor: statusBadge.color + "20" }] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.statusBadgeIcon }, statusBadge.icon), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [styles.statusBadgeText, { color: statusBadge.color }] }, statusBadge.label))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.listItemBadges }, assignment.testCase.track && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: [styles.trackBadge, { backgroundColor: assignment.testCase.track.color }] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.trackBadgeText }, templateInfo[assignment.testCase.track.testTemplate || "steps"].icon)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: [
|
|
13827
|
+
styles.priorityBadge,
|
|
13828
|
+
assignment.testCase.priority === "P0" && styles.priorityP0,
|
|
13829
|
+
assignment.testCase.priority === "P1" && styles.priorityP1
|
|
13830
|
+
] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.priorityText }, assignment.testCase.priority)))),
|
|
13831
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.listItemTitle, numberOfLines: 2 }, assignment.testCase.title),
|
|
13832
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.listItemMeta }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.listItemMetaText }, assignment.testCase.steps.length, " ", assignment.testCase.track?.testTemplate === "checklist" ? "items" : assignment.testCase.track?.testTemplate === "rubric" ? "criteria" : "steps"), assignment.id === currentAssignment?.id && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.currentBadge }, "\u2022 Current"))
|
|
13833
|
+
);
|
|
13834
|
+
}));
|
|
13835
|
+
}))
|
|
13836
|
+
) : justPassed ? (
|
|
13837
|
+
/* Success state after passing */
|
|
13838
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.passedEmoji }, "\u2713"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.passedTitle }, "Passed!"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptySubtitle }, "Loading next test..."))
|
|
13839
|
+
) : showFeedbackPrompt && displayedAssignment ? (
|
|
13840
|
+
/* Feedback prompt after completing a test */
|
|
13841
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.container }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { alignItems: "center", marginBottom: 16 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: { fontSize: 28 } }, pendingFeedbackStatus === "passed" ? "\u2713" : "\u2717"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [feedbackStyles.statusText, pendingFeedbackStatus === "passed" ? { color: "#4ade80" } : { color: "#f87171" }] }, pendingFeedbackStatus === "passed" ? "Test Passed!" : "Test Failed")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.infoBox }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.infoTitle }, "Help us improve this test"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.infoSubtitle }, "Your feedback shapes better tests for everyone.")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.ratingSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.ratingLabel }, "How was this test?"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.starsRow }, [1, 2, 3, 4, 5].map((star) => /* @__PURE__ */ import_react2.default.createElement(
|
|
13444
13842
|
import_react_native2.TouchableOpacity,
|
|
13445
13843
|
{
|
|
13446
|
-
key:
|
|
13447
|
-
onPress: () =>
|
|
13448
|
-
|
|
13449
|
-
|
|
13450
|
-
|
|
13451
|
-
|
|
13844
|
+
key: star,
|
|
13845
|
+
onPress: () => setFeedbackRating(star)
|
|
13846
|
+
},
|
|
13847
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [feedbackStyles.star, star <= feedbackRating ? feedbackStyles.starActive : feedbackStyles.starInactive] }, "\u2605")
|
|
13848
|
+
))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.ratingDesc }, feedbackRating === 1 ? "Needs work" : feedbackRating === 2 ? "Could be better" : feedbackRating === 3 ? "Okay" : feedbackRating === 4 ? "Good" : "Great!")), feedbackRating < 4 && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.flagsSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.ratingLabel }, "What could be improved?"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.flagsGrid }, [
|
|
13849
|
+
{ key: "stepsUnclear", label: "Steps unclear" },
|
|
13850
|
+
{ key: "expectedResultUnclear", label: "Expected result unclear" },
|
|
13851
|
+
{ key: "needsMoreDetail", label: "Needs more detail" },
|
|
13852
|
+
{ key: "isOutdated", label: "Seems outdated" }
|
|
13853
|
+
].map(({ key, label }) => /* @__PURE__ */ import_react2.default.createElement(
|
|
13854
|
+
import_react_native2.TouchableOpacity,
|
|
13855
|
+
{
|
|
13856
|
+
key,
|
|
13857
|
+
onPress: () => setFeedbackFlags((prev) => ({ ...prev, [key]: !prev[key] })),
|
|
13452
13858
|
style: [
|
|
13453
|
-
|
|
13454
|
-
|
|
13859
|
+
feedbackStyles.flagButton,
|
|
13860
|
+
feedbackFlags[key] && feedbackStyles.flagButtonActive
|
|
13455
13861
|
]
|
|
13456
13862
|
},
|
|
13457
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.
|
|
13458
|
-
|
|
13459
|
-
|
|
13460
|
-
|
|
13461
|
-
|
|
13462
|
-
|
|
13463
|
-
|
|
13863
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
|
|
13864
|
+
feedbackStyles.flagButtonText,
|
|
13865
|
+
feedbackFlags[key] && feedbackStyles.flagButtonTextActive
|
|
13866
|
+
] }, label)
|
|
13867
|
+
)))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { marginBottom: 12 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.ratingLabel }, "Suggestions? (optional)"), /* @__PURE__ */ import_react2.default.createElement(
|
|
13868
|
+
import_react_native2.TextInput,
|
|
13869
|
+
{
|
|
13870
|
+
style: feedbackStyles.noteInput,
|
|
13871
|
+
value: feedbackNote,
|
|
13872
|
+
onChangeText: setFeedbackNote,
|
|
13873
|
+
placeholder: "How could this test be improved?",
|
|
13874
|
+
placeholderTextColor: "#71717a",
|
|
13875
|
+
multiline: true,
|
|
13876
|
+
numberOfLines: 2,
|
|
13877
|
+
textAlignVertical: "top"
|
|
13878
|
+
}
|
|
13879
|
+
)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: feedbackStyles.buttonRow }, /* @__PURE__ */ import_react2.default.createElement(
|
|
13880
|
+
import_react_native2.TouchableOpacity,
|
|
13881
|
+
{
|
|
13882
|
+
onPress: handleSkipFeedback,
|
|
13883
|
+
disabled: submitting,
|
|
13884
|
+
style: [feedbackStyles.skipButton, submitting && { opacity: 0.5 }]
|
|
13885
|
+
},
|
|
13886
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.skipButtonText }, "Skip")
|
|
13887
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
13888
|
+
import_react_native2.TouchableOpacity,
|
|
13889
|
+
{
|
|
13890
|
+
onPress: () => handleSubmitFeedback(false),
|
|
13891
|
+
disabled: submitting,
|
|
13892
|
+
style: [feedbackStyles.submitButton, submitting && { opacity: 0.5 }]
|
|
13893
|
+
},
|
|
13894
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: feedbackStyles.submitButtonText }, submitting ? "Submitting..." : "Submit Feedback")
|
|
13464
13895
|
)))
|
|
13465
|
-
) : justPassed ? (
|
|
13466
|
-
/* Success state after passing */
|
|
13467
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.passedEmoji }, "\u2713"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.passedTitle }, "Passed!"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptySubtitle }, "Loading next test..."))
|
|
13468
13896
|
) : displayedAssignment ? (
|
|
13469
13897
|
/* Detail View - Show single test */
|
|
13470
13898
|
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(
|
|
@@ -13481,20 +13909,41 @@ function BugBearButton({
|
|
|
13481
13909
|
styles.priorityBadge,
|
|
13482
13910
|
displayedAssignment.testCase.priority === "P0" && styles.priorityP0,
|
|
13483
13911
|
displayedAssignment.testCase.priority === "P1" && styles.priorityP1
|
|
13484
|
-
] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.priorityText }, displayedAssignment.testCase.priority)))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.testTitle }, displayedAssignment.testCase.title), displayedAssignment.testCase.description && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.testDescription }, displayedAssignment.testCase.description), displayedAssignment.testCase.targetRoute && onNavigate && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: handleNavigate, style: styles.navigateButton }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.navigateButtonText }, "Go to test location \u2192")), renderTestContent(), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.expectedResult }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.expectedLabel }, displayedAssignment.testCase.track?.testTemplate === "checklist" ? "Pass criteria:" : displayedAssignment.testCase.track?.testTemplate === "rubric" ? "Target score:" : "Expected:"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.expectedText }, displayedAssignment.testCase.expectedResult))),
|
|
13912
|
+
] }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.priorityText }, displayedAssignment.testCase.priority)))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.testTitle }, displayedAssignment.testCase.title), displayedAssignment.status === "in_progress" && displayedAssignment.startedAt && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: timerStyles.container }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: timerStyles.dot }), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: timerStyles.label }, "Testing"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: timerStyles.time }, formatElapsedTime(assignmentElapsedTime))), displayedAssignment.testCase.description && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.testDescription }, displayedAssignment.testCase.description), displayedAssignment.testCase.targetRoute && onNavigate && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: handleNavigate, style: styles.navigateButton }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.navigateButtonText }, "Go to test location \u2192")), renderTestContent(), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.expectedResult }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.expectedLabel }, displayedAssignment.testCase.track?.testTemplate === "checklist" ? "Pass criteria:" : displayedAssignment.testCase.track?.testTemplate === "rubric" ? "Target score:" : "Expected:"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.expectedText }, displayedAssignment.testCase.expectedResult))), displayedAssignment.testCase.group && (() => {
|
|
13913
|
+
const folder = groupedAssignments.find((f) => f.group?.id === displayedAssignment.testCase.group?.id);
|
|
13914
|
+
if (!folder) return null;
|
|
13915
|
+
const completedCount = folder.stats.passed + folder.stats.failed + folder.stats.skipped;
|
|
13916
|
+
return /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.detailProgressContainer }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.detailProgressText }, folder.group?.name, ": ", completedCount, "/", folder.stats.total, " complete"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.detailProgressBar }, /* @__PURE__ */ import_react2.default.createElement(
|
|
13917
|
+
import_react_native2.View,
|
|
13918
|
+
{
|
|
13919
|
+
style: [
|
|
13920
|
+
styles.detailProgressFill,
|
|
13921
|
+
{ width: `${completedCount / folder.stats.total * 100}%` }
|
|
13922
|
+
]
|
|
13923
|
+
}
|
|
13924
|
+
)));
|
|
13925
|
+
})(), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.actionButtons }, /* @__PURE__ */ import_react2.default.createElement(
|
|
13485
13926
|
import_react_native2.TouchableOpacity,
|
|
13486
13927
|
{
|
|
13487
13928
|
style: styles.failButton,
|
|
13488
13929
|
onPress: handleFail,
|
|
13489
|
-
disabled: submitting
|
|
13930
|
+
disabled: submitting || skipping
|
|
13490
13931
|
},
|
|
13491
13932
|
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.failButtonText }, "\u2717 Fail")
|
|
13933
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
13934
|
+
import_react_native2.TouchableOpacity,
|
|
13935
|
+
{
|
|
13936
|
+
style: styles.skipButton,
|
|
13937
|
+
onPress: handleOpenSkipModal,
|
|
13938
|
+
disabled: submitting || skipping
|
|
13939
|
+
},
|
|
13940
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipButtonText }, skipping ? "..." : "\u2192 Skip")
|
|
13492
13941
|
), /* @__PURE__ */ import_react2.default.createElement(
|
|
13493
13942
|
import_react_native2.TouchableOpacity,
|
|
13494
13943
|
{
|
|
13495
13944
|
style: styles.passButton,
|
|
13496
13945
|
onPress: handlePass,
|
|
13497
|
-
disabled: submitting
|
|
13946
|
+
disabled: submitting || skipping
|
|
13498
13947
|
},
|
|
13499
13948
|
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.passButtonText }, submitting ? "..." : "\u2713 Pass")
|
|
13500
13949
|
)))
|
|
@@ -13582,6 +14031,166 @@ function BugBearButton({
|
|
|
13582
14031
|
message.senderType === "tester" && styles.messageTimeTester
|
|
13583
14032
|
] }, formatMessageTime(message.createdAt))
|
|
13584
14033
|
))))
|
|
14034
|
+
)), activeTab === "explore" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, !activeSession ? (
|
|
14035
|
+
/* Start Session View */
|
|
14036
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyEmoji }, "\u{1F50D}"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyTitle }, "Exploratory QA Session"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptySubtitle }, "Explore freely and capture findings as you go")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Focus Area (optional)"), /* @__PURE__ */ import_react2.default.createElement(
|
|
14037
|
+
import_react_native2.TextInput,
|
|
14038
|
+
{
|
|
14039
|
+
style: exploreStyles.input,
|
|
14040
|
+
value: sessionFocusArea,
|
|
14041
|
+
onChangeText: setSessionFocusArea,
|
|
14042
|
+
placeholder: "e.g., checkout flow, settings page",
|
|
14043
|
+
placeholderTextColor: "#71717a"
|
|
14044
|
+
}
|
|
14045
|
+
)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Platform"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.platformRow }, [
|
|
14046
|
+
{ key: "ios", label: "\u{1F4F1} iOS" },
|
|
14047
|
+
{ key: "android", label: "\u{1F916} Android" },
|
|
14048
|
+
{ key: "web", label: "\u{1F310} Web" }
|
|
14049
|
+
].map(({ key, label }) => /* @__PURE__ */ import_react2.default.createElement(
|
|
14050
|
+
import_react_native2.TouchableOpacity,
|
|
14051
|
+
{
|
|
14052
|
+
key,
|
|
14053
|
+
onPress: () => setSessionPlatform(key),
|
|
14054
|
+
style: [
|
|
14055
|
+
exploreStyles.platformButton,
|
|
14056
|
+
sessionPlatform === key && exploreStyles.platformButtonActive
|
|
14057
|
+
]
|
|
14058
|
+
},
|
|
14059
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
|
|
14060
|
+
exploreStyles.platformButtonText,
|
|
14061
|
+
sessionPlatform === key && exploreStyles.platformButtonTextActive
|
|
14062
|
+
] }, label)
|
|
14063
|
+
)))), /* @__PURE__ */ import_react2.default.createElement(
|
|
14064
|
+
import_react_native2.TouchableOpacity,
|
|
14065
|
+
{
|
|
14066
|
+
onPress: handleStartSession,
|
|
14067
|
+
disabled: startingSession,
|
|
14068
|
+
style: [exploreStyles.startButton, startingSession && { opacity: 0.5 }]
|
|
14069
|
+
},
|
|
14070
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.startButtonText }, startingSession ? "Starting..." : "\u25B6 Start Session")
|
|
14071
|
+
))
|
|
14072
|
+
) : showEndConfirm ? (
|
|
14073
|
+
/* End Session Confirmation */
|
|
14074
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyEmoji }, "\u270B"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyTitle }, "End Session?"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptySubtitle }, "Duration: ", formatElapsedTime(sessionElapsedTime), " \xB7 ", sessionFindings.length, " finding", sessionFindings.length !== 1 ? "s" : "")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Session Notes (optional)"), /* @__PURE__ */ import_react2.default.createElement(
|
|
14075
|
+
import_react_native2.TextInput,
|
|
14076
|
+
{
|
|
14077
|
+
style: [exploreStyles.input, { height: 80, textAlignVertical: "top" }],
|
|
14078
|
+
value: sessionNotes,
|
|
14079
|
+
onChangeText: setSessionNotes,
|
|
14080
|
+
placeholder: "Any overall observations from this session...",
|
|
14081
|
+
placeholderTextColor: "#71717a",
|
|
14082
|
+
multiline: true
|
|
14083
|
+
}
|
|
14084
|
+
)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.buttonRow }, /* @__PURE__ */ import_react2.default.createElement(
|
|
14085
|
+
import_react_native2.TouchableOpacity,
|
|
14086
|
+
{
|
|
14087
|
+
onPress: () => setShowEndConfirm(false),
|
|
14088
|
+
style: exploreStyles.cancelButton
|
|
14089
|
+
},
|
|
14090
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.cancelButtonText }, "Cancel")
|
|
14091
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
14092
|
+
import_react_native2.TouchableOpacity,
|
|
14093
|
+
{
|
|
14094
|
+
onPress: handleEndSession,
|
|
14095
|
+
disabled: endingSession,
|
|
14096
|
+
style: [exploreStyles.endButton, endingSession && { opacity: 0.5 }]
|
|
14097
|
+
},
|
|
14098
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.endButtonText }, endingSession ? "Ending..." : "End Session")
|
|
14099
|
+
)))
|
|
14100
|
+
) : showAddFinding ? (
|
|
14101
|
+
/* Add Finding Form */
|
|
14102
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.findingHeader }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingHeaderTitle }, "Add Finding"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: () => setShowAddFinding(false) }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingHeaderClose }, "\u2715"))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.findingTypeRow }, [
|
|
14103
|
+
{ type: "bug", label: "\u{1F41B} Bug" },
|
|
14104
|
+
{ type: "concern", label: "\u26A0\uFE0F Concern" },
|
|
14105
|
+
{ type: "suggestion", label: "\u{1F4A1} Idea" },
|
|
14106
|
+
{ type: "question", label: "\u2753 Q" }
|
|
14107
|
+
].map(({ type, label }) => /* @__PURE__ */ import_react2.default.createElement(
|
|
14108
|
+
import_react_native2.TouchableOpacity,
|
|
14109
|
+
{
|
|
14110
|
+
key: type,
|
|
14111
|
+
onPress: () => setFindingType(type),
|
|
14112
|
+
style: [
|
|
14113
|
+
exploreStyles.findingTypeButton,
|
|
14114
|
+
findingType === type && exploreStyles.findingTypeButtonActive
|
|
14115
|
+
]
|
|
14116
|
+
},
|
|
14117
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
|
|
14118
|
+
exploreStyles.findingTypeButtonText,
|
|
14119
|
+
findingType === type && exploreStyles.findingTypeButtonTextActive
|
|
14120
|
+
] }, label)
|
|
14121
|
+
))), findingType === "bug" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Severity"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.severityRow }, ["critical", "high", "medium", "low"].map((sev) => /* @__PURE__ */ import_react2.default.createElement(
|
|
14122
|
+
import_react_native2.TouchableOpacity,
|
|
14123
|
+
{
|
|
14124
|
+
key: sev,
|
|
14125
|
+
onPress: () => setFindingSeverity(sev),
|
|
14126
|
+
style: [
|
|
14127
|
+
exploreStyles.severityButton,
|
|
14128
|
+
findingSeverity === sev && (sev === "critical" ? exploreStyles.severityCritical : sev === "high" ? exploreStyles.severityHigh : sev === "medium" ? exploreStyles.severityMedium : exploreStyles.severityLow)
|
|
14129
|
+
]
|
|
14130
|
+
},
|
|
14131
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
|
|
14132
|
+
exploreStyles.severityButtonText,
|
|
14133
|
+
findingSeverity === sev && exploreStyles.severityButtonTextActive
|
|
14134
|
+
] }, sev)
|
|
14135
|
+
)))), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Title *"), /* @__PURE__ */ import_react2.default.createElement(
|
|
14136
|
+
import_react_native2.TextInput,
|
|
14137
|
+
{
|
|
14138
|
+
style: exploreStyles.input,
|
|
14139
|
+
value: findingTitle,
|
|
14140
|
+
onChangeText: setFindingTitle,
|
|
14141
|
+
placeholder: "Brief description of what you found",
|
|
14142
|
+
placeholderTextColor: "#71717a"
|
|
14143
|
+
}
|
|
14144
|
+
)), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.formGroup }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.label }, "Details (optional)"), /* @__PURE__ */ import_react2.default.createElement(
|
|
14145
|
+
import_react_native2.TextInput,
|
|
14146
|
+
{
|
|
14147
|
+
style: [exploreStyles.input, { height: 60, textAlignVertical: "top" }],
|
|
14148
|
+
value: findingDescription,
|
|
14149
|
+
onChangeText: setFindingDescription,
|
|
14150
|
+
placeholder: "Steps to reproduce, expected behavior, etc.",
|
|
14151
|
+
placeholderTextColor: "#71717a",
|
|
14152
|
+
multiline: true
|
|
14153
|
+
}
|
|
14154
|
+
)), /* @__PURE__ */ import_react2.default.createElement(
|
|
14155
|
+
import_react_native2.TouchableOpacity,
|
|
14156
|
+
{
|
|
14157
|
+
onPress: handleAddFinding,
|
|
14158
|
+
disabled: addingFinding || !findingTitle.trim(),
|
|
14159
|
+
style: [exploreStyles.addFindingButton, (addingFinding || !findingTitle.trim()) && { opacity: 0.5 }]
|
|
14160
|
+
},
|
|
14161
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.addFindingButtonText }, addingFinding ? "Adding..." : "Add Finding")
|
|
14162
|
+
))
|
|
14163
|
+
) : (
|
|
14164
|
+
/* Active Session View */
|
|
14165
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.sessionBanner }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.sessionBannerRow }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.sessionBannerLeft }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.sessionDotLarge }), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.sessionBannerLabel }, "Session Active")), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.sessionTimer }, formatElapsedTime(sessionElapsedTime))), activeSession.focusArea && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.sessionFocus }, "Focus: ", activeSession.focusArea)), /* @__PURE__ */ import_react2.default.createElement(
|
|
14166
|
+
import_react_native2.TouchableOpacity,
|
|
14167
|
+
{
|
|
14168
|
+
onPress: () => setShowAddFinding(true),
|
|
14169
|
+
style: exploreStyles.addButton
|
|
14170
|
+
},
|
|
14171
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.addButtonText }, "+ Add Finding")
|
|
14172
|
+
), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.findingsSection }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingsLabel }, "Findings (", sessionFindings.length, ")"), sessionFindings.length === 0 ? /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: exploreStyles.findingsEmpty }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingsEmptyText }, "No findings yet"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingsEmptyText }, "Explore and add findings as you go")) : /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, sessionFindings.map((finding) => /* @__PURE__ */ import_react2.default.createElement(
|
|
14173
|
+
import_react_native2.View,
|
|
14174
|
+
{
|
|
14175
|
+
key: finding.id,
|
|
14176
|
+
style: [
|
|
14177
|
+
exploreStyles.findingCard,
|
|
14178
|
+
finding.type === "bug" ? exploreStyles.findingCardBug : finding.type === "concern" ? exploreStyles.findingCardConcern : finding.type === "suggestion" ? exploreStyles.findingCardSuggestion : exploreStyles.findingCardQuestion
|
|
14179
|
+
]
|
|
14180
|
+
},
|
|
14181
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingCardIcon }, finding.type === "bug" ? "\u{1F41B}" : finding.type === "concern" ? "\u26A0\uFE0F" : finding.type === "suggestion" ? "\u{1F4A1}" : "\u2753"),
|
|
14182
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: { flex: 1 } }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.findingCardTitle, numberOfLines: 1 }, finding.title), finding.severity && finding.type === "bug" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: [
|
|
14183
|
+
exploreStyles.findingCardSeverity,
|
|
14184
|
+
finding.severity === "critical" ? { color: "#f87171" } : finding.severity === "high" ? { color: "#fb923c" } : finding.severity === "medium" ? { color: "#facc15" } : { color: "#a1a1aa" }
|
|
14185
|
+
] }, finding.severity))
|
|
14186
|
+
)))), /* @__PURE__ */ import_react2.default.createElement(
|
|
14187
|
+
import_react_native2.TouchableOpacity,
|
|
14188
|
+
{
|
|
14189
|
+
onPress: () => setShowEndConfirm(true),
|
|
14190
|
+
style: exploreStyles.endSessionButton
|
|
14191
|
+
},
|
|
14192
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: exploreStyles.endSessionButtonText }, "End Session")
|
|
14193
|
+
))
|
|
13585
14194
|
)), activeTab === "report" && /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, null, submitted ? /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.emptyState }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyEmoji }, "\u{1F389}"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.emptyTitle }, "Report submitted!")) : /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.reportTypes }, [
|
|
13586
14195
|
{ type: "bug", label: "\u{1F41B} Bug" },
|
|
13587
14196
|
{ type: "feedback", label: "\u{1F4A1} Feedback" },
|
|
@@ -13746,9 +14355,64 @@ function BugBearButton({
|
|
|
13746
14355
|
))
|
|
13747
14356
|
) : (
|
|
13748
14357
|
/* Standard Footer */
|
|
13749
|
-
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.footer }, activeTab === "messages" ? /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: refreshThreads }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.refreshText }, "\u21BB Refresh"))) : /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.footerText }, pendingCount, " pending \xB7 ", inProgressCount, " in progress"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: refreshAssignments }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.refreshText }, "\u21BB Refresh"))))
|
|
14358
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.footer }, activeTab === "messages" ? /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.footerText }, threads.length, " thread", threads.length !== 1 ? "s" : "", " \xB7 ", unreadCount, " unread"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: refreshThreads }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.refreshText }, "\u21BB Refresh"))) : activeTab === "explore" ? /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.footerText }, activeSession ? `${sessionFindings.length} findings` : "No active session"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: refreshSession }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.refreshText }, "\u21BB Refresh"))) : /* @__PURE__ */ import_react2.default.createElement(import_react2.default.Fragment, null, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.footerText }, pendingCount, " pending \xB7 ", inProgressCount, " in progress"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.TouchableOpacity, { onPress: refreshAssignments }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.refreshText }, "\u21BB Refresh"))))
|
|
13750
14359
|
))
|
|
13751
14360
|
)
|
|
14361
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
14362
|
+
import_react_native2.Modal,
|
|
14363
|
+
{
|
|
14364
|
+
visible: showSkipModal,
|
|
14365
|
+
transparent: true,
|
|
14366
|
+
animationType: "fade",
|
|
14367
|
+
onRequestClose: () => setShowSkipModal(false)
|
|
14368
|
+
},
|
|
14369
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.skipModalOverlay }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.skipModalContent }, /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipModalTitle }, "Skip Test"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipModalSubtitle }, "Why are you skipping this test?"), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.skipReasonOptions }, [
|
|
14370
|
+
{ value: "blocked", label: "\u{1F6AB} Blocked", desc: "Something is preventing testing" },
|
|
14371
|
+
{ value: "not_ready", label: "\u{1F6A7} Not Ready", desc: "Feature not yet implemented" },
|
|
14372
|
+
{ value: "dependency", label: "\u{1F517} Dependency", desc: "Waiting on another test/feature" },
|
|
14373
|
+
{ value: "other", label: "\u{1F4DD} Other", desc: "Different reason" }
|
|
14374
|
+
].map((option) => /* @__PURE__ */ import_react2.default.createElement(
|
|
14375
|
+
import_react_native2.TouchableOpacity,
|
|
14376
|
+
{
|
|
14377
|
+
key: option.value,
|
|
14378
|
+
style: [
|
|
14379
|
+
styles.skipReasonOption,
|
|
14380
|
+
selectedSkipReason === option.value && styles.skipReasonOptionSelected
|
|
14381
|
+
],
|
|
14382
|
+
onPress: () => setSelectedSkipReason(option.value)
|
|
14383
|
+
},
|
|
14384
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipReasonLabel }, option.label),
|
|
14385
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipReasonDesc }, option.desc)
|
|
14386
|
+
))), /* @__PURE__ */ import_react2.default.createElement(
|
|
14387
|
+
import_react_native2.TextInput,
|
|
14388
|
+
{
|
|
14389
|
+
style: styles.skipNotesInput,
|
|
14390
|
+
value: skipNotes,
|
|
14391
|
+
onChangeText: setSkipNotes,
|
|
14392
|
+
placeholder: "Add notes (optional)...",
|
|
14393
|
+
placeholderTextColor: "#71717a",
|
|
14394
|
+
multiline: true,
|
|
14395
|
+
numberOfLines: 2
|
|
14396
|
+
}
|
|
14397
|
+
), /* @__PURE__ */ import_react2.default.createElement(import_react_native2.View, { style: styles.skipModalActions }, /* @__PURE__ */ import_react2.default.createElement(
|
|
14398
|
+
import_react_native2.TouchableOpacity,
|
|
14399
|
+
{
|
|
14400
|
+
style: styles.skipModalCancel,
|
|
14401
|
+
onPress: () => setShowSkipModal(false)
|
|
14402
|
+
},
|
|
14403
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipModalCancelText }, "Cancel")
|
|
14404
|
+
), /* @__PURE__ */ import_react2.default.createElement(
|
|
14405
|
+
import_react_native2.TouchableOpacity,
|
|
14406
|
+
{
|
|
14407
|
+
style: [
|
|
14408
|
+
styles.skipModalConfirm,
|
|
14409
|
+
!selectedSkipReason && styles.skipModalConfirmDisabled
|
|
14410
|
+
],
|
|
14411
|
+
onPress: handleSkip,
|
|
14412
|
+
disabled: !selectedSkipReason || skipping
|
|
14413
|
+
},
|
|
14414
|
+
/* @__PURE__ */ import_react2.default.createElement(import_react_native2.Text, { style: styles.skipModalConfirmText }, skipping ? "Skipping..." : "Skip Test")
|
|
14415
|
+
))))
|
|
13752
14416
|
));
|
|
13753
14417
|
}
|
|
13754
14418
|
var styles = import_react_native2.StyleSheet.create({
|
|
@@ -14451,6 +15115,13 @@ var styles = import_react_native2.StyleSheet.create({
|
|
|
14451
15115
|
flexDirection: "row",
|
|
14452
15116
|
alignItems: "center"
|
|
14453
15117
|
},
|
|
15118
|
+
sessionDot: {
|
|
15119
|
+
width: 8,
|
|
15120
|
+
height: 8,
|
|
15121
|
+
borderRadius: 4,
|
|
15122
|
+
backgroundColor: "#22c55e",
|
|
15123
|
+
marginLeft: 4
|
|
15124
|
+
},
|
|
14454
15125
|
tabBadge: {
|
|
14455
15126
|
backgroundColor: "#EF4444",
|
|
14456
15127
|
borderRadius: 8,
|
|
@@ -15005,6 +15676,665 @@ var styles = import_react_native2.StyleSheet.create({
|
|
|
15005
15676
|
fontSize: 14,
|
|
15006
15677
|
fontWeight: "500",
|
|
15007
15678
|
color: "#3B82F6"
|
|
15679
|
+
},
|
|
15680
|
+
// Folder grouping styles
|
|
15681
|
+
folderContainer: {
|
|
15682
|
+
marginBottom: 12
|
|
15683
|
+
},
|
|
15684
|
+
folderHeader: {
|
|
15685
|
+
flexDirection: "row",
|
|
15686
|
+
justifyContent: "space-between",
|
|
15687
|
+
alignItems: "center",
|
|
15688
|
+
backgroundColor: "#27272a",
|
|
15689
|
+
padding: 12,
|
|
15690
|
+
borderRadius: 8,
|
|
15691
|
+
marginBottom: 4
|
|
15692
|
+
},
|
|
15693
|
+
folderHeaderLeft: {
|
|
15694
|
+
flexDirection: "row",
|
|
15695
|
+
alignItems: "center",
|
|
15696
|
+
flex: 1
|
|
15697
|
+
},
|
|
15698
|
+
folderIcon: {
|
|
15699
|
+
fontSize: 16,
|
|
15700
|
+
marginRight: 8
|
|
15701
|
+
},
|
|
15702
|
+
folderName: {
|
|
15703
|
+
fontSize: 14,
|
|
15704
|
+
fontWeight: "600",
|
|
15705
|
+
color: "#fafafa"
|
|
15706
|
+
},
|
|
15707
|
+
folderStats: {
|
|
15708
|
+
flexDirection: "row",
|
|
15709
|
+
alignItems: "center"
|
|
15710
|
+
},
|
|
15711
|
+
folderProgress: {
|
|
15712
|
+
fontSize: 12,
|
|
15713
|
+
color: "#71717a",
|
|
15714
|
+
marginRight: 8
|
|
15715
|
+
},
|
|
15716
|
+
folderChevron: {
|
|
15717
|
+
fontSize: 10,
|
|
15718
|
+
color: "#71717a"
|
|
15719
|
+
},
|
|
15720
|
+
folderProgressBar: {
|
|
15721
|
+
height: 3,
|
|
15722
|
+
backgroundColor: "#3f3f46",
|
|
15723
|
+
borderRadius: 2,
|
|
15724
|
+
marginBottom: 8,
|
|
15725
|
+
marginHorizontal: 4
|
|
15726
|
+
},
|
|
15727
|
+
folderProgressFill: {
|
|
15728
|
+
height: "100%",
|
|
15729
|
+
backgroundColor: "#22c55e",
|
|
15730
|
+
borderRadius: 2
|
|
15731
|
+
},
|
|
15732
|
+
listItemInFolder: {
|
|
15733
|
+
marginLeft: 12,
|
|
15734
|
+
borderLeftWidth: 2,
|
|
15735
|
+
borderLeftColor: "#3f3f46",
|
|
15736
|
+
paddingLeft: 12
|
|
15737
|
+
},
|
|
15738
|
+
listItemKeyWithStatus: {
|
|
15739
|
+
flexDirection: "row",
|
|
15740
|
+
alignItems: "center",
|
|
15741
|
+
flex: 1
|
|
15742
|
+
},
|
|
15743
|
+
statusBadge: {
|
|
15744
|
+
flexDirection: "row",
|
|
15745
|
+
alignItems: "center",
|
|
15746
|
+
paddingHorizontal: 6,
|
|
15747
|
+
paddingVertical: 2,
|
|
15748
|
+
borderRadius: 4,
|
|
15749
|
+
marginLeft: 8
|
|
15750
|
+
},
|
|
15751
|
+
statusBadgeIcon: {
|
|
15752
|
+
fontSize: 10,
|
|
15753
|
+
marginRight: 4
|
|
15754
|
+
},
|
|
15755
|
+
statusBadgeText: {
|
|
15756
|
+
fontSize: 10,
|
|
15757
|
+
fontWeight: "600"
|
|
15758
|
+
},
|
|
15759
|
+
// Skip button styles
|
|
15760
|
+
skipButton: {
|
|
15761
|
+
flex: 1,
|
|
15762
|
+
backgroundColor: "#eab308",
|
|
15763
|
+
paddingVertical: 14,
|
|
15764
|
+
borderRadius: 12,
|
|
15765
|
+
alignItems: "center",
|
|
15766
|
+
marginHorizontal: 4
|
|
15767
|
+
},
|
|
15768
|
+
skipButtonText: {
|
|
15769
|
+
fontSize: 15,
|
|
15770
|
+
fontWeight: "600",
|
|
15771
|
+
color: "#18181b"
|
|
15772
|
+
},
|
|
15773
|
+
// Skip modal styles
|
|
15774
|
+
skipModalOverlay: {
|
|
15775
|
+
flex: 1,
|
|
15776
|
+
backgroundColor: "rgba(0, 0, 0, 0.7)",
|
|
15777
|
+
justifyContent: "center",
|
|
15778
|
+
alignItems: "center",
|
|
15779
|
+
padding: 20
|
|
15780
|
+
},
|
|
15781
|
+
skipModalContent: {
|
|
15782
|
+
backgroundColor: "#18181b",
|
|
15783
|
+
borderRadius: 16,
|
|
15784
|
+
padding: 20,
|
|
15785
|
+
width: "100%",
|
|
15786
|
+
maxWidth: 340,
|
|
15787
|
+
borderWidth: 1,
|
|
15788
|
+
borderColor: "#3f3f46"
|
|
15789
|
+
},
|
|
15790
|
+
skipModalTitle: {
|
|
15791
|
+
fontSize: 18,
|
|
15792
|
+
fontWeight: "600",
|
|
15793
|
+
color: "#fafafa",
|
|
15794
|
+
marginBottom: 4
|
|
15795
|
+
},
|
|
15796
|
+
skipModalSubtitle: {
|
|
15797
|
+
fontSize: 14,
|
|
15798
|
+
color: "#71717a",
|
|
15799
|
+
marginBottom: 16
|
|
15800
|
+
},
|
|
15801
|
+
skipReasonOptions: {
|
|
15802
|
+
marginBottom: 16
|
|
15803
|
+
},
|
|
15804
|
+
skipReasonOption: {
|
|
15805
|
+
backgroundColor: "#27272a",
|
|
15806
|
+
padding: 12,
|
|
15807
|
+
borderRadius: 8,
|
|
15808
|
+
marginBottom: 8,
|
|
15809
|
+
borderWidth: 2,
|
|
15810
|
+
borderColor: "transparent"
|
|
15811
|
+
},
|
|
15812
|
+
skipReasonOptionSelected: {
|
|
15813
|
+
borderColor: "#eab308",
|
|
15814
|
+
backgroundColor: "#422006"
|
|
15815
|
+
},
|
|
15816
|
+
skipReasonLabel: {
|
|
15817
|
+
fontSize: 14,
|
|
15818
|
+
fontWeight: "600",
|
|
15819
|
+
color: "#fafafa",
|
|
15820
|
+
marginBottom: 2
|
|
15821
|
+
},
|
|
15822
|
+
skipReasonDesc: {
|
|
15823
|
+
fontSize: 12,
|
|
15824
|
+
color: "#71717a"
|
|
15825
|
+
},
|
|
15826
|
+
skipNotesInput: {
|
|
15827
|
+
backgroundColor: "#27272a",
|
|
15828
|
+
borderWidth: 1,
|
|
15829
|
+
borderColor: "#3f3f46",
|
|
15830
|
+
borderRadius: 8,
|
|
15831
|
+
padding: 12,
|
|
15832
|
+
fontSize: 14,
|
|
15833
|
+
color: "#fafafa",
|
|
15834
|
+
minHeight: 60,
|
|
15835
|
+
textAlignVertical: "top",
|
|
15836
|
+
marginBottom: 16
|
|
15837
|
+
},
|
|
15838
|
+
skipModalActions: {
|
|
15839
|
+
flexDirection: "row",
|
|
15840
|
+
gap: 8
|
|
15841
|
+
},
|
|
15842
|
+
skipModalCancel: {
|
|
15843
|
+
flex: 1,
|
|
15844
|
+
backgroundColor: "#3f3f46",
|
|
15845
|
+
paddingVertical: 12,
|
|
15846
|
+
borderRadius: 8,
|
|
15847
|
+
alignItems: "center"
|
|
15848
|
+
},
|
|
15849
|
+
skipModalCancelText: {
|
|
15850
|
+
fontSize: 14,
|
|
15851
|
+
fontWeight: "600",
|
|
15852
|
+
color: "#e4e4e7"
|
|
15853
|
+
},
|
|
15854
|
+
skipModalConfirm: {
|
|
15855
|
+
flex: 1,
|
|
15856
|
+
backgroundColor: "#eab308",
|
|
15857
|
+
paddingVertical: 12,
|
|
15858
|
+
borderRadius: 8,
|
|
15859
|
+
alignItems: "center"
|
|
15860
|
+
},
|
|
15861
|
+
skipModalConfirmDisabled: {
|
|
15862
|
+
backgroundColor: "#713f12"
|
|
15863
|
+
},
|
|
15864
|
+
skipModalConfirmText: {
|
|
15865
|
+
fontSize: 14,
|
|
15866
|
+
fontWeight: "600",
|
|
15867
|
+
color: "#18181b"
|
|
15868
|
+
},
|
|
15869
|
+
// Detail progress bar styles
|
|
15870
|
+
detailProgressContainer: {
|
|
15871
|
+
backgroundColor: "#27272a",
|
|
15872
|
+
padding: 12,
|
|
15873
|
+
borderRadius: 8,
|
|
15874
|
+
marginTop: 16,
|
|
15875
|
+
marginBottom: 8
|
|
15876
|
+
},
|
|
15877
|
+
detailProgressText: {
|
|
15878
|
+
fontSize: 12,
|
|
15879
|
+
color: "#a1a1aa",
|
|
15880
|
+
marginBottom: 8
|
|
15881
|
+
},
|
|
15882
|
+
detailProgressBar: {
|
|
15883
|
+
height: 4,
|
|
15884
|
+
backgroundColor: "#3f3f46",
|
|
15885
|
+
borderRadius: 2
|
|
15886
|
+
},
|
|
15887
|
+
detailProgressFill: {
|
|
15888
|
+
height: "100%",
|
|
15889
|
+
backgroundColor: "#22c55e",
|
|
15890
|
+
borderRadius: 2
|
|
15891
|
+
}
|
|
15892
|
+
});
|
|
15893
|
+
var exploreStyles = import_react_native2.StyleSheet.create({
|
|
15894
|
+
formGroup: {
|
|
15895
|
+
marginBottom: 12
|
|
15896
|
+
},
|
|
15897
|
+
label: {
|
|
15898
|
+
fontSize: 12,
|
|
15899
|
+
fontWeight: "500",
|
|
15900
|
+
color: "#d4d4d8",
|
|
15901
|
+
marginBottom: 6
|
|
15902
|
+
},
|
|
15903
|
+
input: {
|
|
15904
|
+
backgroundColor: "#27272a",
|
|
15905
|
+
borderRadius: 8,
|
|
15906
|
+
paddingHorizontal: 12,
|
|
15907
|
+
paddingVertical: 10,
|
|
15908
|
+
fontSize: 14,
|
|
15909
|
+
color: "#fafafa",
|
|
15910
|
+
borderWidth: 1,
|
|
15911
|
+
borderColor: "#3f3f46"
|
|
15912
|
+
},
|
|
15913
|
+
platformRow: {
|
|
15914
|
+
flexDirection: "row",
|
|
15915
|
+
gap: 8
|
|
15916
|
+
},
|
|
15917
|
+
platformButton: {
|
|
15918
|
+
flex: 1,
|
|
15919
|
+
paddingVertical: 10,
|
|
15920
|
+
paddingHorizontal: 8,
|
|
15921
|
+
borderRadius: 8,
|
|
15922
|
+
backgroundColor: "#27272a",
|
|
15923
|
+
borderWidth: 2,
|
|
15924
|
+
borderColor: "transparent",
|
|
15925
|
+
alignItems: "center"
|
|
15926
|
+
},
|
|
15927
|
+
platformButtonActive: {
|
|
15928
|
+
backgroundColor: "#172554",
|
|
15929
|
+
borderColor: "#3B82F6"
|
|
15930
|
+
},
|
|
15931
|
+
platformButtonText: {
|
|
15932
|
+
fontSize: 12,
|
|
15933
|
+
fontWeight: "500",
|
|
15934
|
+
color: "#a1a1aa"
|
|
15935
|
+
},
|
|
15936
|
+
platformButtonTextActive: {
|
|
15937
|
+
color: "#93c5fd"
|
|
15938
|
+
},
|
|
15939
|
+
startButton: {
|
|
15940
|
+
backgroundColor: "#16a34a",
|
|
15941
|
+
borderRadius: 8,
|
|
15942
|
+
paddingVertical: 14,
|
|
15943
|
+
alignItems: "center",
|
|
15944
|
+
marginTop: 4
|
|
15945
|
+
},
|
|
15946
|
+
startButtonText: {
|
|
15947
|
+
color: "#fff",
|
|
15948
|
+
fontSize: 14,
|
|
15949
|
+
fontWeight: "600"
|
|
15950
|
+
},
|
|
15951
|
+
buttonRow: {
|
|
15952
|
+
flexDirection: "row",
|
|
15953
|
+
gap: 8
|
|
15954
|
+
},
|
|
15955
|
+
cancelButton: {
|
|
15956
|
+
flex: 1,
|
|
15957
|
+
backgroundColor: "#3f3f46",
|
|
15958
|
+
borderRadius: 8,
|
|
15959
|
+
paddingVertical: 10,
|
|
15960
|
+
alignItems: "center"
|
|
15961
|
+
},
|
|
15962
|
+
cancelButtonText: {
|
|
15963
|
+
color: "#d4d4d8",
|
|
15964
|
+
fontSize: 14,
|
|
15965
|
+
fontWeight: "500"
|
|
15966
|
+
},
|
|
15967
|
+
endButton: {
|
|
15968
|
+
flex: 1,
|
|
15969
|
+
backgroundColor: "#dc2626",
|
|
15970
|
+
borderRadius: 8,
|
|
15971
|
+
paddingVertical: 10,
|
|
15972
|
+
alignItems: "center"
|
|
15973
|
+
},
|
|
15974
|
+
endButtonText: {
|
|
15975
|
+
color: "#fff",
|
|
15976
|
+
fontSize: 14,
|
|
15977
|
+
fontWeight: "500"
|
|
15978
|
+
},
|
|
15979
|
+
findingHeader: {
|
|
15980
|
+
flexDirection: "row",
|
|
15981
|
+
justifyContent: "space-between",
|
|
15982
|
+
alignItems: "center",
|
|
15983
|
+
marginBottom: 12
|
|
15984
|
+
},
|
|
15985
|
+
findingHeaderTitle: {
|
|
15986
|
+
fontSize: 14,
|
|
15987
|
+
fontWeight: "600",
|
|
15988
|
+
color: "#fafafa"
|
|
15989
|
+
},
|
|
15990
|
+
findingHeaderClose: {
|
|
15991
|
+
fontSize: 16,
|
|
15992
|
+
color: "#71717a"
|
|
15993
|
+
},
|
|
15994
|
+
findingTypeRow: {
|
|
15995
|
+
flexDirection: "row",
|
|
15996
|
+
gap: 4,
|
|
15997
|
+
marginBottom: 12
|
|
15998
|
+
},
|
|
15999
|
+
findingTypeButton: {
|
|
16000
|
+
flex: 1,
|
|
16001
|
+
paddingVertical: 8,
|
|
16002
|
+
paddingHorizontal: 4,
|
|
16003
|
+
borderRadius: 6,
|
|
16004
|
+
backgroundColor: "#3f3f46",
|
|
16005
|
+
alignItems: "center"
|
|
16006
|
+
},
|
|
16007
|
+
findingTypeButtonActive: {
|
|
16008
|
+
backgroundColor: "#1e3a5f",
|
|
16009
|
+
borderWidth: 2,
|
|
16010
|
+
borderColor: "#3B82F6"
|
|
16011
|
+
},
|
|
16012
|
+
findingTypeButtonText: {
|
|
16013
|
+
fontSize: 11,
|
|
16014
|
+
fontWeight: "500",
|
|
16015
|
+
color: "#a1a1aa"
|
|
16016
|
+
},
|
|
16017
|
+
findingTypeButtonTextActive: {
|
|
16018
|
+
color: "#93c5fd"
|
|
16019
|
+
},
|
|
16020
|
+
severityRow: {
|
|
16021
|
+
flexDirection: "row",
|
|
16022
|
+
gap: 4
|
|
16023
|
+
},
|
|
16024
|
+
severityButton: {
|
|
16025
|
+
flex: 1,
|
|
16026
|
+
paddingVertical: 6,
|
|
16027
|
+
borderRadius: 6,
|
|
16028
|
+
backgroundColor: "#3f3f46",
|
|
16029
|
+
alignItems: "center"
|
|
16030
|
+
},
|
|
16031
|
+
severityCritical: {
|
|
16032
|
+
backgroundColor: "#dc2626"
|
|
16033
|
+
},
|
|
16034
|
+
severityHigh: {
|
|
16035
|
+
backgroundColor: "#f97316"
|
|
16036
|
+
},
|
|
16037
|
+
severityMedium: {
|
|
16038
|
+
backgroundColor: "#eab308"
|
|
16039
|
+
},
|
|
16040
|
+
severityLow: {
|
|
16041
|
+
backgroundColor: "#3f3f46",
|
|
16042
|
+
borderWidth: 1,
|
|
16043
|
+
borderColor: "#71717a"
|
|
16044
|
+
},
|
|
16045
|
+
severityButtonText: {
|
|
16046
|
+
fontSize: 11,
|
|
16047
|
+
fontWeight: "500",
|
|
16048
|
+
color: "#a1a1aa",
|
|
16049
|
+
textTransform: "capitalize"
|
|
16050
|
+
},
|
|
16051
|
+
severityButtonTextActive: {
|
|
16052
|
+
color: "#fff"
|
|
16053
|
+
},
|
|
16054
|
+
addFindingButton: {
|
|
16055
|
+
backgroundColor: "#3B82F6",
|
|
16056
|
+
borderRadius: 8,
|
|
16057
|
+
paddingVertical: 10,
|
|
16058
|
+
alignItems: "center"
|
|
16059
|
+
},
|
|
16060
|
+
addFindingButtonText: {
|
|
16061
|
+
color: "#fff",
|
|
16062
|
+
fontSize: 14,
|
|
16063
|
+
fontWeight: "500"
|
|
16064
|
+
},
|
|
16065
|
+
sessionBanner: {
|
|
16066
|
+
backgroundColor: "rgba(22, 163, 74, 0.15)",
|
|
16067
|
+
borderRadius: 12,
|
|
16068
|
+
padding: 12,
|
|
16069
|
+
marginBottom: 12,
|
|
16070
|
+
borderWidth: 1,
|
|
16071
|
+
borderColor: "#166534"
|
|
16072
|
+
},
|
|
16073
|
+
sessionBannerRow: {
|
|
16074
|
+
flexDirection: "row",
|
|
16075
|
+
justifyContent: "space-between",
|
|
16076
|
+
alignItems: "center"
|
|
16077
|
+
},
|
|
16078
|
+
sessionBannerLeft: {
|
|
16079
|
+
flexDirection: "row",
|
|
16080
|
+
alignItems: "center",
|
|
16081
|
+
gap: 8
|
|
16082
|
+
},
|
|
16083
|
+
sessionDotLarge: {
|
|
16084
|
+
width: 8,
|
|
16085
|
+
height: 8,
|
|
16086
|
+
borderRadius: 4,
|
|
16087
|
+
backgroundColor: "#22c55e"
|
|
16088
|
+
},
|
|
16089
|
+
sessionBannerLabel: {
|
|
16090
|
+
fontSize: 14,
|
|
16091
|
+
fontWeight: "500",
|
|
16092
|
+
color: "#86efac"
|
|
16093
|
+
},
|
|
16094
|
+
sessionTimer: {
|
|
16095
|
+
fontSize: 20,
|
|
16096
|
+
fontWeight: "600",
|
|
16097
|
+
color: "#4ade80",
|
|
16098
|
+
fontVariant: ["tabular-nums"]
|
|
16099
|
+
},
|
|
16100
|
+
sessionFocus: {
|
|
16101
|
+
fontSize: 12,
|
|
16102
|
+
color: "#4ade80",
|
|
16103
|
+
marginTop: 4
|
|
16104
|
+
},
|
|
16105
|
+
addButton: {
|
|
16106
|
+
backgroundColor: "#3B82F6",
|
|
16107
|
+
borderRadius: 8,
|
|
16108
|
+
paddingVertical: 14,
|
|
16109
|
+
alignItems: "center",
|
|
16110
|
+
marginBottom: 12
|
|
16111
|
+
},
|
|
16112
|
+
addButtonText: {
|
|
16113
|
+
color: "#fff",
|
|
16114
|
+
fontSize: 14,
|
|
16115
|
+
fontWeight: "600"
|
|
16116
|
+
},
|
|
16117
|
+
findingsSection: {
|
|
16118
|
+
marginBottom: 12
|
|
16119
|
+
},
|
|
16120
|
+
findingsLabel: {
|
|
16121
|
+
fontSize: 12,
|
|
16122
|
+
fontWeight: "500",
|
|
16123
|
+
color: "#71717a",
|
|
16124
|
+
marginBottom: 8
|
|
16125
|
+
},
|
|
16126
|
+
findingsEmpty: {
|
|
16127
|
+
backgroundColor: "#27272a",
|
|
16128
|
+
borderRadius: 8,
|
|
16129
|
+
paddingVertical: 16,
|
|
16130
|
+
alignItems: "center"
|
|
16131
|
+
},
|
|
16132
|
+
findingsEmptyText: {
|
|
16133
|
+
fontSize: 12,
|
|
16134
|
+
color: "#71717a"
|
|
16135
|
+
},
|
|
16136
|
+
findingCard: {
|
|
16137
|
+
flexDirection: "row",
|
|
16138
|
+
alignItems: "flex-start",
|
|
16139
|
+
padding: 8,
|
|
16140
|
+
borderRadius: 8,
|
|
16141
|
+
marginBottom: 6,
|
|
16142
|
+
borderWidth: 1,
|
|
16143
|
+
gap: 8
|
|
16144
|
+
},
|
|
16145
|
+
findingCardBug: {
|
|
16146
|
+
backgroundColor: "rgba(220, 38, 38, 0.1)",
|
|
16147
|
+
borderColor: "#991b1b"
|
|
16148
|
+
},
|
|
16149
|
+
findingCardConcern: {
|
|
16150
|
+
backgroundColor: "rgba(249, 115, 22, 0.1)",
|
|
16151
|
+
borderColor: "#9a3412"
|
|
16152
|
+
},
|
|
16153
|
+
findingCardSuggestion: {
|
|
16154
|
+
backgroundColor: "rgba(59, 130, 246, 0.1)",
|
|
16155
|
+
borderColor: "#1e40af"
|
|
16156
|
+
},
|
|
16157
|
+
findingCardQuestion: {
|
|
16158
|
+
backgroundColor: "rgba(139, 92, 246, 0.1)",
|
|
16159
|
+
borderColor: "#5b21b6"
|
|
16160
|
+
},
|
|
16161
|
+
findingCardIcon: {
|
|
16162
|
+
fontSize: 14
|
|
16163
|
+
},
|
|
16164
|
+
findingCardTitle: {
|
|
16165
|
+
fontSize: 12,
|
|
16166
|
+
fontWeight: "500",
|
|
16167
|
+
color: "#fafafa"
|
|
16168
|
+
},
|
|
16169
|
+
findingCardSeverity: {
|
|
16170
|
+
fontSize: 10,
|
|
16171
|
+
fontWeight: "500",
|
|
16172
|
+
marginTop: 2,
|
|
16173
|
+
textTransform: "capitalize"
|
|
16174
|
+
},
|
|
16175
|
+
endSessionButton: {
|
|
16176
|
+
backgroundColor: "#3f3f46",
|
|
16177
|
+
borderRadius: 8,
|
|
16178
|
+
paddingVertical: 10,
|
|
16179
|
+
alignItems: "center"
|
|
16180
|
+
},
|
|
16181
|
+
endSessionButtonText: {
|
|
16182
|
+
color: "#d4d4d8",
|
|
16183
|
+
fontSize: 14,
|
|
16184
|
+
fontWeight: "500"
|
|
16185
|
+
}
|
|
16186
|
+
});
|
|
16187
|
+
var feedbackStyles = import_react_native2.StyleSheet.create({
|
|
16188
|
+
container: {
|
|
16189
|
+
padding: 4
|
|
16190
|
+
},
|
|
16191
|
+
statusText: {
|
|
16192
|
+
fontSize: 16,
|
|
16193
|
+
fontWeight: "600",
|
|
16194
|
+
marginTop: 4
|
|
16195
|
+
},
|
|
16196
|
+
infoBox: {
|
|
16197
|
+
backgroundColor: "rgba(59, 130, 246, 0.1)",
|
|
16198
|
+
borderRadius: 8,
|
|
16199
|
+
padding: 12,
|
|
16200
|
+
marginBottom: 16,
|
|
16201
|
+
borderWidth: 1,
|
|
16202
|
+
borderColor: "#1e3a5f"
|
|
16203
|
+
},
|
|
16204
|
+
infoTitle: {
|
|
16205
|
+
fontSize: 14,
|
|
16206
|
+
fontWeight: "500",
|
|
16207
|
+
color: "#93c5fd",
|
|
16208
|
+
marginBottom: 4
|
|
16209
|
+
},
|
|
16210
|
+
infoSubtitle: {
|
|
16211
|
+
fontSize: 12,
|
|
16212
|
+
color: "#60a5fa"
|
|
16213
|
+
},
|
|
16214
|
+
ratingSection: {
|
|
16215
|
+
alignItems: "center",
|
|
16216
|
+
marginBottom: 16
|
|
16217
|
+
},
|
|
16218
|
+
ratingLabel: {
|
|
16219
|
+
fontSize: 12,
|
|
16220
|
+
fontWeight: "500",
|
|
16221
|
+
color: "#a1a1aa",
|
|
16222
|
+
marginBottom: 8
|
|
16223
|
+
},
|
|
16224
|
+
starsRow: {
|
|
16225
|
+
flexDirection: "row",
|
|
16226
|
+
gap: 4
|
|
16227
|
+
},
|
|
16228
|
+
star: {
|
|
16229
|
+
fontSize: 28
|
|
16230
|
+
},
|
|
16231
|
+
starActive: {
|
|
16232
|
+
color: "#facc15"
|
|
16233
|
+
},
|
|
16234
|
+
starInactive: {
|
|
16235
|
+
color: "#3f3f46"
|
|
16236
|
+
},
|
|
16237
|
+
ratingDesc: {
|
|
16238
|
+
fontSize: 12,
|
|
16239
|
+
color: "#71717a",
|
|
16240
|
+
marginTop: 4
|
|
16241
|
+
},
|
|
16242
|
+
flagsSection: {
|
|
16243
|
+
marginBottom: 12
|
|
16244
|
+
},
|
|
16245
|
+
flagsGrid: {
|
|
16246
|
+
flexDirection: "row",
|
|
16247
|
+
flexWrap: "wrap",
|
|
16248
|
+
gap: 8
|
|
16249
|
+
},
|
|
16250
|
+
flagButton: {
|
|
16251
|
+
paddingHorizontal: 10,
|
|
16252
|
+
paddingVertical: 6,
|
|
16253
|
+
borderRadius: 6,
|
|
16254
|
+
backgroundColor: "#27272a",
|
|
16255
|
+
borderWidth: 1,
|
|
16256
|
+
borderColor: "#3f3f46"
|
|
16257
|
+
},
|
|
16258
|
+
flagButtonActive: {
|
|
16259
|
+
backgroundColor: "#1e3a5f",
|
|
16260
|
+
borderColor: "#3B82F6"
|
|
16261
|
+
},
|
|
16262
|
+
flagButtonText: {
|
|
16263
|
+
fontSize: 12,
|
|
16264
|
+
fontWeight: "500",
|
|
16265
|
+
color: "#a1a1aa"
|
|
16266
|
+
},
|
|
16267
|
+
flagButtonTextActive: {
|
|
16268
|
+
color: "#93c5fd"
|
|
16269
|
+
},
|
|
16270
|
+
noteInput: {
|
|
16271
|
+
backgroundColor: "#27272a",
|
|
16272
|
+
borderRadius: 8,
|
|
16273
|
+
paddingHorizontal: 12,
|
|
16274
|
+
paddingVertical: 10,
|
|
16275
|
+
fontSize: 14,
|
|
16276
|
+
color: "#fafafa",
|
|
16277
|
+
borderWidth: 1,
|
|
16278
|
+
borderColor: "#3f3f46",
|
|
16279
|
+
minHeight: 60
|
|
16280
|
+
},
|
|
16281
|
+
buttonRow: {
|
|
16282
|
+
flexDirection: "row",
|
|
16283
|
+
gap: 8
|
|
16284
|
+
},
|
|
16285
|
+
skipButton: {
|
|
16286
|
+
flex: 1,
|
|
16287
|
+
paddingVertical: 10,
|
|
16288
|
+
backgroundColor: "#3f3f46",
|
|
16289
|
+
borderRadius: 8,
|
|
16290
|
+
alignItems: "center"
|
|
16291
|
+
},
|
|
16292
|
+
skipButtonText: {
|
|
16293
|
+
color: "#a1a1aa",
|
|
16294
|
+
fontSize: 14,
|
|
16295
|
+
fontWeight: "500"
|
|
16296
|
+
},
|
|
16297
|
+
submitButton: {
|
|
16298
|
+
flex: 1,
|
|
16299
|
+
paddingVertical: 10,
|
|
16300
|
+
backgroundColor: "#3B82F6",
|
|
16301
|
+
borderRadius: 8,
|
|
16302
|
+
alignItems: "center"
|
|
16303
|
+
},
|
|
16304
|
+
submitButtonText: {
|
|
16305
|
+
color: "#fff",
|
|
16306
|
+
fontSize: 14,
|
|
16307
|
+
fontWeight: "500"
|
|
16308
|
+
}
|
|
16309
|
+
});
|
|
16310
|
+
var timerStyles = import_react_native2.StyleSheet.create({
|
|
16311
|
+
container: {
|
|
16312
|
+
flexDirection: "row",
|
|
16313
|
+
alignItems: "center",
|
|
16314
|
+
gap: 6,
|
|
16315
|
+
backgroundColor: "rgba(22, 163, 74, 0.15)",
|
|
16316
|
+
paddingHorizontal: 8,
|
|
16317
|
+
paddingVertical: 4,
|
|
16318
|
+
borderRadius: 6,
|
|
16319
|
+
marginBottom: 8,
|
|
16320
|
+
alignSelf: "flex-start"
|
|
16321
|
+
},
|
|
16322
|
+
dot: {
|
|
16323
|
+
width: 6,
|
|
16324
|
+
height: 6,
|
|
16325
|
+
borderRadius: 3,
|
|
16326
|
+
backgroundColor: "#22c55e"
|
|
16327
|
+
},
|
|
16328
|
+
label: {
|
|
16329
|
+
fontSize: 12,
|
|
16330
|
+
fontWeight: "500",
|
|
16331
|
+
color: "#4ade80"
|
|
16332
|
+
},
|
|
16333
|
+
time: {
|
|
16334
|
+
fontSize: 12,
|
|
16335
|
+
fontWeight: "600",
|
|
16336
|
+
color: "#4ade80",
|
|
16337
|
+
fontVariant: ["tabular-nums"]
|
|
15008
16338
|
}
|
|
15009
16339
|
});
|
|
15010
16340
|
// Annotate the CommonJS export names for ESM import in node:
|