Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance form submissions column management #691

Merged
merged 3 commits into from
Feb 12, 2025

Conversation

chiragchhatrala
Copy link
Collaborator

@chiragchhatrala chiragchhatrala commented Feb 3, 2025

Summary by CodeRabbit

  • New Features
    • Introduced a new "Settings Modal" for managing form columns, enhancing organization and usability.
    • Added dynamic text wrapping functionality to table columns, improving content readability.
    • Implemented a custom button group for record operations, streamlining user interactions with edit and delete actions.

Copy link
Contributor

coderabbitai bot commented Feb 3, 2025

Warning

Rate limit exceeded

@JhumanJ has exceeded the limit for the number of commits or files that can be reviewed per hour. Please wait 15 minutes and 56 seconds before requesting another review.

⌛ How to resolve this issue?

After the wait time has elapsed, a review can be triggered using the @coderabbitai review command as a PR comment. Alternatively, push new commits to this PR.

We recommend that you space out your commits to avoid hitting the rate limit.

🚦 How do rate limits work?

CodeRabbit enforces hourly rate limits for each developer per organization.

Our paid plans have higher rate limits than the trial, open-source and free plans. In all cases, we re-allow further reviews after a brief timeout.

Please see our FAQ for further information.

📥 Commits

Reviewing files that changed from the base of the PR and between eac8fc8 and 138ac87.

📒 Files selected for processing (1)
  • client/components/open/forms/components/FormSubmissions.vue (9 hunks)

Walkthrough

The pull request updates several UI components by introducing a new text wrapping functionality. The FormSubmissions component's modal is restructured and renamed to Settings Modal, now implemented as a separate component called FormColumnsSettingsModal. It enhances column management with new properties for display and wrapping states. The OpenTable component also receives a new wrapColumns prop to conditionally apply text wrapping styles to table cells.

Changes

File(s) Summary
client/components/open/forms/.../FormSubmissions.vue Restructured modal into a new component FormColumnsSettingsModal, renamed modal, added properties for display and wrap states, introduced wrapColumns data property, and removed unused methods.
client/components/open/tables/OpenTable.vue Added a new prop wrapColumns (defaulting to an empty object) to conditionally apply classes (whitespace-normal break-words) to table cells based on the wrapping state of each column.
client/components/open/components/RecordOperations.vue Replaced standard <button> elements with a custom <UButtonGroup> containing two <UButton> components for edit and delete actions, updating their properties for size and icons.
client/components/open/forms/components/FormColumnsSettingsModal.vue Introduced a new modal component for managing column settings, including toggle switches for display and wrap states, computed properties for managing form properties, and logic for preserving column widths.

Sequence Diagram(s)

sequenceDiagram
    participant User
    participant Modal as FormSubmissionsModal
    participant Toggle as ToggleSwitchInput

    User->>Modal: Open modal
    Modal->>Toggle: Render display and wrap toggles
    User->>Toggle: Toggle display/wrap option
    Toggle-->>Modal: Update displayColumns/wrapColumns state
    Modal->>Modal: Recompute sections for UI update
Loading
sequenceDiagram
    participant OpenTable
    participant TableCell

    OpenTable->>TableCell: Check wrapColumns[col.id]
    alt wrapColumns[col.id] is true
        TableCell-->>OpenTable: Apply text wrap classes
    else
        TableCell-->>OpenTable: Render normally
    end
Loading

Possibly Related PRs

  • Matrix Improvements #606 – Addresses similar text wrapping functionality with wrapColumns in form and table components.
  • Form editor v2 #579 – Involves adjustments to how text wrapping is managed, linking the FormSubmissions and OpenTable changes.
  • improve RTL mode #625 – Related to the modifications in the OpenTable component where the wrapColumns property is introduced for managing text wrapping.

Poem

Oh, I’m a bunny hopping through the code,
With toggles and grids lighting up my node.
Fields now dance in a wrapped embrace,
Columns managed with such style and grace.
Carrots and code, a delightful abode!
🥕💻
Hop on board, for a joyous reload!


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?

❤️ 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.
    • Generate unit testing code for this file.
    • 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 generate unit testing code for this file.
    • @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 generate unit testing code.
    • @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.

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. (Beta)
  • @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.

Copy link
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

🔭 Outside diff range comments (1)
client/components/open/forms/components/FormSubmissions.vue (1)

279-306: Initialize and persist wrap column settings.

The wrapColumns settings should be initialized and persisted similar to displayColumns for consistency across sessions.

Update the initialization logic:

 initFormStructure() {
   // ... existing code ...

   // Get display columns from local storage
   const tmpColumns = window.localStorage.getItem('display-columns-formid-' + this.form.id)
   if (tmpColumns !== null && tmpColumns) {
     this.displayColumns = JSON.parse(tmpColumns)
     this.onChangeDisplayColumns()
   } else {
     this.properties.forEach((field) => {
       this.displayColumns[field.id] = true
     })
   }

+  // Get wrap columns from local storage
+  const tmpWrapColumns = window.localStorage.getItem('wrap-columns-formid-' + this.form.id)
+  if (tmpWrapColumns !== null && tmpWrapColumns) {
+    this.wrapColumns = JSON.parse(tmpWrapColumns)
+  } else {
+    this.properties.forEach((field) => {
+      this.wrapColumns[field.id] = false
+    })
+  }
 }

Also add a method to persist wrap settings:

+ onChangeWrapColumns() {
+   if (!import.meta.client) return
+   window.localStorage.setItem('wrap-columns-formid-' + this.form.id, JSON.stringify(this.wrapColumns))
+ }

And update the toggle:

 <ToggleSwitchInput
   v-model="wrapColumns[field.id]"
   wrapper-class="mb-0"
   label=""
   :name="`wrap-${field.id}`"
+  @update:model-value="onChangeWrapColumns"
 />
🧹 Nitpick comments (3)
client/components/open/tables/OpenTable.vue (1)

77-77: Add null check for safer access.

While the implementation works, it could be made more robust by adding a null check.

-              'whitespace-normal break-words': wrapColumns[col.id] === true,
+              'whitespace-normal break-words': wrapColumns && wrapColumns[col.id] === true,
client/components/open/forms/components/FormSubmissions.vue (2)

77-84: Add aria-labels to toggle switches for better accessibility.

The toggle switches lack proper aria-labels which are essential for screen readers.

Add aria-labels to both display and wrap toggles:

 <ToggleSwitchInput
   v-model="displayColumns[field.id]"
   wrapper-class="mb-0"
-  label=""
+  label="Toggle display for field"
+  :aria-label="`Toggle display for ${field.name}`"
   :name="`display-${field.id}`"
   @update:model-value="onChangeDisplayColumns"
 />

 <ToggleSwitchInput
   v-model="wrapColumns[field.id]"
   wrapper-class="mb-0"
-  label=""
+  label="Toggle text wrapping for field"
+  :aria-label="`Toggle text wrapping for ${field.name}`"
   :name="`wrap-${field.id}`"
 />

Also applies to: 86-92


43-97: Consider adding a loading state to the modal content.

The modal content might flicker or appear empty momentarily while the sections data is being computed.

Add a loading state:

 <div class="px-4">
+  <Loader v-if="isModalLoading" class="h-6 w-6 text-nt-blue mx-auto" />
+  <template v-else>
     <template
       v-for="(section, sectionIndex) in sections"
       :key="sectionIndex"
     >
     <!-- ... existing content ... -->
     </template>
+  </template>
 </div>
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between 717fcc7 and b9e12d9.

📒 Files selected for processing (2)
  • client/components/open/forms/components/FormSubmissions.vue (4 hunks)
  • client/components/open/tables/OpenTable.vue (2 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build the Nuxt app
🔇 Additional comments (2)
client/components/open/forms/components/FormSubmissions.vue (2)

44-96: Well-structured grid layout with clear visual hierarchy!

The new modal structure with sections and grid layout provides a clear and organized way to manage columns. The use of consistent styling and proper spacing improves the user experience.


246-257: Clean implementation of sections computed property!

The sections computed property provides a clear and maintainable way to organize fields into logical groups.

Comment on lines +162 to +165
wrapColumns: {
type: Object,
default: () => {},
},
Copy link
Contributor

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance prop definition with proper defaults and validation.

The prop definition needs improvements:

  1. The default value should return an empty object.
  2. Add prop validation for the object structure.
  3. Add prop documentation.
     wrapColumns: {
       type: Object,
-      default: () => {},
+      default: () => ({}),
+      validator(value) {
+        return Object.values(value).every(v => typeof v === 'boolean')
+      },
     },

Also, consider adding JSDoc documentation above the prop:

    /**
     * Controls text wrapping for individual columns.
     * @type {Object.<string, boolean>}
     * @example { column1: true, column2: false }
     */

- Refactor RecordOperations component to use UButtonGroup and UButton
- Update FormSubmissions component with Nuxt UI buttons and modal
- Improve table cell styling in OpenTable component
- Simplify column management and export functionality
Copy link
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: 0

🔭 Outside diff range comments (1)
client/components/open/forms/components/FormSubmissions.vue (1)

222-248: 🛠️ Refactor suggestion

Enhance error handling in CSV export.

While the CSV export implementation is functional, the error handling could be improved:

  1. The catch block only logs to console
  2. No user feedback on error

Consider this enhancement:

 downloadAsCsv() {
   if (this.exportLoading) {
     return
   }
   this.exportLoading = true
   opnFetch(this.exportUrl, {
     responseType: "blob",
     method: "POST",
     body: {
       columns: this.displayColumns
     }
   }).then(blob => {
     const filename = `${this.form.slug}-${Date.now()}-submissions.csv`
     const a = document.createElement("a")
     document.body.appendChild(a)
     a.style = "display: none"
     const url = window.URL.createObjectURL(blob)
     a.href = url
     a.download = filename
     a.click()
     window.URL.revokeObjectURL(url)
   }).catch((error) => {
-    console.error(error)
+    this.useAlert.error('Failed to export CSV. Please try again.')
+    console.error('CSV export failed:', error)
   }).finally(() => {
     this.exportLoading = false
   })
 }
🧹 Nitpick comments (2)
client/components/open/forms/components/FormColumnsSettingsModal.vue (2)

124-132: Enhance storage key security.

The storage key using form ID could be vulnerable to collision. Consider adding a namespace or prefix.

 const columnPreferences = useStorage(
-  computed(() => props.form ? `column-preferences-formid-${props.form.id}` : null),
+  computed(() => props.form ? `opn-form-columns-${props.form.id}` : null),
   {
     display: {},
     wrap: {},
     widths: {}
   }
 )

151-175: Improve width initialization robustness.

The width preservation logic could be more robust by:

  1. Adding type checking for width values
  2. Setting reasonable min/max bounds
 function preserveColumnWidths(newColumns, existingColumns = []) {
   if (!columnPreferences.value) {
     columnPreferences.value = { display: {}, wrap: {}, widths: {} }
   }
   if (!columnPreferences.value.widths) {
     columnPreferences.value.widths = {}
   }

   return newColumns.map(col => {
     // First try to find width in storage
     const storedWidth = columnPreferences.value?.widths?.[col.id]
     // Then try current table columns
     const currentCol = props.columns?.find(c => c.id === col.id)
     // Then fallback to form properties
     const existing = existingColumns?.find(e => e.id === col.id)
     
-    const width = storedWidth || currentCol?.cell_width || currentCol?.width || existing?.cell_width || existing?.width || col.width || 150
+    const MIN_WIDTH = 80
+    const MAX_WIDTH = 500
+    const DEFAULT_WIDTH = 150
+    
+    let width = parseInt(storedWidth) || 
+                parseInt(currentCol?.cell_width) || 
+                parseInt(currentCol?.width) || 
+                parseInt(existing?.cell_width) || 
+                parseInt(existing?.width) || 
+                parseInt(col.width) || 
+                DEFAULT_WIDTH
+    
+    // Ensure width is within bounds
+    width = Math.max(MIN_WIDTH, Math.min(width, MAX_WIDTH))
     
     return {
       ...col,
       width,
       cell_width: width
     }
   })
 }
📜 Review details

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

📥 Commits

Reviewing files that changed from the base of the PR and between b9e12d9 and eac8fc8.

📒 Files selected for processing (4)
  • client/components/open/components/RecordOperations.vue (1 hunks)
  • client/components/open/forms/components/FormColumnsSettingsModal.vue (1 hunks)
  • client/components/open/forms/components/FormSubmissions.vue (9 hunks)
  • client/components/open/tables/OpenTable.vue (3 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
  • client/components/open/tables/OpenTable.vue
🧰 Additional context used
🪛 GitHub Check: Run client linters
client/components/open/components/RecordOperations.vue

[warning] 2-2:
'orientation' should be on a new line

client/components/open/forms/components/FormSubmissions.vue

[warning] 16-16:
Attribute "v-model:display-columns" should go before ":columns"


[warning] 17-17:
Attribute "v-model:wrap-columns" should go before ":columns"

client/components/open/forms/components/FormColumnsSettingsModal.vue

[warning] 8-8:
'class' should be on a new line

⏰ Context from checks skipped due to timeout of 90000ms (1)
  • GitHub Check: Build the Nuxt app
🔇 Additional comments (3)
client/components/open/components/RecordOperations.vue (1)

2-17: LGTM! UI components upgrade improves consistency.

The changes effectively migrate from raw HTML buttons to the design system's UButtonGroup and UButton components, maintaining functionality while improving UI consistency.

🧰 Tools
🪛 GitHub Check: Run client linters

[warning] 2-2:
'orientation' should be on a new line

client/components/open/forms/components/FormSubmissions.vue (1)

11-20: LGTM! Clean modal integration.

The FormColumnsSettingsModal integration is well-structured with proper prop bindings and event handling.

🧰 Tools
🪛 GitHub Check: Run client linters

[warning] 16-16:
Attribute "v-model:display-columns" should go before ":columns"


[warning] 17-17:
Attribute "v-model:wrap-columns" should go before ":columns"

client/components/open/forms/components/FormColumnsSettingsModal.vue (1)

233-242: LGTM! Efficient column update handling.

The onChangeDisplayColumns function effectively preserves column widths while updating visibility.

@JhumanJ JhumanJ merged commit 29ef44d into main Feb 12, 2025
7 checks passed
@JhumanJ JhumanJ deleted the 17ea6-wrap-text-in-submissions-table branch February 12, 2025 12:48
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