Repository navigation
OpenConceptLab/ocl_online#367 | Limit dialogs show only the next step online-api sends - #116
Merged
Merged
Conversation
… online-api sends When QuotaDialog or PreviewLimitDialog opens, the Mapper asks the configured online-api (OCL_ONLINE_API_URL, already used for match algorithms) for a next step (GET /billing/plan/?context=limit, with the person's token and UI language) and, if one comes back, shows its message and a link button that opens in a new tab. With the setting unset, an error or no action, the dialogs show only what was refused. - The dialogs no longer carry links of their own. PreviewLimitDialog says in neutral words what the account can't use, in all four languages, and the new-project alert uses the same strings. - The call goes through axios rather than APIService, so online-api's responses can't trigger the sign-out or the throttling screen. - GA: limit_hit when a dialog opens, limit_action_click on the button. Refs OpenConceptLab/ocl_online#325, OpenConceptLab/ocl_online#311 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AaZ4qVXboeBSRvAQgQjdbs
…about their permission The Mapper's access-denied dialogs now send permission=<app_label.codename> instead of capability, as online-api's contract now asks. Limits and missing allowances still send capability. GA events carry whichever one was sent. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AaZ4qVXboeBSRvAQgQjdbs
… blocked new project opens the dialog Codex pass 1: - F1.1: without an action, QuotaDialog still showed "N of M used" and a progress bar. It now shows only its neutral line, plus whatever online-api sends. The strings only the meter used are removed in all four languages, and getQuotaError no longer passes the counts along. - F1.2: opening /map-projects/new while blocked showed a toast and redirected, so online-api was never asked and no limit_hit was recorded. MapProject now redirects to the project list with the reason in the route state, and the list opens the same dialog it opens for the New button. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01AaZ4qVXboeBSRvAQgQjdbs
Member
Author
|
Codex review, pass 1 (codex-cli 0.164.0, commit eac6b2d) Verdict: findings, 2 findings
findings.json{
"reviewer": "codex-cli 0.164.0",
"perspective": "defects",
"mode": "full",
"commit": "eac6b2da2295b7269530ce986f33ef74dc36b4ae",
"verdict": "findings",
"prior": [],
"findings": [
{
"id": "F1.1",
"severity": "P1",
"tag": null,
"file": "src/components/common/QuotaDialog.jsx",
"line": 34,
"claim": "QuotaDialog does not provide the required neutral-only fallback.",
"scenario": "With no configured online-api URL, a request failure, or action:null, opening the dialog with usage={used:10, limit:10} still displays a limit breakdown and a computed progress bar. This violates acceptance criterion 4 and retains locally calculated allowance displays in public code.",
"action": "Remove the limit breakdown and progress calculation from the public dialog, leaving the neutral message and any service-supplied message/action. Add a rendering test for the fallback.",
"lines_delta": null,
"confidence": "high"
},
{
"id": "F1.2",
"severity": "P1",
"tag": null,
"file": "src/components/map-projects/MapProject.jsx",
"line": 815,
"claim": "The direct new-project refusal bypasses the connected-service request.",
"scenario": "A signed-in person whose project limit is reached opens /map-projects/new directly. Once capabilities load, this effect shows a refusal toast and the component redirects to /. Neither limit dialog opens, so the configured endpoint is never queried, its available action is never shown, and no limit-hit event is recorded.",
"action": "Carry the refusal through the redirect and open the appropriate limit dialog on the destination page, or otherwise route this refusal through the same request and action-display flow. Cover direct navigation with a test.",
"lines_delta": null,
"confidence": "high"
}
]
} |
Member
Author
|
Codex review, pass 2 (codex-cli 0.164.0, commit 26cfe49) Verdict: clean findings.json{
"reviewer": "codex-cli 0.164.0",
"perspective": "defects",
"mode": "verify",
"commit": "26cfe49f8048e244011c39c30539b494d020e129",
"verdict": "clean",
"prior": [
{
"id": "F1.1",
"status": "resolved"
},
{
"id": "F1.2",
"status": "resolved"
}
],
"findings": []
} |
Member
Author
|
Simplification review (claude subagent, commit 26cfe49) Verdict: 3 proposed cuts, none applied, so no Codex check of new commits is needed.
simplify.json{
"reviewer": "claude subagent",
"perspective": "simplify",
"mode": "full",
"commit": "26cfe49",
"verdict": "findings",
"prior": [],
"findings": [
{
"id": "S1",
"severity": null,
"tag": "dup-test",
"file": "src/components/common/__tests__/limitAction.test.js",
"line": 7,
"claim": "The first test's second and third asserts (baseURL undefined; token undefined) repeat the same falsy-guard branch as the first assert; one missing-URL case and one missing-token case are enough, and the 'url: 42' and 'javascript:' / 'data:' cases in the last test overlap on the protocol check (keep javascript: only, plus not-a-url).",
"scenario": null,
"action": "Drop the baseURL-undefined assert and the data: and 42 url asserts.",
"lines_delta": -3,
"confidence": "low"
},
{
"id": "S2",
"severity": null,
"tag": "yagni",
"file": "src/components/map-projects/PreviewLimitDialog.jsx",
"line": 18,
"claim": "Double fallback to generic: kind already defaults to 'generic' via `|| 'generic'`, and t() is also given an array fallback to the generic key. The new previewLimits test already pins that every non-limit kind has its own message in all four languages, so the t() array fallback is unreachable.",
"scenario": null,
"action": "t(`map_project.limit_unavailable_body_${kind}`)",
"lines_delta": 0,
"confidence": "low"
},
{
"id": "S3",
"severity": null,
"tag": "shrink",
"file": "src/components/common/useLimitAction.js",
"line": 19,
"claim": "`subject` is recomputed every render and is used only inside the effect and the click handler; getLimitActionRequest already calls getLimitSubject, so the request path computes it twice per open. Not worth a separate variable if GA param is derived from request.params.",
"scenario": null,
"action": "Compute subject inside the effect/handler only (or pass it through once); no behavior change.",
"lines_delta": -1,
"confidence": "low"
}
]
} |
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.
Refs OpenConceptLab/ocl_online#367, OpenConceptLab/ocl_online#325 and OpenConceptLab/ocl_online#311. TBv3's side is OpenConceptLab/oclweb3 (same branch name).
What changes
QuotaDialogorPreviewLimitDialogopens, the Mapper callsGET <OCL_ONLINE_API_URL>/billing/plan/?context=limit&lang=<UI language>with the person's token. A limit sendscapability=<capability name>, and an access check sendspermission=<app_label.codename>. If the response carries anaction, the dialog shows itsmessageand a button with itslabelthat opens itsurlin a new tab. Only an http(s) link with a label becomes a button.OCL_ONLINE_API_URLunset (a self-hosted install's default), an error, oraction: null, the dialogs show only what was refused: no extra text and no button.PreviewLimitDialognow says in neutral words what the account can't use (one title, nine messages, in all four languages), and the old toast strings are gone with it.QuotaDialogno longer shows the count or the progress bar. It says what was refused and what still works (Codex pass 1, F1.1)./map-projects/newwhile blocked used to show a toast and redirect. Now it redirects to the project list, which opens the same dialog as the New button (Codex pass 1, F1.2).OCL_ONLINE_API_URLis the setting the Mapper already uses for match algorithms.APIService, so online-api's errors don't reach its sign-out or throttling handling.limit_hitwhen a dialog opens andlimit_action_clickon the button (categoryLimit, label = the error code, paramscapabilityorpermission, andaction_kind).Testing
eslint src --ext .jsx,.jsandnpm run test:all, as CI runs them: 603 unit and 6 integration tests pass. The production build passes.PreviewLimitDialogshows has its own message in each language.cc @snyaggarwal (for reading; no approval needed)
🤖 Generated with Claude Code
https://claude.ai/code/session_01AaZ4qVXboeBSRvAQgQjdbs