Skip to content

Conversation

ashley-o0o
Copy link
Contributor

@ashley-o0o ashley-o0o commented Aug 6, 2025

Closes: https://issues.redhat.com/browse/RHOAIENG-26252

Description

Updates how the server replica deployment min/max works. Before, it was difficult to edit the max using your keyboard, limiting you to use the - / + buttons. Now you're able to edit the max using your keyboard much easier. You're able to properly backspace and modify the number.
There is now a popup that will warn you if you're trying to set a number to max that's lower than min, and when you click away it will snap to the min. Edit: It will now also show the warning if you try to set the min to be higher than the max, and will snap to the max when you click away. It will also now disable the deploy button when the warning is being shown.

How Has This Been Tested?

Tested locally.

  • Navigate to a project, then go to deploy a modal. Within the deploy modal, scroll to the 'Number of model server replicas to deploy'
  • When adjusting the max, you should be able to backspace the number and type whatever you want. It will still max out at 99, and if you try to set it to a number lower than the min, it will show a warning.
  • If you try to set a number lower than the min, when you click away, it will snap to the min number.
  • Same with min, if you try to set the min to a number higher than the max and click away, it will snap to the max.
  • Anytime you're editing the numbers and the warning pops up, the deploy button will change to be disabled

Test Impact

Modified cypress test to check for error message

Screen Record

Before:

Screen.Recording.2025-08-06.at.10.27.26.AM.mov

After:

Screen.Recording.2025-08-14.at.10.43.04.AM.mov

Request review criteria:

Self checklist (all need to be checked):

  • The developer has manually tested the changes and verified that the changes work
  • Testing instructions have been added in the PR body (for PRs involving changes that are not immediately obvious).
  • The developer has added tests or explained why testing cannot be added (unit or cypress tests for related changes)

If you have UI changes:

  • Included any necessary screenshots or gifs if it was a UI change.
  • Included tags to the UX team if it was a UI/UX change.

After the PR is posted & before it merges:

  • The developer has tested their solution on a cluster by using the image produced by the PR to main

Summary by CodeRabbit

  • New Features

    • Inline warnings when minimum and maximum replicas are inconsistent.
    • Form submission is blocked if replica settings are invalid.
    • Replica controls now surface validation status to the parent so the modal can prevent submit when invalid.
    • Layout adjusted to display warnings beneath replica inputs.
  • Bug Fixes

    • Removed unexpected auto-sync between min and max replicas (except for specific raw deployments), reducing accidental value changes.
    • Improved bounds enforcement and clearer control behavior at limits.
  • Tests

    • Added end-to-end tests verifying replica validation messages and modal behavior.

@openshift-ci openshift-ci bot requested review from manaswinidas and pnaik1 August 6, 2025 14:35
Copy link
Contributor

coderabbitai bot commented Aug 6, 2025

Walkthrough

Adds cross-field validation and inline warnings to min/max replica inputs, exposes validation state via onValidationChange up the component chain, renames/refactors ReplicaSection, removes most auto-sync between min/max, updates modal submit gating, and adds Cypress tests and page-object finders for the new messages.

Changes

Cohort / File(s) Summary
Replica section refactor + validation
frontend/src/components/ReplicaSection.tsx
Renamed ReplicaFormGroupReplicaSection, added onValidationChange prop, introduced editingField and empty-value flags, added clamping/normalization, cross-field validation, inline warning helper text, updated focus/blur/change behaviors and button enablement.
Autoscaler wrapper integration
frontend/src/pages/modelServing/screens/projects/kServeModal/KServeAutoscalerReplicaSection.tsx
Added onValidationChange to props and forwarded to ReplicaSection; removed most auto-sync between min/max (retain min→max only when isKServeRawDeployment is true).
Modal submit gating
frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx
Added local hasReplicaValidationErrors state, wired onValidationChange from autoscaler section, and included it in submit-disabled logic to block submission on validation errors.
Cypress page object additions
frontend/src/__tests__/cypress/cypress/pages/modelServing.ts
Added findMaxReplicasErrorMessage() and findMinReplicasErrorMessage() helpers to locate the new inline validation messages.
Cypress E2E validations
frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts
Added E2E assertions for min/max validation message display and clearing behavior; adjusted fixture defaults for predictor min/max (2 → 4).

Sequence Diagram(s)

sequenceDiagram
  participant U as User
  participant RS as ReplicaSection
  participant KA as KServeAutoscalerReplicaSection
  participant MM as ManageKServeModal

  U->>RS: Edit min/max inputs
  RS->>RS: Validate, clamp, set editing/empty flags
  RS-->>KA: onValidationChange(hasErrors)
  KA-->>MM: onValidationChange(hasErrors)
  MM->>MM: set hasReplicaValidationErrors
  MM-->>U: Disable/enable Submit based on errors
Loading
sequenceDiagram
  participant U as User
  participant RS as ReplicaSection
  participant KA as KServeAutoscalerReplicaSection

  U->>RS: Change Min
  RS-->>KA: onMinChange(newMin)
  alt isKServeRawDeployment
    KA->>KA: may update Max to match Min
  else
    KA-->>KA: no auto-sync to Max
  end

  U->>RS: Change Max
  KA-->>KA: no auto-sync to Min
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Poem

I twitch my whiskers at numbers tight,
Min and Max now mind their flight.
A tiny triangle warns with cheer,
“Fix the bounds, then the path is clear.”
Hop, click, submit — the burrow’s near. 🥕

Tip

🔌 Remote MCP (Model Context Protocol) integration is now available!

Pro plan users can now connect to remote MCP servers from the Integrations page. Connect with popular remote MCPs such as Notion and Linear to add more context to your reviews and chats.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these sources in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 296840f and 9112fca.

📒 Files selected for processing (1)
  • frontend/src/components/ReplicaSection.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/ReplicaSection.tsx
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cypress-Setup
  • GitHub Check: Lint
✨ Finishing Touches
  • 📝 Generate Docstrings
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

CodeRabbit Commands (Invoked using PR/Issue comments)

Type @coderabbitai help to get the list of available commands.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • If your editor has YAML language server enabled, you can add the path at the top of this file to enable auto-completion and validation: # yaml-language-server: $schema=https://coderabbit.ai/integrations/schema.v2.json

Status, Documentation and Community

  • Visit our Status Page to check the current availability of CodeRabbit.
  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

@ashley-o0o ashley-o0o requested review from Griffin-Sullivan, emilys314 and katieperry4 and removed request for manaswinidas and pnaik1 August 6, 2025 14:59
@ashley-o0o ashley-o0o force-pushed the 26252/min-max-deployment-improvements branch from 8a8f719 to 32add70 Compare August 6, 2025 15:03
Copy link

codecov bot commented Aug 6, 2025

Codecov Report

❌ Patch coverage is 0% with 53 lines in your changes missing coverage. Please review.
✅ Project coverage is 29.23%. Comparing base (ef678fb) to head (9112fca).
⚠️ Report is 67 commits behind head on main.

Files with missing lines Patch % Lines
frontend/src/components/ReplicaSection.tsx 0.00% 51 Missing ⚠️
...screens/projects/kServeModal/ManageKServeModal.tsx 0.00% 2 Missing ⚠️
Additional details and impacted files

Impacted file tree graph

@@             Coverage Diff             @@
##             main    #4632       +/-   ##
===========================================
- Coverage   82.16%   29.23%   -52.94%     
===========================================
  Files        1846     1854        +8     
  Lines       38533    38504       -29     
  Branches    11480    11815      +335     
===========================================
- Hits        31661    11257    -20404     
- Misses       6872    27247    +20375     
Files with missing lines Coverage Δ
...cts/kServeModal/KServeAutoscalerReplicaSection.tsx 0.00% <ø> (-75.00%) ⬇️
...screens/projects/kServeModal/ManageKServeModal.tsx 0.00% <0.00%> (-94.29%) ⬇️
frontend/src/components/ReplicaSection.tsx 0.00% <0.00%> (-92.86%) ⬇️

... and 1606 files with indirect coverage changes


Continue to review full report in Codecov by Sentry.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update ef678fb...9112fca. Read the comment docs.

🚀 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.

@ashley-o0o
Copy link
Contributor Author

/test-e2e

@rhods-ci-bot
Copy link

E2E Tests #2484 triggered by #4632 (comment)

@rhods-ci-bot
Copy link

E2E Tests #2484 finished with result: UNSTABLE

@katieperry4
Copy link
Contributor

Would it be possible to disable the deploy button if the warning message is showing?
I filled everything in so the deploy button enabled and then I set min to 2 and then tried to set max to 1. I hit deploy without clicking outside the max input and it did snap up to 2 and deploy but would it be better to disable the button if the error message is showing?

Otherwise everything looks great! The leading 0 can be a little confusing but I'm not sure there's a way around that

@Griffin-Sullivan
Copy link
Contributor

Could we replicate these changes for the min > max? Seems like the old ux is present when changing the min

@ashley-o0o
Copy link
Contributor Author

Updated to disable the deploy button when editing numbers and the warning message is showing. Also modifies the minimum replica field to work the same as the maximum.

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: 0

🧹 Nitpick comments (3)
frontend/src/components/ReplicaSection.tsx (3)

41-46: Reduce duplication: use a single “out-of-order” predicate

maxLessThanMin and minGreaterThanMax are equivalent. Consider consolidating to improve readability and prevent drift.

Apply:

-  const maxLessThanMin = !showMinMax && maxValue < value;
-  const minGreaterThanMax = !showMinMax && value > maxValue;
-  const showMinWarning = minGreaterThanMax && editingField === 'min';
-  const showMaxWarning = maxLessThanMin && editingField === 'max';
+  const outOfOrder = !showMinMax && value > maxValue;
+  const showMinWarning = outOfOrder && editingField === 'min';
+  const showMaxWarning = outOfOrder && editingField === 'max';

76-96: Guardrails look correct, but consider explicit empty input handling

Using val === undefined ? 0 : Number(val) makes cleared inputs immediately become 0. That’s fine given requirements, but you might prefer to preserve “empty” during editing and only coerce on blur for a slightly smoother UX (optional).

If you want this behavior, I can propose a wrapper change that passes through undefined while editing and coerces on blur only.


146-175: Optional: add data-testid on helper texts for more stable e2e assertions

Cypress currently locates these by text via page object helpers. Adding dedicated testids will make tests resilient to minor copy changes and reduce flakiness.

Example:

- <FormHelperText
+ <FormHelperText
+   data-testid="min-replicas-error"
    style={{ whiteSpace: 'nowrap' }}
  >
    <HelperText>
      <HelperTextItem icon={<ExclamationTriangleIcon />} variant="warning">
        Minimum replicas must be less than or equal to maximum replicas.
      </HelperTextItem>
    </HelperText>
  </FormHelperText>
...
- <FormHelperText
+ <FormHelperText
+   data-testid="max-replicas-error"
    style={{ whiteSpace: 'nowrap' }}
  >
    <HelperText>
      <HelperTextItem icon={<ExclamationTriangleIcon />} variant="warning">
        Maximum replicas must be greater than or equal to minimum replicas.
      </HelperTextItem>
    </HelperText>
  </FormHelperText>

I can follow up with a small PR to update the Cypress page helpers to use these selectors.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 32add70 and bf91a29.

📒 Files selected for processing (5)
  • frontend/src/__tests__/cypress/cypress/pages/modelServing.ts (1 hunks)
  • frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (2 hunks)
  • frontend/src/components/ReplicaSection.tsx (5 hunks)
  • frontend/src/pages/modelServing/screens/projects/kServeModal/KServeAutoscalerReplicaSection.tsx (2 hunks)
  • frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (2)
  • frontend/src/tests/cypress/cypress/pages/modelServing.ts
  • frontend/src/pages/modelServing/screens/projects/kServeModal/KServeAutoscalerReplicaSection.tsx
🧰 Additional context used
📓 Path-based instructions (1)
frontend/src/__tests__/cypress/cypress/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/cypress-e2e.mdc)

frontend/src/__tests__/cypress/cypress/**/*.{ts,tsx}: Don't create TypeScript interfaces for test data; use direct object access patterns.
All linting errors must be fixed: use object destructuring, proper formatting, no unused variables/imports, no any types unless necessary.
Never hardcode namespaces in tests or utilities; always derive namespaces from test variables or environment variables.

Files:

  • frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts
🧬 Code Graph Analysis (2)
frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (1)
frontend/src/__tests__/cypress/cypress/pages/modelServing.ts (1)
  • kserveModal (846-846)
frontend/src/components/ReplicaSection.tsx (1)
frontend/src/utilities/utils.ts (1)
  • normalizeBetween (152-162)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Lint
  • GitHub Check: Cypress-Setup
🔇 Additional comments (6)
frontend/src/components/ReplicaSection.tsx (1)

40-47: Good addition: local editing context drives symmetric min/max validation and parent callback

The editing-scoped warnings, snap-on-blur behavior, and onValidationChange callback fulfill the PR goals (keyboard editing, symmetric warnings, blur snap, and disabling submit while warning is active). This is a sensible UX and state split.

frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (2)

1925-1937: E2E coverage for min/max warnings is spot on

These checks validate the UX guarantees: error shown when max < min or min > max, and cleared on correction without requiring blur. This mirrors the component’s editing-scoped validation.


2003-2005: Double-check expected min/max (40/40) are intended defaults for this scenario

The request body expectations assert minReplicas: 40 and maxReplicas: 40. Given earlier interactions toggle between Advanced and Standard modes and don’t explicitly set 40 in the UI here, please confirm this is the intended outcome (likely from updated defaults or test data).

If you want, I can scan the codebase to find where 40 is set as the default for raw/standard modes and confirm this path drives the expected payload.

frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx (3)

134-135: Correct: track replica validation errors and wire through to disable submit

This links the new validation surface to the modal submission guard as requested in PR comments. Good integration point.


431-437: Propagating validation via onValidationChange is clean and keeps concerns separated

Forwarding the callback to the underlying section allows the autoscaler component to remain the source of truth for min/max validity. Nice separation of concerns.


506-508: Submit button gating now correctly includes replica validation state

This addresses the “deploy succeeds without blur” feedback by disabling submit while the warning is displayed. Behavior matches the PR objective.

@ashley-o0o
Copy link
Contributor Author

/test-e2e

@rhods-ci-bot
Copy link

E2E Tests #2579 triggered by #4632 (comment)

Copy link
Contributor

@Griffin-Sullivan Griffin-Sullivan left a comment

Choose a reason for hiding this comment

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

To answer @katieperry4 's points there is probably a way to trim the leading zero as we edit the field but everything I tried to change wasn't working so I'm just confused now haha. Other than the component name everything looks good to me.

@rhods-ci-bot
Copy link

E2E Tests #2579 finished with result: UNSTABLE

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: 0

♻️ Duplicate comments (1)
frontend/src/components/ReplicaSection.tsx (1)

30-30: Component naming reverted to ReplicaSection — resolves earlier review

Renaming back to ReplicaSection and exporting it as default addresses the prior feedback.

Also applies to: 180-180

🧹 Nitpick comments (4)
frontend/src/components/ReplicaSection.tsx (4)

41-50: Consolidate duplicated comparisons and compute validation state once

maxLessThanMin and minGreaterThanMax are logically equivalent; you can reduce to a single flag and derive everything else. Also, hasValidationErrors can be expressed in terms of that single flag. This cuts redundant state and clarifies intent.

Apply this refactor:

-  const maxLessThanMin = !showMinMax && maxValue < value;
-  const minGreaterThanMax = !showMinMax && value > maxValue;
-  const showMinWarning = minGreaterThanMax && editingField === 'min';
-  const showMaxWarning = maxLessThanMin && editingField === 'max';
-
-  const hasValidationErrors = showMinWarning || showMaxWarning;
+  const replicasInvalid = !showMinMax && value > maxValue;
+  const showMinWarning = replicasInvalid && editingField === 'min';
+  const showMaxWarning = replicasInvalid && editingField === 'max';
+
+  const hasValidationErrors = replicasInvalid && editingField !== null;

89-95: Let normalizer clamp instead of rejecting out-of-range keystrokes

Currently, onChange ignores values > upperLimit (e.g., typing “100” does nothing). Consider always normalizing/clamping and updating, which simplifies logic and avoids “ignored keystroke” UX. You still retain the hard cap of 99.

Apply across the three handlers:

-                  if (!Number.isNaN(newSize) && newSize <= upperLimit) {
+                  if (!Number.isNaN(newSize)) {
                     onChange(normalizeBetween(newSize, lowerLimit, upperLimit));
                   }
-                if (!Number.isNaN(newSize) && newSize <= upperLimit) {
+                if (!Number.isNaN(newSize)) {
                   onChange(normalizeBetween(newSize, lowerLimit, upperLimit));
                 }
-                  if (!Number.isNaN(newSize) && newSize <= upperLimit) {
+                  if (!Number.isNaN(newSize)) {
                     onMaxChange(normalizeBetween(newSize, lowerLimit, upperLimit));
                   }

Also applies to: 104-110, 134-140


119-119: Inline style may be unnecessary

style={{ position: 'relative' }} on the max FormGroup doesn’t appear to influence layout since helper text is rendered after the Flex container. If not strictly needed, consider removing to reduce styling noise.


146-175: Add aria-live to inline warnings for SR accessibility

To ensure screen readers announce the dynamic warning text as it appears, add aria-live="polite" to the FormHelperText containers.

-            <FormHelperText
+            <FormHelperText
+              aria-live="polite"
               style={{
                 whiteSpace: 'nowrap',
               }}
             >
-            <FormHelperText
+            <FormHelperText
+              aria-live="polite"
               style={{
                 whiteSpace: 'nowrap',
               }}
             >
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between bf91a29 and db864e5.

📒 Files selected for processing (1)
  • frontend/src/components/ReplicaSection.tsx (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
frontend/src/components/ReplicaSection.tsx (1)
frontend/src/utilities/utils.ts (1)
  • normalizeBetween (152-162)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cypress-Setup
  • GitHub Check: Lint
🔇 Additional comments (3)
frontend/src/components/ReplicaSection.tsx (3)

2-12: PF imports for inline warnings look good

Bringing in FormHelperText/HelperText and ExclamationTriangleIcon is appropriate for inline validation messaging. No concerns here.

Also applies to: 12-12


81-88: Button-disable guards are correct and prevent crossing constraints

  • Disabling the min plus button when min >= max prevents overshooting.
  • Disabling the max minus button when max <= min prevents undershooting.

This directly addresses the UX requirement while allowing free-form typing.

Also applies to: 126-133


27-50: Validation wiring OK — E2E coverage unclear

Verified the wiring:

  • frontend/src/components/ReplicaSection.tsx — calls onValidationChange(hasValidationErrors) via useEffect.
  • frontend/src/pages/modelServing/screens/projects/kServeModal/KServeAutoscalerReplicaSection.tsx — forwards onValidationChange to ReplicaSection (onValidationChange={onValidationChange}).
  • frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx — passes setHasReplicaValidationErrors and includes hasReplicaValidationErrors in the isSubmitDisabled condition.

Action required:

  • I couldn't find Cypress/E2E tests that explicitly assert the transient warning scenarios (min > max and max < min while editing, without blur). Please add tests that cover both cases (ensure submit is disabled while the warning is visible and re-enables after blur) or point to the existing tests that already cover them.

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: 0

♻️ Duplicate comments (2)
frontend/src/components/ReplicaSection.tsx (2)

30-39: Rename resolved: component is exported as ReplicaSection

This addresses the previous review note about naming. No further action needed.


194-194: Default export name matches component

Consistent export; aligns with prior naming feedback.

🧹 Nitpick comments (7)
frontend/src/components/ReplicaSection.tsx (7)

40-49: Simplify duplicated invalid-range checks

Both maxLessThanMin and minGreaterThanMax are equivalent (mirror statements). Collapse to a single isInvalidRange for clarity and to avoid drift on future edits.

Apply this diff:

-  const maxLessThanMin = !showMinMax && maxValue < value;
-  const minGreaterThanMax = !showMinMax && value > maxValue;
-  const showMinWarning = minGreaterThanMax && editingField === 'min';
-  const showMaxWarning = maxLessThanMin && editingField === 'max';
+  const isInvalidRange = !showMinMax && value > maxValue;
+  const showMinWarning = isInvalidRange && editingField === 'min';
+  const showMaxWarning = isInvalidRange && editingField === 'max';

79-91: Improve UX: treat 0 as empty on focus to avoid confusing leading zero

Review feedback mentioned a confusing leading “0”. When focusing the min input with a value of 0, pre-clear to make typing smoother without fighting the leading digit. This does not change the underlying value until blur or a valid change occurs.

Apply this diff:

-                onFocus={() => setEditingField('min')}
+                onFocus={() => {
+                  setEditingField('min');
+                  if (value === 0) {
+                    setIsMinEmpty(true);
+                  }
+                }}

92-103: Let normalizeBetween handle upper bound clamping (avoid gating on <= upperLimit)

Current check blocks updates when users type above 99 instead of clamping to 99, causing keystrokes to be ignored. Prefer clamping for a smoother, predictable UX.

Apply this diff:

-                  if (!Number.isNaN(newSize) && newSize <= upperLimit) {
-                    onChange(normalizeBetween(newSize, lowerLimit, upperLimit));
-                  }
+                  if (!Number.isNaN(newSize)) {
+                    onChange(normalizeBetween(newSize, lowerLimit, upperLimit));
+                  }

127-127: Nit: Inline style on FormGroup may be unnecessary

style={{ position: 'relative' }} on the max FormGroup isn’t used by the current inline warnings (rendered outside the group). If this was left for a future overlay/popover, add a brief comment. Otherwise, consider removing it.


130-142: Mirror the “leading zero” UX for max input

Apply the same “0 as empty on focus” behavior to the max input for consistency.

Apply this diff:

-                onFocus={() => setEditingField('max')}
+                onFocus={() => {
+                  setEditingField('max');
+                  if (maxValue === 0) {
+                    setIsMaxEmpty(true);
+                  }
+                }}

143-154: Let normalizeBetween clamp max without manual upper bound gate

Same rationale as the min input: prefer clamping to 99 instead of ignoring keystrokes above 99.

Apply this diff:

-                  if (!Number.isNaN(newSize) && newSize <= upperLimit) {
-                    onMaxChange(normalizeBetween(newSize, lowerLimit, upperLimit));
-                  }
+                  if (!Number.isNaN(newSize)) {
+                    onMaxChange(normalizeBetween(newSize, lowerLimit, upperLimit));
+                  }

160-189: Add test ids and aria-live to warnings for robust E2E and better a11y

Cypress tests that rely on text can be brittle. Test IDs make them resilient. Also consider aria-live="polite" so SR users are informed when the message appears.

Apply this diff:

-          {showMinWarning && (
-            <FormHelperText
+          {showMinWarning && (
+            <FormHelperText
+              data-testid="min-replicas-error"
+              aria-live="polite"
               style={{
                 whiteSpace: 'nowrap',
               }}
             >
               <HelperText>
                 <HelperTextItem icon={<ExclamationTriangleIcon />} variant="warning">
                   Minimum replicas must be less than or equal to maximum replicas.
                 </HelperTextItem>
               </HelperText>
             </FormHelperText>
           )}
-          {showMaxWarning && (
-            <FormHelperText
+          {showMaxWarning && (
+            <FormHelperText
+              data-testid="max-replicas-error"
+              aria-live="polite"
               style={{
                 whiteSpace: 'nowrap',
               }}
             >
               <HelperText>
                 <HelperTextItem icon={<ExclamationTriangleIcon />} variant="warning">
                   Maximum replicas must be greater than or equal to minimum replicas.
                 </HelperTextItem>
               </HelperText>
             </FormHelperText>
           )}
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between db864e5 and 078cd8e.

📒 Files selected for processing (1)
  • frontend/src/components/ReplicaSection.tsx (4 hunks)
🧰 Additional context used
🧬 Code Graph Analysis (1)
frontend/src/components/ReplicaSection.tsx (1)
frontend/src/utilities/utils.ts (1)
  • normalizeBetween (152-162)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cypress-Setup
  • GitHub Check: Lint
🔇 Additional comments (3)
frontend/src/components/ReplicaSection.tsx (3)

2-12: LGTM on expanded imports to support warning UX

The added PatternFly helper text components and warning icon are appropriate for the inline validation UI.


27-27: Public API extension (onValidationChange) is clear and useful

Optional callback to surface validation state upward is the right hook for disabling the Deploy action while warnings are visible.


50-53: Verified — Deploy button is disabled while replica validation warnings are present

Wiring confirmed end-to-end: ReplicaSection emits validation state, KServeAutoscalerReplicaSection forwards the prop, and ManageKServeModal uses the state to disable the submit.

  • frontend/src/components/ReplicaSection.tsx — useEffect calls onValidationChange?.(hasValidationErrors) (lines ~50–52).
  • frontend/src/pages/modelServing/screens/projects/kServeModal/KServeAutoscalerReplicaSection.tsx — accepts onValidationChange and passes onValidationChange={onValidationChange} into ReplicaSection (lines ~10, 17, 34).
  • frontend/src/pages/modelServing/screens/projects/kServeModal/ManageKServeModal.tsx — sets const [hasReplicaValidationErrors, setHasReplicaValidationErrors] = React.useState(false);, passes onValidationChange={setHasReplicaValidationErrors} to the section (line ~436), and includes hasReplicaValidationErrors in DashboardModalFooter's isSubmitDisabled (line ~507).

No changes required.

@ashley-o0o ashley-o0o force-pushed the 26252/min-max-deployment-improvements branch from 078cd8e to c417741 Compare August 14, 2025 17:47
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

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

💡 Knowledge Base configuration:

  • MCP integration is disabled by default for public repositories
  • Jira integration is disabled by default for public repositories
  • Linear integration is disabled by default for public repositories

You can enable these settings in your CodeRabbit configuration.

📥 Commits

Reviewing files that changed from the base of the PR and between 078cd8e and c417741.

📒 Files selected for processing (2)
  • frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (2 hunks)
  • frontend/src/components/ReplicaSection.tsx (4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • frontend/src/components/ReplicaSection.tsx
🧰 Additional context used
📓 Path-based instructions (1)
frontend/src/__tests__/cypress/cypress/**/*.{ts,tsx}

📄 CodeRabbit Inference Engine (.cursor/rules/cypress-e2e.mdc)

frontend/src/__tests__/cypress/cypress/**/*.{ts,tsx}: Don't create TypeScript interfaces for test data; use direct object access patterns.
All linting errors must be fixed: use object destructuring, proper formatting, no unused variables/imports, no any types unless necessary.
Never hardcode namespaces in tests or utilities; always derive namespaces from test variables or environment variables.

Files:

  • frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts
🧬 Code Graph Analysis (1)
frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (1)
frontend/src/__tests__/cypress/cypress/pages/modelServing.ts (1)
  • kserveModal (846-846)
⏰ Context from checks skipped due to timeout of 90000ms. You can increase the timeout in your CodeRabbit configuration to a maximum of 15 minutes (900000ms). (2)
  • GitHub Check: Cypress-Setup
  • GitHub Check: Lint
🔇 Additional comments (1)
frontend/src/__tests__/cypress/cypress/tests/mocked/modelServing/runtime/servingRuntimeList.cy.ts (1)

2003-2005: Confirm that 4/4 min/max in request body is stable after setting max to 99 and switching to “Standard”.

You assert minReplicas: 4 and maxReplicas: 4, but earlier in this test you set max to 99 (by entering 100 and clamping) and then switch the mode to “Standard” without explicitly setting the Standard-mode replicas. If “Standard” mode derives its single replicas value from the last min (4), this passes; if it derives from max (99) or resets, this can become brittle.

  • Consider explicitly setting and asserting the Standard-mode replicas to 4 just after switching to “Standard” to avoid flakiness.
  • If the page object doesn’t yet expose a Standard-mode replicas input finder, adding one will make this robust and readable.

Example (to add right after selecting “Standard”):

// After switching to "Standard"
kserveModal.findModelServerReplicasInput().clear().type('4');
kserveModal.findModelServerReplicasInput().should('have.value', '4');

@ashley-o0o ashley-o0o force-pushed the 26252/min-max-deployment-improvements branch from c417741 to 296840f Compare August 14, 2025 18:17
@Griffin-Sullivan
Copy link
Contributor

/test-e2e@Modelserving

@rhods-ci-bot
Copy link

E2E Tests #2583 triggered by #4632 (comment)

Copy link
Contributor

@Griffin-Sullivan Griffin-Sullivan left a comment

Choose a reason for hiding this comment

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

/lgtm

Nice work! Let's just double check the e2e again

@rhods-ci-bot
Copy link

E2E Tests #2583 finished with result: UNSTABLE

@ashley-o0o
Copy link
Contributor Author

/test-e2e@Modelserving

@rhods-ci-bot
Copy link

E2E Tests #2596 triggered by #4632 (comment)

@rhods-ci-bot
Copy link

E2E Tests #2596 finished with result: UNSTABLE

@Griffin-Sullivan
Copy link
Contributor

at this point the e2e run here is unreliable so let's just move forward with manual testing

@openshift-ci openshift-ci bot added the lgtm label Aug 15, 2025
Copy link
Contributor

openshift-ci bot commented Aug 15, 2025

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Griffin-Sullivan

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-merge-bot openshift-merge-bot bot merged commit d110aa2 into opendatahub-io:main Aug 15, 2025
41 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

4 participants