Skip to content

fix(web): unify UPC license actions into manage/trial entry#1929

Merged
elibosley merged 2 commits intomainfrom
codex/manage-license-start-trial
Mar 18, 2026
Merged

fix(web): unify UPC license actions into manage/trial entry#1929
elibosley merged 2 commits intomainfrom
codex/manage-license-start-trial

Conversation

@elibosley
Copy link
Member

@elibosley elibosley commented Mar 18, 2026

Summary

  • Collapse UPC legacy license actions (redeem, purchase, recover, activate) into a single entry.
  • Show a single button label of Manage License / Start Trial when trial start is available.
  • Keep the action routed through Manage License (myKeys) to preserve one-click behavior.
  • Restore trialStart account/server action plumbing so trial availability can be represented in UPC state/action lists.

Testing

  • pnpm exec vitest run __test__/store/account.test.ts __test__/components/Registration.test.ts __test__/store/server.test.ts
  • pnpm type-check

Summary by CodeRabbit

  • New Features

    • Added a "Start Trial" action in the license management menu and consolidated license actions into a unified "Manage License" entry with context-aware behavior.
  • Localization

    • Removed the previous generic manage-license helper text from many locales; added a new English helper string for the trial-start flow.
  • Tests

    • Added/updated tests covering the new trial start and manage-license UI behaviors.

@coderabbitai
Copy link
Contributor

coderabbitai bot commented Mar 18, 2026

Caution

Review failed

The pull request is closed.

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 649a0451-fa36-447b-8a7c-161a5f5a57be

📥 Commits

Reviewing files that changed from the base of the PR and between a5e4712 and 4789574.

📒 Files selected for processing (29)
  • web/__test__/components/DropdownContent.test.ts
  • web/__test__/store/account.test.ts
  • web/src/components/UserProfile/DropdownContent.vue
  • web/src/locales/ar.json
  • web/src/locales/bn.json
  • web/src/locales/ca.json
  • web/src/locales/cs.json
  • web/src/locales/da.json
  • web/src/locales/de.json
  • web/src/locales/en.json
  • web/src/locales/es.json
  • web/src/locales/fr.json
  • web/src/locales/hi.json
  • web/src/locales/hr.json
  • web/src/locales/hu.json
  • web/src/locales/it.json
  • web/src/locales/ja.json
  • web/src/locales/ko.json
  • web/src/locales/lv.json
  • web/src/locales/nl.json
  • web/src/locales/no.json
  • web/src/locales/pl.json
  • web/src/locales/pt.json
  • web/src/locales/ro.json
  • web/src/locales/ru.json
  • web/src/locales/sv.json
  • web/src/locales/uk.json
  • web/src/locales/zh.json
  • web/src/store/account.ts

Disabled knowledge base sources:

  • Linear integration is disabled

You can enable these sources in your CodeRabbit configuration.


Walkthrough

Adds a new trialStart action across stores and UI: account store publishes trialStart callbacks, server store surfaces a trialStart action for ENOKEYFILE/TRIAL states, UserProfile dropdown integrates manage-license/trial helper behavior, and tests/locales updated accordingly.

Changes

Cohort / File(s) Summary
Account & Server Stores
web/src/store/account.ts, web/src/store/server.ts
Add trialStart action and centralized sendAccountAction; server store exposes trialStartAction and includes it in ENOKEYFILE and TRIAL server state actions.
UI Components
web/src/components/UserProfile/DropdownContent.vue
Introduce manage-license action helper, always present when key actions exist; compute helper text that can show trial-specific text when trialStart is available; render helper text row conditionally.
Tests
web/__test__/store/account.test.ts, web/__test__/components/Registration.test.ts, web/__test__/components/DropdownContent.test.ts
Update/add tests to assert trialStart appears in keyActions and that account store payloads include activationCodeData when present; add DropdownContent tests for manage-license and trial helper behavior.
Locales
web/src/locales/en.json, web/src/locales/* (many).json
Add onboarding.licenseStep.actions.manageLicenseTrialStartHelperText in English; remove onboarding.licenseStep.actions.manageLicenseHelperText from many locale files (helper text entries deleted).

Sequence Diagram

sequenceDiagram
    participant User
    participant Dropdown as DropdownContent.vue
    participant AccountStore as Account Store
    participant Server as Server API

    User->>Dropdown: Click "Manage License / Start Trial"
    Dropdown->>AccountStore: accountStore.trialStart()
    AccountStore->>Server: POST ACCOUNT_CALLBACK (type: "trialStart", payload: serverPayload + activationCode?)
    Server-->>AccountStore: 200 OK
    AccountStore-->>Dropdown: resolve/action complete
Loading

Estimated code review effort

🎯 4 (Complex) | ⏱️ ~45 minutes

Possibly related PRs

Poem

I hopped through stores and dropdowns bright,
A trial button gleamed in morning light.
Payloads and helpers lined up in a row,
Click — callbacks fly — and off we go! 🐇✨

🚥 Pre-merge checks | ✅ 3
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title directly describes the main change: unifying UPC license actions into a single manage/trial entry point, which is the core objective of the PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch codex/manage-license-start-trial
📝 Coding Plan
  • Generate coding plan for human review comments

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link

@chatgpt-codex-connector chatgpt-codex-connector bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: a5e4712078

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

title: text,
};
};
const licenseActionsToManage = new Set(['activate', 'purchase', 'recover', 'redeem', 'trialStart']);

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Keep partner activation on the dedicated callback

Including activate in licenseActionsToManage means partner-activation states now collapse into accountStore.myKeys() instead of the original purchaseStore.activate() path. That is not equivalent: redeemAction only exposes activate for ENOKEYFILE/TRIAL/EEXPIRED systems with an activation code (web/src/store/server.ts:377-397), and purchaseStore.activate() is the code that forwards activationCodeData to UPC (web/src/store/purchase.ts:19-33,60-66). Routing those users through myKeys drops that payload, so the one-click partner activation flow can no longer complete from the profile menu.

Useful? React with 👍 / 👎.

Comment on lines +65 to +69
const createManageLicenseAction = (text: string): UserProfileLink<'manageLicense'> => {
return {
click: () => {
accountStore.myKeys();
emit('close-dropdown');

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P2 Badge Preserve disabled gating on the synthesized license entry

When serverActionsDisable is true, the underlying license actions are intentionally disabled with the "Requires the local unraid-api…" guard (web/src/store/server.ts:327-397,474-484). The synthetic manageLicense item created here never carries over disabled or the reason, so the dropdown stays clickable on servers where the rest of the UI blocks license flows because the local API is offline or CORS-failing. That creates a bypass of the existing safeguard via the profile menu.

Useful? React with 👍 / 👎.

@github-actions
Copy link
Contributor

This plugin has been deployed to Cloudflare R2 and is available for testing.
Download it at this URL:

https://preview.dl.unraid.net/unraid-api/tag/PR1929/dynamix.unraid.net.plg

@codecov
Copy link

codecov bot commented Mar 18, 2026

Codecov Report

❌ Patch coverage is 94.78261% with 6 lines in your changes missing coverage. Please review.
✅ Project coverage is 51.54%. Comparing base (dcb3a5b) to head (4789574).
⚠️ Report is 2 commits behind head on main.

Files with missing lines Patch % Lines
web/src/components/UserProfile/DropdownContent.vue 91.66% 4 Missing ⚠️
web/src/store/server.ts 86.66% 2 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1929      +/-   ##
==========================================
- Coverage   51.61%   51.54%   -0.08%     
==========================================
  Files        1021     1021              
  Lines       70477    70464      -13     
  Branches     7763     7809      +46     
==========================================
- Hits        36379    36321      -58     
- Misses      33976    34021      +45     
  Partials      122      122              

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Copy link
Contributor

@coderabbitai coderabbitai bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
web/__test__/components/Registration.test.ts (1)

442-443: Assert the rendered fallback here, not just the store array.

This only verifies that web/src/store/server.ts now exposes trialStart; it would still pass if Registration.standalone.vue stopped rendering the extra action. Prefer asserting the rendered key-action labels/buttons for this state.

As per coding guidelines "Test component behavior and output, not implementation details".

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@web/__test__/components/Registration.test.ts` around lines 442 - 443, The
test is asserting the store array (serverStore.keyActions) instead of the
component output; update the test to render Registration.standalone.vue (or use
the existing rendered wrapper) and assert the visible fallback/key-action labels
or buttons appear for 'activate', 'recover', and 'trialStart' (e.g., via
getByText/getAllByRole queries) rather than checking actionNames, so the spec
verifies rendered behavior not store internals.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@web/src/components/UserProfile/DropdownContent.vue`:
- Around line 97-99: The string assigned to manageActionText is hard-coded in
the hasTrialStart branch, causing inconsistent localization; change this to a
message key and run it through the same i18n lookup before building the
synthetic link. Update the logic that sets manageActionText (the variable used
for text/title when creating the synthetic link in DropdownContent.vue) so both
branches use translation keys (e.g., add a new key for "Manage License / Start
Trial") and call the same translator function (the existing i18n.t or $t usage)
so the displayed text/title are localized consistently.

---

Nitpick comments:
In `@web/__test__/components/Registration.test.ts`:
- Around line 442-443: The test is asserting the store array
(serverStore.keyActions) instead of the component output; update the test to
render Registration.standalone.vue (or use the existing rendered wrapper) and
assert the visible fallback/key-action labels or buttons appear for 'activate',
'recover', and 'trialStart' (e.g., via getByText/getAllByRole queries) rather
than checking actionNames, so the spec verifies rendered behavior not store
internals.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Pro

Run ID: 2123a876-7a97-4480-a158-f8c1034f69e0

📥 Commits

Reviewing files that changed from the base of the PR and between dcb3a5b and a5e4712.

📒 Files selected for processing (5)
  • web/__test__/components/Registration.test.ts
  • web/__test__/store/account.test.ts
  • web/src/components/UserProfile/DropdownContent.vue
  • web/src/store/account.ts
  • web/src/store/server.ts

## Summary
- Keep UPC actions collapsed to a single `Manage License` entry.
- Add helper copy directly below the action to improve discoverability.
- Use trial-specific helper text when `trialStart` is present in
`keyActions`.

## Testing
- `pnpm type-check`

## Notes
- This PR is stacked on top of #1929 for A/B validation between builds.
@elibosley elibosley merged commit 164198c into main Mar 18, 2026
4 of 7 checks passed
@elibosley elibosley deleted the codex/manage-license-start-trial branch March 18, 2026 19:08
elibosley pushed a commit that referenced this pull request Mar 18, 2026
🤖 I have created a release *beep* *boop*
---


## [4.30.1](v4.30.0...v4.30.1)
(2026-03-18)


### Bug Fixes

* **web:** unify UPC license actions into manage/trial entry
([#1929](#1929))
([164198c](164198c))

---
This PR was generated with [Release
Please](https://github.com/googleapis/release-please). See
[documentation](https://github.com/googleapis/release-please#release-please).

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant