mirror of
https://github.com/ether/etherpad-lite.git
synced 2026-07-18 00:57:55 +00:00
* 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>
52 lines
1.7 KiB
JSON
52 lines
1.7 KiB
JSON
{
|
|
"name": "admin",
|
|
"private": true,
|
|
"version": "2.7.3",
|
|
"type": "module",
|
|
"scripts": {
|
|
"dev": "pnpm gen:api && vite",
|
|
"dev:only": "vite",
|
|
"gen:api": "node scripts/gen-api.mjs",
|
|
"build": "pnpm gen:api && tsc && vite build",
|
|
"lint": "eslint . --ext ts,tsx --report-unused-disable-directives --max-warnings 0",
|
|
"build-copy": "pnpm gen:api && tsc && vite build --outDir ../src/templates/admin --emptyOutDir",
|
|
"preview": "vite preview",
|
|
"test": "pnpm gen:api && tsx --test 'src/**/__tests__/*.test.ts'"
|
|
},
|
|
"dependencies": {
|
|
"@radix-ui/react-switch": "^1.2.6",
|
|
"@tanstack/react-query": "^5.100.10",
|
|
"@tanstack/react-query-devtools": "^5.100.10",
|
|
"jsonc-parser": "^3.3.1",
|
|
"openapi-fetch": "^0.17.0",
|
|
"openapi-react-query": "^0.5.4"
|
|
},
|
|
"devDependencies": {
|
|
"@radix-ui/react-dialog": "^1.1.15",
|
|
"@radix-ui/react-toast": "^1.2.15",
|
|
"@types/react": "^19.2.14",
|
|
"@types/react-dom": "^19.2.3",
|
|
"@typescript-eslint/eslint-plugin": "^8.59.3",
|
|
"@typescript-eslint/parser": "^8.59.3",
|
|
"@vitejs/plugin-react": "^6.0.1",
|
|
"babel-plugin-react-compiler": "19.1.0-rc.3",
|
|
"eslint": "^10.3.0",
|
|
"eslint-plugin-react-hooks": "^7.1.1",
|
|
"eslint-plugin-react-refresh": "^0.5.2",
|
|
"i18next": "^26.1.0",
|
|
"i18next-browser-languagedetector": "^8.2.1",
|
|
"lucide-react": "^1.14.0",
|
|
"openapi-typescript": "^7.13.0",
|
|
"react": "^19.2.6",
|
|
"react-dom": "^19.2.6",
|
|
"react-hook-form": "^7.75.0",
|
|
"react-i18next": "^17.0.7",
|
|
"react-router-dom": "^7.15.0",
|
|
"socket.io-client": "^4.8.3",
|
|
"tsx": "^4.21.0",
|
|
"typescript": "^6.0.3",
|
|
"vite": "^8.0.12",
|
|
"vite-plugin-babel": "^1.6.0",
|
|
"zustand": "^5.0.13"
|
|
}
|
|
}
|