Fix data loading issue and show detail on data selection
This commit is contained in:
		| @@ -19,7 +19,7 @@ | ||||
|       :show-borders="true" | ||||
|       :row-alternation-enabled="true" | ||||
|       :hover-state-enabled="true" | ||||
|       @selection-changed="onSelectionChanged" | ||||
|       @selection-changed="onDataSelectionChanged" | ||||
|       :column-width="100" | ||||
|       @exporting="onExporting" | ||||
|       :allow-column-resizing="true" | ||||
| @@ -35,8 +35,7 @@ | ||||
|         :show-indicator="showIndicator" | ||||
|         :show-pane="showPane" | ||||
|         :shading="shading" | ||||
|         v-if="loading" | ||||
|         v-model:visible="loading" | ||||
|         v-model:visible="loadingData" | ||||
|         :enabled="true" | ||||
|       /> | ||||
|       <DxSearchPanel :visible="true" :highlight-case-sensitive="true" /> | ||||
| @@ -522,19 +521,352 @@ | ||||
|       </template> | ||||
|     </DxDataGrid> | ||||
|   </div> | ||||
|  | ||||
|   <DetailDialog | ||||
|     :open="dialogDetail" | ||||
|     title="Detail Rekapitulasi Gangguan Per Regu" | ||||
|     @on-close="closeDialog" | ||||
|     :full-width="true" | ||||
|   > | ||||
|     <div class="w-full mb-4 lg:w-[70%] lg:float-left"> | ||||
|       <div class="p-4 bg-white rounded-xl lg:mr-4"> | ||||
|         <DxDataGrid | ||||
|           :allow-column-reordering="true" | ||||
|           class="max-h-[calc(100vh-140px)]" | ||||
|           :data-source="dataSub" | ||||
|           :show-column-lines="true" | ||||
|           :show-row-lines="false" | ||||
|           :show-borders="true" | ||||
|           :row-alternation-enabled="true" | ||||
|           :hover-state-enabled="true" | ||||
|           @selection-changed="onDataSubSelectionChanged" | ||||
|           :column-width="100" | ||||
|           @exporting="onExporting" | ||||
|           :allow-column-resizing="true" | ||||
|           column-resizing-mode="widget" | ||||
|         > | ||||
|           <DxSelection mode="single" /> | ||||
|           <DxPaging :page-size="20" :enabled="true" /> | ||||
|           <DxPager | ||||
|             :visible="true" | ||||
|             :allowed-page-sizes="[20, 50, 100]" | ||||
|             display-mode="full" | ||||
|             :show-page-size-selector="true" | ||||
|             :show-info="true" | ||||
|             :show-navigation-buttons="true" | ||||
|           /> | ||||
|           <DxLoadPanel | ||||
|             shading-color="rgba(0,0,0,0.4)" | ||||
|             :position="position" | ||||
|             :show-indicator="showIndicator" | ||||
|             :show-pane="showPane" | ||||
|             :shading="shading" | ||||
|             v-model:visible="loadingSubData" | ||||
|             :enabled="true" | ||||
|           /> | ||||
|           <DxSearchPanel :visible="true" :highlight-case-sensitive="true" /> | ||||
|           <DxExport | ||||
|             :enabled="true" | ||||
|             :formats="['pdf', 'xlsx', 'document']" | ||||
|             :allow-export-selected-data="false" | ||||
|           /> | ||||
|  | ||||
|           <DxColumn | ||||
|             css-class="custom-table-column" | ||||
|             :width="50" | ||||
|             alignment="center" | ||||
|             :calculateCellValue="(item: any) => dataSub.findIndex((i) => i == item) + 1" | ||||
|             data-type="number" | ||||
|             caption="No" | ||||
|             cell-template="formatNumber" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="no_laporan" | ||||
|             caption="No Laporan" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="waktu_lapor" | ||||
|             caption="Tgl Lapor" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="waktu_response" | ||||
|             caption="Tgl Datang" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="waktu_recovery" | ||||
|             caption="Tgl Nyala" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="durasi_response_time" | ||||
|             caption="Durasi Response Time" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatTime" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="durasi_recovery_time" | ||||
|             caption="Durasi Recovery Time" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatTime" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="status_akhir" | ||||
|             caption="Status" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="referensi_marking" | ||||
|             caption="Referensi Marking" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="idpel_nometer" | ||||
|             caption="IDPEL/NO METER" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="nama_pelapor" | ||||
|             caption="Nama Pelapor" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="alamat_pelapor" | ||||
|             caption="Alamat Pelapor" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="no_telp_pelapor" | ||||
|             caption="No Telp Pelapor" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="200" | ||||
|             alignment="center" | ||||
|             data-field="keterangan_pelapor" | ||||
|             caption="Keterangan Pelapor" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="nama_posko" | ||||
|             caption="Posko" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="tindakan" | ||||
|             caption="Tidakan" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|           <DxColumn | ||||
|             :width="150" | ||||
|             alignment="center" | ||||
|             data-field="penyebab" | ||||
|             caption="Penyebab" | ||||
|             css-class="custom-table-column" | ||||
|             cell-template="formatText" | ||||
|           /> | ||||
|  | ||||
|           <template #formatText="{ data }"> | ||||
|             <p class="text-left cursor-pointer"> | ||||
|               {{ data.text }} | ||||
|             </p> | ||||
|           </template> | ||||
|  | ||||
|           <template #formatNumber="{ data }"> | ||||
|             <p class="text-right cursor-pointer"> | ||||
|               {{ data.text }} | ||||
|             </p> | ||||
|           </template> | ||||
|  | ||||
|           <template #formatTime="{ data }"> | ||||
|             <p> | ||||
|               {{ parseInt(data.text) ? formatWaktu(data.text) : '-' }} | ||||
|             </p> | ||||
|           </template> | ||||
|         </DxDataGrid> | ||||
|       </div> | ||||
|     </div> | ||||
|     <div class="w-full mb-4 lg:w-[30%] lg:float-right"> | ||||
|       <div class="p-4 space-y-2 bg-white rounded-xl"> | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">No Laporan:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.no_laporan" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Tgl Lapor:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.waktu_lapor" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Tgl Datang:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.waktu_response" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Tgl Nyala:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.waktu_recovery" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Durasi Response Time:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value=" | ||||
|               parseInt(dataSubSelected?.durasi_response_time) | ||||
|                 ? formatWaktu(dataSubSelected?.durasi_response_time) | ||||
|                 : '-' | ||||
|             " | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Durasi Recovery Time:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value=" | ||||
|               parseInt(dataSubSelected?.durasi_recovery_time) | ||||
|                 ? formatWaktu(dataSubSelected?.durasi_recovery_time) | ||||
|                 : '-' | ||||
|             " | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Status:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.status_akhir" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Referensi Marking:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.referensi_marking" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">IDPEL/NO METER:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.idpel_nometer" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Nama Pelapor:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.nama_pelapor" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Alamat Pelapor:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.alamat_pelapor" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">No Telp Pelapor:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.no_telp_pelapor" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Keterangan Pelapor:</h3> | ||||
|           <InputText | ||||
|             :readonly="true" | ||||
|             :value="dataSubSelected?.keterangan_pelapor" | ||||
|             class-name="flex-1" | ||||
|           /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Posko:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.nama_posko" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Tindakan:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.tindakan" class-name="flex-1" /> | ||||
|         </div> | ||||
|  | ||||
|         <div class="flex flex-row items-center justify-between w-full"> | ||||
|           <h3 class="text-sm font-medium w-[135px] text-gray-800">Penyebab:</h3> | ||||
|           <InputText :readonly="true" :value="dataSubSelected?.penyebab" class-name="flex-1" /> | ||||
|         </div> | ||||
|       </div> | ||||
|     </div> | ||||
|   </DetailDialog> | ||||
| </template> | ||||
|  | ||||
| <script setup lang="ts"> | ||||
| import Filters from '@/components/Form/Filters.vue' | ||||
| import Type9 from '@/components/Form/FiltersType/Type9.vue' | ||||
| import { formatWaktu } from '@/components/Form/FiltersType/reference' | ||||
| import { onMounted, ref } from 'vue' | ||||
| import { onMounted, ref, watch } from 'vue' | ||||
| import { DxDataGrid } from 'devextreme-vue' | ||||
| import { | ||||
|   DxColumn, | ||||
|   DxColumnFixing, | ||||
|   DxExport, | ||||
|   DxLoadPanel, | ||||
|   DxPager, | ||||
|   DxPaging, | ||||
|   DxScrolling, | ||||
|   DxSearchPanel, | ||||
| @@ -550,13 +882,82 @@ import { Workbook } from 'exceljs' | ||||
| import { useQuery } from '@vue/apollo-composable' | ||||
| import { queries } from '@/utils/api/api.graphql' | ||||
| import { formatNumber, formatPercentage, isNumber } from '@/utils/numbers' | ||||
| import DetailDialog from '@/components/Dialogs/DetailDialog.vue' | ||||
| import InputText from '@/components/InputText.vue' | ||||
| import { apolloClient } from '@/utils/api/api.graphql' | ||||
| import { provideApolloClient } from '@vue/apollo-composable' | ||||
|  | ||||
| const client = apolloClient() | ||||
| provideApolloClient(client) | ||||
| const position = { of: '#data' } | ||||
| const showIndicator = ref(true) | ||||
| const shading = ref(true) | ||||
| const showPane = ref(true) | ||||
| const data = ref<any[]>([]) | ||||
| const dataSub = ref<any[]>([]) | ||||
| const dataSelected = ref<any>() | ||||
| const dataSubSelected = ref<any>() | ||||
| const dialogDetail = ref(false) | ||||
| const loadingData = ref(false) | ||||
| const loadingSubData = ref(false) | ||||
|  | ||||
| const getDetail = () => { | ||||
|   loadingSubData.value = true | ||||
|   const dateValue = filters.value?.periode.split(' s/d ') | ||||
|   const ref = dataSelected.value | ||||
|  | ||||
|   const query = { | ||||
|     dateFrom: dateValue[0] | ||||
|       ? dateValue[0].split('-').reverse().join('-') | ||||
|       : new Date().toISOString().slice(0, 10), | ||||
|     dateTo: dateValue[1] | ||||
|       ? dateValue[1].split('-').reverse().join('-') | ||||
|       : new Date().toISOString().slice(0, 10), | ||||
|     posko: ref?.id_posko ? ref?.id_posko : 0, | ||||
|     idUid: ref?.id_uid ? ref?.id_uid : 0, | ||||
|     idUp3: ref?.id_up3 ? ref?.id_up3 : 0, | ||||
|     idRegu: ref?.id_regu ? ref?.id_regu : 0, | ||||
|     idUlp: ref?.id_ulp ? ref?.id_ulp : 0, | ||||
|     namaRegional: ref?.nama_regional ? ref?.nama_regional : '', | ||||
|     media: ref?.media ? ref?.media : '' | ||||
|   } | ||||
|  | ||||
|   const { onResult, onError, loading, refetch } = useQuery( | ||||
|     queries.gangguan.rekap.gangguanAllDetail, | ||||
|     query | ||||
|   ) | ||||
|  | ||||
|   onResult((queryResult) => { | ||||
|     if (queryResult.data != undefined) { | ||||
|       dataSub.value = queryResult.data.detailGangguan | ||||
|     } | ||||
|   }) | ||||
|  | ||||
|   onError((error) => { | ||||
|     console.log(error) | ||||
|   }) | ||||
|  | ||||
|   watch(loading, (value) => { | ||||
|     loadingSubData.value = value | ||||
|   }) | ||||
| } | ||||
|  | ||||
| const dataGridRef = ref<DxDataGrid | null>(null) | ||||
| const clearSelection = () => { | ||||
|   const dataGrid = dataGridRef.value!.instance! | ||||
|   dataGrid.clearSelection() | ||||
| } | ||||
| const showDetail = () => { | ||||
|   clearSelection() | ||||
|   dataSub.value = [] | ||||
|   dataSubSelected.value = null | ||||
|   dialogDetail.value = true | ||||
|   getDetail() | ||||
| } | ||||
|  | ||||
| const closeDialog = () => { | ||||
|   dialogDetail.value = false | ||||
| } | ||||
| const onExporting = (e: any) => { | ||||
|   if (e.format === 'pdf') { | ||||
|     const doc = new jsPDF() | ||||
| @@ -585,28 +986,25 @@ const onExporting = (e: any) => { | ||||
|     e.cancel = true | ||||
|   } | ||||
| } | ||||
| const dataGridRef = ref<DxDataGrid | null>(null) | ||||
| const clearSelection = () => { | ||||
|   const dataGrid = dataGridRef.value!.instance! | ||||
|   dataGrid.clearSelection() | ||||
| } | ||||
| const onSelectionChanged = ({ selectedRowsData }: any) => { | ||||
|   const data = selectedRowsData[0] | ||||
|   clearSelection() | ||||
|  | ||||
| const onDataSelectionChanged = ({ selectedRowsData }: any) => { | ||||
|   if (selectedRowsData[0] != undefined) { | ||||
|     dataSelected.value = selectedRowsData[0] | ||||
|     showDetail() | ||||
|   } | ||||
| } | ||||
|  | ||||
| const { onResult, onError, loading, refetch } = useQuery(queries.gangguan.rekap.gangguanPerRegu, { | ||||
|   dateFrom: new Date('2023-10-01').toISOString().slice(0, 10), | ||||
|   dateTo: new Date('2023-10-01').toISOString().slice(0, 10), | ||||
|   posko: 0, | ||||
|   idUid: 0, | ||||
|   idUp3: 0 | ||||
| }) | ||||
| const onDataSubSelectionChanged = ({ selectedRowsData }: any) => { | ||||
|   if (selectedRowsData[0] != undefined) { | ||||
|     dataSubSelected.value = selectedRowsData[0] | ||||
|   } | ||||
| } | ||||
|  | ||||
| const filterData = (params: any) => { | ||||
|   const dateValue = params.periode.split(' s/d ') | ||||
|   const { posko, uid, up3 } = params | ||||
|   refetch({ | ||||
|  | ||||
|   const { onResult, onError, loading, refetch } = useQuery(queries.gangguan.rekap.gangguanPerRegu, { | ||||
|     dateFrom: dateValue[0] | ||||
|       ? dateValue[0].split('-').reverse().join('-') | ||||
|       : new Date().toISOString().slice(0, 10), | ||||
| @@ -617,18 +1015,27 @@ const filterData = (params: any) => { | ||||
|     idUid: uid ? uid.id : 0, | ||||
|     idUp3: up3 ? up3.id : 0 | ||||
|   }) | ||||
|  | ||||
|   onResult((queryResult) => { | ||||
|     if (queryResult.data != undefined) { | ||||
|       data.value = queryResult.data.rekapitulasiGangguanPerRegu | ||||
|     } | ||||
|     console.log(queryResult.data) | ||||
|   }) | ||||
|  | ||||
|   onError((error) => { | ||||
|     console.log(error) | ||||
|   }) | ||||
|  | ||||
|   watch(loading, (value) => { | ||||
|     loadingData.value = value | ||||
|   }) | ||||
| } | ||||
|  | ||||
| const filters = ref({ | ||||
|   uid: 0, | ||||
|   up3: 0, | ||||
|   posko: 0, | ||||
|   periode: '', | ||||
|   groupBy: false | ||||
| }) | ||||
|  | ||||
|   | ||||
| @@ -743,8 +743,8 @@ const onExporting = (e: any) => { | ||||
| const onDataSelectionChanged = ({ selectedRowsData }: any) => { | ||||
|   if (selectedRowsData[0] != undefined) { | ||||
|     dataSelected.value = selectedRowsData[0] | ||||
|     showDetail() | ||||
|   } | ||||
|   showDetail() | ||||
| } | ||||
|  | ||||
| const onDataSubSelectionChanged = ({ selectedRowsData }: any) => { | ||||
| @@ -754,6 +754,7 @@ const onDataSubSelectionChanged = ({ selectedRowsData }: any) => { | ||||
| } | ||||
|  | ||||
| const filterData = (params: any) => { | ||||
|   loadingData.value = true | ||||
|   const dateValue = params.periode.split(' s/d ') | ||||
|   const { posko, uid, up3 } = params | ||||
|  | ||||
| @@ -775,16 +776,13 @@ const filterData = (params: any) => { | ||||
|   onResult((queryResult) => { | ||||
|     if (queryResult.data != undefined) { | ||||
|       data.value = queryResult.data.rekapitulasiGangguanPerTanggal | ||||
|       loadingData.value = false | ||||
|     } | ||||
|     console.log(queryResult.data) | ||||
|   }) | ||||
|  | ||||
|   onError((error) => { | ||||
|     console.log(error) | ||||
|   }) | ||||
|  | ||||
|   watch(loading, (value) => { | ||||
|     loadingData.value = value | ||||
|     loadingData.value = false | ||||
|   }) | ||||
| } | ||||
|  | ||||
|   | ||||
		Reference in New Issue
	
	Block a user