@bbearai/react-native 0.4.1 → 0.5.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/index.js +50 -7
- package/dist/index.mjs +55 -12
- package/package.json +2 -2
package/dist/index.js
CHANGED
|
@@ -11393,7 +11393,7 @@ function shouldShowDeprecationWarning() {
|
|
|
11393
11393
|
}
|
|
11394
11394
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11395
11395
|
|
|
11396
|
-
//
|
|
11396
|
+
// node_modules/@bbearai/core/dist/index.mjs
|
|
11397
11397
|
var MAX_CONSOLE_LOGS = 50;
|
|
11398
11398
|
var MAX_NETWORK_REQUESTS = 20;
|
|
11399
11399
|
var MAX_NAVIGATION_HISTORY = 20;
|
|
@@ -14021,10 +14021,19 @@ var import_react_native5 = require("react-native");
|
|
|
14021
14021
|
function TestListScreen({ nav }) {
|
|
14022
14022
|
const { assignments, currentAssignment, refreshAssignments } = useBugBear();
|
|
14023
14023
|
const [filter, setFilter] = (0, import_react5.useState)("all");
|
|
14024
|
+
const [roleFilter, setRoleFilter] = (0, import_react5.useState)(null);
|
|
14024
14025
|
const [collapsedFolders, setCollapsedFolders] = (0, import_react5.useState)(/* @__PURE__ */ new Set());
|
|
14025
14026
|
(0, import_react5.useEffect)(() => {
|
|
14026
14027
|
refreshAssignments();
|
|
14027
14028
|
}, []);
|
|
14029
|
+
const availableRoles = (0, import_react5.useMemo)(() => {
|
|
14030
|
+
const roleMap = /* @__PURE__ */ new Map();
|
|
14031
|
+
for (const a of assignments) {
|
|
14032
|
+
if (a.testCase.role) roleMap.set(a.testCase.role.id, a.testCase.role);
|
|
14033
|
+
}
|
|
14034
|
+
return Array.from(roleMap.values());
|
|
14035
|
+
}, [assignments]);
|
|
14036
|
+
const selectedRole = availableRoles.find((r) => r.id === roleFilter);
|
|
14028
14037
|
const groupedAssignments = (0, import_react5.useMemo)(() => {
|
|
14029
14038
|
const groups = /* @__PURE__ */ new Map();
|
|
14030
14039
|
for (const assignment of assignments) {
|
|
@@ -14068,16 +14077,39 @@ function TestListScreen({ nav }) {
|
|
|
14068
14077
|
});
|
|
14069
14078
|
}, []);
|
|
14070
14079
|
const filterAssignment = (a) => {
|
|
14080
|
+
if (roleFilter && a.testCase.role?.id !== roleFilter) return false;
|
|
14071
14081
|
if (filter === "pending") return a.status === "pending" || a.status === "in_progress";
|
|
14072
14082
|
if (filter === "completed") return a.status === "passed" || a.status === "failed";
|
|
14073
14083
|
return true;
|
|
14074
14084
|
};
|
|
14075
|
-
return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, null, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { key: f, style: [styles3.filterBtn, filter === f && styles3.filterBtnActive], onPress: () => setFilter(f) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.filterBtnText, filter === f && styles3.filterBtnTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length})` : `Done (${assignments.filter((a) => a.status === "passed" || a.status === "failed").length})`)))),
|
|
14085
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, null, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { key: f, style: [styles3.filterBtn, filter === f && styles3.filterBtnActive], onPress: () => setFilter(f) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.filterBtnText, filter === f && styles3.filterBtnTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length})` : `Done (${assignments.filter((a) => a.status === "passed" || a.status === "failed").length})`)))), availableRoles.length >= 2 && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleSection }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles3.roleBar }, /* @__PURE__ */ import_react5.default.createElement(
|
|
14086
|
+
import_react_native5.TouchableOpacity,
|
|
14087
|
+
{
|
|
14088
|
+
style: [styles3.roleBtn, !roleFilter && styles3.roleBtnActive],
|
|
14089
|
+
onPress: () => setRoleFilter(null)
|
|
14090
|
+
},
|
|
14091
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.roleBtnText, !roleFilter && styles3.roleBtnTextActive] }, "All Roles")
|
|
14092
|
+
), availableRoles.map((role) => {
|
|
14093
|
+
const isActive = roleFilter === role.id;
|
|
14094
|
+
return /* @__PURE__ */ import_react5.default.createElement(
|
|
14095
|
+
import_react_native5.TouchableOpacity,
|
|
14096
|
+
{
|
|
14097
|
+
key: role.id,
|
|
14098
|
+
style: [
|
|
14099
|
+
styles3.roleBtn,
|
|
14100
|
+
isActive && { backgroundColor: role.color + "20", borderColor: role.color + "60", borderWidth: 1 }
|
|
14101
|
+
],
|
|
14102
|
+
onPress: () => setRoleFilter(isActive ? null : role.id)
|
|
14103
|
+
},
|
|
14104
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.roleDot, { backgroundColor: role.color }] }),
|
|
14105
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.roleBtnText, isActive && { color: role.color, fontWeight: "600" }] }, role.name)
|
|
14106
|
+
);
|
|
14107
|
+
})), selectedRole?.loginHint && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.loginHint, { backgroundColor: selectedRole.color + "10", borderColor: selectedRole.color + "30" }] }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.loginHintText }, "Log in as: ", selectedRole.loginHint))), groupedAssignments.map((folder) => {
|
|
14076
14108
|
const folderId = folder.group?.id || "ungrouped";
|
|
14077
14109
|
const isCollapsed = collapsedFolders.has(folderId);
|
|
14078
14110
|
const filtered = folder.assignments.filter(filterAssignment);
|
|
14079
14111
|
if (filtered.length === 0 && filter !== "all") return null;
|
|
14080
|
-
return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { key: folderId, style: styles3.folder }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { style: styles3.folderHeader, onPress: () => toggleFolder(folderId) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderToggle }, isCollapsed ? "\u25B6" : "\u25BC"), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderName }, folder.group?.name || "Ungrouped"), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.folderProgress }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.folderProgressFill, { width: `${Math.round((folder.stats.passed + folder.stats.failed) / folder.stats.total * 100)}%` }] })), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderCount }, folder.stats.passed + folder.stats.failed, "/", folder.stats.total)), !isCollapsed && filtered.map((assignment) => {
|
|
14112
|
+
return /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { key: folderId, style: styles3.folder }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { style: styles3.folderHeader, onPress: () => toggleFolder(folderId) }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderToggle }, isCollapsed ? "\u25B6" : "\u25BC"), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderName, numberOfLines: 1 }, folder.group?.name || "Ungrouped"), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.folderProgress }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.folderProgressFill, { width: `${folder.stats.total > 0 ? Math.round((folder.stats.passed + folder.stats.failed) / folder.stats.total * 100) : 0}%` }] })), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.folderCount }, folder.stats.passed + folder.stats.failed, "/", folder.stats.total)), !isCollapsed && filtered.map((assignment) => {
|
|
14081
14113
|
const badge = getStatusBadge(assignment.status);
|
|
14082
14114
|
const isCurrent = currentAssignment?.id === assignment.id;
|
|
14083
14115
|
return /* @__PURE__ */ import_react5.default.createElement(
|
|
@@ -14088,17 +14120,28 @@ function TestListScreen({ nav }) {
|
|
|
14088
14120
|
onPress: () => nav.push({ name: "TEST_DETAIL", testId: assignment.id })
|
|
14089
14121
|
},
|
|
14090
14122
|
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testBadge }, badge.icon),
|
|
14091
|
-
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testInfo }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.retestTag }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, assignment.testCase.
|
|
14123
|
+
/* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testInfo }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.retestTag }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, assignment.testCase.testKey, " \xB7 ", assignment.testCase.priority), assignment.testCase.role && /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: styles3.roleBadgeRow }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.testMeta }, " \xB7 "), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.View, { style: [styles3.roleBadgeDot, { backgroundColor: assignment.testCase.role.color }] }), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: [styles3.testMeta, { color: assignment.testCase.role.color, fontWeight: "500" }] }, assignment.testCase.role.name))))
|
|
14092
14124
|
);
|
|
14093
14125
|
}));
|
|
14094
|
-
}), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { style: styles3.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.refreshText }, "\u21BB Refresh")));
|
|
14126
|
+
}), /* @__PURE__ */ import_react5.default.createElement(import_react_native5.TouchableOpacity, { style: styles3.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ import_react5.default.createElement(import_react_native5.Text, { style: styles3.refreshText }, "\u21BB", " Refresh")));
|
|
14095
14127
|
}
|
|
14096
14128
|
var styles3 = import_react_native5.StyleSheet.create({
|
|
14097
|
-
filterBar: { flexDirection: "row", gap: 8, marginBottom:
|
|
14129
|
+
filterBar: { flexDirection: "row", gap: 8, marginBottom: 8 },
|
|
14098
14130
|
filterBtn: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 8, backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border },
|
|
14099
14131
|
filterBtnActive: { backgroundColor: colors.blue, borderColor: colors.blue },
|
|
14100
14132
|
filterBtnText: { fontSize: 12, color: colors.textSecondary },
|
|
14101
14133
|
filterBtnTextActive: { color: "#fff", fontWeight: "600" },
|
|
14134
|
+
roleSection: { marginBottom: 12 },
|
|
14135
|
+
roleBar: { flexDirection: "row", marginBottom: 6 },
|
|
14136
|
+
roleBtn: { flexDirection: "row", alignItems: "center", gap: 5, paddingHorizontal: 10, paddingVertical: 4, borderRadius: 6, marginRight: 6, borderWidth: 1, borderColor: "transparent" },
|
|
14137
|
+
roleBtnActive: { backgroundColor: colors.card, borderColor: colors.border },
|
|
14138
|
+
roleBtnText: { fontSize: 11, color: colors.textMuted },
|
|
14139
|
+
roleBtnTextActive: { color: colors.textPrimary, fontWeight: "600" },
|
|
14140
|
+
roleDot: { width: 6, height: 6, borderRadius: 3 },
|
|
14141
|
+
loginHint: { borderRadius: 6, padding: 8, borderWidth: 1 },
|
|
14142
|
+
loginHintText: { fontSize: 11, color: colors.textSecondary },
|
|
14143
|
+
roleBadgeRow: { flexDirection: "row", alignItems: "center", gap: 3 },
|
|
14144
|
+
roleBadgeDot: { width: 5, height: 5, borderRadius: 3 },
|
|
14102
14145
|
folder: { marginBottom: 12 },
|
|
14103
14146
|
folderHeader: { flexDirection: "row", alignItems: "center", gap: 8, paddingVertical: 8, paddingHorizontal: 4 },
|
|
14104
14147
|
folderToggle: { fontSize: 10, color: colors.textMuted, width: 14 },
|
|
@@ -14111,7 +14154,7 @@ var styles3 = import_react_native5.StyleSheet.create({
|
|
|
14111
14154
|
testBadge: { fontSize: 16, marginRight: 10, width: 20 },
|
|
14112
14155
|
testInfo: { flex: 1 },
|
|
14113
14156
|
testTitle: { fontSize: 14, color: colors.textPrimary, marginBottom: 2 },
|
|
14114
|
-
testMetaRow: { flexDirection: "row", alignItems: "center", gap: 6 },
|
|
14157
|
+
testMetaRow: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
14115
14158
|
retestTag: { backgroundColor: "#422006", borderWidth: 1, borderColor: "#854d0e", borderRadius: 4, paddingHorizontal: 5, paddingVertical: 1 },
|
|
14116
14159
|
retestTagText: { fontSize: 10, fontWeight: "600", color: "#fbbf24" },
|
|
14117
14160
|
testMeta: { fontSize: 11, color: colors.textDim },
|
package/dist/index.mjs
CHANGED
|
@@ -11360,7 +11360,7 @@ function shouldShowDeprecationWarning() {
|
|
|
11360
11360
|
}
|
|
11361
11361
|
if (shouldShowDeprecationWarning()) console.warn("\u26A0\uFE0F Node.js 18 and below are deprecated and will no longer be supported in future versions of @supabase/supabase-js. Please upgrade to Node.js 20 or later. For more information, visit: https://github.com/orgs/supabase/discussions/37217");
|
|
11362
11362
|
|
|
11363
|
-
//
|
|
11363
|
+
// node_modules/@bbearai/core/dist/index.mjs
|
|
11364
11364
|
var MAX_CONSOLE_LOGS = 50;
|
|
11365
11365
|
var MAX_NETWORK_REQUESTS = 20;
|
|
11366
11366
|
var MAX_NAVIGATION_HISTORY = 20;
|
|
@@ -13220,7 +13220,7 @@ import {
|
|
|
13220
13220
|
Image as Image3,
|
|
13221
13221
|
TouchableOpacity as TouchableOpacity12,
|
|
13222
13222
|
Modal as Modal2,
|
|
13223
|
-
ScrollView as
|
|
13223
|
+
ScrollView as ScrollView3,
|
|
13224
13224
|
StyleSheet as StyleSheet14,
|
|
13225
13225
|
Dimensions as Dimensions2,
|
|
13226
13226
|
KeyboardAvoidingView,
|
|
@@ -13999,14 +13999,23 @@ var styles2 = StyleSheet3.create({
|
|
|
13999
13999
|
|
|
14000
14000
|
// src/widget/screens/TestListScreen.tsx
|
|
14001
14001
|
import React4, { useState as useState3, useMemo as useMemo2, useCallback as useCallback3, useEffect as useEffect4 } from "react";
|
|
14002
|
-
import { View as View3, Text as Text3, TouchableOpacity as TouchableOpacity3, StyleSheet as StyleSheet4 } from "react-native";
|
|
14002
|
+
import { View as View3, Text as Text3, TouchableOpacity as TouchableOpacity3, StyleSheet as StyleSheet4, ScrollView } from "react-native";
|
|
14003
14003
|
function TestListScreen({ nav }) {
|
|
14004
14004
|
const { assignments, currentAssignment, refreshAssignments } = useBugBear();
|
|
14005
14005
|
const [filter, setFilter] = useState3("all");
|
|
14006
|
+
const [roleFilter, setRoleFilter] = useState3(null);
|
|
14006
14007
|
const [collapsedFolders, setCollapsedFolders] = useState3(/* @__PURE__ */ new Set());
|
|
14007
14008
|
useEffect4(() => {
|
|
14008
14009
|
refreshAssignments();
|
|
14009
14010
|
}, []);
|
|
14011
|
+
const availableRoles = useMemo2(() => {
|
|
14012
|
+
const roleMap = /* @__PURE__ */ new Map();
|
|
14013
|
+
for (const a of assignments) {
|
|
14014
|
+
if (a.testCase.role) roleMap.set(a.testCase.role.id, a.testCase.role);
|
|
14015
|
+
}
|
|
14016
|
+
return Array.from(roleMap.values());
|
|
14017
|
+
}, [assignments]);
|
|
14018
|
+
const selectedRole = availableRoles.find((r) => r.id === roleFilter);
|
|
14010
14019
|
const groupedAssignments = useMemo2(() => {
|
|
14011
14020
|
const groups = /* @__PURE__ */ new Map();
|
|
14012
14021
|
for (const assignment of assignments) {
|
|
@@ -14050,16 +14059,39 @@ function TestListScreen({ nav }) {
|
|
|
14050
14059
|
});
|
|
14051
14060
|
}, []);
|
|
14052
14061
|
const filterAssignment = (a) => {
|
|
14062
|
+
if (roleFilter && a.testCase.role?.id !== roleFilter) return false;
|
|
14053
14063
|
if (filter === "pending") return a.status === "pending" || a.status === "in_progress";
|
|
14054
14064
|
if (filter === "completed") return a.status === "passed" || a.status === "failed";
|
|
14055
14065
|
return true;
|
|
14056
14066
|
};
|
|
14057
|
-
return /* @__PURE__ */ React4.createElement(View3, null, /* @__PURE__ */ React4.createElement(View3, { style: styles3.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ React4.createElement(TouchableOpacity3, { key: f, style: [styles3.filterBtn, filter === f && styles3.filterBtnActive], onPress: () => setFilter(f) }, /* @__PURE__ */ React4.createElement(Text3, { style: [styles3.filterBtnText, filter === f && styles3.filterBtnTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length})` : `Done (${assignments.filter((a) => a.status === "passed" || a.status === "failed").length})`)))),
|
|
14067
|
+
return /* @__PURE__ */ React4.createElement(View3, null, /* @__PURE__ */ React4.createElement(View3, { style: styles3.filterBar }, ["all", "pending", "completed"].map((f) => /* @__PURE__ */ React4.createElement(TouchableOpacity3, { key: f, style: [styles3.filterBtn, filter === f && styles3.filterBtnActive], onPress: () => setFilter(f) }, /* @__PURE__ */ React4.createElement(Text3, { style: [styles3.filterBtnText, filter === f && styles3.filterBtnTextActive] }, f === "all" ? `All (${assignments.length})` : f === "pending" ? `To Do (${assignments.filter((a) => a.status === "pending" || a.status === "in_progress").length})` : `Done (${assignments.filter((a) => a.status === "passed" || a.status === "failed").length})`)))), availableRoles.length >= 2 && /* @__PURE__ */ React4.createElement(View3, { style: styles3.roleSection }, /* @__PURE__ */ React4.createElement(ScrollView, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles3.roleBar }, /* @__PURE__ */ React4.createElement(
|
|
14068
|
+
TouchableOpacity3,
|
|
14069
|
+
{
|
|
14070
|
+
style: [styles3.roleBtn, !roleFilter && styles3.roleBtnActive],
|
|
14071
|
+
onPress: () => setRoleFilter(null)
|
|
14072
|
+
},
|
|
14073
|
+
/* @__PURE__ */ React4.createElement(Text3, { style: [styles3.roleBtnText, !roleFilter && styles3.roleBtnTextActive] }, "All Roles")
|
|
14074
|
+
), availableRoles.map((role) => {
|
|
14075
|
+
const isActive = roleFilter === role.id;
|
|
14076
|
+
return /* @__PURE__ */ React4.createElement(
|
|
14077
|
+
TouchableOpacity3,
|
|
14078
|
+
{
|
|
14079
|
+
key: role.id,
|
|
14080
|
+
style: [
|
|
14081
|
+
styles3.roleBtn,
|
|
14082
|
+
isActive && { backgroundColor: role.color + "20", borderColor: role.color + "60", borderWidth: 1 }
|
|
14083
|
+
],
|
|
14084
|
+
onPress: () => setRoleFilter(isActive ? null : role.id)
|
|
14085
|
+
},
|
|
14086
|
+
/* @__PURE__ */ React4.createElement(View3, { style: [styles3.roleDot, { backgroundColor: role.color }] }),
|
|
14087
|
+
/* @__PURE__ */ React4.createElement(Text3, { style: [styles3.roleBtnText, isActive && { color: role.color, fontWeight: "600" }] }, role.name)
|
|
14088
|
+
);
|
|
14089
|
+
})), selectedRole?.loginHint && /* @__PURE__ */ React4.createElement(View3, { style: [styles3.loginHint, { backgroundColor: selectedRole.color + "10", borderColor: selectedRole.color + "30" }] }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.loginHintText }, "Log in as: ", selectedRole.loginHint))), groupedAssignments.map((folder) => {
|
|
14058
14090
|
const folderId = folder.group?.id || "ungrouped";
|
|
14059
14091
|
const isCollapsed = collapsedFolders.has(folderId);
|
|
14060
14092
|
const filtered = folder.assignments.filter(filterAssignment);
|
|
14061
14093
|
if (filtered.length === 0 && filter !== "all") return null;
|
|
14062
|
-
return /* @__PURE__ */ React4.createElement(View3, { key: folderId, style: styles3.folder }, /* @__PURE__ */ React4.createElement(TouchableOpacity3, { style: styles3.folderHeader, onPress: () => toggleFolder(folderId) }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderToggle }, isCollapsed ? "\u25B6" : "\u25BC"), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderName }, folder.group?.name || "Ungrouped"), /* @__PURE__ */ React4.createElement(View3, { style: styles3.folderProgress }, /* @__PURE__ */ React4.createElement(View3, { style: [styles3.folderProgressFill, { width: `${Math.round((folder.stats.passed + folder.stats.failed) / folder.stats.total * 100)}%` }] })), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderCount }, folder.stats.passed + folder.stats.failed, "/", folder.stats.total)), !isCollapsed && filtered.map((assignment) => {
|
|
14094
|
+
return /* @__PURE__ */ React4.createElement(View3, { key: folderId, style: styles3.folder }, /* @__PURE__ */ React4.createElement(TouchableOpacity3, { style: styles3.folderHeader, onPress: () => toggleFolder(folderId) }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderToggle }, isCollapsed ? "\u25B6" : "\u25BC"), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderName, numberOfLines: 1 }, folder.group?.name || "Ungrouped"), /* @__PURE__ */ React4.createElement(View3, { style: styles3.folderProgress }, /* @__PURE__ */ React4.createElement(View3, { style: [styles3.folderProgressFill, { width: `${folder.stats.total > 0 ? Math.round((folder.stats.passed + folder.stats.failed) / folder.stats.total * 100) : 0}%` }] })), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.folderCount }, folder.stats.passed + folder.stats.failed, "/", folder.stats.total)), !isCollapsed && filtered.map((assignment) => {
|
|
14063
14095
|
const badge = getStatusBadge(assignment.status);
|
|
14064
14096
|
const isCurrent = currentAssignment?.id === assignment.id;
|
|
14065
14097
|
return /* @__PURE__ */ React4.createElement(
|
|
@@ -14070,17 +14102,28 @@ function TestListScreen({ nav }) {
|
|
|
14070
14102
|
onPress: () => nav.push({ name: "TEST_DETAIL", testId: assignment.id })
|
|
14071
14103
|
},
|
|
14072
14104
|
/* @__PURE__ */ React4.createElement(Text3, { style: styles3.testBadge }, badge.icon),
|
|
14073
|
-
/* @__PURE__ */ React4.createElement(View3, { style: styles3.testInfo }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ React4.createElement(View3, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ React4.createElement(View3, { style: styles3.retestTag }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.testMeta }, assignment.testCase.
|
|
14105
|
+
/* @__PURE__ */ React4.createElement(View3, { style: styles3.testInfo }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.testTitle, numberOfLines: 1 }, assignment.testCase.title), /* @__PURE__ */ React4.createElement(View3, { style: styles3.testMetaRow }, assignment.isVerification && /* @__PURE__ */ React4.createElement(View3, { style: styles3.retestTag }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.retestTagText }, "Retest")), /* @__PURE__ */ React4.createElement(Text3, { style: styles3.testMeta }, assignment.testCase.testKey, " \xB7 ", assignment.testCase.priority), assignment.testCase.role && /* @__PURE__ */ React4.createElement(View3, { style: styles3.roleBadgeRow }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.testMeta }, " \xB7 "), /* @__PURE__ */ React4.createElement(View3, { style: [styles3.roleBadgeDot, { backgroundColor: assignment.testCase.role.color }] }), /* @__PURE__ */ React4.createElement(Text3, { style: [styles3.testMeta, { color: assignment.testCase.role.color, fontWeight: "500" }] }, assignment.testCase.role.name))))
|
|
14074
14106
|
);
|
|
14075
14107
|
}));
|
|
14076
|
-
}), /* @__PURE__ */ React4.createElement(TouchableOpacity3, { style: styles3.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.refreshText }, "\u21BB Refresh")));
|
|
14108
|
+
}), /* @__PURE__ */ React4.createElement(TouchableOpacity3, { style: styles3.refreshBtn, onPress: refreshAssignments }, /* @__PURE__ */ React4.createElement(Text3, { style: styles3.refreshText }, "\u21BB", " Refresh")));
|
|
14077
14109
|
}
|
|
14078
14110
|
var styles3 = StyleSheet4.create({
|
|
14079
|
-
filterBar: { flexDirection: "row", gap: 8, marginBottom:
|
|
14111
|
+
filterBar: { flexDirection: "row", gap: 8, marginBottom: 8 },
|
|
14080
14112
|
filterBtn: { paddingHorizontal: 12, paddingVertical: 6, borderRadius: 8, backgroundColor: colors.card, borderWidth: 1, borderColor: colors.border },
|
|
14081
14113
|
filterBtnActive: { backgroundColor: colors.blue, borderColor: colors.blue },
|
|
14082
14114
|
filterBtnText: { fontSize: 12, color: colors.textSecondary },
|
|
14083
14115
|
filterBtnTextActive: { color: "#fff", fontWeight: "600" },
|
|
14116
|
+
roleSection: { marginBottom: 12 },
|
|
14117
|
+
roleBar: { flexDirection: "row", marginBottom: 6 },
|
|
14118
|
+
roleBtn: { flexDirection: "row", alignItems: "center", gap: 5, paddingHorizontal: 10, paddingVertical: 4, borderRadius: 6, marginRight: 6, borderWidth: 1, borderColor: "transparent" },
|
|
14119
|
+
roleBtnActive: { backgroundColor: colors.card, borderColor: colors.border },
|
|
14120
|
+
roleBtnText: { fontSize: 11, color: colors.textMuted },
|
|
14121
|
+
roleBtnTextActive: { color: colors.textPrimary, fontWeight: "600" },
|
|
14122
|
+
roleDot: { width: 6, height: 6, borderRadius: 3 },
|
|
14123
|
+
loginHint: { borderRadius: 6, padding: 8, borderWidth: 1 },
|
|
14124
|
+
loginHintText: { fontSize: 11, color: colors.textSecondary },
|
|
14125
|
+
roleBadgeRow: { flexDirection: "row", alignItems: "center", gap: 3 },
|
|
14126
|
+
roleBadgeDot: { width: 5, height: 5, borderRadius: 3 },
|
|
14084
14127
|
folder: { marginBottom: 12 },
|
|
14085
14128
|
folderHeader: { flexDirection: "row", alignItems: "center", gap: 8, paddingVertical: 8, paddingHorizontal: 4 },
|
|
14086
14129
|
folderToggle: { fontSize: 10, color: colors.textMuted, width: 14 },
|
|
@@ -14093,7 +14136,7 @@ var styles3 = StyleSheet4.create({
|
|
|
14093
14136
|
testBadge: { fontSize: 16, marginRight: 10, width: 20 },
|
|
14094
14137
|
testInfo: { flex: 1 },
|
|
14095
14138
|
testTitle: { fontSize: 14, color: colors.textPrimary, marginBottom: 2 },
|
|
14096
|
-
testMetaRow: { flexDirection: "row", alignItems: "center", gap: 6 },
|
|
14139
|
+
testMetaRow: { flexDirection: "row", alignItems: "center", gap: 6, flexWrap: "wrap" },
|
|
14097
14140
|
retestTag: { backgroundColor: "#422006", borderWidth: 1, borderColor: "#854d0e", borderRadius: 4, paddingHorizontal: 5, paddingVertical: 1 },
|
|
14098
14141
|
retestTagText: { fontSize: 10, fontWeight: "600", color: "#fbbf24" },
|
|
14099
14142
|
testMeta: { fontSize: 11, color: colors.textDim },
|
|
@@ -14188,10 +14231,10 @@ import { View as View5, Text as Text5, TouchableOpacity as TouchableOpacity5, St
|
|
|
14188
14231
|
|
|
14189
14232
|
// src/widget/ImagePreviewStrip.tsx
|
|
14190
14233
|
import React5 from "react";
|
|
14191
|
-
import { View as View4, Text as Text4, TouchableOpacity as TouchableOpacity4, ScrollView, Image, ActivityIndicator, StyleSheet as StyleSheet5 } from "react-native";
|
|
14234
|
+
import { View as View4, Text as Text4, TouchableOpacity as TouchableOpacity4, ScrollView as ScrollView2, Image, ActivityIndicator, StyleSheet as StyleSheet5 } from "react-native";
|
|
14192
14235
|
function ImagePreviewStrip({ images, onRemove }) {
|
|
14193
14236
|
if (images.length === 0) return null;
|
|
14194
|
-
return /* @__PURE__ */ React5.createElement(
|
|
14237
|
+
return /* @__PURE__ */ React5.createElement(ScrollView2, { horizontal: true, showsHorizontalScrollIndicator: false, style: styles4.strip }, images.map((img) => /* @__PURE__ */ React5.createElement(View4, { key: img.id, style: styles4.thumbContainer }, /* @__PURE__ */ React5.createElement(Image, { source: { uri: img.localUri }, style: styles4.thumb }), img.status === "uploading" && /* @__PURE__ */ React5.createElement(View4, { style: styles4.thumbOverlay }, /* @__PURE__ */ React5.createElement(ActivityIndicator, { size: "small", color: "#fff" })), img.status === "error" && /* @__PURE__ */ React5.createElement(View4, { style: [styles4.thumbOverlay, styles4.thumbOverlayError] }, /* @__PURE__ */ React5.createElement(Text4, { style: styles4.thumbErrorText }, "!")), /* @__PURE__ */ React5.createElement(TouchableOpacity4, { style: styles4.thumbRemove, onPress: () => onRemove(img.id) }, /* @__PURE__ */ React5.createElement(Text4, { style: styles4.thumbRemoveText }, "\u2715")))));
|
|
14195
14238
|
}
|
|
14196
14239
|
var styles4 = StyleSheet5.create({
|
|
14197
14240
|
strip: {
|
|
@@ -15157,7 +15200,7 @@ function BugBearButton({
|
|
|
15157
15200
|
style: styles13.modalOverlay
|
|
15158
15201
|
},
|
|
15159
15202
|
/* @__PURE__ */ React14.createElement(View13, { style: styles13.modalContainer }, /* @__PURE__ */ React14.createElement(View13, { style: styles13.header }, /* @__PURE__ */ React14.createElement(View13, { style: styles13.headerLeft }, canGoBack ? /* @__PURE__ */ React14.createElement(View13, { style: styles13.headerNavRow }, /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => nav.pop(), style: styles13.backButton }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.backText }, "\u2190 Back")), /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => nav.reset(), style: styles13.homeButton }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.homeText }, "\u{1F3E0}"))) : /* @__PURE__ */ React14.createElement(View13, { style: styles13.headerTitleRow }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.headerTitle }, "BugBear"), testerInfo && /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: () => push({ name: "PROFILE" }) }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.headerName }, testerInfo.name, " \u270E")))), getHeaderTitle() ? /* @__PURE__ */ React14.createElement(Text13, { style: styles13.headerScreenTitle, numberOfLines: 1 }, getHeaderTitle()) : null, /* @__PURE__ */ React14.createElement(TouchableOpacity12, { onPress: handleClose, style: styles13.closeButton }, /* @__PURE__ */ React14.createElement(Text13, { style: styles13.closeText }, "\u2715"))), /* @__PURE__ */ React14.createElement(
|
|
15160
|
-
|
|
15203
|
+
ScrollView3,
|
|
15161
15204
|
{
|
|
15162
15205
|
style: styles13.content,
|
|
15163
15206
|
contentContainerStyle: styles13.contentContainer,
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@bbearai/react-native",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "BugBear React Native components for mobile apps",
|
|
5
5
|
"main": "./dist/index.js",
|
|
6
6
|
"module": "./dist/index.mjs",
|
|
@@ -49,7 +49,7 @@
|
|
|
49
49
|
}
|
|
50
50
|
},
|
|
51
51
|
"devDependencies": {
|
|
52
|
-
"@bbearai/core": "^0.
|
|
52
|
+
"@bbearai/core": "^0.4.0",
|
|
53
53
|
"@eslint/js": "^9.39.2",
|
|
54
54
|
"@types/react": "^18.2.0",
|
|
55
55
|
"eslint": "^9.39.2",
|