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

Form focused mode #640

Open
wants to merge 12 commits into
base: main
Choose a base branch
from
Open

Form focused mode #640

wants to merge 12 commits into from

Conversation

chiragchhatrala
Copy link
Collaborator

@chiragchhatrala chiragchhatrala commented Dec 10, 2024

Summary by CodeRabbit

Release Notes

  • New Features

    • Introduced a new format field for forms, allowing users to select between "Regular" and "Focused" formats.
    • Added a modal for confirming format changes, enhancing user experience.
    • New components for handling focused format submissions and customization options.
    • Enhanced form initialization with a default format property.
  • Bug Fixes

    • Improved error handling and state management for form submissions.
  • Localization

    • Added translations for navigation buttons ("Back" and "Next") in multiple languages including Arabic, English, Spanish, French, Hindi, Japanese, Portuguese, Chinese, Bengali, German, Indonesian, Korean, Marathi, Punjabi, Russian, Tamil, Telugu, Turkish, Urdu, and Vietnamese.
  • UI Enhancements

    • Dynamic adjustments to form layouts and visibility based on selected formats.

…ed component

- Updated OpenCompleteForm.vue to conditionally render OpenFormFocused for forms with 'focused' format.
- Introduced OpenFormFocused.vue to handle focused form submissions, including progress bar, navigation buttons, and captcha support.
- Enhanced form submission handling and added necessary props for improved functionality.

This change enhances user experience by providing a dedicated focused mode for form submissions.
…tency

- Added a check for empty previous fields in OpenForm.vue to prevent errors.
- Refactored button layout in OpenFormFocused.vue to improve UI structure and added a slot for submit button when on the last page.
- Updated label for cover picture input in FormCustomization.vue to reflect context based on form format.
- Adjusted styles in FormEditorPreview.vue to ensure responsive behavior and visual clarity when focused.

These changes aim to enhance user experience and maintain consistency across form components.
… customization

- Updated OpenFormFocused.vue to allow dynamic button text for navigation based on form configuration.
- Added focused format options in FieldOptions.vue, enabling customization of previous and next button texts.

These changes improve the flexibility and user experience of the form components.
… for navigation buttons

- Modified OpenFormFocused.vue to utilize localized text for 'Back' and 'Next' buttons using the $t function.
- Added translations for 'Back' and 'Next' buttons in multiple languages (Arabic, English, Spanish, French, Hindi, Japanese, Portuguese, Chinese).

These changes enhance the user experience by providing localized navigation options in the form component.
…mprove navigation

- Replaced `currentFields` with `currentField` to simplify field access and enhance clarity in the component's logic.
- Updated navigation button text to utilize the new `currentField` structure, ensuring dynamic text rendering based on the current form state.
- Removed deprecated code related to `currentFields` to clean up the component and improve maintainability.

These changes enhance the overall functionality and readability of the OpenFormFocused component.
Copy link
Contributor

coderabbitai bot commented Dec 10, 2024

Walkthrough

The pull request introduces several changes to support a new format attribute in form handling. Key modifications include adding a validation rule for the format field in UserFormRequest, defining a new constant FORMATS in the Form model, and updating the database schema to include the format column. Additionally, new components and UI elements are created to manage and render forms based on the selected format, enhancing user interaction and experience.

Changes

File Path Change Summary
api/app/Http/Requests/UserFormRequest.php Added validation rule for format field: 'format' => ['required', Rule::in(Form::FORMATS)].
api/app/Models/Forms/Form.php Introduced constant FORMATS with values ['regular', 'focused'] and added format to the fillable property.
api/database/factories/FormFactory.php Updated definition() method to include 'format' => 'regular'.
api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php Added migration to introduce format column to forms table with default value 'regular'.
client/components/open/editors/FormatChangeModal.vue Created modal component for confirming format changes, includes dynamic block removal message and confirmation buttons.
client/components/open/forms/OpenCompleteForm.vue Added conditional rendering for OpenFormFocused based on form.format.
client/components/open/forms/OpenForm.vue Added null check for previousFields in previousFieldsPageBreak computed property.
client/components/open/forms/OpenFormFocused.vue Introduced new component for focused form submissions, includes pagination and validation features.
client/components/open/forms/components/form-components/AddFormBlock.vue Added isFocused computed property to filter layout blocks based on form format.
client/components/open/forms/components/form-components/FormCustomization.vue Added format selection feature with FlatSelectInput and modal integration.
client/components/open/forms/components/form-components/FormEditorPreview.vue Introduced isFocused computed property for dynamic height adjustments in form preview.
client/pages/forms/[slug]/index.vue Added dynamic class binding for layout based on isFocused state.
client/pages/forms/create/CreateFormBaseModal.vue Added form prop to create-form-base-modal component for direct form data access.
client/i18n/lang/ar.json Added Arabic translations for "Back" and "Next".
client/i18n/lang/en.json Added English translations for "Back" and "Next".
client/i18n/lang/es.json Added Spanish translations for "Back" and "Next".
client/i18n/lang/fr.json Added French translations for "Back" and "Next".
client/i18n/lang/hi.json Added Hindi translations for "Back" and "Next".
client/i18n/lang/ja.json Added Japanese translations for "Back" and "Next".
client/i18n/lang/pt.json Added Portuguese translations for "Back" and "Next".
client/i18n/lang/zh.json Added Chinese translations for "Back" and "Next".
client/i18n/lang/bn.json Added Bengali translations for "Back" and "Next".
client/i18n/lang/de.json Added German translations for "Back" and "Next".
client/i18n/lang/jv.json Added Indonesian translations for "Back" and "Next".
client/i18n/lang/ko.json Added Korean translations for "Back" and "Next".
client/i18n/lang/mr.json Added Marathi translations for "Back" and "Next".
client/i18n/lang/pa.json Added Punjabi translations for "Back" and "Next".
client/i18n/lang/ru.json Added Russian translations for "Back" and "Next".
client/i18n/lang/ta.json Added Tamil translations for "Back" and "Next".
client/i18n/lang/te.json Added Telugu translations for "Back" and "Next".
client/i18n/lang/tr.json Added Turkish translations for "Back" and "Next".
client/i18n/lang/ur.json Added Urdu translations for "Back" and "Next".
client/i18n/lang/vi.json Added Vietnamese translations for "Back" and "Next".

Possibly related PRs

  • Better form themes #465: Modifies UserFormRequest.php to include additional validation rules, related to the validation changes in this PR.
  • apply first submission modal changes #584: Introduces a new boolean variable $isFirstSubmission in the PublicFormController, which is relevant to the changes in the main PR that involve the UserFormRequest and the Form class, as both deal with form submissions and their handling.
  • Apply Mentions everywhere #595: This PR focuses on the implementation of mentions throughout the application, which is relevant to the changes in the main PR that involve the UserFormRequest and the Form class, as they both pertain to form handling and user interactions.
  • Form Editor v2.5 #599: This PR introduces enhancements to the form editor, which is related to the main PR's focus on form submissions and validation, as both involve improving user interactions with forms.

Suggested reviewers

  • JhumanJ

Poem

🐰 In the fields where forms do play,
A new format joins the fray.
With modals bright and buttons clear,
Users hop with joy and cheer!
From regular to focused view,
Every change brings something new! 🌼


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. (Experiment)
  • @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: 6

🧹 Outside diff range and nitpick comments (8)
client/pages/forms/[slug]/index.vue (1)

Line range hint 1-73: Document the new focused format feature.

The introduction of the focused format significantly changes the form's layout and behavior. Consider adding:

  1. Documentation about this new feature
  2. Usage guidelines in the README
  3. Examples of when to use focused vs. regular format

Would you like me to help create the documentation or open a GitHub issue for tracking this task?

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

10-10: Simplify the submit event handler.

The @submit.prevent="" attribute is unnecessary if no handler is provided. You can shorten it to @submit.prevent or remove it entirely if not needed.

Apply this diff to simplify:

- @submit.prevent=""
+ @submit.prevent
client/components/open/editors/FormatChangeModal.vue (1)

63-63: Add type definitions for better maintainability

Consider adding TypeScript or JSDoc type definitions for the computed property.

-const removeBlocks = computed(() => form.value.properties.filter(field => removeTypes.includes(field.type)))
+/**
+ * @type {import('vue').ComputedRef<Array<{ id: string, type: string, name: string }>>}
+ */
+const removeBlocks = computed(() => form.value.properties.filter(field => removeTypes.includes(field.type)))
client/pages/forms/create/index.vue (1)

8-8: Add prop type validation

Consider adding prop type validation for the form prop in CreateFormBaseModal component.

In CreateFormBaseModal.vue:

+defineProps({
+  form: {
+    type: Object,
+    required: true
+  }
+})
client/components/open/forms/components/form-components/AddFormBlock.vue (1)

94-94: Improve readability of layoutBlocks filter

The filter condition is complex and could benefit from being broken down for better readability.

Consider refactoring to:

-const layoutBlocks = computed(() => Object.values(blocksTypes).filter(block => block.name.startsWith('nf-') && (isFocused.value ? !['nf-page-break','nf-divider','nf-image','nf-code'].includes(block.name) : true)))
+const FOCUSED_MODE_EXCLUDED_BLOCKS = ['nf-page-break', 'nf-divider', 'nf-image', 'nf-code']
+const layoutBlocks = computed(() => {
+  return Object.values(blocksTypes).filter(block => {
+    const isLayoutBlock = block.name.startsWith('nf-')
+    const isAllowedInFocusedMode = !isFocused.value || !FOCUSED_MODE_EXCLUDED_BLOCKS.includes(block.name)
+    return isLayoutBlock && isAllowedInFocusedMode
+  })
+})
client/components/open/forms/components/form-components/FormCustomization.vue (1)

282-286: Consider handling both format cases explicitly

The current implementation only handles the 'focused' case. Consider handling the 'regular' case explicitly for better maintainability.

 const onChangeFormat = (val) => {
   if (val === 'focused') {
     showFormatChangeModal.value = true
+  } else if (val === 'regular') {
+    form.value.format = val
   }
 }
client/components/open/forms/OpenCompleteForm.vue (2)

Line range hint 111-155: Consider extracting the submit button template to reduce duplication.

The submit button template is identical in both form components. Consider extracting it into a separate component or slot to improve maintainability.

Example refactor:

-<template #submit-btn="{submitForm}">
-  <open-form-button
-    :loading="loading"
-    :theme="theme"
-    :color="form.color"
-    class="mt-2 px-8 mx-1"
-    :class="submitButtonClass"
-    @click.prevent="submitForm"
-  >
-    {{ form.submit_button_text }}
-  </open-form-button>
-</template>

Create a new component FormSubmitButton.vue and use it in both places:

<template #submit-btn="{submitForm}">
  <form-submit-button
    :loading="loading"
    :theme="theme"
    :form="form"
    :submit-button-class="submitButtonClass"
    @submit="submitForm"
  />
</template>

228-229: Remove unused FormTimer import.

The FormTimer component is imported but not utilized in the template. Consider removing it if it's not needed.

-import FormTimer from './FormTimer.vue'

Also applies to: 238-238

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between ea4cd85 and 9a19502.

📒 Files selected for processing (25)
  • api/app/Http/Requests/UserFormRequest.php (1 hunks)
  • api/app/Models/Forms/Form.php (2 hunks)
  • api/database/factories/FormFactory.php (1 hunks)
  • api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php (1 hunks)
  • client/components/open/editors/FormatChangeModal.vue (1 hunks)
  • client/components/open/forms/OpenCompleteForm.vue (4 hunks)
  • client/components/open/forms/OpenForm.vue (1 hunks)
  • client/components/open/forms/OpenFormFocused.vue (1 hunks)
  • client/components/open/forms/components/form-components/AddFormBlock.vue (1 hunks)
  • client/components/open/forms/components/form-components/FormCustomization.vue (5 hunks)
  • client/components/open/forms/components/form-components/FormEditorPreview.vue (4 hunks)
  • client/components/open/forms/fields/components/FieldOptions.vue (1 hunks)
  • client/components/pages/forms/create/CreateFormBaseModal.vue (3 hunks)
  • client/components/pages/forms/create/FormFormatModal.vue (1 hunks)
  • client/composables/forms/initForm.js (1 hunks)
  • client/i18n/lang/ar.json (1 hunks)
  • client/i18n/lang/en.json (1 hunks)
  • client/i18n/lang/es.json (1 hunks)
  • client/i18n/lang/fr.json (1 hunks)
  • client/i18n/lang/hi.json (1 hunks)
  • client/i18n/lang/ja.json (1 hunks)
  • client/i18n/lang/pt.json (1 hunks)
  • client/i18n/lang/zh.json (1 hunks)
  • client/pages/forms/[slug]/index.vue (3 hunks)
  • client/pages/forms/create/index.vue (1 hunks)
🔇 Additional comments (26)
client/i18n/lang/zh.json (1)

6-7: LGTM! Translations are accurate and consistent.

The Chinese translations are idiomatic and align with common UI patterns. Note that "返回" is consistently used for "back" across the UI (also used in cameraUpload.goBack).

client/i18n/lang/ja.json (1)

6-7: LGTM! Translations are accurate and consistent.

The Japanese translations are idiomatic and follow standard UI conventions. Note that "戻る" is consistently used for "back" across the UI (also used in cameraUpload.goBack).

client/i18n/lang/ar.json (1)

6-7: LGTM! Translations are accurate and consistent.

The Arabic translations are idiomatic and follow standard UI conventions. Note that "رجوع" is consistently used for "back" across the UI (also used in cameraUpload.goBack).

Since Arabic is RTL (right-to-left), let's verify that the UI components using these translations have proper RTL support:

✅ Verification successful

Based on the search results, I can see that the application has proper RTL support implemented:

  1. The form layout has an RTL toggle option (layout_rtl property) that controls the text direction
  2. RTL-specific CSS classes and styling are present in the codebase
  3. The form's direction is properly set using both CSS direction property and HTML dir attribute
  4. Components like PhoneInput, VSelect, and MatrixInput have RTL-specific styling classes

The Arabic translations are safe to use as the UI properly handles RTL text direction.

Key evidence:

  • client/pages/forms/[slug]/index.vue: Sets form direction based on layout_rtl property
  • client/components/open/forms/OpenCompleteForm.vue: Applies RTL styling and direction
  • client/tailwind.config.js: Has RTL-specific variants
  • Multiple components have RTL-specific classes for proper alignment and styling
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for RTL-related styling and components in the codebase

# Look for RTL-related CSS classes and directives
rg -i 'rtl|direction:|dir=' --type html --type vue --type css

# Look for RTL-aware component usage
rg -i 'v-rtl|rtl-|isRTL|direction' --type vue --type js

Length of output: 177


Script:

#!/bin/bash
# Let's try a different approach to find RTL-related code

# Search for RTL-related patterns in all files
rg -i 'rtl|direction:|dir=' 

# Search for style-related files that might contain RTL support
fd -e css -e scss -e less -e styled.js

# Look for i18n or locale configuration files
fd -e js -e ts -e json | rg -i "i18n|locale|lang"

Length of output: 67857


Script:

#!/bin/bash
# Let's search for UI component files and styling that might handle RTL
# Look for any styling files
fd -e css -e scss -e less -e styl -e sass

# Look for component files that might contain RTL handling
fd -e jsx -e tsx -e js -e vue

# Search for direction/RTL related code in all files
rg -i "direction|rtl|ltr|right-to-left|left-to-right" --type-add 'frontend:*.{js,jsx,ts,tsx,vue,css,scss,less,styl,sass}'

Length of output: 100918

client/i18n/lang/en.json (1)

6-7: LGTM! Verify translations across all language files.

The English translations for navigation buttons are accurate and properly capitalized.

Let's verify the consistency of these new keys across all language files:

✅ Verification successful

Translation keys 'back' and 'next' are properly defined across all language files

All language files (ar, en, es, fr, hi, ja, pt, zh) have the required translations for both 'back' and 'next' keys under the 'forms' section. Each translation is appropriately localized for its respective language.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check if 'back' and 'next' keys exist in all language files
# and ensure no language file is missing these translations

# Find all language files
echo "Checking translation consistency across language files..."
for lang_file in $(fd -e json . client/i18n/lang/); do
  echo "\nChecking $lang_file:"
  # Check for back key
  jq -r '.forms.back // "MISSING"' "$lang_file"
  # Check for next key
  jq -r '.forms.next // "MISSING"' "$lang_file"
done

Length of output: 2298

client/i18n/lang/hi.json (1)

6-7: LGTM! Hindi translations are accurate.

The Hindi translations "पिछला" (back) and "अगला" (next) are grammatically correct and properly convey the navigation context.

client/i18n/lang/pt.json (1)

6-7: LGTM! Portuguese translations are accurate.

The Portuguese translations "Voltar" (back) and "Próximo" (next) are correctly spelled with proper accents and follow Brazilian Portuguese conventions.

client/i18n/lang/es.json (1)

6-7: LGTM! Translations are accurate and consistent

The Spanish translations for navigation buttons are correct and follow common web interface conventions:

  • "Atrás" is the standard translation for "back"
  • "Siguiente" is the standard translation for "next"
client/i18n/lang/fr.json (2)

6-7: LGTM! Translations are accurate and consistent

The French translations for navigation buttons are correct and follow common web interface conventions:

  • "Retour" is the standard translation for "back"
  • "Suivant" is the standard translation for "next"

6-6: Consider standardizing "back" translations

Note that both forms.back and forms.cameraUpload.goBack are translated as "Retour". While this is correct, you might want to verify if these should be using the same translation key for consistency and maintainability.

Let's check if other language files have the same pattern:

Also applies to: 35-35

client/pages/forms/[slug]/index.vue (1)

64-73: 🛠️ Refactor suggestion

Ensure proper positioning context and responsive behavior.

The absolute positioning with inset-0 requires a positioned ancestor to work correctly. Additionally, on smaller screens, the centered form might be partially hidden or inaccessible.

Let's check if there's a positioned ancestor:

Consider these improvements:

-<div :class="{'absolute inset-0 flex items-center justify-center': isFocused}">
+<div :class="{
+  'absolute inset-0 flex items-center justify-center min-h-screen overflow-auto': isFocused,
+  'relative': !isFocused
+}">
client/components/pages/forms/create/CreateFormBaseModal.vue (1)

194-194: Verify the initial value of showFormatModal.

The showFormatModal data property is initialized to true, which will display the FormFormatModal immediately upon component mount. Please confirm if this behavior is intentional.

api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php (1)

7-27: Migration looks good.

The migration correctly adds the format column with a default value and provides a proper rollback mechanism.

api/database/factories/FormFactory.php (1)

53-53: Verify consistency of default format value

The default format value 'regular' has been added. Let's ensure this value is consistently used across the codebase.

✅ Verification successful

Default format value 'regular' is consistent with codebase implementation

The verification shows that:

  • The format values are properly defined in Form::FORMATS = ['regular', 'focused']
  • The format field is validated against these values in UserFormRequest using Rule::in(Form::FORMATS)
  • The default value 'regular' in the factory aligns with the available formats
  • No conflicting default values were found in the codebase
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for consistency of default format value across the codebase

# Search for format-related constants and default values
echo "Searching for format-related constants and default values..."
rg -g '!{*.lock,*.min.*}' -A 2 "FORMATS.*=.*\[.*'regular'.*'focused'.*\]"

# Search for direct usage of format values
echo "Searching for direct usage of format values..."
rg -g '!{*.lock,*.min.*}' "'format'.*=>.*'regular'"

Length of output: 676


Script:

#!/bin/bash
# Let's verify the format validation and default value in migrations and models

# Check migrations for format column definition
echo "Checking migrations for format column..."
rg -g "*.php" "format.*string" api/database/migrations/

# Check for format validation rules
echo "Checking validation rules for format..."
rg -g "*.php" "format.*in:.*regular" api/app/

# Check for any other occurrences of format values
echo "Checking other format value usages..."
rg -g "*.php" -B2 -A2 "'format'" api/app/

Length of output: 18351

client/components/open/editors/FormatChangeModal.vue (1)

65-69: Verify block removal logic

The format change logic removes blocks based on type. Let's verify if these are all the block types that need removal in focused mode.

✅ Verification successful

Let me generate additional scripts to verify the block removal logic in focused mode.


Based on the search results, I can now provide a final verification response:

Block removal logic is correctly implemented

The code correctly removes the following block types in focused mode:

  • nf-page-break
  • nf-divider
  • nf-image
  • nf-code

This is verified by:

  1. The removeTypes array definition matches the block types filtered out
  2. The same block types are filtered in the layout blocks selection (AddFormBlock.vue)
  3. The format change modal only shows when these blocks exist and format is being changed to focused mode
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Search for block type definitions and usages

# Search for block type definitions
echo "Searching for block type definitions..."
ast-grep --pattern 'const $blockTypes = [
  $$$
]'

# Search for block type usages in focused mode context
echo "Searching for block type usages in focused mode context..."
rg -g '!{*.lock,*.min.*}' "focused.*format.*type"

Length of output: 65856


Script:

#!/bin/bash
# Search for removeTypes definition and focused mode related code

# Search for removeTypes definition
echo "Searching for removeTypes definition..."
rg -A 5 "removeTypes.*=" client/

# Search for focused mode related code
echo "Searching for focused mode related code..."
rg -A 5 "format.*=.*focused" client/

Length of output: 5410

client/pages/forms/create/index.vue (1)

Line range hint 116-117: Verify form initialization with format property

The form initialization should include the new format property. Let's verify the initialization logic.

✅ Verification successful

Let me try a different search strategy to verify the form initialization.


Let me try one more search to find the form initialization logic.


Based on the initialization code found in client/composables/forms/initForm.js, I can now provide a definitive response:

The format property is already properly handled in form initialization

The initForm function already includes the format property with a default value of "regular" in its initialization:

format: "regular",

This property is part of the default form structure under the "Customization" section. No additional verification or changes are needed.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check form initialization handling of format property

# Search for form initialization logic
echo "Searching for form initialization..."
rg -g '!{*.lock,*.min.*}' "initForm.*format"

# Search for form data structure
echo "Searching for form data structure..."
ast-grep --pattern 'interface $FormData {
  $$$
  format?: string
  $$$
}'

Length of output: 289


Script:

#!/bin/bash
# Search for form initialization and related data structures in the specific file
echo "Checking the specific file content..."
cat client/pages/forms/create/index.vue

# Search for form-related interfaces and types
echo "Searching for form interfaces..."
rg -g '!{*.lock,*.min.*}' "interface.*Form" -A 10

# Search for form initialization methods
echo "Searching for form initialization methods..."
rg -g '!{*.lock,*.min.*}' "initForm" -A 5

Length of output: 69317


Script:

#!/bin/bash
# Search for form initialization in composables
echo "Checking form initialization composable..."
cat client/composables/forms/initForm.js

# Search for form data structure
echo "Searching for form data structure..."
rg -g '!{*.lock,*.min.*}' "interface FormData" -A 10

Length of output: 3830

api/app/Http/Requests/UserFormRequest.php (1)

32-32: Verify Form::FORMATS constant exists

The validation rule references Form::FORMATS which should contain the allowed format values ('regular', 'focused').

✅ Verification successful

Form::FORMATS constant is properly defined with expected values

The constant exists in api/app/Models/Forms/Form.php and contains the expected format values: 'regular' and 'focused'.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify Form::FORMATS constant exists and contains expected values
rg -A 2 "const FORMATS = \[" api/app/Models/Forms/Form.php

Length of output: 185

client/composables/forms/initForm.js (1)

13-13: LGTM! Default format initialization looks good

The default format is correctly set to "regular" in the form initialization.

client/components/open/forms/components/form-components/AddFormBlock.vue (1)

90-91: LGTM! Format check implementation looks good

The computed property correctly determines if the form is in focused mode.

client/components/open/forms/components/form-components/FormEditorPreview.vue (3)

92-106: LGTM! Clean implementation of centered layout

The conditional absolute positioning with flexbox centering is a good approach for the focused mode layout.


135-136: LGTM! Clean computed property implementation

The computed property follows Vue.js best practices and provides a clear way to check the form format.


61-62: Consider viewport height implications

Using 100vh for the cover picture in focused mode might cause issues:

  • Mobile browsers with dynamic toolbars can cause unexpected scrolling
  • Content might be cut off on smaller screens

Also applies to: 67-68

client/components/open/forms/components/form-components/FormCustomization.vue (2)

47-56: LGTM! Clear and user-friendly format selection

The format options are well-labeled and the implementation follows component conventions.


57-60: Verify modal behavior across different scenarios

The modal integration looks good, but we should verify:

  • Modal state reset on component unmount
  • Handling of modal dismissal
✅ Verification successful

Modal implementation is properly handled

The FormatChangeModal component has proper state management and cleanup:

  • Modal visibility is controlled by the show prop with proper two-way binding
  • Modal dismissal is handled through the onCancel method which resets the form format and emits close event
  • No explicit unmount cleanup is needed as the component uses <script setup> with no persistent state
  • Format change logic properly filters out incompatible blocks and updates the form state
🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check FormatChangeModal implementation
ast-grep --pattern 'class FormatChangeModal {
  $$$
  beforeUnmount() {
    $$$
  }
  $$$
}'

Length of output: 94


Script:

#!/bin/bash
# Let's try a different approach to find the FormatChangeModal component
# First, let's locate the file
fd "FormatChangeModal" --type f

# Then examine its content
rg -A 5 "FormatChangeModal" --type vue

Length of output: 151


Script:

#!/bin/bash
# Now that we found the file, let's examine its content
cat client/components/open/editors/FormatChangeModal.vue

Length of output: 1787

api/app/Models/Forms/Form.php (2)

44-45: LGTM! Consistent constant definition

The FORMATS constant follows the established pattern and aligns with the frontend implementation.


59-59: Verify database migration and default values

The format field is properly added to fillable attributes. Ensure there's a corresponding migration with a default value.

✅ Verification successful

Migration exists with default value - format field is properly configured

The migration file 2024_12_04_163142_add_format_to_forms_table.php adds the format column with a default value of 'regular'. The factory also includes this field with the same default value. The database schema is properly configured for this fillable attribute.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Check for migration file adding the format column
fd "add_format_to_forms" --type php

Length of output: 206


Script:

#!/bin/bash
# Search for migration files containing 'format'
rg -l "format" "database/migrations"

# Search for schema definition of 'format' column
rg -A 5 "format" "database/migrations"

Length of output: 191


Script:

#!/bin/bash
# Find all migration files in the repository
fd "\.php$" --type f

# Search for any file containing 'format' column definition
rg -A 5 "format" --type php

Length of output: 68868

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

278-278: LGTM! Null check prevents potential runtime errors.

The added null check for previousFields is a good defensive programming practice that prevents potential runtime errors.

Comment on lines +102 to +103
const isFocused = computed(() => form.value.format === 'focused')

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

Add null check for form.value.

The computed property could throw an error if form.value is null during initial load or after errors.

Consider this safer implementation:

-const isFocused = computed(() => form.value.format === 'focused')
+const isFocused = computed(() => form.value?.format === 'focused')
📝 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
const isFocused = computed(() => form.value.format === 'focused')
const isFocused = computed(() => form.value?.format === 'focused')

Comment on lines +10 to +11
class="w-full overflow-hidden flex items-center justify-center"
:class="{'h-screen': isFocused, 'max-h-56': !isFocused}"
Copy link
Contributor

Choose a reason for hiding this comment

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

💡 Codebase verification

Add keyboard controls for exiting full-screen focused mode

The verification reveals that while there's a computed property isFocused controlling the full-screen behavior, there are no keyboard event handlers to manage this state. To ensure accessibility:

  • Add keyboard handlers (e.g., Escape key) to exit the focused mode
  • Consider adding focus trap management when in full-screen mode
  • Ensure the form content remains keyboard-accessible when cover picture is full-screen
🔗 Analysis chain

LGTM! Consider adding keyboard navigation for full-screen mode.

The dynamic height adjustment for focused mode is well implemented. However, when the cover picture is full-screen (h-screen), ensure that keyboard users can easily navigate past it.

Let's check if there are any accessibility-related components or keyboard handlers:

Also applies to: 17-17

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for keyboard navigation or accessibility-related code
rg -i "key(down|up|press)" client/pages/forms/
rg -i "a11y|accessibility" client/pages/forms/

Length of output: 97


Script:

#!/bin/bash
# Let's search for keyboard event handlers and focus management in the component
ast-grep --pattern 'v-on:keydown="$_"'
ast-grep --pattern '@keydown="$_"'
ast-grep --pattern '@keyup="$_"'
ast-grep --pattern '@keypress="$_"'

# Also check for any focus-related methods or computed properties
rg -A 5 "isFocused" client/pages/forms/

Length of output: 1832

Comment on lines +313 to +316
if (this.form.use_captcha && import.meta.client) {
this.dataForm['h-captcha-response'] = document.getElementsByName('h-captcha-response')[0].value
this.$refs.hcaptcha.reset()
}
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Ensure the hCaptcha element exists before accessing its value.

When accessing document.getElementsByName('h-captcha-response')[0].value, there's a risk of encountering a runtime error if the element doesn't exist. Please add a check to ensure the element is present before accessing its value.

Apply this diff to prevent potential errors:

if (this.form.use_captcha && import.meta.client) {
-   this.dataForm['h-captcha-response'] = document.getElementsByName('h-captcha-response')[0].value
+   const captchaElement = document.getElementsByName('h-captcha-response')[0]
+   if (captchaElement) {
+     this.dataForm['h-captcha-response'] = captchaElement.value
+     this.$refs.hcaptcha.reset()
+   }
}
📝 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 (this.form.use_captcha && import.meta.client) {
this.dataForm['h-captcha-response'] = document.getElementsByName('h-captcha-response')[0].value
this.$refs.hcaptcha.reset()
}
if (this.form.use_captcha && import.meta.client) {
const captchaElement = document.getElementsByName('h-captcha-response')[0]
if (captchaElement) {
this.dataForm['h-captcha-response'] = captchaElement.value
this.$refs.hcaptcha.reset()
}
}

Comment on lines +27 to +34
<script setup>
import { defineProps } from "vue"

const props = defineProps({
show: { type: Boolean, required: true },
form: { type: Object, required: true },
})
</script>
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid directly mutating the form prop.

Modifying the form prop directly within FormFormatModal.vue violates Vue's best practices. Props should be treated as read-only. Consider using a local copy of the form data or emitting an event to update the parent component.

Apply this diff to create a local form copy:

<script setup>
 import { defineProps, ref, toRefs } from "vue"

 const props = defineProps({
   show: { type: Boolean, required: true },
-  form: { type: Object, required: true },
+  form: { type: Object, required: true },
 })

+const localForm = ref({ ...props.form })
</script>

And update the FlatSelectInput to use localForm:

<FlatSelectInput
-  :form="form"
+  :form="localForm"
   name="format"
   ...
/>

Then, when the user clicks "Ok", emit an event to update the parent:

<UButton
  size="md"
  block
- @click="$emit('close')"
+ @click="updateFormat"
>
  Ok
</UButton>

<script setup>
+function updateFormat() {
+  emit('update:format', localForm.value.format)
+  emit('close')
+}
</script>

Committable suggestion skipped: line range outside the PR's diff.

})

const emit = defineEmits(['close'])
const removeTypes = ['nf-page-break','nf-divider','nf-image','nf-code']
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

Move removeTypes to a constants file

The removeTypes array should be moved to a constants file for better maintainability and reusability.

Create a new constant in a shared location:

-const removeTypes = ['nf-page-break','nf-divider','nf-image','nf-code']
+import { REMOVABLE_BLOCK_TYPES } from '@/constants/forms'
+const removeTypes = REMOVABLE_BLOCK_TYPES

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +579 to +600

<!-- Focused Format Options -->
<div
v-if="form.format === 'focused'"
class="px-4"
>
<EditorSectionHeader
icon="i-heroicons-bars-3-bottom-left"
title="Focused Format Options"
/>

<text-input
name="focused_previous_button_text"
:form="field"
label="Previous Button Text"
/>
<text-input
name="focused_next_button_text"
:form="field"
label="Next Button Text"
/>
</div>
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

Add validation and default values for button text fields.

The focused format button text fields lack validation and default values. Consider:

  1. Adding validation to ensure non-empty values
  2. Setting default values in the component's created/mounted lifecycle hooks
  3. Adding help text to guide users

Apply these changes:

 <text-input
   name="focused_previous_button_text"
   :form="field"
   label="Previous Button Text"
+  :required="true"
+  help="Text to display on the previous button in focused mode"
+  placeholder="Previous"
 />
 <text-input
   name="focused_next_button_text"
   :form="field"
   label="Next Button Text"
+  :required="true"
+  help="Text to display on the next button in focused mode"
+  placeholder="Next"
 />

And in the script section:

 mounted() {
   this.setDefaultFieldValues()
+  if (this.form?.format === 'focused') {
+    this.field.focused_previous_button_text = this.field.focused_previous_button_text || 'Previous'
+    this.field.focused_next_button_text = this.field.focused_next_button_text || 'Next'
+  }
 }

Committable suggestion skipped: line range outside the PR's diff.

…management

- Introduced a new 'creating' Boolean prop in OpenForm.vue and OpenFormFocused.vue to manage form submission state.
- Updated the nextPage method to include 'creating' in the condition for advancing the form page index, ensuring proper navigation during form creation.
- Adjusted OpenCompleteForm.vue to bind the 'creating' prop, enhancing the overall functionality and user experience of the form components.
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: 7

🧹 Outside diff range and nitpick comments (9)
client/components/open/forms/components/form-components/FormCustomization.vue (3)

47-56: Add help text to explain format implications.

Consider adding help text to explain how each format affects form behavior and user experience. This will help users make an informed decision when selecting a format.

     <FlatSelectInput
       :form="form"
       name="format"
       :options="[
         { name: 'Regular format', value: 'regular' },
         { name: 'Focused format (1 question per page)', value: 'focused' },
       ]"
       label="Form format"
+      help="Regular format shows all questions at once. Focused format improves concentration by showing one question at a time."
       @update:model-value="onChangeFormat"
     />

162-162: Consider updating help text based on format.

The label changes based on format, but the help text remains static. Consider updating the help text to provide format-specific guidance.

     <image-input
       name="cover_picture"
       :form="form"
       :label="form.format === 'focused' ? 'Background image' : 'Cover image'"
-      help="Not visible when form is embedded"
+      :help="form.format === 'focused' 
+        ? 'Background image appears behind each question in focused mode. Not visible when form is embedded'
+        : 'Cover image appears at the top of the form. Not visible when form is embedded'"
     />

283-287: Add error handling and documentation.

The method could benefit from parameter validation and JSDoc documentation.

+/**
+ * Handles format change events from the format selector
+ * @param {string} val - The new format value ('regular' | 'focused')
+ */
 const onChangeFormat = (val) => {
+  if (typeof val !== 'string' || !['regular', 'focused'].includes(val)) {
+    console.error('Invalid format value:', val);
+    return;
+  }
   if (val === 'focused') {
     showFormatChangeModal.value = true;
   }
 }
client/i18n/lang/de.json (1)

6-7: Consider using more common German UI terminology

While the translations are grammatically correct, consider using more standard German UI terminology:

         "back": "Zurück",
-        "next": "Nächste",
+        "next": "Weiter",

"Weiter" is more commonly used in German user interfaces for the "next" action and would provide a more familiar experience for German users.

client/components/open/forms/OpenFormFocused.vue (5)

21-39: Consider extracting the progress bar into a separate component.

The progress bar implementation is duplicated between iframe and non-iframe versions with only minor styling differences. This violates the DRY principle.

Consider creating a new component like this:

+ <!-- ProgressBar.vue -->
+ <template>
+   <div :class="containerClass">
+     <div class="w-full h-2 bg-gray-200 dark:bg-gray-600 relative overflow-hidden">
+       <div
+         class="h-full transition-all duration-300"
+         :class="{ 'w-0': progress === 0 }"
+         :style="{ width: progress + '%', background: color }"
+       />
+     </div>
+   </div>
+ </template>

Then use it in both places:

- <div v-if="isIframe" class="mb-4 p-2">
-   <div class="w-full h-2 bg-gray-200 dark:bg-gray-600 relative border rounded-full overflow-hidden">
-     <!-- ... -->
-   </div>
- </div>
- <div v-else class="fixed top-0 left-0 right-0 z-50">
-   <div class="w-full h-[0.2rem] bg-gray-200 dark:bg-gray-600 relative overflow-hidden">
-     <!-- ... -->
-   </div>
- </div>
+ <progress-bar
+   :progress="formProgress"
+   :color="form.color"
+   :container-class="isIframe ? 'mb-4 p-2' : 'fixed top-0 left-0 right-0 z-50'"
+ />

136-144: Add error handling for theme injection.

The theme prop's default value implementation could fail if the component is used outside of a provide context. Consider adding proper error handling.

 theme: {
   type: Object,
   default: () => {
-    const theme = inject("theme", null)
-    if (theme) {
-      return theme.value
+    try {
+      const theme = inject("theme", null)
+      return theme?.value ?? CachedDefaultTheme.getInstance()
+    } catch (error) {
+      console.warn('Theme injection failed, falling back to default theme:', error)
+      return CachedDefaultTheme.getInstance()
     }
-    return CachedDefaultTheme.getInstance()
   }
 }

206-214: Optimize formProgress computation.

The current implementation iterates through fields twice. This can be optimized to a single pass.

 formProgress() {
-  const requiredFields = this.fields.filter(field => field.required)
-  if (requiredFields.length === 0) {
-    return 100
-  }
-  const completedFields = requiredFields.filter(field => ![null, undefined, ''].includes(this.dataFormValue[field.id]))
-  const progress = (completedFields.length / requiredFields.length) * 100
-  return Math.round(progress)
+  let total = 0, completed = 0
+  for (const field of this.fields) {
+    if (field.required) {
+      total++
+      if (![null, undefined, ''].includes(this.dataFormValue[field.id])) {
+        completed++
+      }
+    }
+  }
+  return total === 0 ? 100 : Math.round((completed / total) * 100)
 }

235-252: Optimize dataFormValue computation.

The current implementation has nested loops for handling selection fields. Consider using a Map for O(1) lookups.

 dataFormValue() {
   const data = this.dataForm.data()
   const selectionFields = this.fields.filter((field) => {
     return ['select', 'multi_select'].includes(field.type)
   })
   selectionFields.forEach((field) => {
     if (data[field.id] !== undefined && data[field.id] !== null && Array.isArray(data[field.id])) {
+      const optionsMap = new Map(field[field.type].options.map(op => [op.id, op.name]))
       data[field.id] = data[field.id].map(option_nfid => {
-        const tmpop = field[field.type].options.find((op) => {
-          return (op.id === option_nfid)
-        })
-        return (tmpop) ? tmpop.name : option_nfid
+        return optionsMap.get(option_nfid) ?? option_nfid
       })
     }
   })
   return data
 }

520-529: Enhance error handling in setMinHeight.

The current implementation only logs errors to console without any recovery strategy.

 setMinHeight(minHeight) {
   if (!this.isIframe) return
 
   this.minHeight = minHeight
   try {
     window.parentIFrame.size()
   } catch (e) {
-    console.error(e)
+    console.warn('Failed to resize iframe:', e)
+    // Fallback to default sizing mechanism
+    this.$nextTick(() => {
+      const element = this.$el
+      if (element) {
+        element.style.height = `${minHeight}px`
+      }
+    })
   }
 }
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Reviewing files that changed from the base of the PR and between 9a19502 and f24cab9.

📒 Files selected for processing (26)
  • api/app/Http/Requests/UserFormRequest.php (1 hunks)
  • api/app/Models/Forms/Form.php (2 hunks)
  • client/components/open/forms/OpenCompleteForm.vue (4 hunks)
  • client/components/open/forms/OpenForm.vue (3 hunks)
  • client/components/open/forms/OpenFormFocused.vue (1 hunks)
  • client/components/open/forms/components/form-components/FormCustomization.vue (5 hunks)
  • client/i18n/lang/ar.json (1 hunks)
  • client/i18n/lang/bn.json (1 hunks)
  • client/i18n/lang/de.json (1 hunks)
  • client/i18n/lang/en.json (1 hunks)
  • client/i18n/lang/es.json (1 hunks)
  • client/i18n/lang/fr.json (1 hunks)
  • client/i18n/lang/hi.json (1 hunks)
  • client/i18n/lang/ja.json (1 hunks)
  • client/i18n/lang/jv.json (1 hunks)
  • client/i18n/lang/ko.json (1 hunks)
  • client/i18n/lang/mr.json (1 hunks)
  • client/i18n/lang/pa.json (1 hunks)
  • client/i18n/lang/pt.json (1 hunks)
  • client/i18n/lang/ru.json (1 hunks)
  • client/i18n/lang/ta.json (1 hunks)
  • client/i18n/lang/te.json (1 hunks)
  • client/i18n/lang/tr.json (1 hunks)
  • client/i18n/lang/ur.json (1 hunks)
  • client/i18n/lang/vi.json (1 hunks)
  • client/i18n/lang/zh.json (1 hunks)
🚧 Files skipped from review as they are similar to previous changes (12)
  • client/i18n/lang/zh.json
  • client/i18n/lang/ar.json
  • api/app/Http/Requests/UserFormRequest.php
  • client/i18n/lang/en.json
  • api/app/Models/Forms/Form.php
  • client/i18n/lang/es.json
  • client/i18n/lang/fr.json
  • client/i18n/lang/pt.json
  • client/i18n/lang/hi.json
  • client/i18n/lang/ja.json
  • client/components/open/forms/OpenForm.vue
  • client/components/open/forms/OpenCompleteForm.vue
🔇 Additional comments (10)
client/components/open/forms/components/form-components/FormCustomization.vue (1)

229-229: LGTM!

The imports and reactive state management follow Vue's best practices.

Also applies to: 242-242

client/i18n/lang/ko.json (1)

6-7: LGTM! Korean translations are accurate

The translations for "back" (뒤로) and "next" (다음) are correct and follow standard Korean UI conventions.

client/i18n/lang/vi.json (1)

6-7: LGTM! Vietnamese translations are accurate

The translations for "back" (Trở lại) and "next" (Tiếp tục) are correct and follow standard Vietnamese UI conventions.

client/i18n/lang/bn.json (1)

6-7: LGTM! Bengali translations are accurate

The translations for "back" ("পেছনে") and "next" ("পরবর্তী") are correct and follow proper Bengali language conventions.

client/i18n/lang/tr.json (2)

6-7: LGTM! Turkish translations are accurate

The translations for "back" ("Geri") and "next" ("İleri") are correct and follow standard Turkish UI conventions.


6-7: Verify completeness of the Form focused mode implementation

While the navigation translations look good (except for the Urdu "next" translation), the PR title suggests a "Form focused mode" feature, but we only see language file changes. The AI summary also mentions format attributes and database schema changes.

Let's verify if all necessary files are included:

✅ Verification successful

Form focused mode implementation is complete and properly integrated

The implementation of the Form focused mode feature is complete and includes all necessary components:

  • The format selection is implemented in FormFormatModal.vue allowing users to choose between "Regular format" and "Focused format"
  • The focused mode implementation in OpenFormFocused.vue handles one-question-per-page display with proper navigation
  • The preview component in FormEditorPreview.vue correctly renders the focused mode with proper styling
  • The translations for navigation buttons ("back" and "next") are properly integrated

The PR changes are consistent with the complete feature implementation.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Check for related changes in the codebase

# Look for files with "format" related changes
echo "Searching for format-related files..."
rg -l "format.*Form" --type php --type vue

# Look for database migration files
echo "Searching for migration files..."
fd -e php -p "database/migrations"

# Look for form-related component changes
echo "Searching for form components..."
rg -l "focused.*mode" --type vue

Length of output: 5422


Script:

#!/bin/bash
# Let's try a different approach to find Vue files and form-related changes

# Look for Vue files with form focus mode changes
echo "Searching for form focus mode in all files..."
rg -l "form.*focus" 

# Look for recent migration about format
echo "Checking recent migration about format..."
cat "api/database/migrations/2024_12_04_163142_add_format_to_forms_table.php"

# Look for Vue files specifically
echo "Finding Vue files..."
fd -e vue

Length of output: 13594


Script:

#!/bin/bash
# Let's examine the focused form mode implementation and format changes

# Check the focused form implementation
echo "Checking OpenFormFocused.vue content..."
cat "client/components/open/forms/OpenFormFocused.vue"

# Check the format modal implementation
echo "Checking FormFormatModal.vue content..."
cat "client/components/pages/forms/create/FormFormatModal.vue"

# Check for format-related changes in the form editor
echo "Checking FormEditorPreview.vue content..."
cat "client/components/open/forms/components/form-components/FormEditorPreview.vue"

Length of output: 23477

client/i18n/lang/jv.json (1)

6-7: LGTM! Translations are accurate

The Indonesian translations for "back" ("Kembali") and "next" ("Lanjut") are correct and consistent with common UI terminology.

client/i18n/lang/ru.json (1)

6-7: LGTM! Translations are accurate and consistent

The Russian translations for "back" ("Назад") and "next" ("Вперед") are correct and align with common UI patterns. The translation for "back" is also consistent with the existing "goBack" translation in the file.

client/components/open/forms/OpenFormFocused.vue (2)

98-112: Ensure the hCaptcha element exists before accessing its value.

This is a duplicate of a previous review comment. The code still needs to check if the captcha element exists before accessing its value to prevent runtime errors.


534-538: LGTM!

The styling implementation is clean and follows Tailwind best practices.

Comment on lines +57 to +60
<FormatChangeModal
:show="showFormatChangeModal"
@close="showFormatChangeModal = false"
/>
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

Reset format selection when modal is closed.

When the format change modal is closed (cancelled), the format selection should revert to 'regular'. This ensures the UI stays in sync with the actual format.

     <FormatChangeModal
       :show="showFormatChangeModal"
-      @close="showFormatChangeModal = false"
+      @close="() => {
+        showFormatChangeModal = false;
+        if (form.format === 'focused') {
+          form.format = 'regular';
+        }
+      }"
     />

Committable suggestion skipped: line range outside the PR's diff.

Comment on lines +6 to +7
"back": "ਪੁਛਣਾ",
"next": "ਪੁਛਣਾ",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect Punjabi translations

The current translations have two issues:

  1. Both "back" and "next" are translated to the same word "ਪੁਛਣਾ" (puchna)
  2. "ਪੁਛਣਾ" means "to ask" which is incorrect for navigation buttons

Please update the translations to:

-        "back": "ਪੁਛਣਾ",
-        "next": "ਪੁਛਣਾ",
+        "back": "ਪਿੱਛੇ",
+        "next": "ਅੱਗੇ",
📝 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
"back": "ਪੁਛਣਾ",
"next": "ਪੁਛਣਾ",
"back": "ਪਿੱਛੇ",
"next": "ਅੱਗੇ",

Comment on lines +6 to +7
"back": "پیچھے",
"next": "پیچھے",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect Urdu translation for "next"

The translation for "next" is incorrectly set to "پیچھے" (meaning "back"), which is the same as the "back" translation. This would confuse users as both navigation buttons would show the same text.

Apply this fix:

  "back": "پیچھے",
- "next": "پیچھے",
+ "next": "آگے",
📝 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
"back": "پیچھے",
"next": "پیچھے",
"back": "پیچھے",
"next": "آگے",

Comment on lines +6 to +7
"back": "पुढे",
"next": "पुढे",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Fix incorrect Marathi translation for "back"

The translation for "back" is incorrect. Currently, both "back" and "next" are translated to "पुढे" (forward/next), which would confuse Marathi users.

Apply this correction:

-        "back": "पुढे",
+        "back": "मागे",
         "next": "पुढे",
📝 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
"back": "पुढे",
"next": "पुढे",
"back": "मागे",
"next": "पुढे",

Comment on lines +6 to +7
"back": "పిలుస్తా",
"next": "పిలుస్తా",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect Telugu translations for navigation buttons

The current translations are incorrect:

  1. Both "back" and "next" are translated to "పిలుస్తా" (pilustā) which means "I will call"
  2. Using the same text for different actions will confuse users

Please update the translations to:

-        "back": "పిలుస్తా",
-        "next": "పిలుస్తా",
+        "back": "వెనుకకు",
+        "next": "తదుపరి",
📝 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
"back": "పిలుస్తా",
"next": "పిలుస్తా",
"back": "వెనుకకు",
"next": "తదుపరి",

Comment on lines +6 to +7
"back": "பின்னுக்கு",
"next": "பின்னுக்கு",
Copy link
Contributor

Choose a reason for hiding this comment

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

⚠️ Potential issue

Incorrect Tamil translation for "next" button

While "பின்னுக்கு" is correct for "back", using it for "next" is incorrect and will confuse users.

Please update the translations to:

         "back": "பின்னுக்கு",
-        "next": "பின்னுக்கு",
+        "next": "அடுத்து",
📝 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
"back": "பின்னுக்கு",
"next": "பின்னுக்கு",
"back": "பின்னுக்கு",
"next": "அடுத்து",

Comment on lines +490 to +496
handleValidationError(error) {
console.error(error)
if (error?.data?.message) {
useAlert().error(error.data.message)
}
this.dataForm.busy = false
},
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

Improve error handling in handleValidationError.

The current implementation only logs errors to console and shows a generic message. Consider providing more detailed error feedback to users.

 handleValidationError(error) {
-  console.error(error)
+  const errorDetails = error?.data?.errors || {}
+  const fieldErrors = Object.entries(errorDetails)
+    .map(([field, messages]) => `${field}: ${messages.join(', ')}`)
+    .join('\n')
+
   if (error?.data?.message) {
-    useAlert().error(error.data.message)
+    useAlert().error({
+      title: error.data.message,
+      message: fieldErrors || 'Please check your input and try again.',
+      duration: 5000
+    })
   }
   this.dataForm.busy = false
 }
📝 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
handleValidationError(error) {
console.error(error)
if (error?.data?.message) {
useAlert().error(error.data.message)
}
this.dataForm.busy = false
},
handleValidationError(error) {
const errorDetails = error?.data?.errors || {}
const fieldErrors = Object.entries(errorDetails)
.map(([field, messages]) => `${field}: ${messages.join(', ')}`)
.join('\n')
if (error?.data?.message) {
useAlert().error({
title: error.data.message,
message: fieldErrors || 'Please check your input and try again.',
duration: 5000
})
}
this.dataForm.busy = false
},

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.

1 participant