diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts b/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts index 5f35d9bfe..897387bfc 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/types.ts @@ -13,7 +13,7 @@ export interface Motive { label: TranslatableString; } -export type TicketState = "open"|"closed"; +export type TicketState = "open" | "closed"; export type TicketEmergencyState = "yes"|"no"; @@ -77,16 +77,20 @@ export interface PersonsState { } export interface StateChange { - new_state: TicketState + new_state: TicketState; } -export interface CreateTicketState {} +export interface StateChange { + new_state: TicketState; +} -//interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {}; -export interface AddCommentEvent - extends TicketHistory<"add_comment", Comment> {} -export interface SetMotiveEvent - extends TicketHistory<"set_motive", MotiveHistory> {} +export interface CreateTicketState { + by: User; +} + +interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {} +export type AddCommentEvent = TicketHistory<"add_comment", Comment>; +export type SetMotiveEvent = TicketHistory<"set_motive", MotiveHistory>; //interface AddAddressee extends TicketHistory<"add_addressee", AddresseeHistory> {}; //interface RemoveAddressee extends TicketHistory<"remove_addressee", AddresseeHistory> {}; export interface AddresseesStateEvent @@ -98,8 +102,9 @@ export interface PersonStateEvent export interface ChangeStateEvent extends TicketHistory<"state_change", StateChange> {} +// TODO : Remove add_persont event from TicketHistoryLine export type TicketHistoryLine = - /* AddPersonEvent */ + | AddPersonEvent | CreateTicketEvent | AddCommentEvent | SetMotiveEvent /*AddAddressee | RemoveAddressee | */ diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/ActionToolbarComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/ActionToolbarComponent.vue index fd965dab8..eca289ef1 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/ActionToolbarComponent.vue +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/ActionToolbarComponent.vue @@ -9,7 +9,7 @@
Annuler - - - - - @@ -183,9 +137,14 @@ import { CHILL_TICKET_TICKET_SET_MOTIVE_ERROR, CHILL_TICKET_TICKET_SET_MOTIVE_SUCCESS, CHILL_TICKET_TICKET_SET_PERSONS_TITLE, - CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE, CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CANCEL, CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_SAVE, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_SUCCESS, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_ERROR, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_REOPEN, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_REOPEN_SUCCESS, + CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_REOPEN_ERROR, } from "translator"; // Types @@ -199,9 +158,8 @@ import { Comment, Motive, Ticket } from "../../../types"; const store = useStore(); const toast = useToast(); -const activeTab = ref( - "" as "" | "add_comment" | "set_motive" | "add_addressee" | "set_persons", -); +const activeTab = ref("" as string); +const actionIcons = ref(store.getters.getActionIcons); const activeTabTitle = computed((): string => { switch (activeTab.value) { @@ -209,16 +167,44 @@ const activeTabTitle = computed((): string => { return trans(CHILL_TICKET_TICKET_ADD_COMMENT_TITLE); case "set_motive": return trans(CHILL_TICKET_TICKET_SET_MOTIVE_TITLE); - case "add_addressee": + case "addressees_state": return trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE); - case "set_persons": + case "persons_state": return trans(CHILL_TICKET_TICKET_SET_PERSONS_TITLE); default: return ""; } }); +const actionButtons = [ + { + key: "set_motive", + label: CHILL_TICKET_TICKET_SET_MOTIVE_TITLE, + icon: computed(() => actionIcons.value["set_motive"]), + disabled: computed(() => !isOpen.value), + }, + { + key: "add_comment", + label: CHILL_TICKET_TICKET_ADD_COMMENT_TITLE, + icon: computed(() => actionIcons.value["add_comment"]), + disabled: computed(() => !isOpen.value), + }, + { + key: "addressees_state", + label: CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE, + icon: computed(() => actionIcons.value["addressees_state"]), + disabled: computed(() => !isOpen.value), + }, + { + key: "persons_state", + label: CHILL_TICKET_TICKET_SET_PERSONS_TITLE, + icon: computed(() => actionIcons.value["persons_state"]), + disabled: computed(() => !isOpen.value), + }, +]; + const ticket = computed(() => store.getters.getTicket as Ticket); +const isOpen = computed(() => store.getters.isOpen); const motives = computed(() => store.getters.getMotives as Motive[]); const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]); const users = computed(() => store.getters.getUsers as User[]); @@ -279,7 +265,7 @@ async function submitAction() { ); } break; - case "add_addressee": + case "addressees_state": if (!addressees.value.length) { toast.error(trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_ERROR)); } else { @@ -299,15 +285,32 @@ async function submitAction() { } } -function handleClick() { - alert("Sera disponible plus tard"); +async function closeTicket() { + try { + await store.dispatch("closeTicket"); + closeAllActions(); + toast.success(trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_SUCCESS)); + } catch (error) { + console.error(error); + toast.success(trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_ERROR)); + } +} + +async function reopenTicket() { + try { + await store.dispatch("reopenTicket"); + toast.success( + trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_REOPEN_SUCCESS), + ); + } catch (error) { + console.error(error); + toast.error(trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_REOPEN_ERROR)); + } } function closeAllActions() { activeTab.value = ""; } - -const actionIcons = ref(store.getters.getActionIcons); diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/BannerComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/BannerComponent.vue index 846a748b8..848f827a5 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/BannerComponent.vue +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/BannerComponent.vue @@ -17,9 +17,17 @@ {{ trans(CHILL_TICKET_TICKET_BANNER_OPEN) }} + + {{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }} +

@@ -49,7 +57,6 @@ :buttonText="person.textAge" :displayBadge="'true' === 'true'" action="show" - CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER >

@@ -88,6 +95,7 @@ import { trans, CHILL_TICKET_TICKET_BANNER_NO_MOTIVE, CHILL_TICKET_TICKET_BANNER_OPEN, + CHILL_TICKET_TICKET_BANNER_CLOSED, CHILL_TICKET_TICKET_BANNER_SINCE, CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER, CHILL_TICKET_TICKET_BANNER_SPEAKER, @@ -98,10 +106,14 @@ import { CHILL_TICKET_TICKET_BANNER_AND, } from "translator"; +// Store +import { useStore } from "vuex"; + const props = defineProps<{ ticket: Ticket; }>(); +const store = useStore(); const today = ref(new Date()); const createdAt = ref(props.ticket.createdAt); @@ -109,6 +121,8 @@ setInterval(() => { today.value = new Date(); }, 5000); +const isOpen = computed(() => store.getters.isOpen); + const since = computed(() => { if (createdAt.value == null) { return ""; diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryAddresseeComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryAddresseeComponent.vue index 464eec294..f3b67e318 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryAddresseeComponent.vue +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryAddresseeComponent.vue @@ -1,17 +1,17 @@ diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryListComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryListComponent.vue index 548ccdc8a..fbd1e5ac4 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryListComponent.vue +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketHistoryListComponent.vue @@ -1,21 +1,24 @@ + + + + diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket.ts b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket.ts index 73e0e38fa..f4c9037a6 100644 --- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket.ts +++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/store/modules/ticket.ts @@ -2,6 +2,7 @@ import { Module } from "vuex"; import { RootState } from ".."; import { Ticket } from "../../../../types"; +import { makeFetch } from "ChillMainAssets/lib/api/apiMethods"; export interface State { ticket: Ticket; @@ -12,18 +13,18 @@ export const moduleTicket: Module = { state: () => ({ ticket: {} as Ticket, action_icons: { - // TODO cleanup those keys add_person: "fa fa-eyedropper", add_comment: "fa fa-comment", set_motive: "fa fa-paint-brush", - //add_addressee: "fa fa-paper-plane", addressees_state: "fa fa-paper-plane", - set_persons: "fa fa-eyedropper", persons_state: "fa fa-eyedropper", + state_change: "fa fa-bolt", }, - toto: "toto", }), getters: { + isOpen(state) { + return state.ticket.currentState === "open"; + }, getTicket(state) { state.ticket.history = state.ticket.history.sort((a, b) => b.at.datetime.localeCompare(a.at.datetime), @@ -35,39 +36,36 @@ export const moduleTicket: Module = { return state.action_icons; }, getDistinctAddressesHistory(state) { - const addresseeHistory = state.ticket.history.reduce( - (result, item) => { - const { datetime } = item.at; - if ( - ![ - "add_addressee", - "remove_addressee", - "add_person", - ].includes(item.event_type) - ) { - result[datetime] = item; - return result; - } - - if (!result[datetime]) { - result[datetime] = []; - } - /* - if (item.event_type === "add_addressee") { - result[datetime].push(item); - } - */ - return result; - }, - {} as any, - ); - return Object.values(addresseeHistory) as Ticket["history"][]; + return state.ticket.history; }, }, mutations: { - setTicket(state, ticket) { + setTicket(state, ticket: Ticket) { state.ticket = ticket; }, }, - actions: {}, + actions: { + async closeTicket({ commit, state }) { + try { + const result: Ticket = await makeFetch( + "POST", + `/api/1.0/ticket/ticket/${state.ticket.id}/close`, + ); + commit("setTicket", result as Ticket); + } catch (e: any) { + throw e.name; + } + }, + async reopenTicket({ commit, state }) { + try { + const result: Ticket = await makeFetch( + "POST", + `/api/1.0/ticket/ticket/${state.ticket.id}/open`, + ); + commit("setTicket", result as Ticket); + } catch (e: any) { + throw e.name; + } + }, + }, }; diff --git a/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml b/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml index f825a7786..b3cbb32c1 100644 --- a/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml +++ b/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml @@ -11,6 +11,11 @@ chill_ticket: cancel: "Annuler" save: "Enregistrer" close: "Fermer" + close_success: "Ticket fermé" + close_error: "Erreur lors de la fermeture du ticket" + reopen: "Rouvrir" + reopen_success: "Rouverture du ticket réussie" + reopen_error: "Erreur lors de la rouverture du ticket" add_comment: title: "Commentaire" label: "Ajouter un commentaire" @@ -37,6 +42,7 @@ chill_ticket: concerned_usager: "Usagers concernés" speaker: "Attribué à" open: "Ouvert" + closed: "Fermé" since: "Depuis {time}" and: "et" days: >-