Skip to content

refactor(multivariate): move-mv-option-saves-to-rtk-query#7760

Open
Zaimwa9 wants to merge 6 commits into
feat/label-variant-key-uifrom
refactor/mv-options-rtk
Open

refactor(multivariate): move-mv-option-saves-to-rtk-query#7760
Zaimwa9 wants to merge 6 commits into
feat/label-variant-key-uifrom
refactor/mv-options-rtk

Conversation

@Zaimwa9

@Zaimwa9 Zaimwa9 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Thanks for submitting a PR! Please check the boxes below:

  • I have read the Contributing Guide.
  • I have added information to docs/ if required so people know about the feature.
  • I have filled in the "Changes" section below.
  • I have filled in the "How did you test this code" section below.

Changes

Migrates the multivariate option save flow from the legacy Flux store to a single RTK Query mutation.

  • New saveMultivariateOptions mutation diffs submitted options against the server's current state before upserting/deleting, so stale client state can no longer create duplicate variants.
  • editFeatureMv becomes a thin adapter preserving the existing contracts: store events, per-card error attribution, and the positional option ordering consumed by both v1 and v2 feature-state saves. All failing options now surface errors, not just the first.
  • Variants are now sorted by id at store ingress and created sequentially, so their order no longer reshuffles after a save (the API returns them unordered; a backend ordering fix will follow separately).

Out of scope (follow-up): retiring the store's event system and converting the modal to mutation hooks.

How did you test this code?

  • Unit tests and E2E tests (including new mv-option E2E coverage for repeated saves, add/remove in one save, and v2 versioning).

Zaimwa9 added 6 commits June 11, 2026 14:15
Stage 1 of the MV-options RTK migration: a new multivariateOption
service replaces the raw data.put/post/delete calls in editFeatureMv
and createFlag. Orchestration, store events and per-option error
attribution are unchanged; failed option creation during createFlag is
no longer silently swallowed.
…utation

Stage 2 of the MV-options RTK migration. saveMultivariateOptions is a
single mutation whose queryFn diffs the input against the server's
current options (fetched fresh, so stale client state can never turn an
update into a duplicate create), runs the PUT/POST/DELETE requests,
and returns the saved options in input order plus per-option errors
keyed by index. On success it invalidates the feature's ProjectFlag
tag so subscribers refetch API-validated data.

editFeatureMv becomes a thin wrapper that maps the composite result
onto the existing store contracts: per-card error surfacing via
store.error.multivariate_options and the positional onComplete
callback. Standard flags skip the round-trip entirely.
@Zaimwa9 Zaimwa9 requested a review from a team as a code owner June 11, 2026 13:27
@Zaimwa9 Zaimwa9 requested review from kyle-ssg and removed request for a team June 11, 2026 13:27
@vercel

vercel Bot commented Jun 11, 2026

Copy link
Copy Markdown

The latest updates on your projects. Learn more about Vercel for GitHub.

Project Deployment Actions Updated (UTC)
flagsmith-frontend-preview Ready Ready Preview, Comment Jun 11, 2026 1:28pm
flagsmith-frontend-staging Ready Ready Preview, Comment Jun 11, 2026 1:28pm
1 Skipped Deployment
Project Deployment Actions Updated (UTC)
docs Ignored Ignored Jun 11, 2026 1:28pm

Request Review

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Docker builds report

Image Build Status Security report
ghcr.io/flagsmith/flagsmith-api-test:pr-7760 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-e2e:pr-7760 Finished ✅ Skipped
ghcr.io/flagsmith/flagsmith-api:pr-7760 Finished ✅ Results
ghcr.io/flagsmith/flagsmith:pr-7760 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-private-cloud:pr-7760 Finished ✅ Results
ghcr.io/flagsmith/flagsmith-frontend:pr-7760 Finished ✅ Results

@github-actions

github-actions Bot commented Jun 11, 2026

Copy link
Copy Markdown
Contributor

Playwright Test Results (oss - depot-ubuntu-latest-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  40.3 seconds
commit  82f0ab2
info  🔄 Run: #17437 (attempt 1)

Playwright Test Results (oss - depot-ubuntu-latest-arm-16)

passed  1 passed

Details

stats  1 test across 1 suite
duration  43.5 seconds
commit  82f0ab2
info  🔄 Run: #17437 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-arm-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  41.1 seconds
commit  82f0ab2
info  🔄 Run: #17437 (attempt 1)

Playwright Test Results (private-cloud - depot-ubuntu-latest-16)

passed  2 passed

Details

stats  2 tests across 2 suites
duration  37.5 seconds
commit  82f0ab2
info  🔄 Run: #17437 (attempt 1)

@github-actions

Copy link
Copy Markdown
Contributor

Visual Regression

19 screenshots compared. See report for details.
View full report

@Zaimwa9

Zaimwa9 commented Jun 11, 2026

Copy link
Copy Markdown
Contributor Author

@gemini-code-assist review

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Code Review

This pull request introduces a new useMultivariateOption service to handle creating, updating, and deleting multivariate options sequentially, ensuring stable creation order and preventing duplicate options. It refactors feature-list-store.ts to use these new endpoints and adds comprehensive E2E tests to verify multivariate option stability. Feedback on the changes suggests normalizing IDs to strings when searching for existing options to avoid type mismatch issues during strict equality checks.

Comment on lines +45 to +46
if (v.id) {
original = serverOptions.find((m) => m.id === v.id)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

high

To prevent potential type mismatch issues (e.g., if v.id is passed as a string from legacy form inputs or client state while m.id is a number from the server), it is safer to compare them by normalizing both to strings or numbers. Strict equality === will fail if one is a string and the other is a number, which would result in creating duplicate options instead of updating the existing ones.

Suggested change
if (v.id) {
original = serverOptions.find((m) => m.id === v.id)
if (v.id) {
original = serverOptions.find((m) => String(m.id) === String(v.id))

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

front-end Issue related to the React Front End Dashboard refactor

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants