Skip to content

Conversation

@jvega190
Copy link
Member

@jvega190 jvega190 commented Sep 30, 2025

craftercms/craftercms#7418

Summary by CodeRabbit

  • New Features

    • Added validation for required checkboxes to enforce selection and show messages.
  • Bug Fixes

    • Checkboxes correctly respect read-only state.
    • Fields now treat empty/absent boolean inputs as unset rather than false, and initialize from field defaults only when appropriate to avoid unintended selections.

@coderabbitai
Copy link

coderabbitai bot commented Sep 30, 2025

Walkthrough

Checkbox control now computes readonly using isFieldReadOnly(field, formReadonly) (prop renamed), value retrieval logic was tightened to only use non-empty defaults, a JSDoc was added for boolean extraction, and a new exported checkboxValidator was introduced and wired into validatorsMap.

Changes

Cohort / File(s) Summary
FormsEngine Checkbox control
ui/app/src/components/FormsEngine/controls/Checkbox.tsx
- Import isFieldReadOnly and rename incoming prop readonlyformReadonly.
- Compute readonly with isFieldReadOnly(field, formReadonly); local value initialization now uses valueProp or field.defaultValue with nnou/nou checks and sets via useEffect when needed.
FormsEngine value retrievers
ui/app/src/components/FormsEngine/lib/valueRetrievers.ts
- retrieveFieldValue only substitutes field.defaultValue when the default is present/non-empty (avoids always substituting).
- Added descriptive JSDoc above booleanFieldExtractor describing its behavior with boolean and string inputs; return type in code unchanged.
FormsEngine validators
ui/app/src/components/FormsEngine/lib/validators.ts
- Added exported checkboxValidator(field, currentValue, messages): boolean enforcing required-checkbox rule and pushing a message when unchecked.
- Wired 'checkbox' in validatorsMap to call checkboxValidator (casts currentValue to boolean).

Sequence Diagram(s)

sequenceDiagram
  autonumber
  participant UI as Checkbox Component
  participant Field as Field Meta
  participant Form as FormsEngine State

  Note over UI,Field: Render / init
  UI->>Field: read defaultValue and metadata
  UI->>UI: compute readonly = isFieldReadOnly(field, formReadonly)
  alt valueProp present (nnou)
    UI->>UI: localValue = valueProp
  else
    UI->>UI: localValue = field.defaultValue (if non-empty)
    UI->>Form: useEffect -> setValue(defaultValue) (when initialized)
  end
  UI->>Form: onChange -> setValue(e.target.checked)
Loading
sequenceDiagram
  autonumber
  participant Src as Source Value
  participant VR as booleanFieldExtractor

  Src-->>VR: value (boolean | string | undefined | '')
  VR-->>Src: process per JSDoc and return boolean (implementation unchanged)
Loading
sequenceDiagram
  autonumber
  participant Validator as validatorsMap
  participant CheckboxVal as checkboxValidator
  participant Field as Field Meta

  Validator->>CheckboxVal: invoke (field, currentValue as boolean, messages)
  alt field.required and currentValue === false
    CheckboxVal->>Validator: push message, return false
  else
    CheckboxVal->>Validator: return true
  end
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Pre-merge checks and finishing touches

❌ Failed checks (2 warnings)
Check name Status Explanation Resolution
Description Check ⚠️ Warning The pull request description only contains a URL link to the issue (craftercms/craftercms#7418) without any additional context or explanation of what changes are included in the PR. While the template requires either a ticket reference or a full description, providing only a bare link falls short of being "mostly complete." The description lacks meaningful information about the specific changes made, their purpose, or how they implement the checkbox control functionality that the changes clearly demonstrate.
Docstring Coverage ⚠️ Warning Docstring coverage is 33.33% which is insufficient. The required threshold is 80.00%. You can run @coderabbitai generate docstrings to improve docstring coverage.
✅ Passed checks (1 passed)
Check name Status Explanation
Title Check ✅ Passed The pull request title "[7418] FE2- Checkbox control" directly relates to the changeset, which implements checkbox control functionality including modifications to the Checkbox component, addition of checkbox validation logic, and improvements to field readiness handling. The title clearly identifies the main focus area and is consistent with the changes across multiple files (Checkbox.tsx, valueRetrievers.ts, and validators.ts). The inclusion of the ticket reference [7418] provides traceability to the original issue.
✨ Finishing touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

📜 Recent review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 9a3aa1a and 3c10496.

📒 Files selected for processing (1)
  • ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • ui/app/src/components/FormsEngine/lib/valueRetrievers.ts
⏰ 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: Travis CI - Pull Request
  • GitHub Check: Codacy Static Code Analysis

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

@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: 2

📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between f06daa4 and ef445bf.

📒 Files selected for processing (2)
  • ui/app/src/components/FormsEngine/controls/Checkbox.tsx (1 hunks)
  • ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (1 hunks)
🧰 Additional context used
🧬 Code graph analysis (2)
ui/app/src/components/FormsEngine/controls/Checkbox.tsx (2)
ui/app/src/components/FormsEngine/types.ts (1)
  • ControlProps (23-30)
ui/app/src/utils/object.ts (1)
  • nnou (141-143)
ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (1)
ui/app/src/utils/object.ts (1)
  • nnou (141-143)
⏰ 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: Codacy Static Code Analysis
  • GitHub Check: Travis CI - Pull Request

@jvega190 jvega190 changed the title [7418] Checkbox control [7418] FE2- Checkbox control Oct 6, 2025
…o feature/checkbox

# Conflicts:
#	ui/app/src/components/FormsEngine/lib/valueRetrievers.ts
…FieldValue to omit empty strings as defaultValue
Copy link

@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

♻️ Duplicate comments (1)
ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (1)

195-198: Fix the return type mismatch in booleanFieldExtractor.

Line 196 declares the return type as boolean, but line 197 returns null when the value is empty or not set. This creates a type mismatch that will fail strict null checks.

Apply this diff to fix the return type:

-export function booleanFieldExtractor(value: unknown): boolean {
+export function booleanFieldExtractor(value: unknown): boolean | null {
 	return nnou(value) && value !== '' ? value === true || value === 'true' : null;
 }
🧹 Nitpick comments (1)
ui/app/src/components/FormsEngine/lib/validators.ts (1)

35-35: Consider updating the type cast to reflect nullable boolean values.

The cast currentValue as boolean is misleading since booleanFieldExtractor returns boolean | null (null when the value is empty or not set). While the validator logic correctly handles null via !currentValue, the type annotation doesn't reflect reality.

Apply this diff to make the type more accurate:

-	checkbox: (field, currentValue, messages) => checkboxValidator(field, currentValue as boolean, messages),
+	checkbox: (field, currentValue, messages) => checkboxValidator(field, currentValue as boolean | null, messages),

And update the validator signature:

-export function checkboxValidator(field: ContentTypeField, currentValue: boolean, messages: FieldValidityMessage[]) {
+export function checkboxValidator(field: ContentTypeField, currentValue: boolean | null, messages: FieldValidityMessage[]) {
📜 Review details

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 67d11a9 and 9a3aa1a.

📒 Files selected for processing (3)
  • ui/app/src/components/FormsEngine/controls/Checkbox.tsx (1 hunks)
  • ui/app/src/components/FormsEngine/lib/validators.ts (2 hunks)
  • ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (2 hunks)
🧰 Additional context used
🧬 Code graph analysis (3)
ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (1)
ui/app/src/utils/object.ts (1)
  • nnou (141-143)
ui/app/src/components/FormsEngine/controls/Checkbox.tsx (2)
ui/app/src/components/FormsEngine/types.ts (1)
  • ControlProps (23-30)
ui/app/src/components/FormsEngine/lib/formUtils.tsx (1)
  • isFieldReadOnly (764-766)
ui/app/src/components/FormsEngine/lib/validators.ts (1)
ui/app/src/models/ContentType.ts (1)
  • ContentTypeField (64-142)
⏰ 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: Codacy Static Code Analysis
  • GitHub Check: Travis CI - Pull Request
🔇 Additional comments (2)
ui/app/src/components/FormsEngine/lib/validators.ts (1)

107-116: LGTM! Checkbox validation logic is correct.

The validator correctly enforces that required checkboxes must be checked (truthy). The condition !currentValue appropriately handles null (from booleanFieldExtractor when no value is set) and false (unchecked).

ui/app/src/components/FormsEngine/lib/valueRetrievers.ts (1)

154-154: LGTM! Default value handling is now more precise.

The updated logic correctly falls back to defaultValue only when it's non-null/non-undefined and not an empty string, otherwise undefined. This prevents empty strings from being treated as meaningful defaults.

@jvega190 jvega190 marked this pull request as ready for review October 22, 2025 17:45
@jvega190 jvega190 requested a review from rart as a code owner October 22, 2025 17:45
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