Files
sencho/docs/features/editor.mdx
T
Anso a25acbec7c feat(editor): opt-in diff preview before save (#855)
* feat(editor): add useComposeDiffPreviewEnabled hook

* feat(editor): add ComposeDiffPreviewDialog component

* fix(editor): replace HTML entity with Unicode arrow in ComposeDiffPreviewDialog

* feat(editor): add diff preview toggle to Appearance settings

Added a new 'Diff preview before save' toggle in the Display section of the Appearance settings panel. Users can now enable or disable the side-by-side diff view before compose and env file edits are saved to disk.

* feat(editor): wire diff preview dialog into compose save flow

* fix(editor): snapshot diff content at open time and fix event name

- Fix useComposeDiffPreviewEnabled and useDeployFeedbackEnabled to use
  the canonical SENCHO_SETTINGS_CHANGED constant from @/lib/events
  instead of the hardcoded string literal (wrong value)
- Snapshot language, original, modified, and fileName into diffPreview
  state at click time to prevent tab-switching from corrupting dialog
  content mid-review
- Remove React.MouseEvent from diffPreview state; pass a no-op stub to
  deployStack in the confirm path (preventDefault/stopPropagation are
  no-ops on an already-settled event anyway)
- Add diff-modal screenshot and document the feature in editor.mdx and
  settings.mdx

* docs(editor): add settings-toggle screenshot for diff preview feature
2026-04-30 22:01:17 -04:00

122 lines
6.8 KiB
Plaintext

---
title: Editor
description: Edit compose files and environment variables, and manage containers directly from the dashboard.
---
Selecting a stack opens the editor view, a two-column layout. The left column shows the command center (stack controls, containers, and an embedded terminal). The right column holds the Monaco code editor.
<Frame>
<img src="/images/editor/editor-overview.png" alt="Editor view showing command center on the left and Monaco editor on the right" />
</Frame>
## Files tab
The **Files** tab gives you a browseable directory tree for everything inside the stack's folder. Community users can view text files in read-only mode. Skipper and above can upload, download, edit and save, create folders, and delete files. Protected files (`compose.yaml`, `.env`, and their variants) redirect to their dedicated editor tabs when clicked.
For full details on permissions, viewing limits, upload caps, and troubleshooting, see the [Stack File Explorer](/features/stack-file-explorer) guide.
## Compose file editor
The right panel shows your `compose.yaml` with full syntax highlighting. By default the editor is **read-only** to prevent accidental changes.
Click **Edit** to enter edit mode. Your changes are unsaved until you explicitly save them.
### Save options
The primary action button is **Save & Deploy**, which writes the file to disk and immediately runs `docker compose up -d`. A dropdown arrow next to it reveals additional options:
| Action | What it does |
|--------|--------------|
| **Save & Deploy** | Writes the file, then runs `docker compose up -d` to apply changes immediately. |
| **Save Only** | Writes the file to disk without restarting any containers. |
| **Discard Changes** | Reverts the editor to the last saved version. Unsaved changes are lost. |
## Environment file editor
Click the **.env** tab to switch to the environment file editor. If your `compose.yaml` references multiple env files (via `env_file:`), a dropdown lets you select which file to edit.
The `.env` editor has the same save/discard controls as the compose editor. Changes take effect the next time the stack is deployed.
<Note>
Sencho reads the `env_file:` paths from your `compose.yaml` to discover available env files. If no `env_file:` is declared, a default `.env` in the stack directory is used.
</Note>
## Diff preview before save
When the **Diff preview before save** toggle is enabled in **Settings → Appearance**, clicking **Save & Deploy** or **Save Only** opens a side-by-side diff modal before anything is written to disk. The left pane shows the current on-disk content; the right pane shows your unsaved edits, with additions highlighted in green.
<Frame>
<img src="/images/compose-diff-preview/diff-modal.png" alt="Diff preview modal showing side-by-side YAML diff with a new comment line highlighted in green on the right" />
</Frame>
Review the diff, then:
- Click **Save & deploy** (or **Save**) to confirm and write the changes to disk.
- Click **Cancel** to return to the editor without saving.
If there are no unsaved changes the modal is skipped and the save proceeds directly.
The toggle is off by default and saved per browser. Each device remembers its own setting independently. Enable it in **Settings → Appearance → Diff preview before save**.
## Container panel
The left column lists all containers that belong to the selected stack under the **CONTAINERS** heading. Each container shows:
- **Status badge** - `running`, `exited`, `starting`, or `unhealthy` (hover for detailed status text)
- **Live stats** - CPU %, RAM usage, and network I/O displayed inline, updated every few seconds
### Container actions
Each container row has action buttons on the right side:
| Button | What it does |
|--------|--------------|
| **Open App** | Opens the container's web UI in a new tab (uses the detected web port). Only shown when a port is mapped. |
| **View Live Logs** | Opens a live log stream modal for that container. Only available when the container is running. |
| **Open Bash Terminal** | Opens an interactive bash session inside the container. Admin only, only available when running. |
<Frame>
<img src="/images/editor/container-actions.png" alt="Container row showing status badge, live stats, and action buttons" />
</Frame>
## Embedded terminal
Below the container list, an embedded terminal streams the combined output from the stack's containers. This provides a persistent view of container logs without opening a separate modal.
The terminal supports search (find text within the log output) and export (download the current log buffer).
### Container terminal (exec)
The terminal modal from the container action buttons gives you an interactive bash shell inside a running container, equivalent to `docker exec -it <id> bash`. It uses a full terminal emulator with colour support, tab completion, and automatic resizing when you resize the browser window.
#### Access requirements
- **Admin role required.** Only admin users see the terminal button in the container actions. Non-admin users cannot open a shell session.
- **Container must be running.** The button is disabled for stopped containers, and the backend will reject exec attempts against non-running containers.
- **API token restrictions.** API tokens with `read-only` or `deploy-only` scope cannot open exec sessions. Only `full-admin` API tokens are permitted.
<Frame>
<img src="/images/editor/container-exec-modal.png" alt="Container exec modal showing a connected bash session with a root shell prompt" />
</Frame>
#### Shell selection
Sencho tries `/bin/bash` first. If bash is not available inside the container, it automatically falls back to `/bin/sh`. This happens transparently; no user action is needed.
<Warning>
The container terminal requires the container to have `bash` or `sh` installed. Minimal base images (e.g. `scratch`, `distroless`) that ship no shell will not work with container exec.
</Warning>
#### Troubleshooting
| Symptom | Cause | Resolution |
|---------|-------|------------|
| "Container is not running" error | The container stopped between clicking the button and the exec starting | Start the container and try again |
| "Failed to start shell" error | The container image has no shell binary (`/bin/bash` or `/bin/sh`) | Use an image that includes a shell, or install one in your Dockerfile |
| Terminal connects but immediately shows "Session ended" | The shell process inside the container exited immediately | Check the container logs for errors; the container's entrypoint may be overriding the shell |
| Terminal is unresponsive | WebSocket connection dropped silently | Close the modal and reopen it to establish a new session |
## Log viewer
The log viewer (opened from the container action buttons) streams output from a single container in real-time using Server-Sent Events. Logs auto-scroll to the bottom as new lines arrive. Close the modal to stop the stream.