diff --git a/Gemfile.lock b/Gemfile.lock index d55cfa0a9..a4a288f07 100644 --- a/Gemfile.lock +++ b/Gemfile.lock @@ -477,7 +477,7 @@ GEM mime-types-data (3.2023.0218.1) mini_magick (4.12.0) mini_mime (1.1.5) - mini_portile2 (2.8.8) + mini_portile2 (2.8.9) minitest (5.25.5) mock_redis (0.36.0) ruby2_keywords @@ -508,14 +508,14 @@ GEM newrelic_rpm (9.6.0) base64 nio4r (2.7.3) - nokogiri (1.18.8) + nokogiri (1.18.9) mini_portile2 (~> 2.8.2) racc (~> 1.4) - nokogiri (1.18.8-arm64-darwin) + nokogiri (1.18.9-arm64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-darwin) + nokogiri (1.18.9-x86_64-darwin) racc (~> 1.4) - nokogiri (1.18.8-x86_64-linux-gnu) + nokogiri (1.18.9-x86_64-linux-gnu) racc (~> 1.4) oauth (1.1.0) oauth-tty (~> 1.0, >= 1.0.1) @@ -823,7 +823,7 @@ GEM stripe (8.5.0) telephone_number (1.4.20) test-prof (1.2.1) - thor (1.3.1) + thor (1.4.0) tilt (2.3.0) time_diff (0.3.0) activesupport diff --git a/app/controllers/api/v1/accounts/inboxes_controller.rb b/app/controllers/api/v1/accounts/inboxes_controller.rb index e7b3b197b..78b4b9e2f 100644 --- a/app/controllers/api/v1/accounts/inboxes_controller.rb +++ b/app/controllers/api/v1/accounts/inboxes_controller.rb @@ -69,6 +69,17 @@ class Api::V1::Accounts::InboxesController < Api::V1::Accounts::BaseController render status: :ok, json: { message: I18n.t('messages.inbox_deletetion_response') } end + def sync_templates + unless @inbox.channel.is_a?(Channel::Whatsapp) + return render status: :unprocessable_entity, json: { error: 'Template sync is only available for WhatsApp channels' } + end + + Channels::Whatsapp::TemplatesSyncJob.perform_later(@inbox.channel) + render status: :ok, json: { message: 'Template sync initiated successfully' } + rescue StandardError => e + render status: :internal_server_error, json: { error: e.message } + end + private def fetch_inbox diff --git a/app/javascript/dashboard/api/inboxes.js b/app/javascript/dashboard/api/inboxes.js index 8c09791c8..361b9472f 100644 --- a/app/javascript/dashboard/api/inboxes.js +++ b/app/javascript/dashboard/api/inboxes.js @@ -28,6 +28,10 @@ class Inboxes extends CacheEnabledApiClient { agent_bot: botId, }); } + + syncTemplates(inboxId) { + return axios.post(`${this.url}/${inboxId}/sync_templates`); + } } export default new Inboxes(); diff --git a/app/javascript/dashboard/api/specs/inboxes.spec.js b/app/javascript/dashboard/api/specs/inboxes.spec.js index 628ce0f34..64ba44aea 100644 --- a/app/javascript/dashboard/api/specs/inboxes.spec.js +++ b/app/javascript/dashboard/api/specs/inboxes.spec.js @@ -12,6 +12,7 @@ describe('#InboxesAPI', () => { expect(inboxesAPI).toHaveProperty('getCampaigns'); expect(inboxesAPI).toHaveProperty('getAgentBot'); expect(inboxesAPI).toHaveProperty('setAgentBot'); + expect(inboxesAPI).toHaveProperty('syncTemplates'); }); describe('API calls', () => { @@ -40,5 +41,12 @@ describe('#InboxesAPI', () => { inboxesAPI.deleteInboxAvatar(2); expect(axiosMock.delete).toHaveBeenCalledWith('/api/v1/inboxes/2/avatar'); }); + + it('#syncTemplates', () => { + inboxesAPI.syncTemplates(2); + expect(axiosMock.post).toHaveBeenCalledWith( + '/api/v1/inboxes/2/sync_templates' + ); + }); }); }); diff --git a/app/javascript/dashboard/components-next/dropdown-menu/DropdownPrimitives.story.vue b/app/javascript/dashboard/components-next/dropdown-menu/DropdownPrimitives.story.vue index a174b1eea..397f45d93 100644 --- a/app/javascript/dashboard/components-next/dropdown-menu/DropdownPrimitives.story.vue +++ b/app/javascript/dashboard/components-next/dropdown-menu/DropdownPrimitives.story.vue @@ -6,7 +6,7 @@ import DropdownBody from './base/DropdownBody.vue'; import DropdownSection from './base/DropdownSection.vue'; import DropdownItem from './base/DropdownItem.vue'; import DropdownSeparator from './base/DropdownSeparator.vue'; -import WootSwitch from 'components/ui/Switch.vue'; +import ToggleSwitch from 'dashboard/components-next/switch/Switch.vue'; const currentUserAutoOffline = ref(false); @@ -61,7 +61,7 @@ const menuItems = ref([ {{ $t('SIDEBAR.SET_AUTO_OFFLINE.TEXT') }}
- +
diff --git a/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenuStatus.vue b/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenuStatus.vue index fef196162..41e64dee1 100644 --- a/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenuStatus.vue +++ b/app/javascript/dashboard/components-next/sidebar/SidebarProfileMenuStatus.vue @@ -14,6 +14,7 @@ import { } from 'next/dropdown-menu/base'; import Icon from 'next/icon/Icon.vue'; import Button from 'next/button/Button.vue'; +import ToggleSwitch from 'dashboard/components-next/switch/Switch.vue'; const { t } = useI18n(); const store = useStore(); @@ -48,6 +49,16 @@ const activeStatus = computed(() => { return availabilityStatuses.value.find(status => status.active); }); +const autoOfflineToggle = computed({ + get: () => currentUserAutoOffline.value, + set: autoOffline => { + store.dispatch('updateAutoOffline', { + accountId: currentAccountId.value, + autoOffline, + }); + }, +}); + function changeAvailabilityStatus(availability) { if (isImpersonating.value) { useAlert(t('PROFILE_SETTINGS.FORM.AVAILABILITY.IMPERSONATING_ERROR')); @@ -62,13 +73,6 @@ function changeAvailabilityStatus(availability) { useAlert(t('PROFILE_SETTINGS.FORM.AVAILABILITY.SET_AVAILABILITY_ERROR')); } } - -function updateAutoOffline(autoOffline) { - store.dispatch('updateAutoOffline', { - accountId: currentAccountId.value, - autoOffline, - }); -}