|
|
@@ -7,7 +7,8 @@ import BaseButton from "../../components/base/BaseButton.vue";
|
|
|
import {
|
|
|
avaliarAtendimentosPendentes,
|
|
|
estatisticasAvaliacoes,
|
|
|
- listarAvaliacoes
|
|
|
+ listarAvaliacoes,
|
|
|
+ listarSetoresAvaliacoes
|
|
|
} from "../../api/atendimentos.js";
|
|
|
import { resolvidoLabel, resolvidoVariant, scoreVariant, sentimentoLabel, sentimentoVariant } from "../../utils/avaliacoes.js";
|
|
|
|
|
|
@@ -22,12 +23,14 @@ const loteResultado = ref(null);
|
|
|
const stats = ref(null);
|
|
|
const avaliacoes = ref([]);
|
|
|
const total = ref(0);
|
|
|
+const setores = ref([]);
|
|
|
const pageSize = 20;
|
|
|
|
|
|
// 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
|
|
|
const page = ref(Math.max(1, Number(route.query.page) || 1));
|
|
|
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 filtroSentimento = ref(typeof route.query.sentimento === "string" ? route.query.sentimento : "");
|
|
|
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() {
|
|
|
const query = {};
|
|
|
if (page.value > 1) query.page = String(page.value);
|
|
|
+ if (filtroSetor.value) query.setor = filtroSetor.value;
|
|
|
if (filtroResolvido.value) query.resolvido = filtroResolvido.value;
|
|
|
if (filtroSentimento.value) query.sentimento = filtroSentimento.value;
|
|
|
if (filtroBusca.value.trim()) query.q = filtroBusca.value.trim();
|
|
|
@@ -65,12 +69,21 @@ function pct(parte, todo) {
|
|
|
|
|
|
async function carregarStats() {
|
|
|
try {
|
|
|
- stats.value = await estatisticasAvaliacoes();
|
|
|
+ stats.value = await estatisticasAvaliacoes({ setor: filtroSetor.value || undefined });
|
|
|
} catch {
|
|
|
stats.value = null;
|
|
|
}
|
|
|
}
|
|
|
|
|
|
+async function carregarSetores() {
|
|
|
+ try {
|
|
|
+ const r = await listarSetoresAvaliacoes();
|
|
|
+ setores.value = r.results ?? [];
|
|
|
+ } catch {
|
|
|
+ setores.value = [];
|
|
|
+ }
|
|
|
+}
|
|
|
+
|
|
|
async function carregarLista() {
|
|
|
carregando.value = true;
|
|
|
erro.value = "";
|
|
|
@@ -78,6 +91,7 @@ async function carregarLista() {
|
|
|
const r = await listarAvaliacoes({
|
|
|
page: page.value,
|
|
|
pageSize,
|
|
|
+ setor: filtroSetor.value || undefined,
|
|
|
resolvido: filtroResolvido.value || undefined,
|
|
|
sentimento: filtroSentimento.value || undefined,
|
|
|
busca: filtroBusca.value.trim() || undefined
|
|
|
@@ -95,6 +109,7 @@ function aplicarFiltros() {
|
|
|
page.value = 1;
|
|
|
expandido.value = null;
|
|
|
sincronizarQuery();
|
|
|
+ carregarStats();
|
|
|
carregarLista();
|
|
|
}
|
|
|
|
|
|
@@ -148,6 +163,7 @@ let statsTimer = null;
|
|
|
|
|
|
onMounted(async () => {
|
|
|
carregarStats();
|
|
|
+ carregarSetores();
|
|
|
await carregarLista();
|
|
|
|
|
|
// voltando da conversa completa, reposiciona na avaliação que estava aberta
|
|
|
@@ -294,6 +310,14 @@ onBeforeUnmount(() => {
|
|
|
</svg>
|
|
|
</button>
|
|
|
</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
|
|
|
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"
|