Ver código fonte

adicao de filtro por setores

leonardo 2 meses atrás
pai
commit
ce75b0fdb4
2 arquivos alterados com 30 adições e 2 exclusões
  1. 4 0
      src/api/atendimentos.js
  2. 26 2
      src/views/atendimentos/AvaliacoesView.vue

+ 4 - 0
src/api/atendimentos.js

@@ -43,3 +43,7 @@ export function estatisticasAvaliacoes({ setor } = {}) {
   const qs = query.toString();
   const qs = query.toString();
   return apiFetch(`/api/atendimentos/avaliacoes/estatisticas${qs ? `?${qs}` : ""}`);
   return apiFetch(`/api/atendimentos/avaliacoes/estatisticas${qs ? `?${qs}` : ""}`);
 }
 }
+
+export function listarSetoresAvaliacoes() {
+  return apiFetch("/api/atendimentos/avaliacoes/setores");
+}

+ 26 - 2
src/views/atendimentos/AvaliacoesView.vue

@@ -7,7 +7,8 @@ import BaseButton from "../../components/base/BaseButton.vue";
 import {
 import {
   avaliarAtendimentosPendentes,
   avaliarAtendimentosPendentes,
   estatisticasAvaliacoes,
   estatisticasAvaliacoes,
-  listarAvaliacoes
+  listarAvaliacoes,
+  listarSetoresAvaliacoes
 } from "../../api/atendimentos.js";
 } from "../../api/atendimentos.js";
 import { resolvidoLabel, resolvidoVariant, scoreVariant, sentimentoLabel, sentimentoVariant } from "../../utils/avaliacoes.js";
 import { resolvidoLabel, resolvidoVariant, scoreVariant, sentimentoLabel, sentimentoVariant } from "../../utils/avaliacoes.js";
 
 
@@ -22,12 +23,14 @@ const loteResultado = ref(null);
 const stats = ref(null);
 const stats = ref(null);
 const avaliacoes = ref([]);
 const avaliacoes = ref([]);
 const total = ref(0);
 const total = ref(0);
+const setores = ref([]);
 const pageSize = 20;
 const pageSize = 20;
 
 
 // página, filtros e avaliação aberta vivem na query string para o gestor não perder
 // página, filtros e avaliação aberta vivem na query string para o gestor não perder
 // o ponto da revisão ao entrar na conversa completa e voltar
 // o ponto da revisão ao entrar na conversa completa e voltar
 const page = ref(Math.max(1, Number(route.query.page) || 1));
 const page = ref(Math.max(1, Number(route.query.page) || 1));
 const expandido = ref(route.query.aberto ? Number(route.query.aberto) : null);
 const expandido = ref(route.query.aberto ? Number(route.query.aberto) : null);
+const filtroSetor = ref(typeof route.query.setor === "string" ? route.query.setor : "");
 const filtroResolvido = ref(typeof route.query.resolvido === "string" ? route.query.resolvido : "");
 const filtroResolvido = ref(typeof route.query.resolvido === "string" ? route.query.resolvido : "");
 const filtroSentimento = ref(typeof route.query.sentimento === "string" ? route.query.sentimento : "");
 const filtroSentimento = ref(typeof route.query.sentimento === "string" ? route.query.sentimento : "");
 const filtroBusca = ref(typeof route.query.q === "string" ? route.query.q : "");
 const filtroBusca = ref(typeof route.query.q === "string" ? route.query.q : "");
@@ -35,6 +38,7 @@ const filtroBusca = ref(typeof route.query.q === "string" ? route.query.q : "");
 function sincronizarQuery() {
 function sincronizarQuery() {
   const query = {};
   const query = {};
   if (page.value > 1) query.page = String(page.value);
   if (page.value > 1) query.page = String(page.value);
+  if (filtroSetor.value) query.setor = filtroSetor.value;
   if (filtroResolvido.value) query.resolvido = filtroResolvido.value;
   if (filtroResolvido.value) query.resolvido = filtroResolvido.value;
   if (filtroSentimento.value) query.sentimento = filtroSentimento.value;
   if (filtroSentimento.value) query.sentimento = filtroSentimento.value;
   if (filtroBusca.value.trim()) query.q = filtroBusca.value.trim();
   if (filtroBusca.value.trim()) query.q = filtroBusca.value.trim();
@@ -65,12 +69,21 @@ function pct(parte, todo) {
 
 
 async function carregarStats() {
 async function carregarStats() {
   try {
   try {
-    stats.value = await estatisticasAvaliacoes();
+    stats.value = await estatisticasAvaliacoes({ setor: filtroSetor.value || undefined });
   } catch {
   } catch {
     stats.value = null;
     stats.value = null;
   }
   }
 }
 }
 
 
+async function carregarSetores() {
+  try {
+    const r = await listarSetoresAvaliacoes();
+    setores.value = r.results ?? [];
+  } catch {
+    setores.value = [];
+  }
+}
+
 async function carregarLista() {
 async function carregarLista() {
   carregando.value = true;
   carregando.value = true;
   erro.value = "";
   erro.value = "";
@@ -78,6 +91,7 @@ async function carregarLista() {
     const r = await listarAvaliacoes({
     const r = await listarAvaliacoes({
       page: page.value,
       page: page.value,
       pageSize,
       pageSize,
+      setor: filtroSetor.value || undefined,
       resolvido: filtroResolvido.value || undefined,
       resolvido: filtroResolvido.value || undefined,
       sentimento: filtroSentimento.value || undefined,
       sentimento: filtroSentimento.value || undefined,
       busca: filtroBusca.value.trim() || undefined
       busca: filtroBusca.value.trim() || undefined
@@ -95,6 +109,7 @@ function aplicarFiltros() {
   page.value = 1;
   page.value = 1;
   expandido.value = null;
   expandido.value = null;
   sincronizarQuery();
   sincronizarQuery();
+  carregarStats();
   carregarLista();
   carregarLista();
 }
 }
 
 
@@ -148,6 +163,7 @@ let statsTimer = null;
 
 
 onMounted(async () => {
 onMounted(async () => {
   carregarStats();
   carregarStats();
+  carregarSetores();
   await carregarLista();
   await carregarLista();
 
 
   // voltando da conversa completa, reposiciona na avaliação que estava aberta
   // voltando da conversa completa, reposiciona na avaliação que estava aberta
@@ -294,6 +310,14 @@ onBeforeUnmount(() => {
                 </svg>
                 </svg>
               </button>
               </button>
             </div>
             </div>
+            <select
+              v-model="filtroSetor"
+              class="rounded-lg border border-gray-200 bg-background px-3 py-1.5 text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-primary/30 dark:border-gray-700 dark:text-gray-200 [&>option]:dark:bg-gray-800"
+              @change="aplicarFiltros"
+            >
+              <option value="">Setor: todos</option>
+              <option v-for="s in setores" :key="s.sigla" :value="s.sigla">{{ s.nome }} ({{ s.total }})</option>
+            </select>
             <select
             <select
               v-model="filtroResolvido"
               v-model="filtroResolvido"
               class="rounded-lg border border-gray-200 bg-background px-3 py-1.5 text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-primary/30 dark:border-gray-700 dark:text-gray-200 [&>option]:dark:bg-gray-800"
               class="rounded-lg border border-gray-200 bg-background px-3 py-1.5 text-sm text-gray-700 focus:outline-none focus:ring-2 focus:ring-primary/30 dark:border-gray-700 dark:text-gray-200 [&>option]:dark:bg-gray-800"