mirror of
https://github.com/RuoJi6/ARTEX.git
synced 2026-10-28 17:13:50 +08:00
fix(web): sync finding traffic bindings between overview and reproduction steps
This commit is contained in:
1 parent
8ad507e31f
commit
4273ef5d97
3 files changed
+27
-9
No files matched your search
@@ -63,6 +63,7 @@ function FindingDetailInner() {
|
||||
const [finding, setFinding] = React.useState<Finding | null>(null);
|
||||
const [loaded, setLoaded] = React.useState(false);
|
||||
const [tab, setTab] = React.useState("overview");
|
||||
const [trafficReload, setTrafficReload] = React.useState(0);
|
||||
|
||||
const load = React.useCallback(() => {
|
||||
if (!id) {
|
||||
@@ -79,6 +80,11 @@ function FindingDetailInner() {
|
||||
load();
|
||||
}, [load]);
|
||||
|
||||
const handleTrafficChanged = React.useCallback(() => {
|
||||
setTrafficReload((value) => value + 1);
|
||||
load();
|
||||
}, [load]);
|
||||
|
||||
const changeSeverity = React.useCallback(
|
||||
async (next: Severity) => {
|
||||
if (!finding || finding.inherited || next === finding.severity) return;
|
||||
@@ -191,7 +197,8 @@ function FindingDetailInner() {
|
||||
reproduction={finding.reproduction}
|
||||
contextTask={contextTaskId || undefined}
|
||||
readOnly={finding.inherited}
|
||||
onChanged={load}
|
||||
onChanged={handleTrafficChanged}
|
||||
trafficReload={trafficReload}
|
||||
/>
|
||||
) : null}
|
||||
<details open={!structuredReproduction} className="group">
|
||||
@@ -215,7 +222,8 @@ function FindingDetailInner() {
|
||||
readOnly={finding.inherited}
|
||||
stepIndex={structuredReproduction ? 0 : undefined}
|
||||
title={structuredReproduction ? "未归入步骤的流量" : undefined}
|
||||
onChanged={load}
|
||||
onChanged={handleTrafficChanged}
|
||||
trafficReload={trafficReload}
|
||||
/>
|
||||
{/* 证据下方:详细报告(Markdown 渲染) */}
|
||||
<Card>
|
||||
|
||||
@@ -43,12 +43,14 @@ export function FindingReproductionSection({
|
||||
contextTask,
|
||||
readOnly,
|
||||
onChanged,
|
||||
trafficReload = 0,
|
||||
}: {
|
||||
findingId: string;
|
||||
reproduction: Reproduction;
|
||||
contextTask?: string;
|
||||
readOnly?: boolean;
|
||||
onChanged?: () => void;
|
||||
trafficReload?: number;
|
||||
}) {
|
||||
const [traffic, setTraffic] = React.useState<FindingTraffic | null>(null);
|
||||
const [pickerStep, setPickerStep] = React.useState<number | null>(null);
|
||||
@@ -59,14 +61,20 @@ export function FindingReproductionSection({
|
||||
const [editingStepIndex, setEditingStepIndex] = React.useState("0");
|
||||
const [busy, setBusy] = React.useState(false);
|
||||
const [reload, setReload] = React.useState(0);
|
||||
const load = React.useCallback(() => {
|
||||
React.useEffect(() => {
|
||||
let active = true;
|
||||
api
|
||||
.findingTraffic(findingId, contextTask)
|
||||
.then(setTraffic)
|
||||
.catch(() => setTraffic(null));
|
||||
}, [findingId, contextTask]);
|
||||
// biome-ignore lint/correctness/useExhaustiveDependencies: retry token intentionally refreshes this request.
|
||||
React.useEffect(() => load(), [load, reload]);
|
||||
.then((value) => {
|
||||
if (active) setTraffic(value);
|
||||
})
|
||||
.catch(() => {
|
||||
if (active) setTraffic(null);
|
||||
});
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [findingId, contextTask, reload, trafficReload]);
|
||||
|
||||
const steps = reproduction.steps ?? [];
|
||||
const allBindings = traffic?.bindings ?? [];
|
||||
|
||||
@@ -46,6 +46,7 @@ export function FindingTrafficPanel({
|
||||
onChanged,
|
||||
stepIndex: filterStepIndex,
|
||||
title,
|
||||
trafficReload = 0,
|
||||
}: {
|
||||
findingId: string;
|
||||
contextTask?: string;
|
||||
@@ -53,6 +54,7 @@ export function FindingTrafficPanel({
|
||||
onChanged: () => void;
|
||||
stepIndex?: number;
|
||||
title?: string;
|
||||
trafficReload?: number;
|
||||
}) {
|
||||
const [data, setData] = React.useState<FindingTraffic | null>(null);
|
||||
const [error, setError] = React.useState("");
|
||||
@@ -84,7 +86,7 @@ export function FindingTrafficPanel({
|
||||
return () => {
|
||||
active = false;
|
||||
};
|
||||
}, [findingId, contextTask, reload, filterStepIndex]);
|
||||
}, [findingId, contextTask, reload, filterStepIndex, trafficReload]);
|
||||
|
||||
async function mutate(action: () => Promise<FindingTraffic>) {
|
||||
setBusy(true);
|
||||
|
||||
Reference in new issue
Block a user