Skip to content

Bug fixes#824

Merged
JhumanJ merged 4 commits intomainfrom
238a6-bug-fixes
Jul 28, 2025
Merged

Bug fixes#824
JhumanJ merged 4 commits intomainfrom
238a6-bug-fixes

Conversation

@chiragchhatrala
Copy link
Copy Markdown
Collaborator

@chiragchhatrala chiragchhatrala commented Jul 23, 2025

Refactor OpenCompleteForm and index.vue for improved branding and app…… store integration

  • Replaced the branding link in OpenCompleteForm.vue with a PoweredBy component for better maintainability and consistency.
  • Updated the import path for the PoweredBy component to align with the new directory structure.
  • Integrated appStore.hideFeatureBaseButton() in index.vue to enhance user experience by managing feature visibility on page load.

These changes aim to streamline the form's branding presentation and improve the overall functionality of the public form page.

Summary by CodeRabbit

  • Refactor

    • Replaced hardcoded branding text with a reusable branding component for consistency and maintainability.
  • Chores

    • Updated import paths for improved code organization.
    • Added logic to hide an additional interface element when viewing form pages.
  • New Features

    • Introduced a character limit enforcement in the rich text editor to improve content control.

… store integration

- Replaced the branding link in `OpenCompleteForm.vue` with a `PoweredBy` component for better maintainability and consistency.
- Updated the import path for the `PoweredBy` component to align with the new directory structure.
- Integrated `appStore.hideFeatureBaseButton()` in `index.vue` to enhance user experience by managing feature visibility on page load.

These changes aim to streamline the form's branding presentation and improve the overall functionality of the public form page.
@chiragchhatrala chiragchhatrala requested a review from JhumanJ July 23, 2025 19:14
@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai bot commented Jul 23, 2025

"""

Walkthrough

The changes update the form completion component to use a reusable PoweredBy Vue component instead of hardcoded branding links and adjust its import path. The form page component now hides a feature base button on mount by invoking a method from the application store, alongside existing behavior. Additionally, the rich text editor component enforces a hard character limit by deleting excess input beyond the specified maximum.

Changes

File(s) Change Summary
Branding update
client/components/open/forms/OpenCompleteForm.vue
Replaced hardcoded branded link with reusable PoweredBy component; updated import path.
Form page lifecycle side effects
client/pages/forms/[slug]/index.vue
Added import and usage of appStore; now hides feature base button on mount and shows it on leave, alongside Crisp widget handling.
Rich text editor enhancement
client/components/forms/heavy/RichTextAreaInput.client.vue
Added max character limit enforcement by deleting excess text in Quill editor on text-change.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant FormPage (index.vue)
    participant appStore
    participant Crisp

    User->>FormPage: Page loads (mount)
    FormPage->>Crisp: Hide Crisp chat widget
    FormPage->>appStore: hideFeatureBaseButton()

    User->>FormPage: Navigates away (route leave)
    FormPage->>appStore: showFeatureBaseButton()
    FormPage->>Crisp: Show Crisp chat widget
Loading
sequenceDiagram
    participant User
    participant RichTextAreaInput
    participant QuillEditor

    User->>RichTextAreaInput: Types text
    RichTextAreaInput->>QuillEditor: text-change event
    QuillEditor->>RichTextAreaInput: Current content length
    RichTextAreaInput->>QuillEditor: Delete excess text if over maxCharLimit
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~15 minutes

Possibly related PRs

Poem

A bunny hops with code so neat,
Branding links now obsolete!
A button hides, a store invoked,
Vue components re-awoke.
Characters capped, no overflow,
The editor’s limits now in tow.
🐇✨
"""

Note

⚡️ Unit Test Generation is now available in beta!

Learn more here, or try it out under "Finishing Touches" below.


📜 Recent review details

Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 559f99d and 8bb1c69.

📒 Files selected for processing (1)
  • client/components/open/forms/OpenCompleteForm.vue (2 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/components/open/forms/OpenCompleteForm.vue
⏰ 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: Build the Nuxt app
  • GitHub Check: Run client linters
✨ Finishing Touches
🧪 Generate unit tests
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch 238a6-bug-fixes

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
🪧 Tips

Chat

There are 3 ways to chat with CodeRabbit:

  • Review comments: Directly reply to a review comment made by CodeRabbit. Example:
    • I pushed a fix in commit <commit_id>, please review it.
    • Explain this complex logic.
    • Open a follow-up GitHub issue for this discussion.
  • Files and specific lines of code (under the "Files changed" tab): Tag @coderabbitai in a new review comment at the desired location with your query. Examples:
    • @coderabbitai explain this code block.
    • @coderabbitai modularize this function.
  • PR comments: Tag @coderabbitai in a new PR comment to ask questions about the PR branch. For the best results, please provide a very specific query, as very limited context is provided in this mode. Examples:
    • @coderabbitai gather interesting stats about this repository and render them as a table. Additionally, render a pie chart showing the language distribution in the codebase.
    • @coderabbitai read src/utils.ts and explain its main purpose.
    • @coderabbitai read the files in the src/scheduler package and generate a class diagram using mermaid and a README in the markdown format.
    • @coderabbitai help me debug CodeRabbit configuration file.

Support

Need help? Create a ticket on our support page for assistance with any issues or questions.

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)

  • @coderabbitai pause to pause the reviews on a PR.
  • @coderabbitai resume to resume the paused reviews.
  • @coderabbitai review to trigger an incremental review. This is useful when automatic reviews are disabled for the repository.
  • @coderabbitai full review to do a full review from scratch and review all the files again.
  • @coderabbitai summary to regenerate the summary of the PR.
  • @coderabbitai generate docstrings to generate docstrings for this PR.
  • @coderabbitai generate sequence diagram to generate a sequence diagram of the changes in this PR.
  • @coderabbitai generate unit tests to generate unit tests for this PR.
  • @coderabbitai resolve resolve all the CodeRabbit review comments.
  • @coderabbitai configuration to show the current CodeRabbit configuration for the repository.
  • @coderabbitai help to get help.

Other keywords and placeholders

  • Add @coderabbitai ignore anywhere in the PR description to prevent this PR from being reviewed.
  • Add @coderabbitai summary to generate the high-level summary at a specific location in the PR description.
  • Add @coderabbitai anywhere in the PR title to generate the title automatically.

CodeRabbit Configuration File (.coderabbit.yaml)

  • You can programmatically configure CodeRabbit by adding a .coderabbit.yaml file to the root of your repository.
  • Please see the configuration documentation for more information.
  • 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

Documentation and Community

  • Visit our Documentation for detailed information on how to use CodeRabbit.
  • Join our Discord Community to get help, request features, and share feedback.
  • Follow us on X/Twitter for updates and announcements.

- Implemented a character limit feature in `RichTextAreaInput.client.vue` to restrict user input based on the `maxCharLimit` prop.
- Added an event listener to the Quill editor instance to delete excess text when the limit is exceeded.

These changes enhance user experience by preventing input overflow and ensuring compliance with character constraints.
Copy link
Copy Markdown
Contributor

@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: CodeRabbit UI
Review profile: CHILL
Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 752e416 and d456483.

📒 Files selected for processing (1)
  • client/components/forms/heavy/RichTextAreaInput.client.vue (1 hunks)
🧰 Additional context used
📓 Path-based instructions (4)
**/*.vue

📄 CodeRabbit Inference Engine (.cursor/rules/api-query.mdc)

In Vue components, use .mutateAsync().then().catch() for mutations to keep control flow explicit and avoid try/catch inside template methods.

Files:

  • client/components/forms/heavy/RichTextAreaInput.client.vue
client/**/*.{js,vue}

📄 CodeRabbit Inference Engine (.cursor/rules/front-end.mdc)

client/**/*.{js,vue}: Use functional and declarative programming patterns; avoid classes.
Use descriptive variable names with auxiliary verbs (e.g., isLoading, hasError).
For promises and async, always use ().then().error().finally() syntax over try/catch/await.
Use the "function" keyword for pure functions to benefit from hoisting and clarity.
Implement proper error boundaries or try-catch mechanisms to handle errors gracefully, especially in asynchronous operations.

Files:

  • client/components/forms/heavy/RichTextAreaInput.client.vue
client/**/*.vue

📄 CodeRabbit Inference Engine (.cursor/rules/front-end.mdc)

client/**/*.vue: Do not import Vue Reactivity APIs like ref or computed, as well as lifecycle hooks and helpers in .vue components, as they are auto-imported by Nuxt.
Always use the Vue Composition API script setup style. If a legacy file is still using options API and is short, directly update the script section. If it's longer and a bit more complex, make the required change using the existing options API and at the end ask if you should migrate to composition API.
Use Nuxt UI v3 components (e.g., , , , ) and Tailwind for components and styling. Use NuxtUI for everything except form components.
Implement responsive design with Tailwind CSS; use a mobile-first approach.
For icons, use the component, and for icon names always use i-library-icon syntax.
Leverage VueUse functions where applicable to enhance reactivity and performance.
Wrap asynchronous components in Suspense with a fallback UI made with components.
Use dynamic loading for non-critical components.

Files:

  • client/components/forms/heavy/RichTextAreaInput.client.vue
client/components/forms/**/*.vue

📄 CodeRabbit Inference Engine (.cursor/rules/front-end.mdc)

For form inputs, use the components in client/components/forms such as etc., and wrap them in @VForm.vue.

Files:

  • client/components/forms/heavy/RichTextAreaInput.client.vue
🧠 Learnings (1)
📓 Common learnings
Learnt from: JhumanJ
PR: JhumanJ/OpnForm#424
File: client/components/open/forms/components/FormEditor.vue:256-258
Timestamp: 2024-07-28T04:27:19.900Z
Learning: When setting properties like `no_branding` based on conditions, consider centralizing the logic in the parent component and passing it as a parameter to child components for better manageability.
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.{vue,js,ts} : Use form state properties: `form.busy`, `form.successful`, `form.recentlySuccessful`, `form.errors` for UI feedback and logic
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.vue : Use semantic HTML form elements in form templates
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.{vue,js,ts} : Use form methods: `form.data()`, `form.reset()`, `form.resetAndFill(data)`, `form.clear()`, `form.fill(data)` for managing form state
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.vue : Use placeholders and help text for guidance in input components
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.{vue,js,ts} : Use descriptive field names in form initialization that match API expectations
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.{vue,js,ts} : Always use `useForm()` composable for form state management
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/front-end.mdc:0-0
Timestamp: 2025-07-21T09:21:16.455Z
Learning: Applies to client/**/*.vue : Use Nuxt UI v3 components (e.g., <UModal>, <UPopover>, <UToolTip>, <UBadge>) and Tailwind for components and styling. Use NuxtUI for everything except form components.
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.vue : Pass `:form="form"` to all form input components
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.{vue,js,ts} : Initialize forms with default values to prevent reactivity issues
Learnt from: CR
PR: JhumanJ/OpnForm#0
File: .cursor/rules/forms.mdc:0-0
Timestamp: 2025-07-21T09:20:48.001Z
Learning: Applies to components/forms/**/*.vue : Use proper input types (`email`, `tel`, `url`, etc.) for accessibility and validation
⏰ 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). (1)
  • GitHub Check: Build the Nuxt app

Comment on lines +218 to +226

// Limit the number of characters
if (props.maxCharLimit) {
quillInstance.on('text-change', function() {
if (quillInstance.getLength() > props.maxCharLimit) {
quillInstance.deleteText(props.maxCharLimit, quillInstance.getLength())
}
})
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix the character limit implementation for better UX and accuracy.

The current implementation has several issues:

  1. Off-by-one error: Quill's getLength() includes a trailing newline character, so the actual character count should be getLength() - 1.
  2. Poor user experience: Hard deletion after typing creates a jarring experience where users lose text mid-keystroke.
  3. Formatting interference: Abrupt deletion could disrupt rich text formatting and mentions.

Consider this improved implementation:

  // Limit the number of characters
  if (props.maxCharLimit) {
-    quillInstance.on('text-change', function() {
-      if (quillInstance.getLength() > props.maxCharLimit) {
-        quillInstance.deleteText(props.maxCharLimit, quillInstance.getLength())
-      }
-    })
+    quillInstance.on('text-change', function(delta, oldDelta, source) {
+      if (source === 'user') {
+        const length = quillInstance.getLength() - 1 // Subtract trailing newline
+        if (length > props.maxCharLimit) {
+          quillInstance.deleteText(props.maxCharLimit, length)
+        }
+      }
+    })
+    
+    // Prevent typing when at limit
+    quillInstance.keyboard.addBinding({
+      key: /./,
+      handler: function(range, context) {
+        const length = quillInstance.getLength() - 1
+        if (length >= props.maxCharLimit && context.format === undefined) {
+          return false // Prevent default behavior
+        }
+        return true
+      }
+    })
  }

This approach:

  • Fixes the length calculation
  • Only applies to user-generated changes
  • Prevents typing when at the limit instead of deleting after
  • Maintains better user experience
📝 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
// Limit the number of characters
if (props.maxCharLimit) {
quillInstance.on('text-change', function() {
if (quillInstance.getLength() > props.maxCharLimit) {
quillInstance.deleteText(props.maxCharLimit, quillInstance.getLength())
}
})
}
// Limit the number of characters
if (props.maxCharLimit) {
quillInstance.on('text-change', function(delta, oldDelta, source) {
if (source === 'user') {
const length = quillInstance.getLength() - 1 // Subtract trailing newline
if (length > props.maxCharLimit) {
quillInstance.deleteText(props.maxCharLimit, length)
}
}
})
// Prevent typing when at limit
quillInstance.keyboard.addBinding({
key: /./,
handler: function(range, context) {
const length = quillInstance.getLength() - 1
if (length >= props.maxCharLimit && context.format === undefined) {
return false // Prevent default behavior
}
return true
}
})
}
🤖 Prompt for AI Agents
In client/components/forms/heavy/RichTextAreaInput.client.vue around lines 218
to 226, the character limit logic incorrectly counts characters due to Quill's
trailing newline and deletes text abruptly, harming UX and formatting. Fix this
by adjusting the length check to use getLength() - 1, listen only to
user-generated text changes, and prevent further input when the limit is reached
instead of deleting text after typing. This will improve accuracy and provide a
smoother user experience without disrupting formatting.

- Integrated `appStore.showFeatureBaseButton()` in `index.vue` to improve user experience by managing feature visibility when navigating away from the page.
- This change ensures that the feature base button is displayed appropriately, enhancing the overall functionality of the public form page.
Copy link
Copy Markdown
Collaborator

@JhumanJ JhumanJ left a comment

Choose a reason for hiding this comment

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

Like we used to do for the Navbar, need to show again feedback button when leaving the public form page

@JhumanJ JhumanJ merged commit 50d7485 into main Jul 28, 2025
6 checks passed
@JhumanJ JhumanJ deleted the 238a6-bug-fixes branch July 28, 2025 11:49
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.

2 participants