@@ -3,19 +3,19 @@ q-scroll-area(:style="{height: '100%'}")
33 q-card
44 q-toolbar.justify-end
55 q-btn-group
6- q-btn( @click ="showCloseTicketDialog()" color ="red" icon ="mdi-close" size ="md" : disable= "disabled " )
6+ q-btn( @click ="showCloseTicketDialog()" color ="red" icon ="mdi-close" size ="md" : disable= "isDisabledTicket " )
77 q-tooltip.text-body2 Cloturer
88 q-btn(
99 v-if ="!props.ticketData.envelope.assigned.find((user: any) => user.id === store.state.value.auth.user._id)"
10- color ="green" icon ="mdi-clipboard-arrow-down-outline" @click ="assignTicket" size ="md" : disable= "disabled "
10+ color ="green" icon ="mdi-clipboard-arrow-down-outline" @click ="assignTicket" size ="md" : disable= "isDisabledTicket "
1111 )
1212 q-tooltip.text-body2 M'assigner le ticket
13- q-btn( v-else color ="red" icon ="mdi-clipboard-arrow-up-outline" size ="md" @click ="unasignTicket" : disable= "disabled " )
13+ q-btn( v-else color ="red" icon ="mdi-clipboard-arrow-up-outline" size ="md" @click ="unasignTicket" : disable= "isDisabledTicket " )
1414 q-tooltip.text-body2 Me désassigner le ticket
1515
1616 q-btn( color ="primary" icon ="mdi-printer" @click ="console.log('Imprimer')" size ="md" )
1717 q-tooltip.text-body2 Imprimer
18- q-btn( color ="info" icon ="mdi-content-save-all" @click ="console.log('Save')" size ="md" : disable= "disabled " )
18+ q-btn( color ="info" icon ="mdi-content-save-all" @click ="console.log('Save')" size ="md" : disable= "isDisabledTicket " )
1919 q-tooltip.text-body2 Sauvegarder
2020 q-btn( color ="red" icon ="mdi-arrow-left" @click ="console.log(router.go(-1))" size ="md" )
2121 q-tooltip.text-body2 Retour
@@ -27,25 +27,30 @@ q-scroll-area(:style="{height: '100%'}")
2727 q-card
2828 q-card-section
2929 q-select.q-my-xs (
30- label ="Appelant(s)" filled v-model ="props.ticketData.envelope.senders"
30+ @update:model-value ="updateData({field: 'envelope.senders', value: $event})"
31+ label ="Appelant(s)" filled
32+ v-model ="ticketDataRef.envelope.senders"
3133 option-label ="name"
3234 use-input use-chips multiple
33- new-value-mode ="add-unique"
34- :disable ="disabled"
35+ :readonly ="true"
3536 )
3637 q-select.q-my-xs (
3738 option-label ="name"
38- label ="Concerné(s)" filled v-model ="props.ticketData.envelope.observers"
39+ @update:model-value ="updateData({field: 'envelope.observers', value: $event})"
40+ label ="Concerné(s)" filled
41+ v-model ="ticketDataRef.envelope.observers"
3942 use-input use-chips multiple
40- new-value-mode = "add-unique "
41- :disable = "disabled "
43+ :disable = "isDisabledTicket "
44+ :options = "observers "
4245 )
4346 q-select.q-my-xs (
4447 option-label ="name"
45- label ="Assigné(s)" filled v-model ="props.ticketData.envelope.assigned"
48+ @update:model-value ="updateData({field: 'envelope.assigned', value: $event})"
49+ label ="Assigné(s)" filled
50+ v-model ="ticketDataRef.envelope.assigned"
4651 use-input use-chips multiple
47- new-value-mode = "add-unique "
48- :disable = "disabled "
52+ :disable = "isDisabledTicket "
53+ :options = "assigned "
4954 )
5055 q-expansion-item( label ="Informations" ) .bg-gray-4
5156 q-card
@@ -56,34 +61,38 @@ q-scroll-area(:style="{height: '100%'}")
5661 q-chip( :icon ="typeOfTicket.icon" : color= "typeOfTicket.color" outline ) .q-mx-auto {{ typeOfTicket.label }}
5762 q-select.q-my-xs (
5863 label ="Projet(s)" filled
59- v-model ="props.ticketData.project"
64+ @update:model-value ="updateData({field: 'project', value: $event})"
65+ v-model ="ticketDataRef.project"
6066 :options ="getProjectsData"
6167 option-label ="name"
62- :disable ="disabled "
68+ :disable ="isDisabledTicket "
6369 )
6470 q-select.q-my-xs (
6571 label ="Priorité" filled
66- v-model ="props.ticketData.priority"
72+ @update:model-value ="updateData({field: 'priority', value: $event})"
73+ v-model ="ticketDataRef.priority"
6774 :options ="priority"
6875 option-label ="name"
69- :disable ="disabled "
76+ :disable ="isDisabledTicket "
7077 )
7178 q-select.q-my-xs (
7279 label ="Impact" filled
73- v-model ="props.ticketData.impact"
80+ @update:model-value ="updateData({field: 'impact', value: $event})"
81+ v-model ="ticketDataRef.impact"
7482 :options ="impact"
7583 option-label ="name"
76- :disable ="disabled "
84+ :disable ="isDisabledTicket "
7785 )
7886 q-select.q-my-xs (
7987 label ="SLA" filled
80- v-model ="props.ticketData.sla"
81- :options ="sla.data"
88+ @update:model-value ="updateData({field: 'sla', value: $event})"
89+ v-model ="ticketDataRef.sla"
90+ :options ="getSlaData"
8291 option-label ="name"
83- :disable ="disabled "
92+ :disable ="isDisabledTicket "
8493 )
8594 q-input.q-my-xs ( label ="Due date" type ="date" filled v-model ="dueDate"
86- :disable ="disabled " )
95+ :disable ="isDisabledTicket " )
8796 q-input.q-my-xs ( label ="Temps total" type ="time" filled readonly v-model ="totalTime" )
8897 q-expansion-item( label ="Cycle de vie" ) .bg-gray-4
8998 q-card
@@ -108,46 +117,99 @@ q-scroll-area(:style="{height: '100%'}")
108117 q-card-actions
109118 q-btn( color ="red" label ="Annuler" flat @click ="closeDialog = false" )
110119 q-btn( color ="green" label ="Confirmer" flat @click ="closeTicket" )
111- q-btn( color ="primary" label ="Réouvrir" flat @click ="openTicket" )
120+ //- q-btn(color="primary" label="Réouvrir" flat @click="openTicket")
112121 </template >
113122
114123<script lang="ts" setup>
115124import { ref , onMounted , computed , inject , watch } from ' vue'
116- import { ticketType , lifeSteps , useDayjs , usePinia } from ' #imports' ;
125+ import { ticketType , lifeSteps , useDayjs , usePinia , useQuasar } from ' #imports' ;
117126import { useHttpApi } from ' ~/composables/useHttpApi' ;
118127import { useRouter } from ' vue-router' ;
119- import { impact , priority , LifeStep } from ' ~/utils' ;
128+ import { impact , priority , LifeStep , EntityType } from ' ~/utils' ;
120129import type { components } from ' #build/types/service-api'
121-
122- type TicketType = components [' schemas' ][' Ticket' ]
130+ type TicketUpdateDto = components [' schemas' ][' TicketUpdateDto' ]
131+ type IdnamePartDto = components [" schemas" ][" IdnamePartDto" ]
132+ type SlaPartDto = components [" schemas" ][" SlaPartDto" ]
133+ type EntityPartDto = components [" schemas" ][" EntityPartDto" ]
134+ type TicketType = components [' schemas' ][' TicketDto' ]
123135const props = defineProps ({
124136 ticketData: {
125137 type: Object ,
126138 required: true
127- } as TicketType ,
128- disabled: {
129- type: Boolean ,
130- default: false
131139 }
132140})
133- const emit = defineEmits ([' update:ticketData' ])
141+ const emit = defineEmits ([' fetch:ticketData ' , ' update:ticketData' ])
134142const dayjs = useDayjs ()
135143const router = useRouter ()
136144const store = usePinia ()
137-
138- const ticket = ref (props .ticketData )
145+ const $q = useQuasar ()
146+ const ticketDataRef = ref (props .ticketData )
139147const closeTicketDialog = ref <boolean >(false )
140148const { data : states, pending : statesPending, refresh : statesRefresh, error : statesError } = await useHttpApi (' /tickets/state' , {
141149 method: ' get'
142150})
151+ if (statesError .value ) {
152+ $q .notify ({
153+ message: ' Erreur lors de la recupération des états' ,
154+ color: ' negative'
155+ })
156+ }
143157
144158const { data : projects, pending : projectsPending, refresh : projectsRefresh, error : projectsError } = await useHttpApi (' /core/project' , {
145159 method: ' get'
146160})
161+ if (projectsError .value ) {
162+ $q .notify ({
163+ message: ' Erreur lors de la recupération des projets' ,
164+ color: ' negative'
165+ })
166+ }
147167
148168const { data : sla, pending : slaPending, refresh : slaRefresh, error : slaError } = await useHttpApi (' /tickets/sla' , {
149169 method: ' get'
150170})
171+ if (slaError .value ) {
172+ $q .notify ({
173+ message: ' Erreur lors de la recupération des sla' ,
174+ color: ' negative'
175+ })
176+ }
177+
178+ const { data : entities, pending : entitiesPending, refresh : entitiesRefresh, error : entitiesError } = await useHttpApi (' /core/entities' , {
179+ method: ' get'
180+ })
181+ if (entitiesError .value ) {
182+ $q .notify ({
183+ message: ' Erreur lors de la recupération des entités' ,
184+ color: ' negative'
185+ })
186+ }
187+
188+ const observers = computed (() => {
189+ return entities .value ?.data .reduce ((acc : any , entity : any ) => {
190+ if (entity .type <= EntityType .OTHER ) {
191+ acc .push ({
192+ id: entity ._id ,
193+ name: entity .profile .commonName ,
194+ type: entity .type
195+ })
196+ }
197+ return acc
198+ }, [])
199+ })
200+
201+ const assigned = computed (() => {
202+ return entities .value ?.data .reduce ((acc : any , entity : any ) => {
203+ if (entity .type <= EntityType .AGENT ) {
204+ acc .push ({
205+ id: entity ._id ,
206+ name: entity .profile .commonName ,
207+ type: entity .type
208+ })
209+ }
210+ return acc
211+ }, [])
212+ })
151213
152214const typeOfTicket = computed (() => {
153215 return ticketType .find ((type : any ) => type .value === props .ticketData .type )
@@ -158,7 +220,7 @@ const lifestepOfTicket = computed(() => {
158220})
159221
160222const stateOfTicket = computed (() => {
161- return states .value ?.data .find ((state : any ) => state ._id === props .ticketData .state .id )
223+ return states .value ?.data .find ((state : any ) => state ._id === props .ticketData .state ? .id )
162224})
163225
164226const getProjectsData = computed (() => {
@@ -179,33 +241,54 @@ const getSlaData = computed(() => {
179241 })
180242})
181243
244+ const body = ref <TicketUpdateDto >({})
182245const countdown = ref (0 )
183- let interval: NodeJS .Timeout
184246
185- watch (ticket , (newTicket , oldTicket ) => {
247+ let timeoutId: NodeJS .Timeout
248+ let intervalId: NodeJS .Timeout
249+
250+ const updateData = (ticket : { field: string , value: IdnamePartDto | SlaPartDto | EntityPartDto [] | LifeStep }) => {
251+ console .log (' ticket' , ticket )
252+ clearTimeout (timeoutId )
253+ clearInterval (intervalId )
254+ if (ticket .field === ' envelope.senders' ) {
255+ body .value .envelope = {
256+ ... props .ticketData .envelope ,
257+ senders: ticket .value as EntityPartDto []
258+ }
259+ }
260+ if (ticket .field === ' envelope.observers' ) {
261+ body .value .envelope = {
262+ ... props .ticketData .envelope ,
263+ observers: ticket .value as EntityPartDto []
264+ }
265+ }
266+ if (ticket .field === ' envelope.assigned' ) {
267+ body .value .envelope = {
268+ ... props .ticketData .envelope ,
269+ assigned: ticket .value as EntityPartDto []
270+ }
271+ }
272+ if (ticket .field === ' project' ) body .value .project = ticket .value as IdnamePartDto
273+ if (ticket .field === ' priority' ) body .value .priority = ticket .value as IdnamePartDto
274+ if (ticket .field === ' impact' ) body .value .impact = ticket .value as IdnamePartDto
275+ if (ticket .field === ' sla' ) body .value .sla = { ... ticket .value , manual: true } as SlaPartDto
276+ if (ticket .field === ' lifestep' ) body .value .lifestep = ticket .value as LifeStep
277+
186278 countdown .value = 3
187- clearInterval (interval )
188- interval = setInterval (() => {
279+ intervalId = setInterval (() => {
189280 countdown .value --
190- if (countdown .value === 0 ) {
191- clearInterval (interval )
192- useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
193- method: ' patch' ,
194- body: {
195- envelope: {
196- ... newTicket .envelope ,
197- },
198- project: { ... newTicket .project },
199- priority: { ... newTicket .priority },
200- impact: { ... newTicket .impact },
201- state: { ... newTicket .state },
202- // sla: { ...newTicket.sla}
203- lifestep: newTicket .lifestep ,
204- }
205- })
206- }
207281 }, 1000 )
208- }, { deep: true })
282+ timeoutId = setTimeout (() => {
283+ useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
284+ method: ' patch' ,
285+ body: body .value
286+ })
287+ body .value = {}
288+ console .log (' updated' )
289+ emit (' fetch:ticketData' )
290+ }, 3000 )
291+ }
209292
210293const ticketCountdown = computed (() => {
211294 const dueAt = dayjs (props .ticketData .sla .dueAt )
@@ -232,30 +315,44 @@ const showCloseTicketDialog = () => {
232315}
233316
234317const closeTicket = async () => {
235- const data = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
318+ const { data, error } = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
236319 method: ' patch' ,
237320 body: {
238321 lifestep: LifeStep .CLOSED ,
239322 }
240323 })
241- emit (' update:ticketData' )
324+ if (error .value ) {
325+ $q .notify ({
326+ message: ' Erreur lors de la cloture du ticket' ,
327+ color: ' negative'
328+ })
329+ }
330+
331+ emit (' fetch:ticketData' )
242332 closeTicketDialog .value = false
243333}
244334
245335const openTicket = async () => {
246- const data = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
336+ const { data, error } = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
247337 method: ' patch' ,
248338 body: {
249339 lifestep: LifeStep .OPEN ,
250340 }
251341 })
252- emit (' update:ticketData' )
342+
343+ if (error .value ) {
344+ $q .notify ({
345+ message: ' Erreur lors de la réouverture du ticket' ,
346+ color: ' negative'
347+ })
348+ }
349+ emit (' fetch:ticketData' )
253350 closeTicketDialog .value = false
254351}
255352
256353const assignTicket = async () => {
257354 const user = store .state .value .auth .user
258- const data = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
355+ const { data, error } = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
259356 method: ' patch' ,
260357 body: {
261358 envelope: {
@@ -271,12 +368,18 @@ const assignTicket = async () => {
271368 }
272369 }
273370 })
274- emit (' update:ticketData' )
371+ if (error .value ) {
372+ $q .notify ({
373+ message: ' Erreur lors de l\' assignation du ticket' ,
374+ color: ' negative'
375+ })
376+ }
377+ emit (' fetch:ticketData' )
275378}
276379
277380const unasignTicket = async () => {
278381 const user = store .state .value .auth .user
279- const data = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
382+ const { data, error } = await useHttpApi (` /tickets/ticket/${props .ticketData ._id } ` , {
280383 method: ' patch' ,
281384 body: {
282385 envelope: {
@@ -285,7 +388,15 @@ const unasignTicket = async () => {
285388 }
286389 }
287390 })
288- emit (' update:ticketData' )
391+ if (error .value ) {
392+ $q .notify ({
393+ message: ' Erreur lors de la désassignation du ticket' ,
394+ color: ' negative'
395+ })
396+ }
397+ emit (' fetch:ticketData' )
289398}
290399
400+ const isDisabledTicket = inject (' isDisabledTicket' )
401+
291402 </script >
0 commit comments