feat(feedback): route failed-run Report issue through the offline handoff (#429)

Apply the always-on handoff to the failed-run Report issue button too. Un-gate the two buttons in tool-page.tsx from the analytics toggle, and extend the dialog offline handoff to source=failed_job, prefilling the GitHub issue with the tool id and error category so it is actionable even with an empty message. Follows #428.

Claude-Session: https://claude.ai/code/session_01XVrHKXwzZDWBWgkGQdPZ3A
This commit is contained in:
SnapOtter
2026-07-04 18:06:16 +08:00
committed by GitHub
parent e0dbf2a5c3
commit 8cdd85a493
3 changed files with 48 additions and 18 deletions
+9 -14
View File
@@ -51,7 +51,6 @@ import { ICON_MAP } from "@/lib/icon-map";
import { MULTI_FILE_TOOLS } from "@/lib/tool-display-modes";
import { getToolName } from "@/lib/tool-i18n";
import { getToolRegistryEntry } from "@/lib/tool-registry";
import { useAnalyticsStore } from "@/stores/analytics-store";
import { useBase64Store } from "@/stores/base64-store";
import { useCollageStore } from "@/stores/collage-store";
import { useDuplicateStore } from "@/stores/duplicate-store";
@@ -327,8 +326,6 @@ export function ToolPage() {
);
const [mobileSettingsOpen, setMobileSettingsOpen] = useState(false);
const [failedFeedbackOpen, setFailedFeedbackOpen] = useState(false);
const analyticsConfig = useAnalyticsStore((s) => s.config);
const feedbackEnabled = Boolean(analyticsConfig?.enabled);
const [previewTransform, setPreviewTransform] = useState<PreviewTransform | null>(null);
const [previewFilter, setPreviewFilter] = useState<string>("");
const [imageWrapperStyle, setImageWrapperStyle] = useState<React.CSSProperties | null>(null);
@@ -791,16 +788,14 @@ export function ToolPage() {
>
{t.toolPage.tryDifferentFile}
</button>
{feedbackEnabled && (
<button
type="button"
onClick={() => setFailedFeedbackOpen(true)}
className="px-4 py-2 rounded-md border border-border text-sm text-muted-foreground hover:bg-muted hover:text-foreground inline-flex items-center justify-center gap-2"
>
<MessageSquare className="h-3.5 w-3.5" />
{t.feedback.reportIssue}
</button>
)}
<button
type="button"
onClick={() => setFailedFeedbackOpen(true)}
className="px-4 py-2 rounded-md border border-border text-sm text-muted-foreground hover:bg-muted hover:text-foreground inline-flex items-center justify-center gap-2"
>
<MessageSquare className="h-3.5 w-3.5" />
{t.feedback.reportIssue}
</button>
</div>
</div>
</div>
@@ -1120,7 +1115,7 @@ export function ToolPage() {
</Suspense>
</div>
{feedbackEnabled && currentEntry?.status === "failed" && (
{currentEntry?.status === "failed" && (
<button
type="button"
onClick={() => setFailedFeedbackOpen(true)}