55 tk-searchfilters( :fields ="fieldsList" )
66 .q-pa-md
77 q-table(
8- :rows ="tickets.data" : rows- per- page- options= "[5, 10, 15]" : loading= "pending" : columns= "columns" row-key ="sequence " : visible- columns= "visibleColumns"
8+ :rows ="tickets.data" : rows- per- page- options= "[5, 10, 15]" : loading= "pending" : columns= "columns" row-key ="_id " : visible- columns= "visibleColumns"
99 v-model:pagination ="pagination" title ="Tickets" @request ="onRequest"
1010 rows-per-page-label ="Lignes par page" no-data-label ="Aucune donnée" loading-label ="Chargement..." no-results-label ="Aucun résultat"
1111 :pagination-label ="(firstRowIndex, endRowIndex, totalRowsNumber) => `${firstRowIndex}-${endRowIndex} sur ${totalRowsNumber} lignes`"
@@ -20,8 +20,10 @@ q-page
2020 q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) Fusionner les tickets sélectionnés
2121 q-btn( flat icon ="mdi-eye" color ="primary" rounded @click ="goToTicket(selected[0])" size ="md" : disable= "selected.length === 0 || selected.length !== 1" )
2222 q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) Afficher les tickets sélectionnés
23- q-btn( flat icon ="mdi-delete" color ="primary" rounded @click ="deleteTickets" size ="md" : disable= "selected.length === 0" )
24- q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) Supprimer les tickets sélectionnés
23+ q-btn( flat icon ="mdi-delete" color ="primary" rounded @click ="closeTicketsDialog = true" size ="md" : disable= "selected.length === 0" )
24+ q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) Cloturer les tickets sélectionnés
25+ q-btn( flat icon ="mdi-close" color ="primary" rounded @click ="selected = []" size ="md" )
26+ q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) Nettoyer la selection
2527 .col-12.col-sm.flex.justify-end
2628 q-btn-group( rounded flat )
2729 q-btn( flat icon ="mdi-table-headers-eye" color ="primary" )
@@ -65,13 +67,23 @@ q-page
6567 span.q-ml-sm {{ props.row.envelope.assigned.length === 0 ? "Pas d'assigné" : props.row.envelope.assigned[0].name }}
6668 span( v-if ="props.row.envelope.assigned.length > 1" ) , {{ props.row.envelope.assigned.length -1 }} autre{{ props.row.envelope.assigned.length === 2 ? '' : 's' }}...
6769 q-tooltip.text-body2 ( transition-show ="scale" transition-hide ="scale" ) ...{{ [...props.row.envelope.assigned].slice(1).map(s => s.name).join(', ') }}
70+
71+ q-dialog( v-model ="closeTicketsDialog" )
72+ q-card.q-pa-sm
73+ q-card-section.row.items-center
74+ .col-12.text-h6.text-center
75+ | Voulez vous vraiment cloturer les tickets sélectionnés ?
76+ q-card-actions
77+ q-btn( color ="red" label ="Annuler" flat @click ="closeTicketsDialog = false" )
78+ q-btn( color ="green" label ="Confirmer" flat @click ="closeTickets" )
6879</template >
6980
7081<script lang="ts" setup>
7182import { ref , provide } from " vue" ;
7283import { useHttpApi } from " ~/composables/useHttpApi" ;
7384import { computed , useDayjs , onMounted } from " #imports" ;
7485import { useRoute , useRouter } from " nuxt/app" ;
86+ import { useQuasar } from " quasar" ;
7587import type { QTableProps } from " quasar" ;
7688import type { components } from ' #build/types/service-api'
7789import { ticketType , lifeSteps } from " #imports" ;
@@ -81,22 +93,45 @@ type State = components["schemas"]['StatesDto']
8193const daysjs = useDayjs ()
8294const route = useRoute ()
8395const router = useRouter ()
96+ const $q = useQuasar ()
8497
98+ const closeTicketsDialog = ref <boolean >(false )
8599const { data : tickets, pending, refresh, error } = await useHttpApi (' /tickets/ticket' , {
86100 method: ' get' ,
87101 query: computed (() => {
88102 return {
89103 ... route .query ,
90104 }
91105 })
92- }).catch ((err ) => console .error (err ))
106+ })
107+
108+ if (error .value ) {
109+ $q .notify ({
110+ message: ' Impossible de récupérer les tickets' ,
111+ type: ' negative'
112+ })
113+ }
93114const { data : categories, pending : categoriesPending, refresh : categoriesRefresh, error : categoriesError } = await useHttpApi (' /core/categories' , {
94115 method: ' get'
95116})
117+
118+ if (categoriesError .value ) {
119+ $q .notify ({
120+ message: ' Impossible de récupérer les catégories' ,
121+ type: ' negative'
122+ })
123+ }
96124const { data : states, pending : statesPending, refresh : statesRefresh, error : statesError } = await useHttpApi (' /tickets/state' , {
97125 method: ' get'
98126})
99127
128+ if (statesError .value ) {
129+ $q .notify ({
130+ message: ' Impossible de récupérer les états' ,
131+ type: ' negative'
132+ })
133+ }
134+
100135onMounted (async () => {
101136 pagination .value ! .rowsNumber = tickets .value ?.total
102137 const query = { ... route .query }
@@ -105,7 +140,7 @@ onMounted(async () => {
105140 pagination .value ! .rowsPerPage = parseInt (limit as string )
106141 pagination .value ! .page = parseInt (skip as string ) / parseInt (limit as string ) + 1
107142
108- let sortKey = ' updatedAt '
143+ let sortKey = ' metadata.lastUpdatedAt '
109144 let sortDirection = ' desc'
110145 for (const key in query ) {
111146 if (key .startsWith (' sort' )) {
@@ -298,8 +333,31 @@ const mergeTickets = () => {
298333 console .log (' mergeTickets' )
299334}
300335
301- const deleteTickets = () => {
302- console .log (' deleteTickets' )
336+ const openCloseTicketsModale = () => {
337+ closeTicketsDialog .value = true
338+ }
339+
340+ const closeTickets = async () => {
341+ const { data, error } = await useHttpApi (' /tickets/ticket/close-many' , {
342+ method: ' post' ,
343+ body: {
344+ ids: selected .value .map (s => s ._id )
345+ }
346+ })
347+ if (error .value ) {
348+ closeTicketsDialog .value = false
349+ $q .notify ({
350+ message: ' Impossible de cloturer les tickets' ,
351+ type: ' negative'
352+ })
353+ } else {
354+ refresh ()
355+ closeTicketsDialog .value = false
356+ $q .notify ({
357+ message: ' Tickets cloturés' ,
358+ type: ' positive'
359+ })
360+ }
303361}
304362
305363provide (' fieldsList' , fieldsList )
0 commit comments