etherpad-lite/src/node/hooks/express
John McLear ab60ed33c1
admin: parsed JSONC settings editor (takes over #7666, closes #7603) (#7709)
* admin: parsed JSONC settings editor with form view (#7603, #7666)

Takes over #7666 / closes #7603. Squashed rebase of 32 commits onto
current develop (which has since absorbed admin design rework #7716
and admin i18n fixes #7736 — granular history preserved on
takeover/7666-admin-settings-editor before this squash, see PR
description for the original commit log).

Highlights:

- New parsed JSONC settings editor under
  admin/src/components/settings/ — FormView, ModeToggle,
  ParseErrorBanner, JsoncNode dispatcher, leaf widgets (string,
  number, bool, null, env pill), and pure helpers (comments,
  envPill, jsoncEdit, labels, templateComments).
- ${VAR:default} env placeholders render as editable inline inputs
  that round-trip through the raw textarea (env-pill spec asserts
  this; docker-template spec protects against form-view degradation
  on env-heavy configs).
- Schema-driven help text sourced from settings.json.template,
  inlined at build time via vite (drops the runtime fs.allow
  widening that earlier iterations needed).
- ModeToggle switches between FormView and raw textarea on
  /admin/settings; parse errors surface in a non-blocking banner.
- jsonc-parser dep added; pure helpers wrap modify() for stable
  edits that preserve key order and trailing comments (stops at
  end-of-line so trailing-comment trains don't bleed into the next
  property).
- i18n keys added for form mode, parse error, env pill,
  default_label, and input aria.
- Playwright specs cover form view, env pill, parse error banner,
  raw round-trip, and form-mode regressions called out in #7666
  review (stable React keys from AST offsets, save-toast on server
  ack only, NumberInput draft sync, parse-error flash during
  initial load, .settings CSS conflict resolution, focus retention
  via rAF, IconButton type defaulting to 'button').

Co-authored-by: Ayushi Gupta <ayushigupta36881@gmail.com>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(admin): stabilise React keys to prevent focus loss in settings editor

Switch React keys in JsoncNode and FormView from byte offsets to stable
JSON paths (`getNodePath(...).join('.')`). Byte offsets shift on every
keystroke because the edit changes the surrounding character count,
which forces React to remount inputs and lose focus mid-typing.

- Object children key on the property path.
- Array elements key on their JSON path index.
- Add a Playwright regression test pinning focus stability for array
  element edits.

Co-authored-by: John McLear <john@mclear.co.uk>
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

* fix(admin): stop trailing /* */ comments from bleeding into next key's label (#7740)

In the parsed settings form view, each key's row was rendering its label
as the previous keys' source lines concatenated together. Root cause:
findLeading() in admin/src/components/settings/comments.ts treated any
line ending in `*/` as a comment continuation, so a JSON line like
  "altF9": true, /* focus on the File Menu and/or editbar */
was absorbed into the next sibling's leading comment block, and then
each subsequent key picked up an even longer accumulation.

- Tighten findLeading's isComment check to only match structural comment
  lines (`//`, `/*`, or a `*`-prefixed continuation/close), so JSON code
  with a trailing block comment no longer matches.
- Surface leading and trailing comments separately from the template
  map. Leaf rows with only a trailing same-line comment now render the
  humanized key as the row label and the comment as the help text below
  the control, matching settings.json.template's convention (and #7740's
  recommendation that "helper text should be below").
- Add unit tests pinning the regression and the JSDoc/`//` leading
  styles, plus a Playwright spec that asserts altC's row carries a
  clean label and the "focus on the Chat window" help text.

Closes #7740.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Ayushi Gupta <ayushigupta36881@gmail.com>
Co-authored-by: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-15 10:41:37 +01:00
..
admin.ts chore: fix minor issue on admin retrieval 2025-09-08 20:11:45 +02:00
adminplugins.ts feat: disable stats endpoint if enableMetrics is false 2025-07-27 22:22:18 +02:00
adminsettings.ts admin: parsed JSONC settings editor (takes over #7666, closes #7603) (#7709) 2026-05-15 10:41:37 +01:00
apicalls.ts chore: fixed objectAsString 2025-08-01 21:58:10 +02:00
errorhandling.ts Added typescript to etherpad 2024-02-05 21:13:02 +01:00
importexport.ts feat(export): native DOCX export via html-to-docx (opt-in) (#7568) 2026-05-08 18:33:50 +01:00
openapi-admin.ts feat(admin): document admin endpoints in OpenAPI (#7693) (#7705) 2026-05-10 15:55:33 +08:00
openapi.ts feat(api): clean up published OpenAPI spec for downstream codegens (#7714) 2026-05-10 13:02:05 +01:00
padurlsanitize.ts Added typescript to etherpad 2024-02-05 21:13:02 +01:00
pwa.ts chore: migrated settings to esm6 (#7062) 2025-08-04 22:42:50 +02:00
socketio.ts feat(updater): tier 2 — manual-click update from /admin/update (#7607) (#7704) 2026-05-10 09:00:07 +01:00
specialpages.ts feat(pad): scrub history in-place on the pad URL (#7659) (#7710) 2026-05-10 16:21:56 +01:00
static.ts chore: migrated settings to esm6 (#7062) 2025-08-04 22:42:50 +02:00
tokenTransfer.ts feat(gdpr): HttpOnly author-token cookie (PR3 of #6701) (#7548) 2026-05-03 05:56:56 +01:00
updateActions.ts feat(updater): tier 3 — auto update with grace window (#7607) (#7720) 2026-05-12 20:50:06 +01:00
updateStatus.ts feat(updater): tier 2 — manual-click update from /admin/update (#7607) (#7704) 2026-05-10 09:00:07 +01:00
webaccess.ts feat(gdpr): IP/privacy audit (PR2 of #6701) (#7547) 2026-05-01 13:47:40 +01:00