8.1 KiB
Articles
Route: /article, /articles?page=2&size=50. API: GET /v1/article/ · PATCH …/publish · PATCH …/unpublish · DELETE /v1/article/{id} · GET /v1/article/?page=&size=&q=&status= (page, size; total in the X-Total-Count header; invalid values are normalised in the URL, never shown as an error).
Rows update when the server responds, not optimistically. Search, tab and sort are stored in the query string.
Visual reference: RenewCMS Screens Back-office.dc.html, groups "Articles", "Articles: pagination". Frames: AppFrame.dc.html (shell, sidebar, topbar, drawer) plus the screen frame where listed in components.md.
Copy per state (generated from the board source, pass 2)
Every state below is drawn in light and dark (theme switch on the board), at 1440×900 and 390×844 (both frames sit side by side). Board: RenewCMS Screens Back-office.dc.html. Copy is exact; where a cell is empty the state reuses the fixed copy.
Fixed copy in the frame
- Articles
- Everything you've written, online and in draft.
- New article
- Retry
- Title
- Status
- Created
- Updated
- Online
- Draft
- Edit
- Copy API URL
- Delete…
- Previous
- Next
Articles (group "Articles", 14 states)
Route: /article. API: GET /v1/article/ · PATCH …/publish · PATCH …/unpublish · DELETE /v1/article/{id}.
Rows update when the server responds, not optimistically. Search, tab and sort are stored in the query string.
| # | State | Trigger | Copy |
|---|---|---|---|
| 1 | Default | The list loaded, sorted by last updated. | |
| 2 | Row menu open | The ellipsis button, or Enter on the focused menu button. | |
| 3 | Loading | The first load, or a retry. | |
| 4 | Empty | The list is empty. | "No articles yet" / "Write your first one. It stays a draft until you publish it." / "New article" |
| 5 | No results | Search matched nothing. The tab counts still show the full list. | "No articles match "tiles"" / "Check the spelling, or search for a shorter part of the title." / "Clear search" |
| 6 | No drafts | Drafts tab with nothing in it. The "Online" tab has an equivalent "Nothing is online yet" state. | "Everything you've written is online." / "New article" |
| 7 | Action in progress | Publish chosen from the row menu. That row is disabled. | "Publishing…" |
| 8 | Published | 200: the row updates in place and a toast confirms. Clock-sensitive: shows a relative time or a countdown. | "Just now" / "Article published" / ""Winter checklist for timber windows" is now online." |
| 9 | Action failed | A 500 or network error. The row stays as it was, and the toast stays until retried or dismissed. | "Couldn't unpublish" / "The server didn't respond. Nothing changed." / "Retry" |
| 10 | Row vanished (404) | Any row action gets a 404. | "That article no longer exists" / "It was deleted somewhere else, so we removed it from the list." |
| 11 | Delete: confirm | Delete… from the row menu. | |
| 12 | Delete: in progress | DELETE in flight. The dialog can't be dismissed. | |
| 13 | Delete: failed | 500, a partial failure where the article is kept. The error shows inside the dialog. | "Couldn't delete the article, so it's still there. Try again in a moment." |
| 14 | Deleted | 204: the row is removed and focus moves to the next row. This is also where a delete from the editor ends up. | "Article deleted" / ""Winter checklist for timber windows" and its images are gone." |
Articles: pagination (group "Articles: pagination", 11 states)
Route: /articles?page=2&size=50. API: GET /v1/article/?page=&size=&q=&status= (page, size; total in the X-Total-Count header; invalid values are normalised in the URL, never shown as an error).
Page and page size live in the URL as page and size. Defaults (page 1, size 25) are omitted. Allowed sizes 5, 25, 50, 100. Search, tab or sort changes reset to page 1. Rows equal the page size; the frames draw at most 10 rows. The paginator hides when everything fits on one page; the summary stays. Mobile shows Previous, "Page N of M" and Next. Keyboard: Tab reaches page size, first, previous, each page, next, last; Enter or Space activates; the current page has aria-current="page"; ArrowDown opens the page-size list, Enter selects, Esc closes.
| # | State | Trigger | Copy |
|---|---|---|---|
| 1 | First page | /articles. Previous and First are disabled. Summary "Showing 1–25 of 312". | |
| 2 | Middle page | /articles?page=7. Current page uses --rc-sand and --rc-on-sand; ellipses mark skipped ranges. | |
| 3 | Last page | /articles?page=13. Next and Last are disabled. Summary "Showing 301–312 of 312". | |
| 4 | Single page | Total fits in one page. Paginator hidden; summary "Showing 1–6 of 6" and the page-size select stay. | |
| 5 | Loading next page | Next was pressed. Skeleton rows keep the table height, controls are disabled, summary reads "Loading page 7…". | |
| 6 | Error loading a page | 500 or network failure on page change. Previous rows stay; Retry sits in the notice. | "Couldn't load page 7. Showing page 6." |
| 7 | Page out of range | /articles?page=99 is replaced with ?page=13 and this notice is shown. | "That page doesn't exist. Showing the last page." |
| 8 | Search resets to page 1 | Searching "plaster" from page 7 goes to /articles?q=plaster (page omitted). Same for tab, sort and size changes. | |
| 9 | Empty after search | Zero results. Paginator and summary are hidden. | "No articles match "tiles"" / "Check the spelling, or search for a shorter part of the title." / "Clear search" |
| 10 | Page size menu | The select opens upward. 5, 25, 50 or 100; the chosen size is saved as size and the page resets to 1. | |
| 11 | Focus-visible | Keyboard focus on Next: 2 px --ui-primary outline, 2 px offset. Same ring on every paginator control. |
Changed in pass 3: authors, site column and site filter
Articles: sites and authors (group "Articles: sites and authors", 3 states)
Route: /articles?site=journal. API: GET /v1/article/?site={key}&page=&size=&q=&status=.
Every Articles frame has the Authors column (avatars, at most 3 plus "+N"; "—" when none; on mobile avatars with the first name). When more than one site exists, a Site column and a Site filter appear, read-only text for every role; with one site they are not rendered.
| # | State | Trigger | Copy |
|---|---|---|---|
| 1 | Several sites | More than one site exists. | Authors · Site · All sites · Renew · Journal · Projects |
| 2 | Site filter open | The Site select in the toolbar. Choosing a site stores ?site=key and resets the page to 1. | All sites · Renew · Journal · Projects · Archive |
| 3 | No articles on a site | The chosen site has no articles. | No articles on "Archive" · Move articles here from the editor, or choose another site. · Show all sites |
All existing Articles frames show the Authors column (avatars, at most 3 plus "+N", "—" when none).
Articles: search status (SEO round)
Route: /articles?seo=suggestions. API: GET /v1/article/?seo=suggestions&page=&size= (items carry seo_status and seo_suggestions).
A quiet indicator in the Status cell on desktop and under the title on mobile cards: a lightbulb chip with a count when there are suggestions, an eye-off chip "Hidden" when noindex is on, nothing when the article is ready. The toolbar gets a "Needs attention" toggle with a count next to the search field. Tabs and their counts are unchanged. On a single-site install nothing changes: the Site filter and column stay hidden and the toggle works the same, over all articles.
| # | State | Trigger | Copy |
|---|---|---|---|
| 1 | Status chips | Row 2 has 2 suggestions, row 3 is hidden, row 4 has 3, row 5 has 1. | Needs attention · 3 · Hidden · 2 suggestions (tooltip) · Hidden from search engines (tooltip) |
| 2 | Needs attention on | The toggle is pressed. The list shows only articles with suggestions. Hidden-only articles are not included. | Needs attention · 3 |
| 3 | Needs attention: none | Nothing to show with the toggle on. | Nothing needs attention · Every article has a clean check. Suggestions are optional, so this is just a bonus. · Show all articles |
Filter: "Needs attention" sets ?seo=suggestions and resets page to 1. Tab counts do not change. Single-site installs behave the same; the Site filter stays hidden.