# Preview a version before restoring

## Goal
In the version-history modal, let the user **preview** a version on the canvas
before restoring, with a banner marking the editor as being in preview mode.

## Context
- `getJourneyData()` builds the canvas from a journey `payload`:
  `JSON.parse(payload).flowchart.jsonData` → `{ nodes, edges }` → `setNodes/setEdges`.
- A version's `payload` has the same shape, so preview renders client-side.
- Every version has `payload` (even pre-`save_payload` rows) → preview works for
  all versions; restore stays limited to versions with `save_payload`.
- Existing `isFrozen` gates canvas interaction (`nodesDraggable`, `panOnDrag`).

## Decisions
- Exit preview = **cache & restore** (no reload, no data loss).
- Preview is **read-only** (Save/silent-save disabled, canvas non-editable).
- Banner offers **Restore + Exit**.

## Changes

### Backend
`GET /api/v1/journey-versions/{versionId}/preview` → `{ payload: <version.payload> }`
(404 if not found). Keeps the list endpoint lightweight.

### flow.jsx
State:
- `previewState`: `null` | `{ versionId, number, dateLabel }`.
- `preSnapshotRef`: cached `{ nodes, edges }` taken before entering preview.

`handlePreview(version)`:
1. `preSnapshotRef.current = { nodes, edges }`.
2. `GET .../preview` → parse `payload.flowchart.jsonData` → `setNodes/setEdges`
   (essential slice of getJourneyData; skips live BI-status remap).
3. Set `previewState`, close the modal. On parse/HTTP error → Swal, no state change.

`restoreVersion(version)` (moved here from the modal): Swal confirm →
`POST /api/v1/journey-versions/{id}/restore` with `{ edited_by }` → loading Swal →
reload on success / error Swal. Passed to the modal as `onRestore` and reused by
the banner.

Banner (rendered when `previewState`): amber fixed bar atop the editor —
"Preview — Version #N (date). This is a past version, not saved." with:
- **Restore this version** → `restoreVersion`.
- **Exit preview** → restore `preSnapshotRef` via `setNodes/setEdges`, clear
  `previewState`.

Read-only lock while `previewState` is set:
- "Save Journey" and "Version history" buttons disabled.
- `silentSaveJourney` no-ops (guard at top).
- ReactFlow: `nodesDraggable={false}`, `nodesConnectable={false}`, delete disabled.

### VersionHistoryModal.jsx
- Add a **Preview** button per row (always enabled) calling `onPreview(version)`.
- Restore button now calls `onRestore(version, number)` (logic lives in flow.jsx);
  remove the modal's own restore/axios code.
- New props: `onPreview`, `onRestore`. `editedBy` no longer needed in the modal.

### CSS (reactflow-styles.css)
`.version-preview-banner` amber fixed bar; `.version-preview-btn` for the row's
Preview button.

## Out of scope (`ponytail:`)
- Live template-status refresh during preview (cosmetic).
- Previewing the version's sidebar/config (only the canvas swaps).
