| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167 |
- <template>
- <div>
- <DefaultHeaderPage title="Suporte" />
- <DefaultTable
- ref="tableRef"
- :columns="columns"
- :api-call="getSupportTickets"
- add-item
- title="Tickets"
- :female="false"
- description="tickets"
- @on-add-item="openAddEditTicketDialog()"
- >
- <template #body-cell-severity="{ row }">
- <q-td align="left">
- <q-badge
- :color="severityColor(row.severity)"
- :label="severityLabel(row.severity)"
- style="padding: 6px 10px"
- />
- </q-td>
- </template>
- <template #body-cell-origin="{ row }">
- <q-td align="left">{{ originLabel(row) }}</q-td>
- </template>
- <template #body-cell-status="{ row }">
- <q-td align="left">
- <q-badge
- :color="statusColor(row.status)"
- :label="statusLabel(row.status)"
- style="padding: 6px 10px"
- />
- </q-td>
- </template>
- <template #body-cell-actions="{ row }">
- <q-td style="display: flex; gap: 4px; align-items: center; justify-content: center">
- <q-btn
- outline
- :icon="canManage(row) ? 'mdi-pencil-outline' : 'mdi-eye-outline'"
- style="width: 36px"
- @click.prevent.stop="handleEdit(row)"
- />
- <q-btn
- v-if="canManage(row) && row.status === 'in_progress'"
- outline
- icon="mdi-check-circle-outline"
- style="width: 36px"
- @click.prevent.stop="handleClose(row)"
- />
- <q-btn
- v-if="canManage(row) && row.status === 'in_progress'"
- outline
- icon="mdi-trash-can-outline"
- style="width: 36px"
- @click.prevent.stop="handleDelete(row)"
- />
- </q-td>
- </template>
- </DefaultTable>
- </div>
- </template>
- <script setup>
- import { defineAsyncComponent, useTemplateRef } from "vue";
- import { useQuasar } from "quasar";
- import DefaultTable from "src/components/defaults/DefaultTable.vue";
- import DefaultHeaderPage from "src/components/layout/DefaultHeaderPage.vue";
- import { getSupportTickets, deleteSupportTicket } from "src/api/support_ticket";
- const AddEditTicketDialog = defineAsyncComponent(
- () => import("src/pages/support/components/AddEditTicketDialog.vue"),
- );
- const CloseTicketDialog = defineAsyncComponent(
- () => import("src/pages/support/components/CloseTicketDialog.vue"),
- );
- const $q = useQuasar();
- const tableRef = useTemplateRef("tableRef");
- const openAddEditTicketDialog = (ticket = null) => {
- $q.dialog({
- component: AddEditTicketDialog,
- componentProps: { ticket },
- }).onOk(() => {
- tableRef.value?.refresh();
- });
- };
- const columns = [
- { name: "id", label: "Ticket", field: "id", align: "left", style: "width: 5%", format: (val) => `#${String(val).padStart(6, "0")}` },
- { name: "severity", label: "Prioridade", field: "severity", align: "left", style: "width: 10%" },
- { name: "created_at", label: "Data", field: "created_at", align: "left", style: "width: 12%" },
- { name: "origin", label: "Origem", field: "origin", align: "left", style: "width: 12%" },
- { name: "sector", label: "Setor", field: "sector", align: "left", style: "width: 16%" },
- { name: "title", label: "Título", field: "title", align: "left", style: "width: 25%" },
- { name: "status", label: "Status", field: "status", align: "left", style: "width: 10%" },
- { name: "actions", label: "Ações", field: "actions", align: "center", style: "width: 10%" },
- ];
- const originLabel = (row) => {
- if (row.scope === "internal") return "Interno";
- return "Matriz";
- };
- // Franchisee só pode gerenciar tickets internos que ela mesma criou
- const canManage = (row) => row.origin === "unit" && row.scope === "internal";
- const severityLabel = (severity) => {
- const map = { alta: "Alta", normal: "Normal", baixa: "Baixa" };
- return map[severity] ?? severity;
- };
- const severityColor = (severity) => {
- const map = { alta: "negative", normal: "warning", baixa: "positive" };
- return map[severity] ?? "grey";
- };
- const statusLabel = (status) => {
- const map = {
- in_progress: "Em andamento",
- resolved: "Resolvido",
- unresolved: "Não resolvido",
- };
- return map[status] ?? status;
- };
- const statusColor = (status) => {
- const map = {
- in_progress: "warning",
- resolved: "positive",
- unresolved: "negative",
- };
- return map[status] ?? "grey";
- };
- const handleEdit = (row) => {
- openAddEditTicketDialog(row);
- };
- const handleClose = (row) => {
- $q.dialog({
- component: CloseTicketDialog,
- componentProps: { ticket: row },
- }).onOk(() => {
- tableRef.value?.refresh();
- });
- };
- const handleDelete = (row) => {
- $q.dialog({
- title: "Confirmar exclusão",
- message: "Tem certeza que deseja excluir este ticket?",
- ok: { color: "negative", label: "Excluir" },
- cancel: { color: "primary", outline: true, label: "Cancelar" },
- }).onOk(async () => {
- await deleteSupportTicket(row.id);
- tableRef.value?.refresh();
- });
- };
- </script>
|