Files
RenewCMS/docs/design/screens/settings.md
T

22 KiB

Settings

  • Route: /settings
  • API: GET /v1/media/purge-settings · PATCH /v1/media/purge-settings · GET /v1/media/purge-preview · POST /v1/media/purge (see "Media cleanup (third card)" at the end) · GET /v1/settings (version) · GET /v1/system/update · POST /v1/system/update/check · POST /v1/system/update/download · POST /v1/system/update/restart
  • Visual reference: source/RenewCMS Screens Back-office.dc.html, group "Settings", drawn by source/AppFrame.dc.html (open it in a browser; each state is drawn at desktop and mobile, with a light/dark toggle).

Opened from the sidebar (Settings, settings icon, after Integration) and from the mobile drawer. Every verified user sees it. It holds two sections: Version (everyone) and Updates (the owner has the buttons, admins read the status).

The Updates card lets a non-technical owner update the site without a terminal. Update downloads the new version and checks it, and changes nothing. Restart installs it and restarts the site (about 10 seconds). "Restart later" is simply closing the dialog or leaving the page; the update waits. A plain Restart appears only when no update is waiting. The state lives on the server, so any owner on any device sees the same card, and the buttons are disabled while any step runs.

Out of scope: choosing versions, downgrades, automatic updates, update history.

The page

One column of cards, top to bottom: Version, Updates, Media cleanup, Retention (owner only). Title "Settings" (20 px/28 px semibold), subtitle "Workspace information.", 720 px at most, 20 px between sections. Every card heading (Version, Updates, Media cleanup, Retention) is 15 px/24 px semibold in --ui-text-highlighted; a card heading is never larger than the page title and never smaller than a body line. The Back-office board draws this page scrolled to the card each state is about. Page padding 32 px on desktop and 20px 16px 88px on mobile.

Version card (unchanged): label "Version" and the running build's version in IBM Plex Mono 14 px, shown exactly as the server reports it (for example v2.2.0-beta).

Updates card, under it: --ui-bg, 1 px --ui-border, 20 px padding (16 px on mobile), 16 px gap. A region labelled by its heading "Updates" (id="updates-h", tabindex="-1", focus ring 2px solid var(--ui-primary) with 4 px offset when focus is moved there). Inside:

Part Content
Status block A polite live region (aria-live="polite"): 14 px padding, 12 px gap, an 18 px icon, a semibold title, the text, and a muted meta line. Background and icon color follow the tone: neutral --ui-bg-muted, success, info, warning, error (--rc-<tone>-soft fill, --ui-<tone> icon). The title row is a flex row with an 8 px gap that wraps. In "Ready to install" it carries a Pending tag after the title and the block holds the Restart button (see below).
Pending tag Only in "Ready to install", right after the title: 20 px high, 0 6 px padding, IBM Plex Mono 11 px medium, --ui-bg fill, --ui-warning text and 1 px --ui-warning border, square corners, text "Pending".
In-block button Only in "Ready to install", "Restart: confirm" and "Restart: request failed": the primary Restart button sits inside the status block, under the meta line, after 8 px of extra top padding, left-aligned (content width, 14 px side padding, 32 px high, 44 px on mobile, not stretched). The buttons row under the block is not drawn in these states. The hint stays under the card.
Progress A progressbar with a value (aria-valuenow) while downloading, labelled for example "Downloading version 2.3.0", with the text 42% · 11 of 26 MB. Indeterminate while verifying (35 % wide moving bar), labelled "Checking the download", text "Almost there". Announced at 25 % steps and when the step changes, never on every tick.
Release notes A button "What's new in 2.3.0" with aria-expanded and a chevron, collapsed by default. Open: "Released 24 Sep 2026" and a plain-text list.
Server command Only in the "Not prepared" state: "For whoever manages the server", a one-line code block, a Copy button (reads "Copied" with a check for 2 s, announced), and the note "They run this once on the server. After that, Update and Restart appear here." The command shown is renewcms enable-browser-updates and is subject to the real one.
Buttons 32 px high (44 px on mobile, stacked full width), 14 px side padding. One primary at most. Disabled buttons use 40 % opacity.
Hint 12 px muted line under the buttons.
Link Underlined, with an external-link: "How to update" or "Read the release notes".

Buttons used: Check for updates (refresh-cw, secondary), Update (download, primary), Restart (power, primary and inside the status block when an update is ready, otherwise secondary in the buttons row), Try again (rotate-cw, primary), and the disabled "Checking…" and "Updating…" (loader-circle). Copy such as "Version 2.3.0" names the newer release. Decision for the spec: show the release tag without its leading v ("Version 2.3.0-beta" for tag v2.3.0-beta), while the Version card keeps the running build exactly as the server reports it.

Copy

Where Copy
Up to date circle-check, success: "You're up to date" / "You have the latest version of RenewCMS." / "Last checked today at 09:41"; buttons "Check for updates" and "Restart"; hint "Restart takes about 10 seconds. Your site is unavailable while it restarts."
Checking loader-circle: "Checking for updates…" / "This usually takes a few seconds."; "Checking…" disabled
Check failed wifi-off, warning: "Couldn't check for updates" / "RenewCMS couldn't reach the update server. Check your connection and try again. Your site isn't affected." / "Last checked yesterday at 18:12"; "Try again" (primary) and "Restart"
Available circle-arrow-up, info: "Version 2.3.0 is available" / "You have v2.2.0-beta. Update downloads the new version and checks it. Nothing changes until you restart."; "Update"; hint "Takes about 2 minutes. Your site stays online."
Downloading download, info: "Downloading version 2.3.0…" / "You can leave this page. The download continues and your site stays online."; "Updating…" disabled
Verifying shield-check, info: "Checking the download…" / "Making sure the file is complete and safe to install. This takes a few seconds."
Ready clock, warning, with the "Pending" tag after the title: "Version 2.3.0 is ready to install" / "The download is checked. Restart to install it. Your site will be unavailable for about 10 seconds." / "Nothing has changed yet."; "Restart" (primary, inside the block); hint "Not now? Leave this page. The update waits here, and the banner on Home reminds you."
Done "You're on version 2.3.0" / "The update is installed and your site is running again." / "Updated today at 09:52"; link "Read the release notes"; toast circle-check "Update installed" / "RenewCMS is now on version 2.3.0."
Rolled back triangle-alert, warning: "The update didn't install" / "RenewCMS put the previous version back, so your site is running as before. Nothing was lost." / "What to do next: try again in a few minutes. If it fails again, ask whoever manages your server to check the update."; "Try again"; toast (error, stays) circle-x "The update didn't install" / "Your site is back on v2.2.0-beta."
Download failed circle-x, error: "The download didn't finish" / "The connection dropped before the file was complete. Nothing was changed and your site is running as before."; "Try again"
Not trusted triangle-alert, warning: "We didn't use this update" / "The file didn't pass our safety check, so it was not installed. Nothing was changed. Try downloading it again. If this keeps happening, contact RenewCMS support." Technical detail goes to the server log.
Rate limited info: "Too many tries" / "Wait a moment before trying again."; button "Try again in 0:42" counting down Retry-After
Not prepared info: "Version 2.3.0 is available" / "This site can't update itself from the browser yet. Whoever manages your server can set it up once, or update RenewCMS for you." and a link "How to update". No buttons, not even Restart.
Admin "Version 2.3.0 is available" / "You have v2.2.0-beta. Only the owner can update RenewCMS. Ask the owner of this site." No buttons. Up to date reads "You're up to date" and "Only the owner can update or restart the site."

Dialogs and overlays

Both dialogs use the ConfirmDialog behaviour: focus moves to the first button, Escape and the cancel button close it, and focus returns to the button that opened it. The confirm button is neutral, not red, because nothing is lost.

Dialog Title Description Cancel / Confirm
Install "Restart to finish the update?" "RenewCMS will install version 2.3.0 and restart. Your site will be unavailable for about 10 seconds. This page reloads on its own when the site is back. Save anything you're editing first." "Restart later" / "Restart now"
Plain restart "Restart the site?" "Your site will be unavailable for about 10 seconds. This page reloads on its own when the site is back. Save anything you're editing first." "Cancel" / "Restart site"

Failure inside the install dialog: "Couldn't start the restart. Nothing was changed and your site is still running. Try again in a moment."

Restart overlay: a full-page role="status" live region (--ui-bg-muted, 440 px card) that survives the server going away, with a moving bar. Copy: "Installing version 2.3.0" / "Your site is restarting with the new version. This takes about 10 seconds. This page reloads on its own when the site is back." / "Started at 09:51". Announced once as "Installing version 2.3.0. Your site is restarting." After 60 seconds with no answer: "Still restarting" / "This is taking longer than usual. Keep this page open. It reloads on its own when the site is back, or you can reload it now." / "Started at 09:51 · 1 minute ago" and a "Reload page" button. Plain restart: "Restarting your site" / "This takes about 10 seconds. This page reloads on its own when the site is back." After the reload: focus lands on the "Updates" heading and a toast circle-check "Site restarted" / "Your site is running again."

Elsewhere

For the owner only: an Update pill on the Settings sidebar item, and a dot on the menu icon on mobile (read as "Update available"). Admins see neither. The Home banner is described in home.

Status to copy

Status Where Copy
200 Check, up to date "You're up to date" and the last-checked line
200 Check, newer version "Version 2.3.0 is available" and its text
202 Update, Restart Accepted. The card switches to progress, announced as "Downloading version 2.3.0, 25 percent".
200 Update finished "Version 2.3.0 is ready to install"
200 After restart Toast "Update installed" or "Site restarted"
400 Update, nothing to install Info toast "Nothing to update" / "You already have the latest version." The card refreshes.
401 any Global: /login?redirect=/settings&reason=expired. No local copy.
403 any button, not the owner Error toast "Only the owner can do this" / "Ask the owner of this site to update RenewCMS." The card reloads as the admin view. An unverified account is handled globally.
409 Update, Restart Already running: info toast "An update is already running" / "Another owner started it. Progress shows here." Not prepared: the card shows the "Not prepared" state.
422 Update, file not trusted The "Not trusted" card above
429 Check, Update The rate-limited card above
500 / network Check "Couldn't check for updates" with "Try again"
500 / network Update "The download didn't finish" with "Try again"
500 / network Restart dialog "Couldn't start the restart. Nothing was changed and your site is still running. Try again in a moment."
Site back, old version after restart The rolled-back card above
No answer, 60 s restart overlay "Still restarting"
Offline whole page Existing banner. Check, Update and Restart are disabled. During a restart the overlay keeps polling and ignores the offline state.

Behaviour notes

  • The page asks for GET /v1/system/update on open and, when a step is running, polls it every second. The server holds the state (idle, downloading, verifying, ready, restarting, succeeded, failed), so another device or owner sees the same card.
  • A check runs on the first open after 24 hours and when "Check for updates" is pressed.
  • Update takes no confirmation because it changes nothing. Restart always asks.

States

State Trigger and behaviour
Up to date Opened with no newer version. Restart is available but not emphasised.
Checking Check for updates pressed, or the first open after 24 hours. Announced as "Checking for updates". Buttons are disabled.
Check failed Offline, or the update server didn't answer (500, network). The last known result is kept.
Update available A newer version exists. Release notes are collapsed. Update is the one primary button.
Update available, notes open "What's new in 2.3.0" expanded. It is a button with aria-expanded, and the list is plain text.
Downloading Update pressed (202). Progress polls every second. Announced as "Downloading, 25 percent" and so on, never every tick.
Verifying The download finished. No percentage, so the bar is indeterminate. Announced as "Checking the download".
Ready to install The file passed its checks. The card turns warning (orange) with a "Pending" tag and a clock icon, and Restart, the primary action, sits inside it. "Restart later" is closing the dialog or leaving the page.
Restart: confirm Restart pressed. The card behind the dialog keeps the Ready look. Same dialog behaviour as the delete confirm: focus moves to the first button, Escape and "Restart later" close it, and focus returns to Restart. The confirm button is neutral, not red, because nothing is lost.
Restart: request failed 500 or network failure before the restart began. The site is still running. The card behind the dialog keeps the Ready look.
Restarting to install Full-page overlay, so it survives the server going away. The page polls until the site answers, then reloads. It is a live region announced once as "Installing version 2.3.0. Your site is restarting."
Restarting, taking longer No answer after 60 seconds. The copy changes and a manual reload appears. The overlay stays until the site is back.
Update done The page reloaded on the new version. Focus lands on the "Updates" heading (ring shown), the toast is announced, and the version updates.
Update failed, rolled back The site came back on v2.2.0-beta. The error toast stays until dismissed and the card keeps the explanation.
Download failed A 500, or the connection dropped. Focus moves to the card heading. Try again restarts the download.
Verification failed The downloaded file isn't trusted. The tone is a warning, and the file is thrown away. Technical detail goes to the server log, not the screen.
Too many requests (429) Retry-After counted down in the button. It re-enables at zero.
Not prepared The server can't update from the browser. No buttons, not even Restart. The command is for the person who runs the server and is a single line. The placeholder command is subject to the real one.
Not prepared: command copied Copy pressed. The button reads "Copied" for 2 s and it is announced.
Plain restart: confirm Restart with no update waiting. Nothing is installed.
Plain restart: restarting Same overlay as the update restart with shorter copy.
Plain restart: done The page reloaded. Focus lands on the "Updates" heading.
Admin view Admins see the version and the note, with no buttons. Up to date: "You're up to date" and "Only the owner can update or restart the site." No Home banner or Settings pill.
Role changed (403) An owner was changed to admin while the page was open and pressed a button. The card reloads in the admin view.
Update already running (409) Another owner started it. The card switches to that run's progress.

Media cleanup (third card)

Route: /settings. Visual reference: source/RenewCMS Screens Back-office.dc.html, groups "Settings: Media cleanup", "Purge dialog", "Purge results" and "Media duplicates entry" (frames: source/AppFrame.dc.html, source/MediaFrame.dc.html). API: GET/PATCH /v1/media/purge-settings (owner, admin), GET /v1/media/purge-preview, POST /v1/media/purge. 401 and 403 are global: no local copy.

Rule: a group is purged only if at least one copy is used in an article. All copies merge into the one used in the most articles (ties: oldest, then lowest id). Groups with no used copy are left alone. Automatic purge is off by default.

Card

Third card, below Updates, 20 px gap, same card styling as the others. The board scrolls the page to this card for its states.

  • Title: "Media cleanup". Description: "Merge identical images so your library stays tidy. Articles that use a copy are switched to the most used one."
  • "Automatic purge" / helper "Runs in the background. Off by default." / USwitch.
  • When on: "Every" / helper "Between 1 and 365 days." / number input, suffix "days", default 30.
  • Read-only lines: "Last purge: 14 Jun 2026 · 3 copies merged · 5 articles updated" or "Never run". When on, also "Next purge: 14 Jul 2026".
  • Divider, then "Purge now" / "Merge every group of duplicates that has an image in use, right away." / outline button "Purge duplicates" (merge).
  • No Save button. Saves on toggle and on blur or Enter of the days field. "Saved" (check, success) sits in the card header and fades after 2 s; "Saving…" (loader-circle) while pending.
  • Non-owner/admin: switch and input disabled, button and divider hidden, info alert "Only owners and admins can change this."

States (names matched exactly)

  • Default: off, never run
  • On: 30 days, last run
  • Saving
  • Saved
  • Save failed: "Couldn't save. Try again in a moment." under the field; the control reverts.
  • Validation error: "Enter a whole number of days between 1 and 365." Nothing is sent.
  • Read-only (non-admin)
  • Loading skeleton (after 150 ms)
  • Offline: banner "You're offline. Changing automatic purge and purging duplicates need a connection." Switch, input and button disabled.

Dialog

UModal, sm:max-w-md, bottom sheet on mobile, cancel first.

  • Title "Purge duplicates?". Description "Articles that use a duplicate will be switched to the most used copy of that image, and the other copies will be deleted. This can't be undone."
  • Summary: "4 groups · 9 copies will be deleted · 12 articles will be updated". Singular: "1 group · 1 copy will be deleted · 2 articles will be updated".
  • Bordered list of up to 5 groups: thumbnail, filename, "Kept · used in 4 articles", and "2 copies merged". More: "and 3 more groups".
  • Link "Review in Duplicates" to /media?filter=duplicates.
  • Buttons: "Cancel", danger "Purge 4 groups". Pending: "Purging…" with loader-circle, dialog can't be dismissed.
  • Loading preview: skeleton rows, confirm disabled.
  • Nothing to purge: icon copy, "Nothing to purge", "No duplicate is used in an article, so there is nothing to merge.", button "Close". No confirm.
  • Error (stays open): "Couldn't purge the duplicates. Nothing was changed. Try again in a moment."
  • Partial: "Some groups couldn't be merged. 3 of 4 groups were purged. Try again to finish." Buttons "Close", "Retry". Summary refreshes to the remaining groups.
  • Conflict (409): "The library changed, so nothing was purged. Check the new summary and try again." Summary refreshes.

Results

  • Toast (5 s): circle-check, "Duplicates purged" / "9 copies merged. 12 articles updated."
  • "Last purge" updates in place; "Next purge" moves forward by the interval.
  • An unattended run shows no toast. The next visit shows the updated line.

Media entry point

Duplicates tab: secondary "Purge duplicates" button (merge) next to the sort menu; stacked toolbar on mobile. Opens the same dialog. Hidden for non-owner/admin and when there are no groups. "Merge into this one" is unchanged.

Components (Nuxt UI v4)

UCard, USwitch, UInputNumber (min 1, max 365, suffix), UFormField, UAlert, UButton, UModal, USkeleton, useToast.

Activity retention

API: GET /v1/settings · PATCH /v1/settings (owner only). Visual reference: source/RenewCMS Screens Back-office.dc.html, group "Settings: Retention", drawn by source/AppFrame.dc.html.

The last card on the page, below Media cleanup, owner only (hidden for admins and for the read-only Media cleanup view), same card styling and 720 px column as the others.

  • Header: "Retention" / "How long activity is kept." "Saved" (check, success) at the right after a save, fading after 2 s.
  • "Keep activity for" USelectMenu: 30 days, 90 days, 365 days, Forever. Default 90 days. Helper: "Older events are removed automatically." For Forever: "Nothing is removed automatically. The log grows over time."
  • Info alert (lock): "Activity logs are append-only", "Events can't be edited or deleted from the app. Only the retention period removes them."
  • Divider, then read-only lines: "Last cleanup: 6 Oct 2026, 03:00 · 142 events removed" and "Next cleanup: 7 Oct 2026, 03:00". Forever: "Never" and "Not scheduled".
  • Saves on change. Choosing a shorter period than the current one first shows a warning alert, "Events older than 30 days will be removed", "This happens at the next cleanup on 7 Oct 2026, 03:00. It can't be undone.", buttons "Apply 30 days" and "Cancel"; nothing is sent until Apply. Lengthening or choosing Forever saves at once.
  • Save error alert: "Couldn't save the retention period", "Your previous setting is still in place.", "Try again". The control reverts.
  • States: Default (90 days, saved), Shortening the period, Forever, Save error. Loading and Offline follow the Media cleanup card.
  • GET /v1/settings adds activity_retention_days (30, 90, 365 or 0 for forever), activity_last_cleanup_at (null before the first cleanup) and activity_last_cleanup_removed. PATCH /v1/settings takes { "activity_retention_days": 30 }; any other value answers 400 "The request cannot be processed due to a mismatch in the format of the body."; a non-owner gets 403 "Only the owner can do this.". The cleanup runs once a day at 03:00 server time and never touches the last 24 hours.