|
@@ -0,0 +1,163 @@
|
|
|
|
|
+<template>
|
|
|
|
|
+ <q-dialog ref="dialogRef" @hide="onDialogHide">
|
|
|
|
|
+ <q-card style="width: 800px; max-width: 95vw; border-radius: 12px">
|
|
|
|
|
+ <q-bar class="bg-transparent q-px-md" style="height: 55px">
|
|
|
|
|
+ <span class="text-h6 text-dark" style="font-weight: 600"
|
|
|
|
|
+ >Tickets em Aberto</span
|
|
|
|
|
+ >
|
|
|
|
|
+ <q-space />
|
|
|
|
|
+ <q-btn dense flat icon="mdi-close" @click="onDialogCancel" />
|
|
|
|
|
+ </q-bar>
|
|
|
|
|
+
|
|
|
|
|
+ <q-card-section class="q-pt-none q-pb-md q-px-md">
|
|
|
|
|
+ <q-card flat bordered style="border-radius: 8px">
|
|
|
|
|
+ <q-card-section class="q-pb-sm">
|
|
|
|
|
+ <q-input
|
|
|
|
|
+ v-model="search"
|
|
|
|
|
+ dense
|
|
|
|
|
+ borderless
|
|
|
|
|
+ placeholder="Busque por ticket, nome, data , setor"
|
|
|
|
|
+ >
|
|
|
|
|
+ <template #prepend>
|
|
|
|
|
+ <q-icon name="mdi-magnify" color="grey-6" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </q-input>
|
|
|
|
|
+ </q-card-section>
|
|
|
|
|
+
|
|
|
|
|
+ <q-separator />
|
|
|
|
|
+
|
|
|
|
|
+ <div class="list-header q-px-md q-py-xs">
|
|
|
|
|
+ <span class="text-caption text-grey-7">Ticket</span>
|
|
|
|
|
+ <span class="text-caption text-grey-7">Prioridade</span>
|
|
|
|
|
+ <span class="text-caption text-grey-7">Data</span>
|
|
|
|
|
+ <span class="text-caption text-grey-7">Setor</span>
|
|
|
|
|
+ <span class="text-caption text-grey-7">Status</span>
|
|
|
|
|
+ <span class="text-caption text-grey-7">Ações</span>
|
|
|
|
|
+ </div>
|
|
|
|
|
+
|
|
|
|
|
+ <q-separator />
|
|
|
|
|
+
|
|
|
|
|
+ <div style="max-height: 320px; overflow-y: auto">
|
|
|
|
|
+ <template v-for="(ticket, index) in filteredTickets" :key="ticket.id">
|
|
|
|
|
+ <div
|
|
|
|
|
+ class="list-row q-px-md q-py-sm"
|
|
|
|
|
+ :class="{ 'row-selected': index === selectedIndex }"
|
|
|
|
|
+ @click="selectedIndex = index"
|
|
|
|
|
+ >
|
|
|
|
|
+ <span class="text-body2 text-dark">{{ ticket.numero }}</span>
|
|
|
|
|
+ <q-badge
|
|
|
|
|
+ :label="ticket.prioridade"
|
|
|
|
|
+ :color="prioridadeColor(ticket.prioridade)"
|
|
|
|
|
+ style="border-radius: 8px; font-size: 11px; padding: 4px 8px; width: max-content"
|
|
|
|
|
+ />
|
|
|
|
|
+ <span class="text-caption text-dark">{{ ticket.data }}</span>
|
|
|
|
|
+ <span class="text-caption text-dark">{{ ticket.setor }}</span>
|
|
|
|
|
+ <q-badge
|
|
|
|
|
+ :label="ticket.status"
|
|
|
|
|
+ :color="statusColor(ticket.status)"
|
|
|
|
|
+ style="border-radius: 8px; font-size: 11px; padding: 4px 8px; width: max-content"
|
|
|
|
|
+ />
|
|
|
|
|
+ <div class="row" style="gap: 6px">
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ flat
|
|
|
|
|
+ dense
|
|
|
|
|
+ icon="mdi-clipboard-outline"
|
|
|
|
|
+ color="dark"
|
|
|
|
|
+ style="border: 1px solid #ccc; border-radius: 6px; width: 30px; height: 30px"
|
|
|
|
|
+ />
|
|
|
|
|
+ <q-btn
|
|
|
|
|
+ flat
|
|
|
|
|
+ dense
|
|
|
|
|
+ icon="mdi-delete-outline"
|
|
|
|
|
+ color="dark"
|
|
|
|
|
+ style="border: 1px solid #ccc; border-radius: 6px; width: 30px; height: 30px"
|
|
|
|
|
+ />
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ <q-separator v-if="index < filteredTickets.length - 1" />
|
|
|
|
|
+ </template>
|
|
|
|
|
+ </div>
|
|
|
|
|
+ </q-card>
|
|
|
|
|
+ </q-card-section>
|
|
|
|
|
+ </q-card>
|
|
|
|
|
+ </q-dialog>
|
|
|
|
|
+</template>
|
|
|
|
|
+
|
|
|
|
|
+<script setup>
|
|
|
|
|
+import { ref, computed } from "vue";
|
|
|
|
|
+import { useDialogPluginComponent } from "quasar";
|
|
|
|
|
+
|
|
|
|
|
+defineEmits([...useDialogPluginComponent.emits]);
|
|
|
|
|
+
|
|
|
|
|
+const { dialogRef, onDialogHide, onDialogCancel } = useDialogPluginComponent();
|
|
|
|
|
+
|
|
|
|
|
+const search = ref("");
|
|
|
|
|
+const selectedIndex = ref(0);
|
|
|
|
|
+
|
|
|
|
|
+const tickets = [
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 1,
|
|
|
|
|
+ numero: "#12577",
|
|
|
|
|
+ prioridade: "Baixa",
|
|
|
|
|
+ data: "15/02/2026",
|
|
|
|
|
+ setor: "Financeiro",
|
|
|
|
|
+ status: "Não Resolvido",
|
|
|
|
|
+ },
|
|
|
|
|
+ {
|
|
|
|
|
+ id: 2,
|
|
|
|
|
+ numero: "#12578",
|
|
|
|
|
+ prioridade: "Alta",
|
|
|
|
|
+ data: "16/02/2026",
|
|
|
|
|
+ setor: "Comercial",
|
|
|
|
|
+ status: "Em Análise",
|
|
|
|
|
+ },
|
|
|
|
|
+];
|
|
|
|
|
+
|
|
|
|
|
+const prioridadeColor = (p) => {
|
|
|
|
|
+ if (p === "Alta") return "negative";
|
|
|
|
|
+ if (p === "Média") return "warning";
|
|
|
|
|
+ return "orange";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const statusColor = (s) => {
|
|
|
|
|
+ if (s === "Resolvido") return "positive";
|
|
|
|
|
+ if (s === "Em Análise") return "warning";
|
|
|
|
|
+ return "negative";
|
|
|
|
|
+};
|
|
|
|
|
+
|
|
|
|
|
+const filteredTickets = computed(() => {
|
|
|
|
|
+ if (!search.value) return tickets;
|
|
|
|
|
+ const q = search.value.toLowerCase();
|
|
|
|
|
+ return tickets.filter(
|
|
|
|
|
+ (t) =>
|
|
|
|
|
+ t.numero.toLowerCase().includes(q) ||
|
|
|
|
|
+ t.data.includes(q) ||
|
|
|
|
|
+ t.setor.toLowerCase().includes(q) ||
|
|
|
|
|
+ t.status.toLowerCase().includes(q),
|
|
|
|
|
+ );
|
|
|
|
|
+});
|
|
|
|
|
+</script>
|
|
|
|
|
+
|
|
|
|
|
+<style scoped>
|
|
|
|
|
+.list-header {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 90px 100px 110px 1fr 140px 90px;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.list-row {
|
|
|
|
|
+ display: grid;
|
|
|
|
|
+ grid-template-columns: 90px 100px 110px 1fr 140px 90px;
|
|
|
|
|
+ align-items: center;
|
|
|
|
|
+ cursor: pointer;
|
|
|
|
|
+ transition: background-color 0.15s;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.list-row:hover {
|
|
|
|
|
+ background-color: #f5f5f5;
|
|
|
|
|
+}
|
|
|
|
|
+
|
|
|
|
|
+.row-selected {
|
|
|
|
|
+ background-color: #b2dfdb !important;
|
|
|
|
|
+}
|
|
|
|
|
+</style>
|