|
@@ -5,7 +5,8 @@ import LayoutSistema from "../../layout/LayoutSistema.vue";
|
|
|
import BaseBadge from "../../components/base/BaseBadge.vue";
|
|
import BaseBadge from "../../components/base/BaseBadge.vue";
|
|
|
import BaseButton from "../../components/base/BaseButton.vue";
|
|
import BaseButton from "../../components/base/BaseButton.vue";
|
|
|
import BaseDropdown from "../../components/base/BaseDropdown.vue";
|
|
import BaseDropdown from "../../components/base/BaseDropdown.vue";
|
|
|
-import { estatisticasAvaliacoes, listarAvaliacoes, listarSetoresAvaliacoes } from "../../api/atendimentos.js";
|
|
|
|
|
|
|
+import { baixarRelatorioNaoResolvidos, estatisticasAvaliacoes, listarAvaliacoes, listarSetoresAvaliacoes } from "../../api/atendimentos.js";
|
|
|
|
|
+import { useToast } from "../../composables/useToast.js";
|
|
|
import {
|
|
import {
|
|
|
cancelamentoLabel,
|
|
cancelamentoLabel,
|
|
|
cancelamentoVariant,
|
|
cancelamentoVariant,
|
|
@@ -22,6 +23,7 @@ const opcoesSentimento = Object.entries(sentimentoLabel).map(([value, label]) =>
|
|
|
|
|
|
|
|
const route = useRoute();
|
|
const route = useRoute();
|
|
|
const router = useRouter();
|
|
const router = useRouter();
|
|
|
|
|
+const toast = useToast();
|
|
|
|
|
|
|
|
function formatISO(date) {
|
|
function formatISO(date) {
|
|
|
return date.toISOString().slice(0, 10);
|
|
return date.toISOString().slice(0, 10);
|
|
@@ -35,6 +37,7 @@ function padraoDataInicio() {
|
|
|
|
|
|
|
|
const carregando = ref(false);
|
|
const carregando = ref(false);
|
|
|
const erro = ref("");
|
|
const erro = ref("");
|
|
|
|
|
+const gerandoRelatorio = ref(false);
|
|
|
|
|
|
|
|
const stats = ref(null);
|
|
const stats = ref(null);
|
|
|
const statsGeral = ref(null);
|
|
const statsGeral = ref(null);
|
|
@@ -195,6 +198,25 @@ function verConversa(id) {
|
|
|
router.push({ name: "atendimento", params: { id } });
|
|
router.push({ name: "atendimento", params: { id } });
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
|
|
+async function baixarRelatorio() {
|
|
|
|
|
+ if (gerandoRelatorio.value) return;
|
|
|
|
|
+ gerandoRelatorio.value = true;
|
|
|
|
|
+ try {
|
|
|
|
|
+ await baixarRelatorioNaoResolvidos({
|
|
|
|
|
+ setor: filtroSetor.value || undefined,
|
|
|
|
|
+ sentimento: filtroSentimento.value || undefined,
|
|
|
|
|
+ busca: filtroBusca.value.trim() || undefined,
|
|
|
|
|
+ ordenacao: filtroOrdenacao.value,
|
|
|
|
|
+ dataInicio: filtroDataInicio.value || undefined,
|
|
|
|
|
+ dataFim: filtroDataFim.value || undefined
|
|
|
|
|
+ });
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ toast.erro(err?.message ?? "Falha ao gerar o relatório");
|
|
|
|
|
+ } finally {
|
|
|
|
|
+ gerandoRelatorio.value = false;
|
|
|
|
|
+ }
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
onMounted(async () => {
|
|
onMounted(async () => {
|
|
|
carregarStats();
|
|
carregarStats();
|
|
|
carregarSetores();
|
|
carregarSetores();
|
|
@@ -346,6 +368,19 @@ onBeforeUnmount(() => {
|
|
|
<path v-else stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
<path v-else stroke-linecap="round" stroke-linejoin="round" d="m19.5 8.25-7.5 7.5-7.5-7.5" />
|
|
|
</svg>
|
|
</svg>
|
|
|
</BaseButton>
|
|
</BaseButton>
|
|
|
|
|
+ <BaseButton
|
|
|
|
|
+ variant="secondary"
|
|
|
|
|
+ size="sm"
|
|
|
|
|
+ :loading="gerandoRelatorio"
|
|
|
|
|
+ :disabled="total === 0"
|
|
|
|
|
+ title="Baixar PDF com os atendimentos filtrados"
|
|
|
|
|
+ @click="baixarRelatorio"
|
|
|
|
|
+ >
|
|
|
|
|
+ Baixar relatório
|
|
|
|
|
+ <svg class="h-3.5 w-3.5" viewBox="0 0 24 24" fill="none" stroke="currentColor" stroke-width="2">
|
|
|
|
|
+ <path stroke-linecap="round" stroke-linejoin="round" d="M12 3v12m0 0-4-4m4 4 4-4M4 20h16" />
|
|
|
|
|
+ </svg>
|
|
|
|
|
+ </BaseButton>
|
|
|
<div class="ml-auto text-xs text-gray-500 dark:text-gray-400">
|
|
<div class="ml-auto text-xs text-gray-500 dark:text-gray-400">
|
|
|
{{ total }} não resolvidos
|
|
{{ total }} não resolvidos
|
|
|
</div>
|
|
</div>
|