feat: emit null on empty text widget input for nullable columns#1740
Conversation
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>
📝 WalkthroughWalkthroughThese changes introduce a Changes
Estimated Code Review Effort🎯 2 (Simple) | ⏱️ ~10 minutes Poem
🚥 Pre-merge checks | ✅ 5 | ❌ 1❌ Failed checks (1 inconclusive)
✅ Passed checks (5 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches📝 Generate docstrings
🧪 Generate unit tests (beta)
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. Comment |
There was a problem hiding this comment.
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
📒 Files selected for processing (4)
frontend/src/app/components/dashboard/db-table-view/db-table-widgets/db-table-widgets.component.tsfrontend/src/app/components/ui-components/record-edit-fields/text/text.component.htmlfrontend/src/app/components/ui-components/record-edit-fields/text/text.component.spec.tsfrontend/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)) { |
There was a problem hiding this comment.
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.
| @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.
There was a problem hiding this comment.
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_stringwidget param parsing and ahandleValueChangehandler to emitnullon 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)) { |
There was a problem hiding this comment.
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.
| @if (maxLength && maxLength > 0 && value() && 100 > (maxLength - value().length)) { | |
| @if (maxLength && maxLength > 0 && value() && (maxLength - value().length) < 100) { |
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