Skip to content

feat(web): editable code window for mode 1 (issue #125)#239

Merged
ArtVsMark merged 3 commits into
mainfrom
feat/web-solution-editor-125
Jul 9, 2026
Merged

feat(web): editable code window for mode 1 (issue #125)#239
ArtVsMark merged 3 commits into
mainfrom
feat/web-solution-editor-125

Conversation

@ArtVsMark

Copy link
Copy Markdown
Owner

Summary

  • Owner flagged feat(web): реализовать рабочую область проверки решения #125 as not fully done: mode 1's file-picker only ever showed a read-only preview of an already-on-disk solution (GET /api/source) — no way to write/edit code in the browser and check it without a pre-existing file.
  • New web/viewmodels.py::save_solution(folder, path, code) + _next_solution_filename(): writes the editor's code to path if one was selected, otherwise to a new file whose name extends the folder's existing task<N>_<M>.py numbering series (or starts at task_1.py if none exists). No such "next free filename" helper existed anywhere in the codebase before.
  • New POST /api/save-solution (body {"folder","path"?,"code"}), server.py's do_POST restructured from a single-route if into an if/elif shared with the existing /api/download parsing.
  • Frontend: the read-only #selected-source-block is replaced by a persistent, editable <textarea id="solution-editor">. Picking a file loads its code into it (editable); leaving nothing picked lets you type a new solution from scratch. grade() now saves first (via the new endpoint), then grades the path the backend actually wrote to. Run is no longer blocked just because no file was picked.
  • Issue ✨ [Feature] feat(stepik): полуавтоматический импорт закреплённого решения из saved JSON через target page #55 ("Найти эталонное решение") intentionally left untouched — owner confirmed it stays disabled for now.
  • Docs (docs/web-mvp.md) + CHANGELOG.md updated.

Test plan

  • pytest tests/test_web.py -q — new TestSaveSolution (unit) + 3 HTTP tests for /api/save-solution, all passing
  • pytest tests/ -q (full regression) — 946 passed, pre-existing unrelated Windows subprocess-spawn flakiness only (test_pytest_plugin.py/test_packaging.py/test_entrypoint.py/etc., confirmed as baseline earlier this session)
  • ruff check . / ruff format --check . / mypy src/stepik_grader --ignore-missing-imports — clean
  • Manual verification via preview on a real folder:
    • (a) pick an existing file → edit the buggy line in the textarea → ▶ → file on disk is overwritten, grading runs against the fixed code (OK)
    • (b) no file picked → type new code from scratch → ▶ → a new task_2.py is created (next in the folder's numbering series) and appears selected in the solutions list
    • modes 2/3/4 unaffected (Run still enables normally)

🤖 Generated with Claude Code

ArtVsMark and others added 3 commits July 9, 2026 22:55
…#125)

The owner flagged #125 as not actually done: mode 1 ("Один файл") only
ever showed a read-only preview of an already-on-disk file via
GET /api/source -- there was no way to type or edit code in the browser
and check it without a pre-existing file.

web/viewmodels.py::save_solution(folder, path, code) writes code to path
if one was picked, or to a newly-generated filename in folder otherwise.
The new name comes from _next_solution_filename(), which scans the
folder's direct children (non-recursive -- mode 1 saves into exactly the
shown folder, not a guessed subfolder) for files matching the same
task<N>_<M>.py mask is_solution_file()/downloader.py already use, and
extends the dominant numbering series by one (task4_1.py/task4_2.py present
-> task4_3.py; nothing present -> task_1.py). No such "next free filename"
helper existed anywhere in the codebase before this.

server.py's do_POST gains a second route, POST /api/save-solution (body:
{"folder", "path"?, "code"}), restructured from the single-route
if-return into an if/elif shared with the existing /api/download parsing.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
index.html/app.css: #selected-source-block's read-only codeBlock() preview
is replaced by a persistent <textarea id="solution-editor" class="code-editor">,
always visible in the file-picker panel (not just after picking a file).

app.js:
- selectSolutionFile() now populates the textarea's value (editable)
  instead of building read-only codeBlock() HTML.
- updateRunButtonState() no longer requires a picked file in mode 1 --
  it enables Run once there's a folder path AND non-empty editor content,
  so starting a solution from scratch (no existing file) is now possible.
- grade() gains a pre-save step for file mode: POSTs the editor's content
  to /api/save-solution with the currently selected path (or null), then
  proceeds to grade the path the backend actually wrote to. A new
  refreshSolutionsList() (list refresh without resetting the current
  selection) shows the saved/new file highlighted afterward --
  findSolutions() itself still resets selection, for the explicit
  "Найти решения" button click.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
docs/web-mvp.md's mode-1 description no longer says the code preview is
read-only; documents the save-then-grade flow and the task<N>_<M>.py
numbering series new files extend. CHANGELOG.md gets an Added entry.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@ArtVsMark ArtVsMark merged commit 72873ec into main Jul 9, 2026
9 checks passed
@ArtVsMark ArtVsMark deleted the feat/web-solution-editor-125 branch July 9, 2026 20:07
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant