feat: save or suggest per language from the in-context dialog (pitch tolgee/tolgee-platform#3780, scope B) - #3541
Merged
Anty0 merged 6 commits intoSep 24, 2026
Conversation
|
Important Review skippedAuto reviews are disabled on base/target branches other than the default branch. Please check the settings in the CodeRabbit UI or the ⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Essentials Run ID: You can disable this status message by setting the Use the checkbox below for a quick retry:
Comment |
…lation - WEB_INTERNAL_URL (CYPRESS_WEB_INTERNAL_URL) overrides the hardcoded http://localhost:8114 app URL, like API_URL already did for the server, so two worktrees can run the suite at once - findDcyWithCustom retries like findDcy instead of a one-shot jQuery find, which silently yielded an empty set when the element rendered a moment later - mockPermissions() extracted from simulateReqAndResponse for reuse - presets carry suggestionsMode / translationProtection, required since the schema regeneration - specs locate the submit button by data-cy instead of its label
The web-internal suite could only ever run against tolgee/tolgee:latest, so anyone needing a pre-release server had to edit the compose file. TOLGEE_IMAGE now names the image; the default is unchanged.
Pure move ahead of the work that grows this file: ErrorAlert, severityFor, getErrorContent, OpenExtension, DocsAPIKeys and DocsInContext each get their own file; the index keeps every existing import path working.
A member who may only suggest on some languages, or a community contributor who may only suggest, used to get a disabled form. Each language field now has a disposition: editable fields are saved, fields the user may only suggest on are sent as suggestions, the rest are read-only. One button does both; its label follows the changed set (Save / Suggest / Save & suggest). The key update goes first and suggestions are sent only if it succeeded (a suggestion racing a plural toggle could be stored with the wrong plural-ness, and a suggestion that went through while the save failed would make the retry fail with duplicate_suggestion). A failed suggestion keeps the dialog open with the error under its field, and a read-only rejection of a suggestion shows under its field instead of flipping the whole dialog to read-only; a field whose suggestion went through is re-seeded silently. A suggest-only user gets a working form: no permissions alert, tags hidden, the button disabled until there is something to suggest. The dialog context also exposes refreshTranslation(reseedLanguage?) for the suggestion list: it refreshes server data while keeping the other dirty fields, unsaved tags and pending screenshots.
current-permissions now reports the user's own project scopes (userScopes) next to the credential's. Where the dialog says a permission is lacking — the disabled form, a read-only language field, an operation_not_permitted error — it tells the user when their account could do it but the API key or plugin sign-in cannot, and how to fix that; when the account lacks it too, it says nothing about signing in. Servers that do not send userScopes keep today's wording.
Translators who open a string in the page often have no idea what the string is for; the description is where that context lives on the platform, so show it right under the key name. Long descriptions are clamped to five lines with the full text as a hover title, and the hint next to the key name moves to the same theme colour as the description.
Anty0
force-pushed
the
jirikuchynka/community-sdk-suggestions-b
branch
from
September 24, 2026 09:44
a7530df to
46fe2a2
Compare
Anty0
merged commit Sep 24, 2026
46fe2a2
into
jirikuchynka/community-sdk-suggestions
2 of 3 checks passed
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Scope B of pitch tolgee/tolgee-platform#3780 (community suggestions from the SDK). PR into the pitch's integration branch.
Problem
A member who may edit some languages and only suggest on others, or a community contributor who may only suggest, opens the in-context dialog and gets a disabled form with "permissions not sufficient". The dialog only understands edit scopes; the suggestion backend and the community permission floor exist, but nothing in the dialog uses them.
Solution
getDisposition:save,suggest(the field says "Your change will be sent as a suggestion", or why, for a protected reviewed translation) or read-only.duplicate_suggestion. Suggestions among themselves go in parallel and are all awaited.duplicate_suggestionandsuggestions_disabledhave copy); fields whose suggestion went through say so and are re-seeded.reloadKeepingEdits({ except? })for the suggestion list (scope A): reloads the key from the server while keeping what the user typed, except in the one language named, plus unsaved tags and pending screenshots; fields are locked while it runs.commitToPagewrites a saved or accepted text into the page for both the form and the list.Pure logic (
planSubmit,isSuggestOnly,keepFormFields) is unit-tested indialogContext/tools.ts. Not built: the "Suggest instead" dropdown (optional in the pitch, skipped).The first commit is harness only (
WEB_INTERNAL_URLoverride so two worktrees can run web-internal e2e at once, a retryingfindDcyWithCustom, presets updated for the regenerated schema, specs selecting the submit button bydata-cy) and can be skipped by the reviewer.Follow-ups on the same branch
refactor:one per-field error state (the simplification the reviewer asked for) — a successful suggestion is re-seeded silently, a read-only rejection shows under its field.feat:whose permission is missing:current-permissionsnow returnsuserScopes(feat: backfill translation-suggestions.own-access into granular permissions (pitch tolgee/tolgee-platform#3780, scope D) tolgee-platform#3937, must merge first — the regenerated schema hunk is that PR'suserId+userScopes). Where the dialog says a permission is lacking it tells the user when their account could do it but the API key / plugin sign-in cannot, and how to fix that.refactor:one component per file underKeyDialog/ErrorAlert/— a pure move, no behaviour change.feat:the key description under the key name, clamped to five lines with the full text on hover (optional in the pitch, built on request).test:TOLGEE_IMAGEnames the server image ine2e/docker-compose.yml, defaulting totolgee/tolgee:latestas before, so a local run can point the web-internal suite at a pre-release image without editing the file. CI is unaffected.What it looks like
Every shot is the real in-context dialog in the SDK dev app, same key, same languages, same viewport. Before is this PR's base, the pitch's integration branch. Permissions and the language list are mocked the way the e2e specs mock them, because the released server the dev app runs against has no suggestion API yet. The same shots with more context: https://claude.ai/artifact/N7BPD6TUwppBRr6vWcs4d2
The submit button says what the click will do
The dialog no longer only saves, so the button stops claiming it does. Creating a key still says Create.
A contributor who may only suggest gets a form, not a wall
With
translations.suggestand suggestions on, the fields open for editing, each says where the change will go, tags are hidden, and the button reads Suggest — disabled until there is something to send. On this PR's base the same user gets read-only fields and an Update button with nothing to submit; onmain, before the foundation landed, they got the "permissions not sufficient" alert.Saying whose permission is missing
When the account could do the thing but the credential the page uses cannot, the dialog says so and names the fix, instead of sending everyone to an admin.
The key description, where the translator is looking
The description that lives on the platform now sits under the key name, clamped to five lines with the full text on hover.
States that did not exist before
No before shot for these: on the base branch the user either could not open a working form at all, or the state had no way to arise.
One click saves what it may and suggests the rest — May translate English, may only suggest German. Changing both makes the button read Save & suggest; the key update goes first, the suggestions follow only if it succeeded.
A rejected suggestion keeps the dialog open — German was suggested twice, so the server rejects it. The error sits under that field with the text still in it, while the other fields went through and were re-seeded.
A reviewed translation on a protected project — The user may edit this language, but the translation is reviewed and the project protects reviewed strings — so the change becomes a suggestion, and the field says why.
An emptied field cannot be suggested — There is no "suggest removing this translation" on the server, so a field cleared to nothing is left alone and says so.
Why this one field is read-only — The key may only suggest German, while the account could translate English. The note sits on the English field, not on the whole form.
The same hint when the page is signed in through the plugin — Same rule, different fix: the copy points at the browser plugin's sign-in instead of at the API key.
Tests
packages/web: 32 suites, 300 tests.suggestForm.cy.ts(suggest-only submit, mixed save + suggest, partial failure, the credential notes, the key description).tolgee/tolgee:latest; the new spec mockscurrent-permissionsand the suggestion endpoint, so it does not depend on the foundation server changes.