Skip to content

feat: editable route on page create#722

Merged
NagariaHussain merged 7 commits into
developfrom
feat/editable-page-route
Jul 26, 2026
Merged

feat: editable route on page create#722
NagariaHussain merged 7 commits into
developfrom
feat/editable-page-route

Conversation

@NagariaHussain

@NagariaHussain NagariaHussain commented Jul 26, 2026

Copy link
Copy Markdown
Member
image

Why?

Closes #714.

The new-page dialog only asked for a Title. The URL was derived behind the author's back from the folder hierarchy, and renaming the page later silently moved it. Authors never saw the URL they were creating and couldn't choose it.

What?

The dialog now has a Route field that fills in from the title as you type and stops tracking it the moment you edit it by hand — the same interaction the new-space dialog already has.

  • The prefilled default is still the hierarchy path (docs/guides/advanced/caching). Want a flat URL? Delete the middle segments.
  • A route already in use is flagged inline while you type, instead of failing at merge time.
  • Once the page exists the route is sticky: renaming the title no longer moves it. Changing the URL is an explicit edit through the existing route control.
  • Existing documents are untouched — no migration, no broken URLs.

How?

  • sanitize_route() normalises every author-supplied route through the app's existing slug rule, so a hand-written route can't produce a URL a derived one couldn't.
  • check_route_available() (new whitelisted read) checks live documents and, when one exists, the change request's own staged items. It's space-scoped with an optional cr_name because the draft CR is created lazily — the dialog can open before one exists. Only the newest in-flight check is allowed to write the result, so a stale reply can't block a valid route.
  • create_cr_page gains a route param; the batch create_node op already forwarded one.
  • _update_cr_item's recompute_route path is gone.
  • The route prefix is derived client-side: a group's route already carries the space route plus every ancestor slug, so a child's prefix is just the parent's route (the space root, whose own route is a bare slug, is the one exception). No round-trip per keystroke, and it works when the parent group is itself an unsaved draft.

Spec: specs/editable_page_route.md.

Testing

  • 4 backend cases in test_wiki_change_request.py (route honoured, route sanitised, rename-keeps-route regression, availability across live + CR). The rename regression was verified by temp-reverting the fix.
  • e2e e2e/tests/page-route-editable.spec.ts covers prefill → auto-track → manual override → save.

🤖 Generated with Claude Code

https://claude.ai/code/session_01Dn1ETNV7ufoM8xA6FCLnnE

NagariaHussain and others added 6 commits July 26, 2026 12:55
Surface the derived route in the new-page dialog as a prefilled but
editable field, and stop rewriting it when the title is renamed.

Closes #714

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
Routes were derived from the folder hierarchy and never shown before the
page existed, and a later title rename silently moved the URL.

Accept an author-supplied route on create (sanitised through the app's
slug rule, so a hand-written route can't produce a URL a derived one
couldn't), add check_route_available so a clash surfaces while the author
types instead of at merge time, and stop recomputing the route when the
title changes.

Deriving stays the fallback: a create without a route still gets the same
hierarchy path as before.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
The dialog now shows a Route field that fills in from the title as you
type and stops tracking it the moment you edit it by hand — the same
interaction the new-space dialog already has. A route already in use is
flagged inline instead of failing at merge.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
The field speaks for itself.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
Guarding on the route text alone wasn't enough: two checks of the same
text can legitimately disagree when a page claiming that route is
created in between, so a late reply could clear a valid error (or
reinstate a stale one). Sequence the checks and drop every reply but the
newest, including on the failure path and across dialog reopens.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01FM7M5p9XtQv8UNLWW59qrv
@greptile-apps

greptile-apps Bot commented Jul 26, 2026

Copy link
Copy Markdown

Confidence Score: 4/5

Not safe to merge until saving waits for pending route validation.

A duplicate route can still be submitted during the debounce or network window and fail only when merged.

Files Needing Attention: frontend/src/composables/useTreeDialogs.js

Reviews (2): Last reviewed commit: "refactor(route): use ErrorMessage for th..." | Re-trigger Greptile

Comment thread frontend/src/composables/useTreeDialogs.js
The hand-rolled paragraph duplicated what frappe-ui's ErrorMessage
already renders, and drifted from it on colour and size.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01Dn1ETNV7ufoM8xA6FCLnnE
@NagariaHussain
NagariaHussain merged commit a78d8dc into develop Jul 26, 2026
10 checks passed
@NagariaHussain
NagariaHussain deleted the feat/editable-page-route branch July 26, 2026 09:41
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.

Route should not be auto-created

1 participant