[DRAFT] dp ← Auto-save for version edits by alvarosabu · Pull Request #27158 · directus/directus · GitHub
Skip to content

[DRAFT] dp ← Auto-save for version edits#27158

Draft
alvarosabu wants to merge 3 commits intoalvaro/cms-1865-discard-item-less-versions-navigate-to-collectionfrom
alvaro/cms-1867-auto-save-for-version-edits-should-have
Draft

[DRAFT] dp ← Auto-save for version edits#27158
alvarosabu wants to merge 3 commits intoalvaro/cms-1865-discard-item-less-versions-navigate-to-collectionfrom
alvaro/cms-1867-auto-save-for-version-edits-should-have

Conversation

@alvarosabu
Copy link
Copy Markdown
Contributor

Scope

What's changed:

  • Add useAutoSave composable (app/src/composables/use-auto-save.ts) — debounced (750ms) auto-save driven by edits watcher. One revision per editing session: first save of the session creates a revision, subsequent saves patch it in place until AUTO_SAVE_SNAPSHOT_INTERVAL_MINUTES (5m) of inactivity promotes the next save to a new revision. Exposes autoSaveError and resetSession; resets on currentVersion change.
  • Add createRevision option to VersionsService.save() and ?createRevision=false query param on POST /versions/:id/save. When false and the version has an item, skip the activity/revision insert and merge the clean delta into the latest existing revision so the sidebar reflects accumulated edits. Snapshots revisionDelta before deepMapObjects mutates it with _user/_date metadata.
  • Integrate auto-save in item.vue for versioned items via autoSaveRevision(forceNew): manual save / stale session → saveVersion(...) (creates revision); otherwise → saveVersion(..., { createRevision: false }). Manual stay/quit shortcuts for versions removed — auto-save handles it.
  • Remove the now-redundant patchVersionDelta path in use-versions.ts (was a raw PATCH /versions/:id that bypassed VersionsService.save — prepareDelta, hooks, permissions). Consolidates auto-save and manual save onto a single server pipeline.
  • Fix: confirmVersionExists only returns false on HTTP 404; other errors (network, 5xx) are re-thrown instead of being silently treated as "version gone".

Potential Risks / Drawbacks

  • In-place revision merge uses assign({}, latestRevision.data ?? {}, cleanRevisionDelta) — shallow merge. Nested objects in the delta overwrite whole subtrees rather than deep-merging. Matches prior client-side behaviour but worth confirming for complex relational payloads.
  • cleanRevisionDelta is captured via JSON.parse(JSON.stringify(...)) — any non-JSON values in the delta (Date, undefined, Map) will be lost. Current payloads are JSON so this should be fine, but sharp edge.
  • Auto-save fires on every edits mutation (deep watch). Debounced at 750ms; overlapping saves guarded by an isSaving mutex. Worth monitoring for very large forms.
  • Session staleness threshold is a hard-coded 5 minutes; no user-facing toggle.
  • Query param parsed as req.query['createRevision'] !== 'false' — any other truthy string evaluates to true. Consistent with existing Directus patterns.

Tested Scenarios

  • Versioned item: typing → one revision appears, continues accumulating changes without spawning new rows.
  • Idle >5m then type → new revision created on next save.
  • Switching currentVersion → session resets; next save creates a new revision.
  • Manual save shortcut still creates a revision (no query flag).
  • Auto-save fires only when user has version update permission and currentVersion !== null.
  • Version deleted/promoted mid-session → handleVersionGone swallows the error silently; autoSaveError not set.
  • Non-404 network/server errors on confirmVersionExists now surface instead of being silenced.

Review Notes / Questions

  • Stacked on top of alvaro/cms-1865-discard-item-less-versions-navigate-to-collection; merge that first.
  • No changeset added — should this get a minor or patch entry for the new ?createRevision query param? It's additive and defaults to current behavior.
  • No new API tests covering the createRevision: false branch of VersionsService.save() (latest-revision lookup + accumulated merge). Would appreciate guidance on where those belong in api/src/services/versions.test.ts.
  • AUTO_SAVE_SNAPSHOT_INTERVAL_MINUTES and AUTO_SAVE_DEBOUNCE_MS are module constants — open to moving to settings if product wants them configurable.
  • Special attention on the shallow merge semantics for revisions with relational/M2A deltas.

Checklist

  • Added or updated tests
  • Documentation PR created here or not required
  • OpenAPI package PR created here or not required

Fixes CMS-1867

@linear
Copy link
Copy Markdown

linear Bot commented Apr 17, 2026

@alvarosabu alvarosabu changed the title Auto-save for version edits dp ← Auto-save for version edits Apr 17, 2026
@alvarosabu alvarosabu changed the title dp ← Auto-save for version edits [DRAFT] dp ← Auto-save for version edits Apr 17, 2026
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