Skip to content

Conversation

@wkarts
Copy link

@wkarts wkarts commented Oct 5, 2024

Descrição

Este Pull Request atualiza a configuração da UnoAPI, adicionando a capacidade de manipulação de webhooks dentro das configurações da UnoAPI. Agora é possível gerenciar webhooks diretamente pela interface de configuração, facilitando a integração com sistemas externos.

Fixes: #(número da issue, se aplicável)

Tipo de mudança

  • Correção de bug (mudança que corrige um problema sem quebrar funcionalidades existentes)
  • Nova funcionalidade (mudança que adiciona uma nova funcionalidade sem quebrar funcionalidades existentes)
  • Mudança crítica (mudança que pode quebrar funcionalidades existentes)
  • Atualização de documentação necessária

Como foi testado?

Descreva os testes realizados para garantir que a funcionalidade está funcionando corretamente. Inclua instruções para reproduzir os testes e detalhes da configuração de ambiente de teste.

  • Teste manual da interface de configuração de webhooks
  • Teste automatizado dos endpoints relacionados aos webhooks

Checklist

  • Meu código segue as diretrizes de estilo do projeto
  • Realizei uma autoavaliação do meu código
  • Comentei meu código em áreas de difícil compreensão
  • Fiz as mudanças necessárias na documentação
  • Minhas mudanças não geram novos avisos
  • Adicionei testes que comprovam a eficácia da correção/funcionalidade
  • Os testes unitários novos e existentes passaram localmente
  • Quaisquer mudanças dependentes foram mescladas e publicadas nos módulos a jusante

Esse modelo serve como base para informar sobre a nova funcionalidade de manipulação de webhooks dentro da UnoAPI.

Summary by CodeRabbit

  • New Features

    • Introduced a tabbed interface for managing WhatsApp settings with "Parameters" and "Webhooks" sections.
    • Added fields for managing webhook settings, including call rejection and message handling options.
    • Implemented a table for viewing, editing, and deleting existing webhooks.
    • Added modal forms for adding and editing webhook details.
    • Expanded localization support for English, Spanish, and Portuguese, enhancing user experience across languages.
  • Bug Fixes

    • Improved validation error messages for input fields to enhance user feedback.
  • Enhancements

    • Enhanced overall usability for managing WhatsApp settings through a structured interface.

@coderabbitai
Copy link

coderabbitai bot commented Oct 5, 2024

Walkthrough

The changes encompass significant updates to the UnoapiConfiguration.vue component and the Whatsapp::UnoapiWebhookSetupService class. The Vue component now features a tabbed interface for managing WhatsApp settings, including a "Parameters" tab for input fields and a "Webhooks" tab for managing webhook entries. The service class has been enhanced with a new method to prevent duplicate webhook entries and to allow dynamic configuration of webhooks. Additionally, localization files have been updated to support these new features in multiple languages.

Changes

File Path Change Summary
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue Introduced a tabbed interface with "Parameters" and "Webhooks" sections; added input fields and validation; implemented methods for managing webhooks and tab changes.
app/services/whatsapp/unoapi_webhook_setup_service.rb Added create_webhook method to manage webhook creation and prevent duplicates; updated params method for dynamic webhook configuration.
app/javascript/dashboard/i18n/locale/en/inboxMgmt.json Added new keys for "Parameters" and "Webhooks" in the WhatsApp section, including labels and error messages for webhook management.
app/javascript/dashboard/i18n/locale/es/inboxMgmt.json Introduced new keys for "Parameters" and "Webhooks" in the WhatsApp section, enhancing webhook management capabilities.
app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json Added new section for WhatsApp integration with labels and error messages for webhook management.
app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json Enhanced localization for WhatsApp webhook management with new keys for parameters and actions.

Poem

In the garden of code, where changes bloom,
Tabs now dance, dispelling the gloom.
Webhooks frolic, no duplicates found,
With each new feature, joy does abound!
Hops of delight in a structured embrace,
Managing WhatsApp with elegance and grace. 🐇✨


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

@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: 8

🧹 Outside diff range and nitpick comments (7)
app/services/whatsapp/unoapi_webhook_setup_service.rb (2)

101-101: Remove commented-out code if not needed

The commented-out code for the 'Typebot' webhook may not be necessary to keep in the codebase. Removing unused code can improve readability.

Apply this diff to remove the commented code:

-    # Webhook Typebot
-    # create_webhook(provider_config, phone_number, 'typebot', "#{ENV.fetch('FRONTEND_URL', '')}/webhooks/typebot/#{phone_number}")

Line range hint 95-119: Consider refactoring the 'params' method to reduce complexity

The params method is lengthy and marked with rubocop:disable Metrics/MethodLength, indicating it exceeds recommended complexity. Refactoring it into smaller helper methods can enhance readability and maintainability.

Example:

def params(provider_config, phone_number)
  create_default_webhooks(provider_config, phone_number)
  provider_config.slice(
    'ignore_group_messages',
    'ignore_broadcast_statuses',
    'ignore_broadcast_messages',
    'ignore_history_messages',
    'ignore_own_messages',
    'ignore_yourself_messages',
    'send_connection_status',
    'notify_failed_messages',
    'composing_message',
    'reject_calls',
    'message_calls_webhook',
    'webhooks',
    'send_reaction_as_reply',
    'send_profile_picture',
    'api_key',
    'use_reject_calls'
  ).transform_keys(&:to_sym)
end
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (5)

371-371: Use 'password' type for token input to enhance security

The input field for the token on line 371 uses type="text", which displays the token in plain text. This could lead to security vulnerabilities if someone overlooks the screen.

Apply this change to obscure the token input:

-        <input v-model="webhookForm.token" type="text" />
+        <input v-model="webhookForm.token" type="password" />

Line range hint 562-580: Ensure socket connection is properly closed to prevent memory leaks

In the listenerQrCode() method, the socket connection is established but not closed when the component is destroyed. This can lead to memory leaks and unintended behavior.

Add a beforeDestroy hook to disconnect the socket:

+  beforeDestroy() {
+    if (this.socket) {
+      this.socket.disconnect();
+    }
+  },

Also, store the socket instance as a component property:

-    const socket = io(url, { path: '/ws' });
+    this.socket = io(url, { path: '/ws' });

Line range hint 577-585: Use a cryptographically secure method for token generation

The generateToken() method uses Math.random(), which is not suitable for generating cryptographically secure tokens. This may lead to predictable tokens, compromising security.

Consider using the Web Crypto API's window.crypto.getRandomValues() method:

-  generateToken() {
-    const characters = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789';
-    let token = '';
-    for (let i = 0; i < 64; i++) {
-      token += characters.charAt(Math.floor(Math.random() * characters.length));
-    }
-    // Rest of the code
-  },
+  generateToken() {
+    const array = new Uint8Array(64);
+    window.crypto.getRandomValues(array);
+    const token = Array.from(array, byte => byte.toString(16).padStart(2, '0')).join('');
+    // Rest of the code
+  },

183-205: Clarify similar variable names to avoid confusion

Variables ignoreOwnMessages and ignoreYourselfMessages are used between lines 183 and 205. The similarity in names could lead to confusion about their purposes.

Consider renaming these variables to more descriptive names that clearly differentiate their functionalities.


317-322: Clean up commented-out code in the table header

Lines 320 and 321 contain empty <th> elements with commented-out code inside. This can clutter the codebase and may cause confusion.

Remove the commented-out code if it's no longer needed:

          <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ID') }}</th>
          <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.URL_ABSOLUT') }}</th>
-         <th></th> <!-- <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.BUTTON') }}</th> -->
-         <th></th> <!-- <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ACTIONS') }}</th> -->
+         <th></th>
+         <th></th>
📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 117a5e8 and 2f7d1d4.

📒 Files selected for processing (2)
  • app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (8 hunks)
  • app/services/whatsapp/unoapi_webhook_setup_service.rb (2 hunks)
🔇 Additional comments (3)
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (3)

628-638: Ensure all provider configurations are correctly updated

The updateInbox method updates several provider configurations between lines 628 and 638. Verify that all these configurations are correctly passed to the backend and stored.

Run the following script to check the usage of the updateInbox action:

#!/bin/bash
# Description: Verify that the 'updateInbox' action handles all provider configurations.

# Test: Search for the 'updateInbox' action definition. Expect: Handling of all provider_config properties.
rg --type=js "updateInbox.*provider_config.*{" -A 15

231-233: ⚠️ Potential issue

Remove unused validation rule for 'generateQrcode'

In the validations object, generateQrcode is included but does not correspond to any data property or usage in the component.

Remove the unused validation rule to clean up the code:

validations: {
  apiKey: { required },
  ignoreGroupMessages: { required },
-  generateQrcode: { required },
  // Rest of the validations
},

Likely invalid or redundant comment.


533-539: Verify the alert function in 'removeWebhook' method

In the removeWebhook method, useAlert is called on line 537 to notify the user when attempting to delete a default webhook. Ensure that useAlert is properly imported and functioning.

Run the following script to check for the import of useAlert:

✅ Verification successful

'useAlert' is properly imported and functioning in the 'removeWebhook' method within UnoapiConfiguration.vue.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Description: Verify that 'useAlert' is imported in the component.

# Test: Search for the import statement. Expect: An import of 'useAlert' from 'dashboard/composables'.
rg --type=vue "import\s+{.*useAlert.*}\s+from\s+['\"]dashboard/composables['\"]"

Length of output: 274


Script:

#!/bin/bash
# Description: Verify that 'useAlert' is imported in the component.

# Corrected Test: Search for the import statement. Expect: An import of 'useAlert' from 'dashboard/composables'.
rg --type=vue "import\s+\{[^}]*useAlert[^}]*\}\s+from\s+['\"]dashboard/composables['\"]"

Length of output: 122


Script:

#!/bin/bash
# Description: Verify that 'useAlert' is imported in the component.

# Updated Test: Search for the import statement in .vue files. Expect: An import of 'useAlert' from 'dashboard/composables'.
rg "import\s+\{[^}]*useAlert[^}]*\}\s+from\s+['\"]dashboard/composables['\"]" --glob '*.vue'

Length of output: 18335

Comment on lines +75 to +76
# Função que adiciona webhooks sem duplicar
def create_webhook(provider_config, phone_number, id_base, url_base)
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Inconsistent comment language: Use English for code comments

The comments on lines 75 and 76 are in Portuguese. For consistency and to aid collaboration among team members, it's recommended to use English for all code comments.

Apply this diff to update the comments:

-  # Função que adiciona webhooks sem duplicar
+  # Function that adds webhooks without duplication
  def create_webhook(provider_config, phone_number, id_base, url_base)
📝 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
# Função que adiciona webhooks sem duplicar
def create_webhook(provider_config, phone_number, id_base, url_base)
# Function that adds webhooks without duplication
def create_webhook(provider_config, phone_number, id_base, url_base)


# Função que adiciona webhooks sem duplicar
def create_webhook(provider_config, phone_number, id_base, url_base)
webhooks = provider_config['webhooks']
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Initialize 'webhooks' to prevent potential 'nil' errors

If provider_config['webhooks'] is nil, assigning it to webhooks will lead to a NoMethodError when calling .any? or <<. Ensure that 'webhooks' is initialized as an array to prevent errors.

Apply this diff to initialize 'webhooks' if necessary:

-    webhooks = provider_config['webhooks']
+    webhooks = provider_config['webhooks'] ||= []
📝 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
webhooks = provider_config['webhooks']
webhooks = provider_config['webhooks'] ||= []


# Adiciona o webhook no provider_config
webhooks << {
sendNewMessages: provider_config['webhook_send_new_messages'] || true,
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Use 'fetch' to correctly handle default values

The expression provider_config['webhook_send_new_messages'] || true will return true even if provider_config['webhook_send_new_messages'] is false. This might not be the intended behavior if you want to respect a false value. Consider using fetch with a default to handle this correctly.

Apply this diff to ensure the default value is used only when the key is missing:

-      sendNewMessages: provider_config['webhook_send_new_messages'] || true,
+      sendNewMessages: provider_config.fetch('webhook_send_new_messages', true),
📝 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
sendNewMessages: provider_config['webhook_send_new_messages'] || true,
sendNewMessages: provider_config.fetch('webhook_send_new_messages', true),

# Exemplo de configuração para múltiplos webhooks
def params(provider_config, phone_number)
# Webhook padrão
create_webhook(provider_config, phone_number, 'default', "#{ENV.fetch('FRONTEND_URL', '')}/webhooks/whatsapp/#{phone_number}")
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Validate 'FRONTEND_URL' to ensure valid webhook URLs

If ENV.fetch('FRONTEND_URL', '') returns an empty string, the constructed url_base might be invalid. This could lead to issues when setting up webhooks with an incorrect URL.

Consider adding validation for FRONTEND_URL:

+    frontend_url = ENV.fetch('FRONTEND_URL', '')
+    if frontend_url.empty?
+      raise "FRONTEND_URL environment variable is not set"
+    end
+    create_webhook(provider_config, phone_number, 'default', "#{frontend_url}/webhooks/whatsapp/#{phone_number}")
📝 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
create_webhook(provider_config, phone_number, 'default', "#{ENV.fetch('FRONTEND_URL', '')}/webhooks/whatsapp/#{phone_number}")
frontend_url = ENV.fetch('FRONTEND_URL', '')
if frontend_url.empty?
raise "FRONTEND_URL environment variable is not set"
end
create_webhook(provider_config, phone_number, 'default', "#{frontend_url}/webhooks/whatsapp/#{phone_number}")

Comment on lines +88 to +91
id: id_base,
urlAbsolute: url_base,
token: provider_config['webhook_verify_token'],
header: 'Authorization'
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consistency in handling default values for optional parameters

Similar to sendNewMessages, other parameters might also need to handle default values correctly. Using fetch with a default value ensures that false values are not overridden unintentionally.

Consider updating the parameters as follows:

-      id: id_base,
-      urlAbsolute: url_base,
-      token: provider_config['webhook_verify_token'],
-      header: 'Authorization'
+      id: id_base,
+      urlAbsolute: url_base,
+      token: provider_config.fetch('webhook_verify_token', 'default_token'),
+      header: provider_config.fetch('header', 'Authorization')
📝 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
id: id_base,
urlAbsolute: url_base,
token: provider_config['webhook_verify_token'],
header: 'Authorization'
id: id_base,
urlAbsolute: url_base,
token: provider_config.fetch('webhook_verify_token', 'default_token'),
header: provider_config.fetch('header', 'Authorization')

apiKey: '',
wavoipToken: '',
url: 'https://unoapi.cloud',
url: 'https://cloud.unoapi',
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Avoid hardcoding URLs to enhance flexibility

The url data property is hardcoded to 'https://cloud.unoapi' on line 417. Hardcoding URLs can lead to issues if the endpoint changes or if different environments require different URLs.

Consider retrieving the URL from a configuration file or environment variable to make the application more flexible and adaptable.

Comment on lines +716 to +717
transform: translatex(407px) translatey(-347px);
width: 300px;
Copy link

Choose a reason for hiding this comment

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

⚠️ Potential issue

Correct CSS transform properties for proper rendering

In lines 716 and 717, the CSS uses translatex and translatey. CSS transform functions are case-sensitive and should be translateX and translateY.

Apply this correction:

.flex-shrink div img {
-  transform: translatex(407px) translatey(-347px);
+  transform: translateX(407px) translateY(-347px);
  width: 300px;
  height: 300px;
}
📝 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
transform: translatex(407px) translatey(-347px);
width: 300px;
transform: translateX(407px) translateY(-347px);
width: 300px;

Copy link

@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: 4

🧹 Outside diff range and nitpick comments (11)
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (3)

Line range hint 417-417: Avoid hardcoding URLs to enhance flexibility

The url data property is hardcoded to 'https://unoapi.cloud' on line 417. Hardcoding URLs can lead to issues if the endpoint changes or if different environments require different URLs.

Consider retrieving the URL from a configuration file or environment variable to make the application more flexible and adaptable. For example:

data() {
  return {
    url: process.env.VUE_APP_UNOAPI_URL || 'https://unoapi.cloud',
    // ... other data properties
  };
},

Make sure to set the VUE_APP_UNOAPI_URL environment variable in your deployment process or .env file.


Line range hint 563-589: Optimize socket connection handling for better performance

The current implementation of the socket connection in the listenerQrCode method could potentially lead to performance issues, especially if the component is mounted and unmounted frequently.

Consider the following improvements:

  1. Move the socket connection logic to a separate service or composable function.
  2. Implement proper connection cleanup in the beforeUnmount lifecycle hook.
  3. Use a single, persistent socket connection for the entire application instead of creating a new one for each component instance.

Here's an example of how you could start refactoring this:

// socketService.js
import { io } from 'socket.io-client';

let socket = null;

export const connectSocket = (url) => {
  if (!socket) {
    socket = io(url, { path: '/ws' });
  }
  return socket;
};

export const disconnectSocket = () => {
  if (socket) {
    socket.disconnect();
    socket = null;
  }
};

// In your component
import { connectSocket, disconnectSocket } from '@/services/socketService';

export default {
  // ...
  mounted() {
    this.setupSocketListener();
  },
  beforeUnmount() {
    this.cleanupSocketListener();
  },
  methods: {
    setupSocketListener() {
      const url = `${this.inbox.provider_config.url}`.replace('https', 'wss').replace('http', 'ws');
      this.socket = connectSocket(url);
      this.socket.on('broadcast', this.handleBroadcast);
    },
    cleanupSocketListener() {
      if (this.socket) {
        this.socket.off('broadcast', this.handleBroadcast);
      }
    },
    handleBroadcast(data) {
      // Handle broadcast data
    },
  },
};

This refactoring will improve the performance and reliability of the socket connection handling.


Line range hint 663-745: Improve CSS organization and use of Vue's scoped styles

The current style section could be improved for better maintainability and to take full advantage of Vue's scoped styles feature.

Consider the following improvements:

  1. Use more specific selectors to avoid potential conflicts with global styles.
  2. Leverage Vue's scoped styles feature more effectively by using the ::v-deep selector only when necessary.
  3. Group related styles together and use comments to separate different sections of the stylesheet.
  4. Consider using CSS custom properties (variables) for repeated values like colors and sizes.

Here's an example of how you could start refactoring the styles:

<style lang="scss" scoped>
// Variables
$primary-color: #369eff;
$spacing-unit: 8px;

// General layout
.unoapi-configuration {
  &__content {
    ::v-deep input {
      margin-bottom: 0;
    }
  }

  &__checkbox {
    margin: 0 $spacing-unit/2;
  }
}

// Switch styles
.switch {
  flex: 0 0 auto;
  margin-right: $spacing-unit * 1.25;

  &-label {
    display: flex;
    align-items: center;
  }
}

// Specific element styles
.messaging-service-helptext {
  width: 343px;
  max-width: 343px;
  margin-bottom: $spacing-unit;
}

.webhook-table {
  width: 100%;
  
  th,
  td {
    padding: $spacing-unit;
    text-align: left;
  }
}

// Modal styles
.modal {
  &__header {
    background-color: $primary-color;
    color: white;
  }
}

// ... other styles
</style>

This refactoring will improve the organization and maintainability of your styles, making it easier to manage and update in the future.

app/javascript/dashboard/i18n/locale/es/inboxMgmt.json (3)

232-233: Consider clarifying the webhook description.

The current translation for the webhook description is:

"DESCRIPTION": "Lista de Webhooks Disponibles - Evite crear webhooks con el mismo ID y URL de otro ya existente.",

To improve clarity and consistency with technical terms, consider revising it to:

"DESCRIPTION": "Lista de Webhooks Disponibles - Evite crear webhooks con el mismo ID o URL que uno ya existente.",

This small change makes the instruction more precise and easier to understand.


236-237: Improve consistency in button and action labels.

For better consistency and clarity, consider the following changes:

  1. Change "BUTTON" to "BUTTON_LABEL" to match the naming convention of other label keys.
  2. Modify the "ACTIONS" translation to be more specific:
"BUTTON_LABEL": "Enviar nuevos mensajes al Webhook",
"ACTIONS": "Acciones"

This change improves consistency with other parts of the translation file and makes the purpose of each key clearer.


240-241: Clarify the "HEADER" translation.

The current translation for "HEADER" is:

"HEADER": "Encabezado del Token",

To make it clearer that this refers to the HTTP header, consider changing it to:

"HEADER": "Encabezado HTTP del Token",

This change provides more context and reduces potential confusion for users.

app/javascript/dashboard/i18n/locale/en/inboxMgmt.json (3)

229-250: New localization strings added for WhatsApp webhook management.

The addition of the TAB_NAME object under the WHATSAPP key introduces localization strings for a new feature related to webhook management. This is a good practice for internationalization. Here are some observations:

  1. The structure is well-organized, with clear separation between different elements of the UI.
  2. The strings provide good context for users, especially the DESCRIPTION which explains the purpose and limitations of webhooks.
  3. The inclusion of action-specific strings (e.g., EDIT, DELETE, SAVE) allows for consistent terminology across the application.

However, there are a couple of points to consider:

  1. The key URL_ABSOLUT seems to have a typo. It should probably be URL_ABSOLUTE.
  2. Consider adding a string for a "no webhooks" state to guide users when the list is empty.

Consider making the following minor improvements:

  1. Correct the typo in the URL_ABSOLUT key to URL_ABSOLUTE.
  2. Add a string for the empty state of the webhook list, e.g., "NO_WEBHOOKS": "No webhooks configured yet. Add one to get started.".

Line range hint 251-338: New WhatsApp configuration options added.

Several new configuration options have been added to the WhatsApp channel settings. These additions enhance the flexibility and control users have over their WhatsApp integration. Here are some observations:

  1. The new options cover a wide range of features, from handling agent names to managing broadcast messages and connection statuses.
  2. The structure is consistent, with each option having a LABEL, PLACEHOLDER, and ERROR field.
  3. The labels and placeholders are generally clear and descriptive.

However, there are a few points to consider:

  1. Some options like IGNORE_HISTORY and WEBWOOK_SEND_NEW_MESSAGES have identical placeholder text, which might be confusing.
  2. The WAVOIP_TOKEN option mentions "whatsapp calls", but there's no other context about this feature in the file.
  3. The COMPOSING_MESSAGE option's purpose is not immediately clear from its label and placeholder.

Consider the following improvements:

  1. Update the placeholder text for IGNORE_HISTORY and WEBWOOK_SEND_NEW_MESSAGES to be more specific to each option.
  2. Add more context about the WAVOIP_TOKEN and its relation to WhatsApp calls, perhaps in the placeholder text.
  3. Clarify the purpose of the COMPOSING_MESSAGE option in its label or placeholder.
  4. Consider grouping related options together (e.g., all "ignore" options) for better organization.

Line range hint 229-338: Overall enhancement of WhatsApp channel configuration options.

The changes in this file significantly expand the configuration options for the WhatsApp channel, aligning with the PR objective of updating the UnoAPI configuration. The additions include:

  1. A new webhook management interface with appropriate localization strings.
  2. Multiple new configuration options for fine-tuning the WhatsApp integration behavior.

These changes will provide users with more control over their WhatsApp channel, allowing for better customization and integration with external systems. The localization strings are well-structured and should facilitate easy translation to other languages.

To ensure the best user experience, consider the following recommendations:

  1. Review and clarify any ambiguous labels or placeholders.
  2. Group related options together for better organization.
  3. Provide additional context or documentation for complex features (e.g., WAVOIP integration).

As these changes introduce many new configuration options, consider implementing a guided setup or configuration wizard to help users understand and properly set up these options. This could significantly improve the user experience, especially for complex integrations like webhook management.

app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json (2)

223-244: New translations added for WhatsApp webhook management

The new translations for WhatsApp webhook management have been added successfully. The structure and content appear to be consistent with the rest of the file. Here are a few observations:

  1. The translations cover essential elements such as parameters, webhooks, actions, and error messages.
  2. The language used is appropriate for a technical interface.
  3. The translations maintain a consistent style with the rest of the file.

However, there's a minor inconsistency in capitalization that could be addressed:

Consider standardizing the capitalization of the first word in each translation. For example:

-          "DESCRIPTION": "Lista de Webhooks Disponíveis - Evite criar webhooks com o mesmo ID e URL de outro já existente.",
+          "DESCRIPTION": "lista de Webhooks Disponíveis - Evite criar webhooks com o mesmo ID e URL de outro já existente.",
-          "BUTTON": "Enviar novas mensagens para o Webhook",
+          "BUTTON": "enviar novas mensagens para o Webhook",

This would make it consistent with other entries in the file, such as "lista de Webhooks Disponíveis" and "enviar novas mensagens para o Webhook".


Missing documentation for new WhatsApp configuration options

The new WhatsApp configuration options such as SEND_AGENT_NAME, IGNORE_HISTORY, WEBWOOK_SEND_NEW_MESSAGES, and IGNORE_GROUPS are not documented elsewhere in the application. Please ensure that these options are properly documented to aid user understanding and usage.

🔗 Analysis chain

Line range hint 245-359: New WhatsApp configuration options added

The new WhatsApp configuration options have been successfully added to the translation file. These additions enhance the functionality of the WhatsApp integration. Here are some observations:

  1. The new fields cover a wide range of configuration options, including agent name sending, history handling, webhook configuration, and call handling.
  2. The translations are generally clear and concise.
  3. The structure is consistent with the rest of the file.

However, there are a few points that could be improved:

  1. Some translations could be more natural or idiomatic in Portuguese. For example:
-  "PLACEHOLDER": "Selecione para enviar o nome do agent.",
+  "PLACEHOLDER": "Selecione para enviar o nome do agente.",
  1. There's an inconsistency in the use of periods at the end of sentences. Consider standardizing this across all entries.

  2. The "GENERATE_API_KEY" section seems to be in English instead of Portuguese:

-  "GENERATE_API_KEY": {
-    "LABEL": "Generate API Key",
-    "PLACEHOLDER": "Generate API Key",
-    "ERROR": "Generate API Key"
-  },
+  "GENERATE_API_KEY": {
+    "LABEL": "Gerar Chave de API",
+    "PLACEHOLDER": "Gerar Chave de API",
+    "ERROR": "Gerar Chave de API"
+  },
  1. Some new fields might require additional context or explanation. Let's verify if these new options are documented elsewhere in the application:

This will help ensure that users understand the purpose and impact of these new configuration options.

🏁 Scripts executed

The following scripts were executed for the analysis:

Script:

#!/bin/bash
# Search for documentation or usage of new WhatsApp configuration options
rg --type-add 'vue:*.vue' --type vue -i 'SEND_AGENT_NAME|IGNORE_HISTORY|WEBWOOK_SEND_NEW_MESSAGES|IGNORE_GROUPS'

Length of output: 3538

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 2f7d1d4 and 19375c5.

📒 Files selected for processing (5)
  • app/javascript/dashboard/i18n/locale/en/inboxMgmt.json (1 hunks)
  • app/javascript/dashboard/i18n/locale/es/inboxMgmt.json (1 hunks)
  • app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json (1 hunks)
  • app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json (1 hunks)
  • app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (7 hunks)
🔇 Additional comments (6)
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (2)

Line range hint 1-745: Overall assessment: Significant improvements with room for optimization

The changes to UnoapiConfiguration.vue have greatly enhanced its functionality and user experience. The addition of a tabbed interface, new configuration options, and webhook management features are all positive improvements. However, there are several areas where the code could be further optimized for better maintainability, performance, and reusability:

  1. The template section could benefit from creating reusable components for repetitive elements like switches and the webhook table.
  2. The script section could be improved by avoiding hardcoded values, optimizing webhook management methods, and refactoring the socket connection handling.
  3. The style section could be better organized and take full advantage of Vue's scoped styles feature.

While the current implementation is functional, implementing the suggested refactoring and optimizations will result in a more robust, maintainable, and performant component. Consider addressing these points in future iterations of the code.


716-717: ⚠️ Potential issue

Correct CSS transform properties for proper rendering

In lines 716 and 717, the CSS uses translatex and translatey. CSS transform functions are case-sensitive and should be translateX and translateY.

Apply this correction:

.flex-shrink div img {
-  transform: translatex(407px) translatey(-347px);
+  transform: translateX(407px) translateY(-347px);
  width: 300px;
  height: 300px;
}

This will ensure that the transform properties are correctly applied across all browsers.

Likely invalid or redundant comment.

app/javascript/dashboard/i18n/locale/es/inboxMgmt.json (2)

227-248: New translations for webhook functionality look good.

The new translations for the webhook functionality in the WhatsApp section have been added correctly. The structure is consistent with the rest of the file, and the translations seem appropriate for Spanish speakers. Here are a few observations:

  1. The new "TAB_NAME" object is well-structured and includes translations for both parameters and webhooks.
  2. The webhook section includes translations for various actions such as editing, deleting, and saving.
  3. Error messages for duplicate URLs and deletion issues are included.

Overall, the additions enhance the user experience for Spanish-speaking users managing webhooks in the WhatsApp channel.


227-248: Overall, the new translations for webhook functionality are well-implemented.

The additions to the Spanish translation file for webhook management in the WhatsApp channel are comprehensive and generally well-structured. They provide good coverage for the new functionality, including labels for various actions, error messages, and descriptions.

A few minor suggestions have been made to improve clarity and consistency:

  1. Clarifying the webhook description to be more precise about avoiding duplicate IDs or URLs.
  2. Improving consistency in button and action labels.
  3. Clarifying the "HEADER" translation to specify it's an HTTP header.

These small changes would further enhance the quality of the translations and improve the user experience for Spanish-speaking users.

app/javascript/dashboard/i18n/locale/pt/inboxMgmt.json (1)

Line range hint 1-624: Overall assessment of the translation file

The changes to the inboxMgmt.json file for Portuguese translations have successfully added new content for WhatsApp integration and configuration. Here's a summary of the review:

  1. The new translations are well-integrated into the existing structure of the file.
  2. The additions provide comprehensive coverage for the new WhatsApp features, including webhook management and various configuration options.
  3. The language used is generally appropriate and consistent with the rest of the file.

The changes are approved, but there are a few minor suggestions for improvement:

  1. Standardize capitalization in the new translations to match the existing style.
  2. Ensure consistent use of punctuation, particularly periods at the end of sentences.
  3. Translate the "GENERATE_API_KEY" section to Portuguese.
  4. Consider reviewing the new configuration options for clarity and potentially adding contextual information or tooltips in the UI to explain their purpose and impact.

These small adjustments will enhance the overall quality and consistency of the translations. Great job on expanding the functionality of the WhatsApp integration!

app/javascript/dashboard/i18n/locale/pt_BR/inboxMgmt.json (1)

223-244: LGTM! New webhook management section added successfully.

The new "TAB_NAME" object under the "WHATSAPP" section has been added correctly, introducing webhook management functionality to the Portuguese (Brazil) localization. The structure is consistent with the existing format, and the translations appear to be accurate.

Key additions include:

  • Labels for parameters and webhooks
  • Descriptions for webhook management actions
  • Error messages related to webhook operations

These changes align well with the PR objectives of adding webhook management capabilities to the UnoAPI configuration.

Comment on lines +97 to +275
<label :class="{ error: v$.sendAgentName.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendAgentName"
:value="sendAgentName"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.LABEL') }}
<span v-if="v$.sendAgentName.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreGroupMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreGroupMessages"
:value="ignoreGroupMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_GROUPS.LABEL') }}
<span v-if="v$.ignoreGroupMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_GROUPS.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreHistoryMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreHistoryMessages"
:value="ignoreHistoryMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_HISTORY.LABEL') }}
<span v-if="v$.ignoreHistoryMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_HISTORY.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.webhookSendNewMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="webhookSendNewMessages"
:value="webhookSendNewMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBWOOK_SEND_NEW_MESSAGES.LABEL') }}
<span v-if="v$.webhookSendNewMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBWOOK_SEND_NEW_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreBroadcastStatuses.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreBroadcastStatuses"
:value="ignoreBroadcastStatuses"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_STATUSES.LABEL') }}
<span v-if="v$.ignoreBroadcastStatuses.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_STATUSES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreBroadcastMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreBroadcastMessages"
:value="ignoreBroadcastMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_MESSAGES.LABEL') }}
<span v-if="v$.ignoreBroadcastMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreOwnMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreOwnMessages"
:value="ignoreOwnMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_OWN_MESSAGES.LABEL') }}
<span v-if="v$.ignoreOwnMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_OWN_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreYourselfMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreYourselfMessages"
:value="ignoreYourselfMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_YOURSELF_MESSAGES.LABEL') }}
<span v-if="v$.ignoreYourselfMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_YOURSELF_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendConnectionStatus.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendConnectionStatus"
:value="sendConnectionStatus"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_CONNECTION_STATUS.LABEL') }}
<span v-if="v$.sendConnectionStatus.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_CONNECTION_STATUS.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.notifyFailedMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="notifyFailedMessages"
:value="notifyFailedMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.NOTIFY_FAILED_MESSAGES.LABEL') }}
<span v-if="v$.notifyFailedMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.NOTIFY_FAILED_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.composingMessage.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="composingMessage"
:value="composingMessage"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.COMPOSING_MESSAGE.LABEL') }}
<span v-if="v$.composingMessage.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.COMPOSING_MESSAGE.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendReactionAsReply.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendReactionAsReply"
:value="sendReactionAsReply"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_REACTION_AS_REPLY.LABEL') }}
<span v-if="v$.sendReactionAsReply.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_REACTION_AS_REPLY.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendProfilePicture.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendProfilePicture"
:value="sendProfilePicture"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_PROFILE_PICTURE.LABEL') }}
<span v-if="v$.sendProfilePicture.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_PROFILE_PICTURE.ERROR') }}
</span>
</label>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider refactoring repetitive switch components

The code between lines 97 and 275 includes multiple woot-switch components with similar structure. This repetition can make the code harder to maintain and more error-prone.

Consider creating a reusable component for these switch inputs. This will promote code reusability and make it easier to manage changes in the future. Here's an example of how you could refactor this:

  1. Create a new component, e.g., ConfigSwitch.vue:
<template>
  <div class="w-3/4 pb-4 config-helptext">
    <label :class="{ error: error }" style="display: flex; align-items: center;">
      <woot-switch
        v-model="modelValue"
        :value="modelValue"
        style="flex: 0 0 auto; margin-right: 10px;"
        @input="$emit('update:modelValue', $event)"
      />
      {{ label }}
      <span v-if="error" class="message">
        {{ errorMessage }}
      </span>
    </label>
  </div>
</template>

<script>
export default {
  props: ['modelValue', 'label', 'error', 'errorMessage'],
  emits: ['update:modelValue']
}
</script>
  1. Use the new component in UnoapiConfiguration.vue:
<config-switch
  v-model="sendAgentName"
  :label="$t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.LABEL')"
  :error="v$.sendAgentName.$error"
  :error-message="$t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.ERROR')"
/>

This refactoring will significantly reduce code duplication and make the template more maintainable.

Copy link

@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: 5

🧹 Outside diff range and nitpick comments (1)
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (1)

Line range hint 1-746: Overall assessment: Functionality improved, but room for refinement

The changes to UnoapiConfiguration.vue significantly enhance its functionality by adding webhook management and extended configuration options. The implementation of a tabbed interface improves the organization of settings.

However, there are several areas where the code could be improved:

  1. The large number of configuration options could benefit from better grouping for improved usability.
  2. The webhook management interface could be enhanced with pagination, sorting, and more efficient data handling.
  3. Some parts of the code, particularly in the script section, could be optimized for better performance and maintainability.
  4. The CSS styles use some practices (like specific selectors and absolute positioning) that might cause maintainability issues in the future.

Addressing these points will result in a more robust, maintainable, and user-friendly component.

📜 Review details

Configuration used: CodeRabbit UI
Review profile: CHILL

📥 Commits

Files that changed from the base of the PR and between 19375c5 and 82745f4.

📒 Files selected for processing (1)
  • app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (7 hunks)
🔇 Additional comments (5)
app/javascript/dashboard/routes/dashboard/settings/inbox/settingsPage/UnoapiConfiguration.vue (5)

4-11: LGTM: Tabbed interface implementation

The addition of a tabbed interface using woot-tabs and woot-tabs-item components is a good way to organize the configuration options. This improves the user experience by separating the parameters and webhook settings.


430-448: LGTM: New data properties for extended functionality

The addition of new data properties to support the extended functionality is well-structured. The webhooks array and webhookForm object provide a good foundation for managing webhook data.


451-461: LGTM: Watcher for useRejectCalls

The watcher for useRejectCalls is a good addition. It ensures that related fields are cleared when the option is disabled, preventing inconsistent states.


491-493: LGTM: Tab change handler

The onTabChange method is a simple and effective way to handle tab changes.


716-720: ⚠️ Potential issue

Improve CSS transform properties for proper rendering

The CSS transform property is using lowercase translatex and translatey. CSS transform functions are case-sensitive and should be translateX and translateY. Additionally, using such specific pixel values for positioning might cause issues with responsiveness and maintainability.

Consider using more flexible layout techniques, such as Flexbox or Grid, to position elements instead of absolute positioning and transforms.

Apply this correction and consider refactoring the layout:

.flex-shrink div img {
-  transform: translatex(407px) translatey(-347px);
+  transform: translateX(407px) translateY(-347px);
  width: 300px;
  height: 300px;
}

Likely invalid or redundant comment.

Comment on lines +96 to +275
<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendAgentName.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendAgentName"
:value="sendAgentName"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.LABEL') }}
<span v-if="v$.sendAgentName.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_AGENT_NAME.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreGroupMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreGroupMessages"
:value="ignoreGroupMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_GROUPS.LABEL') }}
<span v-if="v$.ignoreGroupMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_GROUPS.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreHistoryMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreHistoryMessages"
:value="ignoreHistoryMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_HISTORY.LABEL') }}
<span v-if="v$.ignoreHistoryMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_HISTORY.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.webhookSendNewMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="webhookSendNewMessages"
:value="webhookSendNewMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBWOOK_SEND_NEW_MESSAGES.LABEL') }}
<span v-if="v$.webhookSendNewMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.WEBWOOK_SEND_NEW_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreBroadcastStatuses.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreBroadcastStatuses"
:value="ignoreBroadcastStatuses"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_STATUSES.LABEL') }}
<span v-if="v$.ignoreBroadcastStatuses.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_STATUSES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreBroadcastMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreBroadcastMessages"
:value="ignoreBroadcastMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_MESSAGES.LABEL') }}
<span v-if="v$.ignoreBroadcastMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_BROADCAST_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreOwnMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreOwnMessages"
:value="ignoreOwnMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_OWN_MESSAGES.LABEL') }}
<span v-if="v$.ignoreOwnMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_OWN_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.ignoreYourselfMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="ignoreYourselfMessages"
:value="ignoreYourselfMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_YOURSELF_MESSAGES.LABEL') }}
<span v-if="v$.ignoreYourselfMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.IGNORE_YOURSELF_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendConnectionStatus.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendConnectionStatus"
:value="sendConnectionStatus"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_CONNECTION_STATUS.LABEL') }}
<span v-if="v$.sendConnectionStatus.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_CONNECTION_STATUS.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.notifyFailedMessages.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="notifyFailedMessages"
:value="notifyFailedMessages"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.NOTIFY_FAILED_MESSAGES.LABEL') }}
<span v-if="v$.notifyFailedMessages.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.NOTIFY_FAILED_MESSAGES.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.composingMessage.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="composingMessage"
:value="composingMessage"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.COMPOSING_MESSAGE.LABEL') }}
<span v-if="v$.composingMessage.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.COMPOSING_MESSAGE.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendReactionAsReply.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendReactionAsReply"
:value="sendReactionAsReply"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_REACTION_AS_REPLY.LABEL') }}
<span v-if="v$.sendReactionAsReply.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_REACTION_AS_REPLY.ERROR') }}
</span>
</label>
</div>

<div class="w-3/4 pb-4 config-helptext">
<label :class="{ error: v$.sendProfilePicture.$error }" style="display: flex; align-items: center;">
<woot-switch
v-model="sendProfilePicture"
:value="sendProfilePicture"
style="flex: 0 0 auto; margin-right: 10px;"
/>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_PROFILE_PICTURE.LABEL') }}
<span v-if="v$.sendProfilePicture.$error" class="message">
{{ $t('INBOX_MGMT.ADD.WHATSAPP.SEND_PROFILE_PICTURE.ERROR') }}
</span>
</label>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Consider grouping related configuration options

The addition of numerous configuration options provides great flexibility for users. However, the large number of switches might be overwhelming. Consider grouping related options together under collapsible sections or subheadings to improve usability and make it easier for users to find and understand the available settings.

For example, you could group options related to message handling, connection status, and notifications separately.

Comment on lines +315 to +355
<table class="webhook-table">
<thead>
<tr>
<th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ID') }}</th>
<th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.URL_ABSOLUT') }}</th>
<th></th> <!-- <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.BUTTON') }}</th> -->
<th></th> <!-- <th>{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ACTIONS') }}</th> -->
</tr>
</thead>
<tbody>
<tr v-for="(webhook, index) in webhooks" :key="index">
<td>{{ webhook.id }}</td>

<!-- URL com truncagem e tooltip -->
<td :title="webhook.urlAbsolute">
{{ webhook.urlAbsolute.length > 80 ? webhook.urlAbsolute.substring(0, 80) + '...' : webhook.urlAbsolute }}
</td>
<td>
<woot-switch
v-model="webhook.sendNewMessages"
:value="webhook.sendNewMessages"
@change="toggleSendNewMessages(index)"
/>
</td>
<td>
<woot-submit-button
:button-text="$t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.EDIT')"
@click="editWebhook(index)"
style="display: inline-block;"
/>
</td>
<td>
<woot-submit-button
:button-text="$t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.DELETE')"
@click="removeWebhook(index)"
style="display: inline-block;"
/>
</td>
</tr>
</tbody>
</table>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Enhance the webhook table for better user experience

The webhook table implementation could be improved:

  1. Consider using a dedicated component for the webhook table to encapsulate its logic and presentation.
  2. Implement pagination or virtual scrolling for better performance with large datasets.
  3. Add sorting functionality to allow users to sort webhooks by different columns.
  4. Use icons for edit and delete actions instead of text buttons to save space and improve visual appeal.

These changes will make the webhook management interface more user-friendly and scalable.

Comment on lines +358 to +387
<modal v-if="showWebhookModal" @close="closeWebhookModal">
<h3>{{ editingWebhook ? $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.EDIT') : $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ADD') }}</h3>
<form @submit.prevent="submitWebhook">
<label>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ID') }}
<input v-model="webhookForm.id" type="text" required />
</label>
<label>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.URL_ABSOLUT') }}
<input v-model="webhookForm.urlAbsolute" type="text" required />
</label>
<label>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.TOKEN') }}
<input v-model="webhookForm.token" type="text" />
</label>
<label>
{{ $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.HEADER') }}
<input v-model="webhookForm.header" type="text" />
</label>
<woot-submit-button
:button-text="editingWebhook ? $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.SAVE') : $t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ADD')"
@click="submitWebhook"
/>
<woot-submit-button
:button-text="$t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.CANCEL')"
@click="closeWebhookModal"
style="margin-left: 10px;"
/>
</form>
</modal>
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Improve modal implementation for better reusability

The current modal implementation for adding/editing webhooks is tightly coupled with the webhook form. Consider creating a separate, reusable modal component that can be used for various purposes throughout the application. This will improve code maintainability and make it easier to implement similar modals in other parts of the application.

Additionally, consider adding form validation to ensure that required fields are filled and the URL is in a valid format before submitting.

Comment on lines +517 to +561
showAddWebhookModal() {
this.showWebhookModal = true;
this.webhookForm = {
id: '',
urlAbsolute: '',
sendNewMessages: true,
token: '',
header: 'Authorization',
};
this.editingWebhook = false;
},
editWebhook(index) {
this.showWebhookModal = true;
this.webhookForm = { ...this.webhooks[index] };
this.editingWebhook = true;
},
removeWebhook(index) {
if (this.webhooks[index].id !== 'default') {
this.webhooks.splice(index, 1);
} else {
useAlert(this.$t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.ERROR_DELETE'));
}
},
closeWebhookModal() {
this.showWebhookModal = false;
},
submitWebhook() {
const existingWebhook = this.webhooks.find(w => w.urlAbsolute === this.webhookForm.urlAbsolute && w.id !== this.webhookForm.id);
if (existingWebhook) {
useAlert(this.$t('INBOX_MGMT.ADD.WHATSAPP.TAB_NAME.TAB_WEBHOOK.DUPLICATE'));
return;
}
if (this.editingWebhook) {
const index = this.webhooks.findIndex(w => w.id === this.webhookForm.id);
if (index !== -1) {
this.webhooks.splice(index, 1, this.webhookForm);
}
} else {
this.webhooks.push(this.webhookForm);
}
this.closeWebhookModal();
},
toggleSendNewMessages(index) {
this.webhooks[index].sendNewMessages = !this.webhooks[index].sendNewMessages;
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Optimize webhook management methods

The methods for managing webhooks (showAddWebhookModal, editWebhook, removeWebhook, submitWebhook, toggleSendNewMessages) could be optimized:

  1. Use Vue's reactivity system more effectively by using Vue.set or the spread operator for array mutations.
  2. Implement error handling and validation in the webhook management methods.
  3. Use a more efficient way to find and update webhooks, such as maintaining a map of webhooks by ID.

These optimizations will improve performance and make the code more robust.

Comment on lines 736 to 746
#app .flex-grow-0 .overflow-hidden .justify-between .flex-shrink div .text-base > div {
width: 63% !important;
}
.flex-shrink div img{
transform:translatex(407px) translatey(-347px);
width:300px;
height:300px;
.flex-shrink modal h3 {
background-color: #369eff;
color: #369eff;
}
.flex-shrink div .message{
margin-top:-20px;
font-size:11px;
#app .overflow-hidden .flex-shrink {
transform: translatex(0px) translatey(0px);
Copy link

Choose a reason for hiding this comment

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

🛠️ Refactor suggestion

Refactor specific CSS selectors and values

The CSS selectors used here are very specific and might be fragile if the HTML structure changes. Additionally, using !important and specific percentage values can make the styles hard to maintain and override when necessary.

Consider refactoring these styles to use more general selectors and relative units (like em, rem, or %) for better maintainability and responsiveness. Also, try to avoid using !important unless absolutely necessary.

@clairton clairton force-pushed the uno branch 2 times, most recently from 4ec8196 to 9bf04a7 Compare October 22, 2024 18:38
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.

4 participants