feat: character limitations to free text question#4047
feat: character limitations to free text question#4047gupta-piyush19 merged 47 commits intoformbricks:mainfrom
Conversation
|
@DeepaPrasanna is attempting to deploy a commit to the formbricks Team on Vercel. A member of the Team first needs to authorize it. |
WalkthroughThe pull request introduces significant modifications to enhance character limit management for open text questions within the survey editor. Key changes include the addition of two state variables, The Assessment against linked issues
Possibly related PRs
Suggested labels
Suggested reviewers
Thank you for using CodeRabbit. We offer it for free to the OSS community and would appreciate your support in helping us grow. If you find it useful, would you consider giving us a shout-out on your favorite social media? 🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
|
Thank you for following the naming conventions for pull request titles! 🙏 |
There was a problem hiding this comment.
Actionable comments posted: 2
🧹 Outside diff range and nitpick comments (3)
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx (2)
73-74: Implementation matches requirements but could be more flexible.The addition of character limits aligns with the PR objectives. However, consider the following improvements:
- Make the limits configurable via props instead of hardcoding:
interface OpenQuestionFormProps { + headlineMaxLength?: number; + headlineMinLength?: number; // ... other props } // In component <QuestionFormInput // ... other props - maxLength={50} - minLength={3} + maxLength={props.headlineMaxLength ?? 50} + minLength={props.headlineMinLength ?? 3} />
73-74: Enhance user experience with character limit feedback.Users should be informed about the character limitations before hitting the limits.
Consider adding:
- Character count display
- Visual feedback when approaching limits
- Clear validation messages
Would you like me to provide an example implementation of these UX enhancements?
packages/ui/components/QuestionFormInput/index.tsx (1)
Line range hint
1-658: Consider adding unit tests for character limitations.The implementation of character limitations is a critical feature that should be thoroughly tested.
Would you like me to help create unit tests for:
- Minimum length validation
- Maximum length validation
- Error message display
- Initial state validation
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
- apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx (1 hunks)
- packages/ui/components/QuestionFormInput/index.tsx (5 hunks)
🔇 Additional comments (3)
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx (1)
73-74: Verify character limit handling in QuestionFormInput component.Let's ensure the QuestionFormInput component properly handles these new props.
✅ Verification successful
QuestionFormInput component properly handles maxLength and minLength props
The verification confirms that the QuestionFormInput component correctly implements both maxLength and minLength validation:
- Props are properly defined in the interface and passed through to the component
- The component implements minLength validation through state management:
if (minLength && value.length < minLength) { SetHasMinChars(false); } else { SetHasMinChars(true); }- Both props are correctly passed to the underlying Input component:
maxLength={maxLength ?? undefined} minLength={minLength ?? undefined}- Invalid state is properly handled when minLength requirement isn't met:
isInvalid={!!(... || (minLength && !hasMinChars))}The implementation is complete and handles the character limits as expected.
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Search for QuestionFormInput implementation to verify proper handling of maxLength and minLength ast-grep --pattern 'interface QuestionFormInputProps { $$$ }' # Search for validation logic rg -A 5 'maxLength|minLength' --type typescriptLength of output: 2133
Script:
#!/bin/bash # Search for the implementation of QuestionFormInput to verify how maxLength and minLength are used ast-grep --pattern 'function QuestionFormInput({$$$}) { $$$ }' # Search for validation logic with proper file type rg -A 5 'maxLength|minLength' --type ts --type tsxLength of output: 147
Script:
#!/bin/bash # Let's try to find the QuestionFormInput implementation and its usage of maxLength/minLength cat packages/ui/components/QuestionFormInput/index.tsx # Also search for any validation logic using ripgrep without file type specification rg -A 5 'maxLength|minLength'Length of output: 34506
packages/ui/components/QuestionFormInput/index.tsx (2)
62-63: LGTM: Props interface changes look good.The addition of optional
minLengthandmaxLengthproperties toQuestionFormInputPropsinterface is well-structured and follows TypeScript best practices.
592-592: 🛠️ Refactor suggestionVerify error message display for minLength validation.
The
isInvalidprop logic has been updated to include minLength validation, but there's no visible error message specifically for the minimum length requirement. Users won't know why their input is invalid.Let's check if there are any error message components in the codebase:
Consider adding an error message for minimum length validation:
+ {minLength && !hasMinChars && ( + <div className="mt-1 text-xs text-red-400"> + Minimum {minLength} characters required + </div> + )}Also applies to: 594-600
There was a problem hiding this comment.
Actionable comments posted: 2
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (1)
- packages/ui/components/QuestionFormInput/index.tsx (5 hunks)
🔇 Additional comments (2)
packages/ui/components/QuestionFormInput/index.tsx (2)
62-63: LGTM: Interface changes are well-defined.The new optional properties
minLengthandmaxLengthare properly typed and follow TypeScript conventions.
488-491: LGTM: Clean validation logic.The minLength validation is implemented correctly and provides real-time feedback.
There was a problem hiding this comment.
Actionable comments posted: 7
🧹 Outside diff range and nitpick comments (1)
packages/types/surveys/types.ts (1)
478-479: Add validation rules for length constraints.
The implementation of minLength and maxLength properties aligns with the PR objectives. However, consider adding validation rules to ensure data integrity.
Apply this diff to add validation rules:
- minLength: z.number().optional(),
- maxLength: z.number().optional(),
+ minLength: z.number().min(0).optional(),
+ maxLength: z.number().min(1).optional(),Also consider adding a .superRefine() to validate that maxLength is greater than minLength when both are provided:
}).superRefine((val, ctx) => {
if (val.minLength !== undefined && val.maxLength !== undefined && val.minLength >= val.maxLength) {
ctx.addIssue({
code: z.ZodIssueCode.custom,
message: "Maximum length must be greater than minimum length",
path: ["maxLength"],
});
}
});📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (3)
- apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx (3 hunks)
- packages/surveys/src/components/questions/OpenTextQuestion.tsx (3 hunks)
- packages/types/surveys/types.ts (1 hunks)
🔇 Additional comments (3)
packages/surveys/src/components/questions/OpenTextQuestion.tsx (1)
Line range hint 95-137: Verify character limit constraints from PR objectives.
The PR objectives specify min=3 and max=50 characters, but the implementation allows for flexible limits. We should verify if these constraints are enforced at the schema/form level.
apps/web/app/(app)/(survey-editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx (2)
5-5: Imports are correctly added.
The import statements for useState, AdvancedOptionToggle, and Input are properly added and will allow the component to utilize state management and UI elements for the new features.
Also applies to: 13-13, 15-15
60-61: 🛠️ Refactor suggestion
Confirm resetting minLength and maxLength on input type change.
When the inputType changes, minLength and maxLength are set to undefined. If the user switches back to a text input, their previously entered character limits will be lost.
Consider preserving the character limit values when toggling between input types or informing the user that their character limits will be reset.
...editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx
Show resolved
Hide resolved
...editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx
Outdated
Show resolved
Hide resolved
...editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx
Outdated
Show resolved
Hide resolved
...editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx
Outdated
Show resolved
Hide resolved
...editor)/environments/[environmentId]/surveys/[surveyId]/edit/components/OpenQuestionForm.tsx
Outdated
Show resolved
Hide resolved
|
The UX isn't ideal, mostly because people who'd fill out the survey when it has a max count are not informed that they've reached the max limit. But this is a design short-coming on my end, so here are /award 750 thanks a lot for your good work! |
|
Awarding DeepaPrasanna: 750 points 🕹️ Well done! Check out your new contribution on oss.gg/DeepaPrasanna |
There was a problem hiding this comment.
Actionable comments posted: 0
🧹 Outside diff range and nitpick comments (1)
packages/lib/survey/tests/__mock__/survey.mock.ts (1)
163-165: LGTM with a suggestion for test coverage.The
charLimitproperty is consistently implemented across all open text questions with appropriate structure. However, consider enhancing test coverage:Consider adding test cases with
charLimit.enabled: trueand various character limit values to ensure the feature works correctly when enabled. For example:{ id: "q1", type: TSurveyQuestionTypeEnum.OpenText, inputType: "text", headline: { default: "What is your favorite color?" }, required: true, charLimit: { - enabled: false + enabled: true, + minCharacters: 3, + maxCharacters: 50 },Also applies to: 316-318, 344-346, 378-380, 442-444
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
packages/lib/response/tests/__mocks__/data.mock.ts(1 hunks)packages/lib/survey/tests/__mock__/survey.mock.ts(5 hunks)
🔇 Additional comments (1)
packages/lib/response/tests/__mocks__/data.mock.ts (1)
403-405: LGTM: Character limit property correctly structured.
The addition of the charLimit property with enabled: false is well-structured and provides appropriate default values for testing backward compatibility.
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (2)
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts (1)
Line range hint
54-439: Consider adding validation rules in templatesWhile the character limit infrastructure is in place, consider pre-configuring some templates with enabled character limits and reasonable defaults based on their specific use cases. For example:
- NPS feedback questions might benefit from a maximum limit to encourage concise feedback
- CSAT improvement suggestions could have a minimum limit to ensure meaningful responses
Example for NPS survey's second question:
{ id: createId(), type: TSurveyQuestionTypeEnum.OpenText, headline: { default: translate("nps_survey_question_2_headline", locale) }, required: false, inputType: "text", charLimit: { - enabled: false, + enabled: true, + max: 500 // Set a reasonable maximum for detailed feedback }, },packages/lib/templates.ts (1)
OpenText questions need character limit configuration update
The implementation needs to be modified to include proper character limits. According to the type definition:
charLimitshould be an object with:
enabled: true(to enable the limits)min: 3(minimum 3 characters)max: 50(maximum 50 characters)The current implementation only sets
enabled: falsewhich effectively disables character limits. This should be updated to:charLimit: { enabled: true, min: 3, max: 50 }🔗 Analysis chain
Line range hint
1-6972: Verify the implementation aligns with requirements.The current implementation adds the charLimit property with
enabled: falseto all OpenText questions. However, according to the PR objectives, there should be:
- A maximum length of 50 characters
- A minimum length of 3 characters
Let's verify if we need additional properties for min/max limits:
The search results reveal important context about character limits in the codebase:
- The types definition in
packages/types/surveys/types.tsshows that charLimit is an object that can haveminandmaxproperties- The OpenTextQuestion component in
packages/surveys/src/components/questions/OpenTextQuestion.tsximplements these limits usingminlengthandmaxlengthHTML attributes- The UI in
apps/web/app/(app)/(survey-editor)/.../OpenQuestionForm.tsxshows there's a toggle and inputs for setting character limitsLet's verify the exact type definition to understand the required structure:
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash # Description: Check if any OpenText questions have min/max character limits defined # Search for charLimit configurations that might include min/max rg -A 5 'charLimit:\s*{' # Search for any other character limit related configurations rg -i 'char.*limit|min.*length|max.*length'Length of output: 17809
Script:
#!/bin/bash # Get the charLimit type definition rg -A 10 'charLimit: z\.object' packages/types/surveys/types.tsLength of output: 480
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (2)
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts(7 hunks)packages/lib/templates.ts(81 hunks)
🔇 Additional comments (2)
apps/web/app/(app)/(onboarding)/environments/[environmentId]/xm-templates/lib/xm-templates.ts (2)
Line range hint 1-459: Verify error handling and type definitions
The implementation maintains existing error handling patterns. However, we should verify that the type system properly enforces the new charLimit property structure.
Let's check the type definitions and their usage:
✅ Verification successful
Type definitions and error handling are properly implemented
The verification shows that:
- The
charLimitproperty is properly typed inpackages/types/surveys/types.tswith Zod schema validation - Error handling for
charLimitincludes validation for:- Enabled state with undefined min/max
- Negative values
- Min greater than max
- The implementation across all survey templates consistently follows the type structure
- No type assertions or bypasses are used with
charLimit
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify type definitions and their usage across the codebase
# Check if charLimit is properly typed in the schema
rg -p 'charLimit.*{' --type typescript
# Look for any type-related comments or TODOs
rg -p 'TODO.*type' --type typescript
# Check for any type assertion usage that might bypass type safety
rg -p 'as.*{.*charLimit' --type typescript
Length of output: 351
Script:
#!/bin/bash
# Search for charLimit type definitions and usage
rg -p "charLimit" --type ts
# Search for OpenText question type definitions
ast-grep --pattern 'type TSurveyQuestion = {
$$$
charLimit?: $_
$$$
}'
# Search for any type errors or warnings in comments
rg -p "(TODO|FIXME|NOTE).*type" --type ts
# Look for type assertions related to charLimit
rg -p "as.*charLimit" --type ts
Length of output: 5637
54-56: LGTM! Consistent implementation of character limit property across all templates.
The changes systematically add the charLimit property to all OpenText questions across different survey templates, with a consistent default state of enabled: false. This aligns well with the PR objectives and provides a uniform foundation for character limit functionality.
Let's verify the type safety of these changes:
Also applies to: 64-66, 165-167, 254-256, 265-267, 296-298, 397-399, 427-429, 437-439
✅ Verification successful
Based on the search results, I can see that:
- The OpenText question type is properly defined in the types with a charLimit property that includes enabled, min, and max fields.
- The charLimit property is validated in the ZSurveyOpenTextQuestion schema with proper validation rules.
- The type definition shows that charLimit.enabled defaults to false, which matches the implementation in the review.
Implementation of charLimit property is type-safe and consistent
The charLimit property implementation in the OpenText questions is properly typed and follows the schema definition:
- Property structure matches the type definition:
{ enabled: boolean, min?: number, max?: number } - Default value of
enabled: falsealigns with the schema - Schema includes validation rules for min/max values when enabled is true
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify that all OpenText questions have the charLimit property
# and that the types are properly defined
# Search for OpenText type questions to ensure all have charLimit property
ast-grep --pattern 'type: TSurveyQuestionTypeEnum.OpenText'
# Check if the TSurveyQuestionTypeEnum and related types are properly updated
rg -A 10 'interface.*OpenText.*{'
Length of output: 205
Script:
#!/bin/bash
# Let's fix the regex and search patterns
# Search for OpenText type questions
rg "type: .*OpenText"
# Check interfaces and types related to OpenText
rg "interface.*OpenText"
# Search for charLimit property definitions
rg "charLimit.*enabled"
# Look for type definitions
fd "types?.ts" --exec cat {}
Length of output: 74798
…feat/char-limit-to-text
…feat/char-limit-to-text
…feat/char-limit-to-text
There was a problem hiding this comment.
Actionable comments posted: 1
🧹 Outside diff range and nitpick comments (3)
packages/js/index.html (1)
10-10: Consider using environment variables for configuration.Hardcoding environment IDs directly in source files can lead to accidental commits of development configurations. Consider using environment variables or configuration files to manage these values.
packages/surveys/src/components/questions/open-text-question.tsx (2)
116-117: Add aria attributes for accessibility.Consider adding aria attributes to improve accessibility when character limits are enabled:
minlength={question.inputType === "text" ? question.charLimit?.min : undefined} maxlength={question.inputType === "text" ? question.charLimit?.max : undefined} +aria-describedby={`${question.id}-char-limit`}Also applies to: 140-141
144-149: Enhance character count UX.The current implementation only shows the count when approaching the maximum. Consider:
- Always showing the count when limits are enabled
- Adding a more descriptive message when limit is reached
-{question.inputType === "text" && question.charLimit?.max !== undefined && ( +{question.inputType === "text" && question.charLimit?.enabled && ( <span + id={`${question.id}-char-limit`} className={`fb-text-xs ${ currentLength >= question.charLimit?.max - ? "fb-text-red-500 font-semibold" + ? "fb-text-red-500 font-semibold" : "text-neutral-400"}`}> - {currentLength}/{question.charLimit?.max} + {currentLength >= question.charLimit?.max + ? `Maximum ${question.charLimit.max} characters reached` + : `${currentLength}/${question.charLimit.max} characters`} </span> )}
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
📒 Files selected for processing (7)
apps/web/playwright/api/management/survey.spec.ts(1 hunks)packages/js/index.html(1 hunks)packages/lib/messages/de-DE.json(2 hunks)packages/lib/messages/en-US.json(2 hunks)packages/lib/messages/fr-FR.json(2 hunks)packages/lib/messages/pt-BR.json(2 hunks)packages/surveys/src/components/questions/open-text-question.tsx(4 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/lib/messages/fr-FR.json
🧰 Additional context used
📓 Learnings (1)
packages/surveys/src/components/questions/open-text-question.tsx (2)
Learnt from: DeepaPrasanna
PR: formbricks/formbricks#4047
File: packages/surveys/src/components/questions/OpenTextQuestion.tsx:136-137
Timestamp: 2024-11-12T04:24:22.684Z
Learning: In the `OpenTextQuestion` component, using camelCase `minLength` and `maxLength` attributes in React can cause undefined values to default to `0`, preventing user input. Therefore, it's acceptable to use lowercase `minlength` and `maxlength` attributes to avoid this issue.
Learnt from: DeepaPrasanna
PR: formbricks/formbricks#4047
File: packages/surveys/src/components/questions/OpenTextQuestion.tsx:113-114
Timestamp: 2024-11-12T04:24:22.684Z
Learning: When setting `minLength` and `maxLength` attributes in React components, passing `undefined` can result in them being set to `0`, which can prevent user input. Use conditional rendering to apply these attributes only when their values are defined.
🔇 Additional comments (4)
packages/surveys/src/components/questions/open-text-question.tsx (1)
45-45: LGTM: State initialization looks good.
The currentLength state is properly initialized with the existing value length, with a fallback to 0.
packages/lib/messages/en-US.json (1)
246-246: Translations for character limits feature look good!
The translations are clear, concise and appropriately placed in their respective sections:
- Common section: "maximum" and "minimum" for reuse
- Surveys section: Toggle specific texts with clear descriptions
Also applies to: 252-252, 1366-1367
packages/lib/messages/pt-BR.json (1)
246-246: LGTM! The new translations for character limits are well-implemented.
The added translations are grammatically correct and maintain consistency with the existing tone. The translations accurately convey the meaning of:
- Maximum/minimum values
- Character limit toggle functionality
- Description of the feature's purpose
Let's verify these translations are used consistently across the codebase:
Also applies to: 252-252, 1366-1367
✅ Verification successful
The character limit translations are correctly implemented and used consistently
The verification shows that:
- The new Portuguese translations align with existing translations in other language files (en-US, fr-FR, de-DE)
- The translation keys are actively used in the OpenQuestionForm component
- The implementation maintains consistency across the internationalization system
🏁 Scripts executed
The following scripts were executed for the analysis:
Script:
#!/bin/bash
# Description: Verify the usage of new character limit translations
# Test: Search for character limit related keys in other language files and components
rg -g '!pt-BR.json' "character_limit_toggle"
Length of output: 1157
packages/lib/messages/de-DE.json (1)
246-246: LGTM! The German translations for character limits look good.
The translations are properly added to the common section and use appropriate German terms for "maximum" and "minimum".
Also applies to: 252-252






What does this PR do?
Fixes #3798
Given max length as 50 chars and min length as 3 chars. Please let me know if I need to change that.
https://www.loom.com/share/e53065dde39f40cd90a7f91dfefedef7?sid=493a8157-0972-48fe-ac5d-bd1c2956b598
Note: Please excuse the error shown at the last seconds in the video. The server kills frequently due to low ram issue, thats why the error failed to fetch shows
How should this be tested?
Checklist
Required
pnpm buildconsole.logsgit pull origin mainAppreciated
Summary by CodeRabbit
New Features
Bug Fixes
Documentation
Chores