Skip to content

feat: emit null on empty text widget input for nullable columns#1740

Merged
lyubov-voloshko merged 2 commits into
mainfrom
feature/text-widget-nullable-empty-handling
Apr 27, 2026
Merged

feat: emit null on empty text widget input for nullable columns#1740
lyubov-voloshko merged 2 commits into
mainfrom
feature/text-widget-nullable-empty-handling

Conversation

@gugu
Copy link
Copy Markdown
Contributor

@gugu gugu commented Apr 27, 2026

Text widget now sends null to the backend when the user clears the field on a nullable column, and "" on a non-nullable column. Adds a new force_send_empty_string widget param (default false) to override the null conversion when callers want a literal empty string stored on a nullable column.

Summary by CodeRabbit

  • New Features
    • Added a new configuration option for text input fields that controls empty value handling. When enabled, clearing a field sends an empty string to the backend instead of a null value, even for nullable columns. This provides greater flexibility in form submission behavior.

Text widget now sends null to the backend when the user clears the
field on a nullable column, and "" on a non-nullable column. Adds a
new force_send_empty_string widget param (default false) to override
the null conversion when callers want a literal empty string stored
on a nullable column.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings April 27, 2026 12:20
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 27, 2026

📝 Walkthrough

Walkthrough

These changes introduce a force_send_empty_string configuration option for the text input widget. When enabled, empty string values are sent to the backend instead of being converted to null for nullable columns. The feature adds a new handleValueChange method and comprehensive test coverage.

Changes

Cohort / File(s) Summary
Widget Configuration
frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts
Extends String widget's default template with new force_send_empty_string boolean setting (default false) to control backend empty value handling behavior.
Text Component Implementation
frontend/src/app/components/ui-components/record-edit-fields/text/text.component.ts, frontend/src/app/components/ui-components/record-edit-fields/text/text.component.html
Adds forceSendEmptyString flag parsing from widget params; introduces handleValueChange method that conditionally converts empty strings to null based on nullability and flag state; updates template to invoke handler instead of direct event emission and refactors counter visibility condition logic.
Test Coverage
frontend/src/app/components/ui-components/record-edit-fields/text/text.component.spec.ts
Expands test suite with cases validating flag default behavior, null emission for nullable columns with flag unset, empty string emission when flag enabled or column non-nullable, and unchanged non-empty value propagation.

Estimated Code Review Effort

🎯 2 (Simple) | ⏱️ ~10 minutes

Poem

🐰 Hops with glee for empty strings so bright,
No more null confusion, the flag sets things right,
Force send those blanks with elegant flair,
A rabbit's blessing floats through the air!

🚥 Pre-merge checks | ✅ 5 | ❌ 1

❌ Failed checks (1 inconclusive)

Check name Status Explanation Resolution
Security Check ❓ Inconclusive Unable to access or review the TextEditComponent.handleValueChange implementation in frontend/src/app/components/ui-components/record-edit-fields/text/text.component.ts to verify force_send_empty_string flag enforcement and input validation. Obtain and review the actual source code from the specified file path to assess default parameter handling and injection prevention mechanisms.
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately describes the main behavioral change: emitting null on empty text widget input for nullable columns, which is the core feature introduced by this PR.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ 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 feature/text-widget-nullable-empty-handling

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

🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In
`@frontend/src/app/components/ui-components/record-edit-fields/text/text.component.html`:
- Line 12: The conditional expression in the template uses a flipped comparison
"100 > (maxLength - value().length)" which triggers HTMLHint for an unescaped
'>' and reduces readability; change it back to the previous form "(maxLength -
value().length) < 100" inside the same conditional (the line referencing
maxLength and value()) to silence the linter and restore clear "remaining chars
below threshold" semantics.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 81f8831f-950e-415a-b951-270aee4e1f0f

📥 Commits

Reviewing files that changed from the base of the PR and between bfcf7d7 and 8de836a.

📒 Files selected for processing (4)
  • frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts
  • frontend/src/app/components/ui-components/record-edit-fields/text/text.component.html
  • frontend/src/app/components/ui-components/record-edit-fields/text/text.component.spec.ts
  • frontend/src/app/components/ui-components/record-edit-fields/text/text.component.ts

[(ngModel)]="value" (ngModelChange)="onFieldChange.emit($event)">
@if (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) {
[(ngModel)]="value" (ngModelChange)="handleValueChange($event)">
@if (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) {
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 | 🟡 Minor

Restore the < form to silence HTMLHint and improve readability.

Flipping the comparison to 100 > (maxLength - value().length) makes HTMLHint flag the > as an unescaped special character (twice on this line). The previous form (maxLength - value().length) < 100 is semantically identical, avoids the lint error, and reads more naturally as "remaining chars below threshold."

🛠 Proposed fix
-    `@if` (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) {
+    `@if` (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) {
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
@if (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) {
`@if` (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) {
🧰 Tools
🪛 HTMLHint (1.9.2)

[error] 12-12: Special characters must be escaped : [ > ].

(spec-char-escape)


[error] 12-12: Special characters must be escaped : [ > ].

(spec-char-escape)

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

In
`@frontend/src/app/components/ui-components/record-edit-fields/text/text.component.html`
at line 12, The conditional expression in the template uses a flipped comparison
"100 > (maxLength - value().length)" which triggers HTMLHint for an unescaped
'>' and reduces readability; change it back to the previous form "(maxLength -
value().length) < 100" inside the same conditional (the line referencing
maxLength and value()) to silence the linter and restore clear "remaining chars
below threshold" semantics.

Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

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

Pull request overview

This PR updates the record-edit text field widget behavior so clearing an input on a nullable column emits null (instead of "") to the backend, with an opt-out widget parameter to force sending an empty string.

Changes:

  • Add force_send_empty_string widget param parsing and a handleValueChange handler to emit null on clear for nullable columns.
  • Update the text widget template to route changes through handleValueChange.
  • Add unit tests covering the new null/empty-string emission behavior and document the new widget param in the widgets settings template.

Reviewed changes

Copilot reviewed 4 out of 4 changed files in this pull request and generated 1 comment.

File Description
frontend/src/app/components/ui-components/record-edit-fields/text/text.component.ts Adds forceSendEmptyString param support and emits null on empty input for nullable columns.
frontend/src/app/components/ui-components/record-edit-fields/text/text.component.html Uses handleValueChange on ngModelChange to apply the new emission logic.
frontend/src/app/components/ui-components/record-edit-fields/text/text.component.spec.ts Adds tests for default param value and the new null/empty-string emission rules.
frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.ts Documents force_send_empty_string in the default widget params snippet for String/Text widget settings.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

[(ngModel)]="value" (ngModelChange)="onFieldChange.emit($event)">
@if (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) {
[(ngModel)]="value" (ngModelChange)="handleValueChange($event)">
@if (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) {
Copy link

Copilot AI Apr 27, 2026

Choose a reason for hiding this comment

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

The counter threshold condition uses a “Yoda-style” comparison (100 > ...), which is inconsistent with similar widgets (e.g., long-text uses (maxLength - value().length) < 100). Consider switching back to the existing style for consistency/readability.

Suggested change
@if (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) {
@if (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) {

Copilot uses AI. Check for mistakes.
@lyubov-voloshko lyubov-voloshko merged commit 7179e2e into main Apr 27, 2026
14 of 15 checks passed
@lyubov-voloshko lyubov-voloshko deleted the feature/text-widget-nullable-empty-handling branch April 27, 2026 13:26
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.

3 participants