From 2b9ada259e05e86cc2ceca14c3b5ff589c5cfe8e Mon Sep 17 00:00:00 2001 From: Rodribm10 Date: Thu, 23 Apr 2026 18:03:26 -0300 Subject: [PATCH] feat(dashboard): aggressive alert on conversation reopening MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Banner persistente + som em loop + OS notification + title flash + vibração mobile quando conversa transiciona pra 'open' vindo de pending/snoozed/resolved. Exige interação pra dismissar — atendente não perde evento de reabertura. - AggressiveConversationBanner.vue: banner full-width no topo, dismissable, mostra nome do contato + inbox + status anterior - aggressiveAlert.js: manager do som (loop infinito), title flash (intervalo 1s), Notification API (requireInteraction: true), navigator.vibrate (padrão 500-200-500-200-500) - actionCable.onStatusChange: detecta transição pra 'open' e dispara trigger via BUS_EVENTS (só se status anterior ≠ open, pra não alertar conversa nova criada já em open) - i18n pt_BR + en: chaves de notificação (title/body/dismiss) - busEvents: AGGRESSIVE_ALERT_TRIGGER + AGGRESSIVE_ALERT_DISMISS Camada 1 da feature. Camada 2 (escalation SMS/WhatsApp se não dismissar em X segundos) fica pra outro PR. Co-Authored-By: Claude Opus 4.7 (1M context) --- app/javascript/dashboard/App.vue | 3 + .../app/AggressiveConversationBanner.vue | 249 ++++++++++++++++++ .../dashboard/helper/actionCable.js | 28 ++ .../dashboard/helper/aggressiveAlert.js | 159 +++++++++++ .../i18n/locale/en/aggressiveBanner.json | 13 + .../dashboard/i18n/locale/en/index.js | 2 + .../i18n/locale/pt_BR/aggressiveBanner.json | 13 + .../dashboard/i18n/locale/pt_BR/index.js | 2 + app/javascript/shared/constants/busEvents.js | 2 + 9 files changed, 471 insertions(+) create mode 100644 app/javascript/dashboard/components/app/AggressiveConversationBanner.vue create mode 100644 app/javascript/dashboard/helper/aggressiveAlert.js create mode 100644 app/javascript/dashboard/i18n/locale/en/aggressiveBanner.json create mode 100644 app/javascript/dashboard/i18n/locale/pt_BR/aggressiveBanner.json diff --git a/app/javascript/dashboard/App.vue b/app/javascript/dashboard/App.vue index 61d7631e7..967fa667d 100644 --- a/app/javascript/dashboard/App.vue +++ b/app/javascript/dashboard/App.vue @@ -5,6 +5,7 @@ import NetworkNotification from './components/NetworkNotification.vue'; import UpdateBanner from './components/app/UpdateBanner.vue'; import PaymentPendingBanner from './components/app/PaymentPendingBanner.vue'; import PendingEmailVerificationBanner from './components/app/PendingEmailVerificationBanner.vue'; +import AggressiveConversationBanner from './components/app/AggressiveConversationBanner.vue'; import vueActionCable from './helper/actionCable'; import { useRouter } from 'vue-router'; import { useStore } from 'dashboard/composables/store'; @@ -30,6 +31,7 @@ export default { PaymentPendingBanner, WootSnackbarBox, PendingEmailVerificationBanner, + AggressiveConversationBanner, }, setup() { const router = useRouter(); @@ -134,6 +136,7 @@ export default { class="flex flex-col w-full h-screen min-h-0 bg-n-background" :dir="isRTL ? 'rtl' : 'ltr'" > +