mirror of
https://github.com/mgeeky/decode-spam-headers.git
synced 2026-02-22 13:33:30 +01:00
MAESTRO: render progress indicator during analysis
This commit is contained in:
@@ -42,7 +42,7 @@ Frontend uses `fetch` with `ReadableStream` reader (not native `EventSource`, wh
|
|||||||
- [x] `pytest backend/tests/api/test_analysis_router.py` passes (all paths: happy, error, oversized, partial failure, timeout)
|
- [x] `pytest backend/tests/api/test_analysis_router.py` passes (all paths: happy, error, oversized, partial failure, timeout)
|
||||||
- [x] All vitest tests pass: `npx vitest run src/__tests__/ProgressIndicator.test.tsx src/__tests__/useAnalysis.test.ts`
|
- [x] All vitest tests pass: `npx vitest run src/__tests__/ProgressIndicator.test.tsx src/__tests__/useAnalysis.test.ts`
|
||||||
- [x] Submitting headers triggers backend analysis with SSE streaming
|
- [x] Submitting headers triggers backend analysis with SSE streaming
|
||||||
- [ ] Progress bar updates in real-time showing current test name and percentage
|
- [x] Progress bar updates in real-time showing current test name and percentage
|
||||||
- [ ] Countdown timer counts down from 30 seconds
|
- [ ] Countdown timer counts down from 30 seconds
|
||||||
- [ ] Partial failures show inline error indicators per FR-25
|
- [ ] Partial failures show inline error indicators per FR-25
|
||||||
- [ ] Timeout at 30s displays partial results with notification listing incomplete tests
|
- [ ] Timeout at 30s displays partial results with notification listing incomplete tests
|
||||||
|
|||||||
@@ -5,6 +5,7 @@ import { useCallback, useState } from "react";
|
|||||||
import AnalyseButton from "../components/AnalyseButton";
|
import AnalyseButton from "../components/AnalyseButton";
|
||||||
import FileDropZone from "../components/FileDropZone";
|
import FileDropZone from "../components/FileDropZone";
|
||||||
import HeaderInput from "../components/HeaderInput";
|
import HeaderInput from "../components/HeaderInput";
|
||||||
|
import ProgressIndicator from "../components/ProgressIndicator";
|
||||||
import useAnalysis from "../hooks/useAnalysis";
|
import useAnalysis from "../hooks/useAnalysis";
|
||||||
import { MAX_HEADER_INPUT_BYTES } from "../lib/header-validation";
|
import { MAX_HEADER_INPUT_BYTES } from "../lib/header-validation";
|
||||||
import type { AnalysisConfig } from "../types/analysis";
|
import type { AnalysisConfig } from "../types/analysis";
|
||||||
@@ -17,11 +18,12 @@ const defaultConfig: AnalysisConfig = {
|
|||||||
|
|
||||||
export default function Home() {
|
export default function Home() {
|
||||||
const [headerInput, setHeaderInput] = useState("");
|
const [headerInput, setHeaderInput] = useState("");
|
||||||
const { status, submit } = useAnalysis();
|
const { status, progress, submit } = useAnalysis();
|
||||||
const hasHeaderInput = headerInput.trim().length > 0;
|
const hasHeaderInput = headerInput.trim().length > 0;
|
||||||
const isOversized = headerInput.length > MAX_HEADER_INPUT_BYTES;
|
const isOversized = headerInput.length > MAX_HEADER_INPUT_BYTES;
|
||||||
const canAnalyse = hasHeaderInput && !isOversized;
|
const canAnalyse = hasHeaderInput && !isOversized;
|
||||||
const isLoading = status === "submitting" || status === "analysing";
|
const isLoading = status === "submitting" || status === "analysing";
|
||||||
|
const showProgress = status === "analysing";
|
||||||
|
|
||||||
const handleAnalyse = useCallback(() => {
|
const handleAnalyse = useCallback(() => {
|
||||||
if (!canAnalyse) {
|
if (!canAnalyse) {
|
||||||
@@ -77,6 +79,14 @@ export default function Home() {
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
{showProgress ? (
|
||||||
|
<ProgressIndicator
|
||||||
|
status={status}
|
||||||
|
progress={progress}
|
||||||
|
timeoutSeconds={30}
|
||||||
|
/>
|
||||||
|
) : null}
|
||||||
</div>
|
</div>
|
||||||
</section>
|
</section>
|
||||||
</div>
|
</div>
|
||||||
|
|||||||
Reference in New Issue
Block a user