feat(web): collapse Index tab's two indexing buttons into one (#582)#592
Merged
feat(web): collapse Index tab's two indexing buttons into one (#582)#592
Conversation
The folder-mode panel exposed two side-by-side buttons — primary ``Index`` (POST /api/index) and ghost ``Index with Progress`` (SSE stream). The two-button shape made users guess which one to pick and diluted the form's primary action. Drop the non-stream button entirely and route the single primary ``인덱스 / Index`` button through the streaming handler so progress is always visible. This is option (a) from the umbrella discussion (Prev #1). Option (b) — single button + a "show progress" toggle — would have kept two indexing paths alive and required a more complex ``STATE.indexing`` shape in #582 PR #6 (4.11). With (a) the indexing path is unified; PR #6 can use a single boolean flag. Made possible by #591 (closes #590), which gave ``index_path_stream`` the missing ``namespace`` parameter and a ``complete.errors`` field — both consumed here. The streaming handler now matches the full UX of the removed inline POST handler: - Reads ``namespace`` from the form input and forwards it as a query param when non-empty. - On ``complete``: renders ``r-errors-row`` with the same 5-cap "+N more" rule that the inline handler used (#354 partial-failure surface), then dispatches either ``toast.index_partial`` (red, with error count + first error) or ``toast.indexed_count`` (green, with the "Register as Source" toast action — folder mode is one-shot, so this nudge mirrors the inline behavior). Removes ``index.stream_btn``, ``toast.stream_complete``, and the ``.index-btn-row`` CSS rule (now wraps a single button → row container unnecessary). Updates ``test_i18n.py``'s required key set so the parity guard stays green. Refs #582 (Prev #1). Co-Authored-By: Claude <[email protected]>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to subscribe to this conversation on GitHub.
Already have an account?
Sign in.
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The folder-mode panel of the Index tab exposed two side-by-side buttons:
Index(primary, blue) →POST /api/index(non-stream)Index with Progress(ghost, gray) → SSE-streamedGET /api/index/streamThe two-button shape made users guess which one to pick and diluted the form's primary action. This PR drops the non-stream button entirely and routes the single primary
인덱스/Indexbutton through the streaming handler so progress is always visible.This is option (a) from the umbrella discussion (Prev #1). Option (b) — single button + a "show progress" toggle — would have kept two indexing paths alive and required a more complex
STATE.indexingshape in #582 PR #6 (4.11). With (a) the indexing path is unified; PR #6 can use a single boolean flag.Made possible by #591
#591 (closed #590) gave
index_path_streamthe missingnamespaceparameter and acomplete.errorsfield — both consumed here. Without #591, this PR would silently regress the namespace input and the partial-failure UX (#354 fix).Changes
web/static/app.js:qs('index-btn').addEventListener('click', async () => {...})handler (~70 LOC) that calledPOST /api/index.runIndexStreamnow: readsnamespacefromqs('index-namespace')and passes it as a query param when non-empty; renderscomplete.errorsintor-errors-rowwith the 5-cap "+N more" rule (preserves the index: POST /api/index returns 200 OK when all embeddings fail #354 partial-failure surface); dispatchestoast.index_partial(red) on partial failure ortoast.indexed_count(green, with the "Register as Source" toast action — folder mode is one-shot, mirroring the previous inline behavior).qs('index-stream-btn')references (button no longer exists).index-stream-btn→index-btn.// Index stream (SSE progress)→// Index (SSE-streamed; folder-mode primary action)to reflect the new role.web/static/index.html: drop the<div class="index-btn-row">wrapper and theindex-stream-btnbutton. Single primaryindex-btnremains.web/static/locales/{en,ko}.json: removeindex.stream_btnandtoast.stream_complete. Other keys (index.index_btn,toast.indexed_count,toast.index_partial,toast.action.register_persistent,toast.index_failed,toast.stream_fallback) stay.web/static/style.css: drop.index-btn-rowrule (it wrapped two buttons; now wraps one → row container unnecessary).tests/test_i18n.py: removetoast.stream_completefrom the required-key set so the parity guard stays green.Net diff: −97 / +47, six files (mostly deletions; a handful of additions inside
runIndexStreamfor namespace + error rendering).What does NOT change
POST /api/indexis still mounted; CLI / MCP callers continue to use it). This PR only changes the web folder-mode UI.runIndexStreamfunction name is kept (the mechanism IS streaming via EventSource — the name describes the implementation faithfully)."Please enter a path to index."(existed in both the inline handler andrunIndexStreampre-PR; pre-existing i18n gap, out of scope here).Refs
STATE.indexingflag sufficesTest plan
uv run ruff check packages/memtomem/src && uv run ruff format --check packages/memtomem/srcuv run pytest packages/memtomem/tests/test_i18n.py -m "not ollama"— 12/12 pass (parity guard green afterstream_completeremoval from the required set).uv run pytest packages/memtomem/tests/test_indexing_engine.py packages/memtomem/tests/test_web_routes.py packages/memtomem/tests/test_i18n.py packages/memtomem/tests/test_web_exclude_guard.py -m "not ollama"— 204/204 pass. No regressions in engine / routes / i18n / exclude guards.인덱스button (no ghost진행률 표시 인덱스sibling).Please enter a path to index.displays directly under the button (the.index-btn-rowremoval does not cause cramping;index-progressandindex-msgkeep their own spacing)./api/*initialization calls return 200.🤖 Generated with Claude Code