Skip to content

fix: prevent Advanced Matching checkbox from auto-unchecking#3094

Closed
khoazero123 wants to merge 1 commit intobluewave-labs:developfrom
khoazero123:fix/advanced-matching-auto-uncheck
Closed

fix: prevent Advanced Matching checkbox from auto-unchecking#3094
khoazero123 wants to merge 1 commit intobluewave-labs:developfrom
khoazero123:fix/advanced-matching-auto-uncheck

Conversation

@khoazero123
Copy link
Copy Markdown

@khoazero123 khoazero123 commented Dec 26, 2025

Describe your changes

Briefly describe the changes you made and their purpose.

Fixes #3093

Please ensure all items are checked off before requesting a review. "Checked off" means you need to add an "x" character between brackets so they turn into checkmarks.

  • (Do not skip this or your PR will be closed) I deployed the application locally.
  • (Do not skip this or your PR will be closed) I have performed a self-review and testing of my code.
  • I have included the issue # in the PR.
  • I have added i18n support to visible strings (instead of <div>Add</div>, use):
const { t } = useTranslation();
<div>{t('add')}</div>
  • I have not included any files that are not related to my pull request, including package-lock and package-json if dependencies have not changed
  • I didn't use any hardcoded values (otherwise it will not scale, and will make it difficult to maintain consistency across the application).
  • I made sure font sizes, color choices etc are all referenced from the theme. I don't have any hardcoded dimensions.
  • My PR is granular and targeted to one specific feature.
  • I ran npm run format in server and client directories, which automatically formats your code.
  • I took a screenshot or a video and attached to this PR if there is a UI change.

Summary by CodeRabbit

  • Improvements
    • Advanced Matching now automatically activates when you configure specific monitor matching fields
    • Advanced Matching state is properly preserved when editing or duplicating monitor configurations

✏️ Tip: You can customize this high-level summary in your review settings.

@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Dec 26, 2025

Note

.coderabbit.yml has unrecognized properties

CodeRabbit is using all valid settings from your configuration. Unrecognized properties (listed below) have been ignored and may indicate typos or deprecated fields that can be removed.

⚠️ Parsing warnings (1)
Validation error: Unrecognized key(s) in object: 'release_notes'
⚙️ Configuration instructions
  • Please see the configuration documentation for more information.
  • You can also validate your configuration using the online YAML validator.
  • 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
📝 Walkthrough

Walkthrough

A bug fix for the Advanced Matching checkbox in the Uptime Monitor creation/editing interface. The change automatically enables Advanced Matching when users enter values in expectedValue or jsonPath fields, and optimizes the useEffect dependency array to prevent unnecessary re-renders that were unchecking the checkbox during editing.

Changes

Cohort / File(s) Summary
Advanced Matching Auto-Enable Logic
client/src/Pages/v1/Uptime/Create/index.jsx
Updated onChange handler to automatically enable Advanced Matching when expectedValue or jsonPath fields receive non-empty values. Modified useEffect to check for existing values across matchMethod, expectedValue, and jsonPath fields. Narrowed dependency array to only watch monitor.matchMethod, monitor.expectedValue, monitor.jsonPath, isCreate, and isClone to prevent unintended state resets during editing.

Estimated code review effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 A checkbox that danced and then fled the scene,
But now stays put with our logic so clean—
When values are typed, Advanced Matching springs true,
No more unchecking as you type anew!
The dependency watch now runs lean and bright,
Uptime monitors configured just right! ✨

Pre-merge checks and finishing touches

✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and directly describes the main fix: preventing the Advanced Matching checkbox from auto-unchecking, which is the core issue being resolved.
Description check ✅ Passed The PR description includes the issue reference (#3093) and confirms testing, but lacks detailed explanation of the changes made and does not provide UI screenshots despite UI changes.
Linked Issues check ✅ Passed The changes directly address all proposed solutions from issue #3093: narrowed useEffect dependency array to specific fields, updated condition to check all three fields, and added onChange logic to auto-enable Advanced Matching.
Out of Scope Changes check ✅ Passed All changes are focused on the single file client/src/Pages/v1/Uptime/Create/index.jsx and directly address the Advanced Matching checkbox auto-uncheck issue without introducing unrelated modifications.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • 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

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

Copy link
Copy Markdown

@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: Path: .coderabbit.yml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 668ea74 and 6dc887f.

📒 Files selected for processing (1)
  • client/src/Pages/v1/Uptime/Create/index.jsx
🧰 Additional context used
🧠 Learnings (2)
📓 Common learnings
Learnt from: Jesulayomy
Repo: bluewave-labs/Checkmate PR: 2664
File: client/src/Pages/Uptime/Create/index.jsx:92-96
Timestamp: 2025-07-24T17:52:55.506Z
Learning: In the Uptime monitor components, the `formatAndSet` function was deprecated due to rendering issues caused by state mutations. The current approach stores intervals internally in milliseconds (API format) but converts for display using `const displayInterval = monitor?.interval / MS_PER_MINUTE || 1;` and converts user input back to milliseconds using `value = value * MS_PER_MINUTE` in the onChange handler.
📚 Learning: 2025-07-24T17:52:55.506Z
Learnt from: Jesulayomy
Repo: bluewave-labs/Checkmate PR: 2664
File: client/src/Pages/Uptime/Create/index.jsx:92-96
Timestamp: 2025-07-24T17:52:55.506Z
Learning: In the Uptime monitor components, the `formatAndSet` function was deprecated due to rendering issues caused by state mutations. The current approach stores intervals internally in milliseconds (API format) but converts for display using `const displayInterval = monitor?.interval / MS_PER_MINUTE || 1;` and converts user input back to milliseconds using `value = value * MS_PER_MINUTE` in the onChange handler.

Applied to files:

  • client/src/Pages/v1/Uptime/Create/index.jsx
🔇 Additional comments (1)
client/src/Pages/v1/Uptime/Create/index.jsx (1)

264-271: Good implementation of auto-checking on user input.

The automatic activation of the Advanced Matching checkbox when users type in expectedValue or jsonPath directly addresses the reported issue. The value.trim() check properly prevents whitespace-only input from triggering the checkbox.

Comment on lines 305 to +313
useEffect(() => {
if (!isCreate || isClone) {
if (monitor.matchMethod) {
setUseAdvancedMatching(true);
} else {
setUseAdvancedMatching(false);
}
// Automatically check "Advanced matching" checkbox if any value exists in matchMethod, expectedValue, or jsonPath
if (monitor.matchMethod || monitor.expectedValue || monitor.jsonPath) {
setUseAdvancedMatching(true);
} else if (!isCreate || isClone) {
// Only uncheck when editing/cloning and no values exist
setUseAdvancedMatching(false);
}
}, [monitor, isCreate]);
}, [monitor.matchMethod, monitor.expectedValue, monitor.jsonPath, isCreate, isClone]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🔴 Critical

🧩 Analysis chain

🏁 Script executed:

# First, let's look at the file structure and check the mentioned lines
wc -l client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 114


🏁 Script executed:

# Check the initial state and default values around lines 60 and 71
sed -n '55,75p' client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 754


🏁 Script executed:

# Check the useEffect implementation at lines 305-313
sed -n '300,320p' client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 896


🏁 Script executed:

# Search for matchMethod default behavior across the codebase
rg -n 'matchMethod.*equal' --type=js --type=jsx -A2 -B2

Repository: bluewave-labs/Checkmate

Length of output: 94


🏁 Script executed:

# Let's search for matchMethod without specifying file type
rg -n 'matchMethod.*equal' -A2 -B2

Repository: bluewave-labs/Checkmate

Length of output: 3867


🏁 Script executed:

# Also check how the monitor state is loaded when editing/cloning
rg -n 'useEffect.*monitor' client/src/Pages/v1/Uptime/Create/index.jsx | head -20

Repository: bluewave-labs/Checkmate

Length of output: 49


🏁 Script executed:

# Check if there are any comments or documentation about the intended behavior of Advanced Matching
rg -n 'Advanced.*[Mm]atching|advanced.*matching' client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 798


🏁 Script executed:

# Check if there are any other related useEffects or initialization logic that might clarify intent
sed -n '260,275p' client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 520


🏁 Script executed:

# Check if there's any handling to distinguish between "default matchMethod" and "user-selected matchMethod"
rg -n 'useAdvancedMatching\|Advanced' client/src/Pages/v1/Uptime/Create/index.jsx | grep -A3 -B3 'useEffect\|onChange'

Repository: bluewave-labs/Checkmate

Length of output: 49


🏁 Script executed:

# Check if there's any specific handling when loading existing monitors (edit/clone scenarios)
rg -n 'setMonitor\|fetchMonitor' client/src/Pages/v1/Uptime/Create/index.jsx | head -15

Repository: bluewave-labs/Checkmate

Length of output: 49


🏁 Script executed:

# Look for any comments about the intended behavior or design decisions
sed -n '1,100p' client/src/Pages/v1/Uptime/Create/index.jsx | grep -A5 -B5 'Advanced\|matchMethod'

Repository: bluewave-labs/Checkmate

Length of output: 758


🏁 Script executed:

# Check the complete context around the useEffect to understand the full logic flow
sed -n '295,320p' client/src/Pages/v1/Uptime/Create/index.jsx

Repository: bluewave-labs/Checkmate

Length of output: 1025


🏁 Script executed:

# Look for where monitors are loaded from the server (to understand edit/clone scenarios)
rg -n 'useParams\|useQuery\|id.*monitor' client/src/Pages/v1/Uptime/Create/index.jsx | head -10

Repository: bluewave-labs/Checkmate

Length of output: 49


Confirm the logic issue with Advanced Matching auto-check for new monitors.

The concern identified in the original review is valid. The useEffect condition at line 307 will always be truthy for new monitors because matchMethod defaults to "equal". Since expectedValue and jsonPath default to empty strings (falsy), only matchMethod being truthy triggers the auto-check.

For new monitor creation (where isCreate=true and isClone=false), the condition !isCreate || isClone evaluates to false, preventing the uncheck logic from running. This means the Advanced Matching checkbox will be auto-checked and advanced fields displayed immediately on mount for all new monitors, regardless of user intent.

The current logic conflates "default matchMethod value" with "user-intentionally-set advanced matching parameters." If Advanced Matching should be opt-in for new monitors, the condition needs to distinguish between default and user-entered values, or only auto-check when expectedValue or jsonPath are non-empty.

🤖 Prompt for AI Agents
In client/src/Pages/v1/Uptime/Create/index.jsx around lines 305-313, the
useEffect currently auto-checks Advanced Matching because monitor.matchMethod
defaults to "equal"; change the condition so Advanced Matching is only
auto-enabled when the user has provided actual advanced values
(monitor.expectedValue or monitor.jsonPath) or when an explicit "user-set" flag
for matchMethod exists; specifically, remove matchMethod from the truthy check
(or add a check for a user-set indicator) so only expectedValue || jsonPath true
will setUseAdvancedMatching(true), and keep the existing uncheck branch for
edits/clones.

Copy link
Copy Markdown

@llamapreview llamapreview Bot left a comment

Choose a reason for hiding this comment

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

AI Code Review by LlamaPReview

🎯 TL;DR & Recommendation

Recommendation: Approve with suggestions

This PR effectively fixes the Advanced Matching checkbox auto-unchecking issue but introduces minor inconsistencies and potential robustness concerns in the logic.

🌟 Strengths

  • Correctly resolves the core bug by updating useEffect dependencies and adding onChange logic for immediate feedback.
Priority File Category Impact Summary Anchors
P2 client/.../index.jsx Bug Excludes matchMethod from auto-check, causing user confusion.
P2 client/.../index.jsx Maintainability Potential performance issues from redundant state updates.
P2 client/.../index.jsx Bug Brittle string trimming could break with non-string values.
P2 client/.../index.jsx Bug Unclear logic for editing/cloning checkbox state.

🔍 Notable Themes

  • UI State Synchronization: Multiple findings highlight the need for consistent handling of advanced matching fields to ensure seamless user experience.
  • Defensive Programming: Issues around type assumptions and logic clarity suggest opportunities for more robust code practices.

💡 Have feedback? We'd love to hear it in our GitHub Discussions.
✨ This review was generated by LlamaPReview Advanced, which is free for all open-source projects. Learn more.

Comment on lines +264 to +271
setMonitor((prev) => {
const updatedMonitor = { ...prev, [name]: value };
// Automatically check "Advanced matching" checkbox if user enters expectedValue or jsonPath
if ((name === "expectedValue" || name === "jsonPath") && value && value.trim()) {
setUseAdvancedMatching(true);
}
return updatedMonitor;
});
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 | Confidence: High

Speculative: The logic in the onChange handler only automatically checks the Advanced Matching checkbox when the user types in expectedValue or jsonPath fields, but notably excludes the matchMethod field. This creates an inconsistent user experience where:

  1. A user could select a matchMethod (e.g., "JSON_PATH", "REGEX") from a dropdown without the checkbox being automatically checked.
  2. This scenario is plausible given the UI likely includes a dropdown/select for matchMethod.
  3. The user might expect advanced matching to be active when they've selected a method, leading to confusion if the checkbox remains unchecked despite having a valid matchMethod.
  4. This inconsistency contradicts the useEffect logic which correctly checks for any of the three fields (matchMethod, expectedValue, jsonPath), creating a potential behavioral mismatch between immediate UI feedback (onChange) and derived state (useEffect).
Suggested change
setMonitor((prev) => {
const updatedMonitor = { ...prev, [name]: value };
// Automatically check "Advanced matching" checkbox if user enters expectedValue or jsonPath
if ((name === "expectedValue" || name === "jsonPath") && value && value.trim()) {
setUseAdvancedMatching(true);
}
return updatedMonitor;
});
setMonitor((prev) => {
const updatedMonitor = { ...prev, [name]: value };
// Automatically check "Advanced matching" checkbox if user enters matchMethod, expectedValue, or jsonPath
if ((name === "matchMethod" || name === "expectedValue" || name === "jsonPath") && value && (typeof value === 'string' ? value.trim() : true)) {
setUseAdvancedMatching(true);
}
return updatedMonitor;
});

Comment on lines 305 to +313
useEffect(() => {
if (!isCreate || isClone) {
if (monitor.matchMethod) {
setUseAdvancedMatching(true);
} else {
setUseAdvancedMatching(false);
}
// Automatically check "Advanced matching" checkbox if any value exists in matchMethod, expectedValue, or jsonPath
if (monitor.matchMethod || monitor.expectedValue || monitor.jsonPath) {
setUseAdvancedMatching(true);
} else if (!isCreate || isClone) {
// Only uncheck when editing/cloning and no values exist
setUseAdvancedMatching(false);
}
}, [monitor, isCreate]);
}, [monitor.matchMethod, monitor.expectedValue, monitor.jsonPath, isCreate, isClone]);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 | Confidence: High

Speculative: The useEffect correctly handles the derived state based on field presence, but its dependency array may cause unnecessary re-renders. The logic conditionally calls setUseAdvancedMatching with the same value (true or false) on every dependency change, even when the resulting state wouldn't change (e.g., when useAdvancedMatching is already true and fields remain present). This could contribute to subtle performance issues in larger forms or with frequent typing. While React optimizes with batching, unnecessary state updates should be minimized for clarity and to prevent potential side-effects in more complex components.

Code Suggestion:

useEffect(() => {
  const hasAdvancedFields = !!(monitor.matchMethod || monitor.expectedValue || monitor.jsonPath);
  const shouldBeChecked = hasAdvancedFields || (!isCreate || isClone ? false : useAdvancedMatching);
  // Only update state if it would change
  if (shouldBeChecked !== useAdvancedMatching) {
    setUseAdvancedMatching(shouldBeChecked);
  }
}, [monitor.matchMethod, monitor.expectedValue, monitor.jsonPath, isCreate, isClone, useAdvancedMatching]);

Comment on lines +267 to +269
if ((name === "expectedValue" || name === "jsonPath") && value && value.trim()) {
setUseAdvancedMatching(true);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 | Confidence: Medium

Speculative: The validation value.trim() assumes value is always a string, which may not hold true for all form fields. If the codebase evolves and expectedValue or jsonPath could receive non-string values (e.g., numbers, arrays, null), calling .trim() would throw a runtime error (TypeError: value.trim is not a function). While the current context suggests these fields are text inputs, this assumption creates a brittle pattern that could break during future refactoring or if field types change. Defensive programming with type checking would improve robustness.

Suggested change
if ((name === "expectedValue" || name === "jsonPath") && value && value.trim()) {
setUseAdvancedMatching(true);
}
if ((name === "expectedValue" || name === "jsonPath") && value && typeof value === 'string' && value.trim()) {
setUseAdvancedMatching(true);
}

Comment on lines +309 to 312
} else if (!isCreate || isClone) {
// Only uncheck when editing/cloning and no values exist
setUseAdvancedMatching(false);
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 | Confidence: Medium

Speculative: The condition (!isCreate || isClone) has ambiguous logic. When isCreate is true (creating a new monitor) and isClone is false, the expression evaluates to (!true || false) = (false || false) = false, so the checkbox won't be unchecked—this seems correct for creation mode. However, when isCreate is false (editing) and isClone is true (cloning), the expression is (!false || true) = (true || true) = true, causing the checkbox to uncheck if no advanced fields exist. This might be intentional for cloning behavior, but the comment "Only uncheck when editing/cloning" doesn't clarify the nuance. The logic should be explicitly validated against the intended UX: Should a cloned monitor with no advanced fields start with the checkbox unchecked? If yes, the logic is correct but the comment should be more precise.

Code Suggestion:

} else if (!isCreate || isClone) {
  // Uncheck when editing (isCreate=false) OR when cloning (isClone=true), if no advanced fields exist
  setUseAdvancedMatching(false);
}

@Br0wnHammer
Copy link
Copy Markdown
Member

Closing as the repo went through major restructuring.

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.

Advanced Matching checkbox gets unchecked when typing in Expected Value field

2 participants