Untitled

 avatar
unknown
plain_text
2 months ago
5.7 kB
6
Indexable
<template>
  <Filters v-model="selectedFilter" @buttonClicked="applyFilters" @sendOrder="formatBodyOrder" />

  <v-data-table
    :headers="headers"
    :items="response"
    v-model="selectedItems"
    show-select
    :items-per-page="25"
    :footer-props="{
      itemsPerPageText: 'Itens por página',
      pageText: (pageStart, pageStop, totalItems) => `${pageStart}-${pageStop} de ${totalItems}`
    }"
  >
    <template v-slot:body="{ items }">
      <tr v-for="(item, index) in items" :key="item.id">
        <td v-for="header in headers" :key="header.value">
          {{ item[header.value] }}
        </td>
        <!-- Botão para expandir -->
        <td>
          <v-btn icon small @click="onActionClick(index)">
            <v-icon>{{ expandedRows.includes(index) ? 'mdi-chevron-up' : 'mdi-chevron-down' }}</v-icon>
          </v-btn>
        </td>
      </tr>

      <!-- Linha de Detalhes -->
      <tr v-if="expandedRows.includes(index)" class="details-row">
        <td :colspan="headers.length + 1">
          <v-data-table
            :headers="detailHeaders"
            :items="item.stretchsFull" <!-- Passando os dados de stretchsFull -->
            v-model="selectedDetails" <!-- Controle da seleção dos itens da tabela de detalhes -->
            show-select <!-- Mostrar a seleção na tabela de detalhes -->
            dense
            hide-default-footer
          >
            <template v-slot:items="props">
              <tr>
                <td>{{ props.item.id }}</td>
                <td>{{ props.item.flight_time_full }}</td>
                <td>{{ props.item.distance_km }} km</td>
                <td>{{ props.item.aircraftFull.prefixo }}</td>
                <td>{{ props.item.aircraftFull.status }}</td>
                <td>{{ props.item.utc }}</td>
              </tr>
            </template>
          </v-data-table>
        </td>
      </tr>
    </template>

    <template v-slot:no-data>
      <v-alert type="info">Nenhum registro encontrado.</v-alert>
    </template>
  </v-data-table>
</template>

<script>
import Filters from './Filters.vue';
import { ref, inject } from "vue";
import useOrders from "../../../../composables/orders";

export default {
  setup() {
    const swal = inject('$swal');
    const Toast = swal.mixin({
      toast: true,
      position: 'top-end',
      showConfirmButton: false,
      timer: 2000,
      timerProgressBar: true,
      didOpen: (toast) => {
        toast.addEventListener('mouseenter', swal.stopTimer);
        toast.addEventListener('mouseleave', swal.resumeTimer);
      }
    });

    const { getClientsContractsRefactor, processOrders } = useOrders();
    const selectedFilter = ref({
      currentDateRange: '',
      selectedProgramObj: '',
      selectedClientObj: '',
      currentDate: new Date(),
    });

    const response = ref([]);
    const selectedItems = ref([]); // Para seleção da tabela principal
    const selectedDetails = ref([]); // Para seleção da tabela de detalhes
    const expandedRows = ref([]);

    const onActionClick = (index) => {
      const idx = expandedRows.value.indexOf(index);
      if (idx === -1) {
        expandedRows.value.push(index); // Expande a linha
      } else {
        expandedRows.value.splice(idx, 1); // Fecha a linha
      }
    };

    function validarFiltros() {
      for (let key of Object.keys(selectedFilter.value)) {
        const value = selectedFilter.value[key];
        if (value === null || value === '') {
          Toast.fire({
            icon: 'info',
            title: `Preencha todos os campos obrigatórios.`
          });
          return false;
        }
      }
      return true;
    }

    const applyFilters = async() => {
      if (validarFiltros()) {
        const dates = [selectedFilter.value.currentDateRange.start, selectedFilter.value.currentDateRange.end].map(date => moment(date).format('YYYY-MM-DD'));
        response.value = await getClientsContractsRefactor('variavel', selectedFilter.value.selectedClientObj, dates, selectedFilter.value.selectedProgramObj);
      }
    };

    const formatBodyOrder = async() => {
      if (selectedItems.value.length === 0) {
        Toast.fire({
          icon: 'info',
          title: `Selecione ao menos uma linha.`
        });
        return;
      }
    };

    const headers = [
      { title: '', align: 'start', value: 'expand' },
      { title: 'Nº da Reserva', align: 'start', value: 'id' },
      { title: 'Status', align: 'start', value: 'status' },
      { title: 'Contexto', align: 'start', value: 'context' },
      { title: 'Hora', align: 'start', value: 'hourGmt' },
      { title: 'Data de Criação', align: 'start', value: 'created_at' },
    ];

    const detailHeaders = [
      { title: 'ID do Trecho', align: 'start', value: 'id' },
      { title: 'Tempo de Voo', align: 'start', value: 'flight_time_full' },
      { title: 'Distância (km)', align: 'start', value: 'distance_km' },
      { title: 'Prefixo da Aeronave', align: 'start', value: 'aircraftFull.prefixo' },
      { title: 'Status da Aeronave', align: 'start', value: 'aircraftFull.status' },
      { title: 'UTC', align: 'start', value: 'utc' },
    ];

    return {
      selectedFilter,
      applyFilters,
      response,
      headers,
      detailHeaders,
      formatBodyOrder,
      selectedItems,
      selectedDetails, // Referência para controle de seleção da tabela de detalhes
      onActionClick,
      expandedRows
    };
  },
  components: {
    Filters
  },
};
</script>
Editor is loading...
Leave a Comment