# Pull Request Template
## Description
Dyte V1 API's are soon going to be deprecated, hence making sure we
update Chatwoot before that happens
Fixes#10704
## Type of change
Please delete options that are not relevant.
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
1. Open a new or existing conversation from the inbox
2. Press the video call icon on the message composer
3. Verify that the message dialog shows up with the join video call
button
4. Verify that clicking on join call does join the call
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] My changes generate no new warnings
- [ ] New and existing unit tests pass locally with my changes (Unable
to run this locally)
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This PR introduces internal feature flags for testing purposes. These
flags will not be displayed on regular instances to prevent customer
confusion.
Additionally, a new feature flag, `contact_chatwoot_support_team`, has
been added for Chatwoot Cloud. This flag disables contact support for
third-party onboarded accounts, as support will be handled by the
original affiliate team.
Co-authored-by: Pranav <pranav@chatwoot.com>
This PR target two issues
### CC & BCC not updated correctly
When moving from one conversation to another, the store may not have the
list of all the messages. A fetch is subsequently made to get the
messages. However, this update does not trigger the `currentChat`
watcher. This PR fixes it by adding a new watcher on
`currentChat.messages`.
We also update the `setCCAndToEmailsFromLastChat` method to reset the
`cc`, `bcc` and `to` fields if the last email is not found. This ensures
that the data is not carried forward from a previous email
Fixes: https://github.com/chatwoot/chatwoot/issues/10477
### To address are not added correctly to the `CC`
If the `to` address of a previous email has multiple recipient, there
was no case to add them to the CC.
Fixes: https://github.com/chatwoot/chatwoot/issues/8925
---
Depends on: https://github.com/chatwoot/utils/pull/41
This PR updates the report pages for agents, inboxes, and teams by
replacing charts with aggregate values (under a feature flag). Users can
click on any item to view more details if needed. Most users seem to
prefer aggregate values, so this change will likely stay.
The PR also includes a few fixes:
- The summary reports now use the same logic for both the front-end and
CSV exports.
- Fixed an issue where a single quote was being added to values with
hyphens in CSV files. Now, ‘n/a’ is used when no value is available.
- Fixed a bug where the average value was calculated incorrectly when
multiple accounts were present.
These changes should make reports easier to use and more consistent.
### Agents:
<img width="1438" alt="Screenshot 2025-01-26 at 10 47 18 AM"
src="https://github.com/user-attachments/assets/bf2fcebc-6207-4701-9703-5c2110b7b8a0"
/>
### Inboxes
<img width="1438" alt="Screenshot 2025-01-26 at 10 47 10 AM"
src="https://github.com/user-attachments/assets/b83e1cf2-fd14-4e8e-8dcd-9033404a9f22"
/>
### Teams:
<img width="1436" alt="Screenshot 2025-01-26 at 10 47 01 AM"
src="https://github.com/user-attachments/assets/96b1ce07-f557-42ca-8143-546a111d6458"
/>
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
# Pull Request Template
## Description
https://github.com/chatwoot/utils/pull/38
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
Migration Guide: https://chwt.app/v4/migration
This PR imports all the work related to Captain into the EE codebase. Captain represents the AI-based features in Chatwoot and includes the following key components:
- Assistant: An assistant has a persona, the product it would be trained on. At the moment, the data at which it is trained is from websites. Future integrations on Notion documents, PDF etc. This PR enables connecting an assistant to an inbox. The assistant would run the conversation every time before transferring it to an agent.
- Copilot for Agents: When an agent is supporting a customer, we will be able to offer additional help to lookup some data or fetch information from integrations etc via copilot.
- Conversation FAQ generator: When a conversation is resolved, the Captain integration would identify questions which were not in the knowledge base.
- CRM memory: Learns from the conversations and identifies important information about the contact.
---------
Co-authored-by: Vishnu Narayanan <vishnu@chatwoot.com>
Co-authored-by: Sojan <sojan@pepalo.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
To test this, set the `useNextBubble` value to `true` in the
localstorage. Here's a quick command to run in the console
```js
localStorage.setItem('useNextBubble', true)
```
```js
localStorage.setItem('useNextBubble', false)
```
---------
Co-authored-by: Pranav <pranavrajs@gmail.com>
# Pull Request Template
## Description
This PR fixes the overflow issue with the chat list header title.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Before**
<img width="484" alt="image"
src="https://github.com/user-attachments/assets/e46f6daf-e2f3-4f1c-ba33-00a932d7788f"
/>
**After**
<img width="484" alt="image"
src="https://github.com/user-attachments/assets/d45808aa-ebbd-47e4-be32-f643c22b363f"
/>
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
- Increase the sidebar and chatlist width on screens bigger than 2xl
- Fix background of the copilot sidebar
- Increase the breakpoint for hiding chatlist from 1024 to 1200
# Pull Request Template
## Description
This PR will fix reactivity issue with `<woot-tabs />` component.
**Cause of issue**
The `<woot-tabs />` component used an internal ref,
`internalActiveIndex` to track the `active` tab. However, it didn’t sync
with the `index` prop when updated by the parent, causing mismatched tab
selections.
**Solution**
The component now directly uses `props.index` to ensure it always
reflects the latest value from the parent. The unnecessary
`internalActiveIndex` ref has been removed. Changes to the active tab
emit a `change` event to update the parent.
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Loom video**
**Before**
https://www.loom.com/share/76eb32f1e7f7422f84055a102bf80951?sid=bc28c6ff-9640-4d3b-956c-99c1ec164971
**After**
https://www.loom.com/share/6bd8125ede5d43dc8fe115c3f1fb159b?sid=c376617a-94fb-4f71-8664-e0bd9e7af0b4
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
This PR adds dropdown primitives to help compose custom dropdowns across the app. The following the sample usage
---------
Co-authored-by: Pranav <pranav@chatwoot.com>
This fix consists of translating the message when another user is typing on the other side.
---
Co-authored-by: Pranav <pranavrajs@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
# Pull Request Template
## Description
This PR fixes the issue where the bulk action inbox assignable agent
list was not showing.
The issue started after merging this [feat: Vite+Vue 3
PR](https://github.com/chatwoot/chatwoot/pull/10047 ).
**Cause of issue**
Previously, `selectedInboxes` was accessed from the `ChatList.vue`
component. However, after moving the bulk action logic from mixin to the
`useBulkActions.js` composable, we were still referencing
`selectedInboxes` from the `ChatList.vue` component, even though it was
being set in the composable. This caused the API failed to load the
assignable agent list.
Ref:https://github.com/chatwoot/chatwoot/blob/develop/app/javascript/dashboard/composables/chatlist/useBulkActions.js#L18
**Solution**
Removed the usage of `selectedInboxes` from the `ChatList.vue` component
ref and using `selectedInboxes` ref directly from the
`useBulkActions.js`
Fixes
https://linear.app/chatwoot/issue/CW-3696/bulk-action-agent-list-is-not-loading
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Loom video**
https://www.loom.com/share/21e3835b3db04e34b94531ec128b586b?sid=beda60f0-1c8e-457b-b617-379d4af91873
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
This PR has the initial version of the new sidebar targeted for the next major redesign of the app. This PR includes the following changes
- Components in the `layouts-next` and `base-next` directories in `dashboard/components`
- Two generic components `Avatar` and `Icon`
- `SidebarGroup` component to manage expandable sidebar groups with nested navigation items. This includes handling active states, transitions, and permissions.
- `SidebarGroupHeader` component to display the header of each navigation group with optional icons and active state indication.
- `SidebarGroupLeaf` component for individual navigation items within a group, supporting icons and active state.
- `SidebarGroupSeparator` component to visually separate nested navigation items. (They look a lot like header)
- `SidebarGroupEmptyLeaf` component to render empty state of any navigation groups.
----
Co-authored-by: Pranav <pranav@chatwoot.com>
Co-authored-by: Pranav <pranavrajs@gmail.com>
# Pull Request Template
## Description
This PR resolves the issue where the modal in the context menu
disappears when not being hovered over.
**Cause of issue.**
The problem occurred because the modal-related component was placed
inside `MessageContextMenu.vue`, and the parent wrapper was using the
classes `group-hover:visible invisible`. This caused the modal to only
appear when the message item, where the context menu was opened, was
hovered over.
**Solution**
To fix this, I removed the `group-hover:visible` invisible class from
the parent wrapper and moved it into the `woot-button` within the
`MessageContextMenu.vue` component. Additionally, I added a nested group
with the class group/context-menu, allowing the focus to remain on the
context menu itself.
Fixes
https://linear.app/chatwoot/issue/PR-1415/modal-in-the-context-menu-disappears-unless-hovered
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Loom video**
**Before**
https://www.loom.com/share/458f90708664493c86e909a56869d065?sid=0564a508-09a5-4e73-800b-8042140a22ba
**After**
https://www.loom.com/share/c119936d181d406d89468f9482ef6b81?sid=5cf3b1b4-6c66-4f8c-8f93-a62465a93b57
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [ ] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
This PR updates the sidebar component to use a native <a> tag for the Help Center URL component. It also updates the build pipeline to use the esbuild options minifyIdentifiers and keepNames set to true.
In the `DropdownList.vue` component, the `onSearch` function was not properly passing the search value to the parent component. This resulted in the `onSearch` event in parent components (such as `LinkIssue.vue`) receiving an undefined value instead of the actual search term.
f18ed01eb7/app/javascript/dashboard/components/ui/Dropdown/DropdownList.vue (L45-L52)
The issue was resolved by modifying the `onSearch` function in `DropdownList.vue` to correctly pass the search value to the `debouncedEmit` function:
On production on multiple instances it may happen that the UI is
rendered in correctly, with a lot of options in the sidebar not
available. On further investigation I found out that the feature flag
checks were disabling multiple of those, and also we could see many
correlated errors that pointed towards missing information.
So, there were two problems here
1. The `vuex-router-sync` was not very reliable in some cases
2. In `App.vue` the watch on `currentAccountId` didn't always trigger.
## Fix Tested on Staging
Basically tried to reload the page ~50 times with cache enabled,
disabled, throttling, navigating different pages.
https://www.loom.com/share/1bb27294aa364ac4acfb647780d6385a?sid=87e31330-8cb7-4ded-8616-5e95e2ae3516
<details><summary>
#### What I thought was the fix
</summary>
<p>
### My chain of actions
Replacing vuex-router-sync at first worked fine, but then I saw it was
still failing in some cases, I assumed (I was half-correct tho) that the
rendering of the `App.vue` and syncing of the route to the store was not
happening in a synchronous pattern. So I decided, let's not rely on the
store when the route is directly available in the App context.
Following this, I refactored `useAccount` composable to use `useRoute`
directly, instead of the store, and then replaced the getter inside
`App.vue`. What this did was surface the issue but more consistently 🤯
I saw the watcher, added some console logs, and turns out it was not
getting triggered in all those cases. So I added an `immediate` to it.
And viola, it works!
At the moment, this is deployed to staging and seems to be working
correctly. But we still need to verify it for sure, since how this issue
was surfaced is still a mystery. All we know is that it shows up when
the widget is also loaded alongside the app (if it loads before or after
the app, it works fine)
### What about the route in the store?
Well I have used the `route` usage there with fallback to the store
state. Since Vuex exists in the app context, the route should always be
available to it. But after today I have lost all trust in JavaScript and
will worship rails until end of my life, so I added that in a
`try-catch` block, logged the error to Sentry
</p>
</details>
## Here's the real fix
If you read the explanation I wrote earlier, I thought I fixed the
issue, but then the chat list navigation completely broke. So I removed
the custom route sync implementation and added the original package
back. Turns out the vuex-router-sync earlier was placed after the app
was initalized, however for it to work, the vue app context is not
required. And it's best to run it before the app is even bootstrapped,
so I added it back and placed it correctly.
So the following changes fixes this problem
1. Hoisting the `sync` function call to before we call `createApp` this
ensures that the stores and route hooks are in place before even the app
is created
2. Ensuring the `initializeAccount` is run immediately when watching
`currentAccountId`
4. Source `currentAccountId` for critical top of the tree components
directly from the route instead of the store
- Switch to pnpm based build
- Switch circleci from docker to machine to have more memory
- Fix frontend and backend tests
Fixes
https://linear.app/chatwoot/issue/CW-3610/fix-circle-ci-for-vite-build
---------
Co-authored-by: Shivam Mishra <scm.mymail@gmail.com>
Co-authored-by: Pranav <pranavrajs@gmail.com>
Co-authored-by: Pranav <pranav@chatwoot.com>
- Implemented custom @play, @pause methods to update the state of the recording. Once the recording is finished the button icon changes from stop button to play/pause button.
- Removes the console error undefined hasAudio
Fixes https://linear.app/chatwoot/issue/CW-3609/audio-recorder-issue
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
This PR makes the following changes
1. Update v-model bindings for components using the old `value` prop and `input` event method
2. Remove components that were not used anywhere
---------
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
These fixes are all auto generated and can be merged directly
Fixes the following issues
1. Event used on components should be hypenated
2. Attribute orders in components
3. Use `unmounted` instead of `destroyed`
4. Add explicit `emits` declarations for components, autofixed [using
this
script](https://gist.github.com/scmmishra/6f549109b96400006bb69bbde392eddf)
We ignore the top level v-if for now, we will fix it later
Fixes https://github.com/chatwoot/chatwoot/issues/6228
There is a country code selector for the phone input field. This is
often a point of frustration. See the response below.
> We are using the phone number field however this can be frustrating
for customers, especially mobile users, to select the +1 US country
code. Our users are typically local businesses and being able to default
to +1 country code in the phone number field or the account would
improve the interaction they have with customers.
Most people who run local businesses don't need a country selector.
However, to preserve the quality of the data we store, we need a country
code.
A balance between these two issues can be found with an auto-populating
country code field based on the browser's timezone. This is what I did
in this PR. Based on the browser timezone, we will resolve it to the
closest country code.
In admin settings, this Pr will add the UI for managing custom roles (
ref: https://github.com/chatwoot/chatwoot/pull/9995 ). It also handles
the routing logic changes to accommodate fine-tuned permissions.
---------
Co-authored-by: Pranav <pranavrajs@gmail.com>
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
Co-authored-by: iamsivin <iamsivin@gmail.com>
Co-authored-by: Muhsin Keloth <muhsinkeramam@gmail.com>
This PR enhances the emoji search functionality in the editor's emoji selector by improving how emoji names are displayed and searched.
The UI now shows emoji names instead of slugs, and the search logic has been updated to generate `searchString` without whitespaces, allowing users to search for emojis like 'face_with' using 'facewith'
This PR continues the design update series, updates the design for the custom attributes management page. This PR improves the interaction in the Add Custom Attribute feature. Now, the attribute model in the add attribute form will default to the currently selected tab.
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
We are fetching linked Linear issues when opening a conversation if Linear integration is enabled. There may be some cases where the API call fails. We don't need to show an error message every time a user opens the conversation, as it's not critical. However, when someone clicks on the Linear icon, we can inform them that the integration is disabled. This PR will fix the issue.
This PR has the following changes
1. Fix tab styles issue caused by adding an additional wrapper for
getting an element ref on `ChatTypeTabs.vue`
2. Refactor `useKeyboardEvents` composable to not require an element
ref. It will use a local abort controller to abort any listener
---------
Co-authored-by: Sivin Varghese <64252451+iamsivin@users.noreply.github.com>
# Pull Request Template
## Description
This PR will replace the usage of `agentMixin`with the utility helpers
functions.
**Files updated**
1. dashboard/components/widgets/conversation/contextMenu/Index.vue
2. dashboard/components/widgets/conversation/ConversationHeader.vue
**(Not used)**
3. dashboard/routes/dashboard/commands/commandbar.vue
4. dashboard/routes/dashboard/conversation/ConversationAction.vue
5. dashboard/routes/dashboard/conversation/ConversationParticipant.vue
Fixes
https://linear.app/chatwoot/issue/CW-3442/rewrite-agentmixin-mixin-to-a-composable
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
**Test cases**
1. See agent list sorting based on availability, if agents are on the
same status, then sorted by name.
2. Test actions like assigning/unassigning agent from conversation
sidebar, CMD bar, Context menu.
3. Test actions like adding/removing participants from conversation
sidebar.
4. See agent list is generated properly, none value.
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
Remove the `user.permissions` field and resolve the permissions directly
from the accounts array in the user. This change ensures that the cache
or previous values from the last active account don't affect the
permissions.
In this PR:
- Remove user.permissions usage, replace it with getUserPermissions
method.
- Remove json.permissions from user.json.jbuilder
We are using `audio` component for rendering audio files in dashboard.
```
<audio v-else-if="isAudio" controls>
<source :src="`${dataUrl}?t=${Date.now()}`" />
</audio>
```
We have added the timestamp for every audio URL for cache busting. For
Instagram, we are getting a signature URL. When we add any value and
access the URL, it results in an "Invalid signature. If I remove the
timestamp, the audio is rendering properly. This PR will change the
logic to construct the URL properly instead of direct string
manipulation.
# Pull Request Template
## Description
This PR will replace the usage of `configMixin` with the `useConfig`
composable.
**Files updated**
1. dashboard/components/layout/sidebarComponents/SecondaryNavItem.vue
2. dashboard/components/widgets/conversation/MessagesView.vue
3. dashboard/routes/dashboard/settings/inbox/Settings.vue **(Not used)**
4. dashboard/routes/dashboard/settings/inbox/FinishSetup.vue **(Not
used)**
5.
dashboard/routes/dashboard/settings/inbox/settingsPage/CollaboratorsPage.vue
6.
dashboard/routes/dashboard/settings/profile/NotificationPreferences.vue
**(Not used)**
7. dashboard/routes/dashboard/settings/profile/AudioNotifications.vue
**(Not used)**
8. dashboard/routes/dashboard/settings/sla/Index.vue **(Not used)**
9. dashboard/routes/dashboard/settings/account/Index.vue
10. survey/views/Response.vue **(Not used)**
Fixes
https://linear.app/chatwoot/issue/CW-3464/rewrite-configmixin-mixin-to-a-composable
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
Test in the component related pages
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
# Pull Request Template
## Description
This PR will fix an error `TypeError cannot read properties of undefined
(reading '$el')` with the keyboard shortcut `Alt+KeyA` for triggering
the file picker.
**Issue**
I couldn't able reproduce this issue. It might be because `$children`
was unavailable at the time of access.
**Solution**
Previously, it relied on `$children`. Now, it uses the more reliable
`querySelector` method to find the target element.
Fixes
https://chatwoot-p3.sentry.io/issues/5708410274/?alert_rule_id=15157525&alert_timestamp=1723552508790&alert_type=email&environment=production¬ification_uuid=be5966b2-f17d-4273-8709-98e3322f1f6f&project=4507182691975168&referrer=alert_email
## Type of change
- [x] Bug fix (non-breaking change which fixes an issue)
## How Has This Been Tested?
**Test cases**
1. Open a conversation
2. And click `Alt+KeyA` to trigger the file picker.
3. See if there is any issue or errors.
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [ ] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
# Pull Request Template
## Description
This PR will replace the usage of `conversation/labelMixin` with a
composable
Fixes
https://linear.app/chatwoot/issue/CW-3439/rewrite-conversationlabelmixin-mixin-to-a-composable
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
**Test cases**
1. Add/remove labels from conversation sidebar
2. See labels are showing up dynamically
3. Check add/remove labels working fine with CMD bar
4. Check card labels in conversation card and SLA reports table.
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules
# Pull Request Template
## Description
This PR will replace the use of `customAttributeMixin` with
`shared/helpers/Validators` helper.
Fixes
https://linear.app/chatwoot/issue/CW-3446/rewrite-customattributemixin-mixin-to-a-composable
**Files updated**
1. widget/components/PreChat/Form.vue
2. dashboard/components/CustomAttribute.vue
3. dashboard/routes/dashboard/settings/attributes/EditAttribute.vue
## Type of change
- [x] New feature (non-breaking change which adds functionality)
## How Has This Been Tested?
Test the custom validation is working or not with the custom attributes.
## Checklist:
- [x] My code follows the style guidelines of this project
- [x] I have performed a self-review of my code
- [x] I have commented on my code, particularly in hard-to-understand
areas
- [ ] I have made corresponding changes to the documentation
- [x] My changes generate no new warnings
- [x] I have added tests that prove my fix is effective or that my
feature works
- [x] New and existing unit tests pass locally with my changes
- [ ] Any dependent changes have been merged and published in downstream
modules