-
@@ -82,13 +80,12 @@ import { Person } from "ChillPersonAssets/types";
import { Thirdparty } from "src/Bundle/ChillThirdPartyBundle/Resources/public/types";
// Components
-import TicketHistoryPersonComponent from "./TicketHistoryPersonComponent.vue";
-import TicketHistoryMotiveComponent from "./TicketHistoryMotiveComponent.vue";
-import TicketHistoryCommentComponent from "./TicketHistoryCommentComponent.vue";
-import TicketHistoryAddresseeComponent from "./TicketHistoryAddresseeComponent.vue";
-import TicketHistoryCreateComponent from "./TicketHistoryCreateComponent.vue";
-import TicketHistoryStateComponent from "./TicketHistoryStateComponent.vue";
-import TicketHistoryEmergencyComponent from "./TicketHistoryEmergencyComponent.vue";
+import PersonComponent from "./Person/PersonComponent.vue";
+import MotiveComponent from "./Motive/MotiveComponent.vue";
+import CommentComponent from "./Comment/CommentComponent.vue";
+import AddresseeComponent from "./Addressee/AddresseeComponent.vue";
+import StateComponent from "./State/StateComponent.vue";
+import EmergencyComponent from "./Emergency/EmergencyComponent.vue";
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListComponent.vue
new file mode 100644
index 000000000..335c32544
--- /dev/null
+++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListComponent.vue
@@ -0,0 +1,39 @@
+
+
+
+ {{ trans(CHILL_TICKET_LIST_NO_TICKETS) }}
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListItemComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListItemComponent.vue
new file mode 100644
index 000000000..902a4df66
--- /dev/null
+++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketListItemComponent.vue
@@ -0,0 +1,128 @@
+
+
+
+
+
+
+
+
+
+
+
+
Patients concernés
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketSelectorComponent.vue b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketSelectorComponent.vue
deleted file mode 100644
index 2e66d5a8e..000000000
--- a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/components/TicketSelectorComponent.vue
+++ /dev/null
@@ -1,36 +0,0 @@
-
-
-
-
- {{ trans(CHILL_TICKET_TICKET_PREVIOUS_TICKETS) }}
-
- {{ tickets.length }}
- Tickets
-
-
-
-
-
-
-
-
-
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 a842d5c6e..fa73223f5 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
@@ -1,18 +1,23 @@
import { Module } from "vuex";
import { RootState } from "..";
-import { Ticket, TicketEmergencyState } from "../../../../types";
+import { Ticket, TicketEmergencyState, TicketSimple } from "../../../../types";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/public/types";
+import { getSinceCreated } from "../../utils/utils";
export interface State {
ticket: Ticket;
+ previous_tickets: TicketSimple[];
+ previous_ticket_details: Ticket;
action_icons: object;
}
export const moduleTicket: Module
= {
state: () => ({
ticket: {} as Ticket,
+ previous_tickets: [] as TicketSimple[],
+ previous_ticket_details: {} as Ticket,
action_icons: {
add_person: "fa fa-user-plus",
add_comment: "fa fa-comment",
@@ -37,18 +42,42 @@ export const moduleTicket: Module = {
);
return state.ticket;
},
-
+ getTicketHistory(state) {
+ return state.ticket.history;
+ },
+ getPreviousTickets(state) {
+ return state.previous_tickets;
+ },
+ getPreviousTicketHistory(state) {
+ return state.previous_ticket_details.history;
+ },
+ getPreviousTicketDetails(state) {
+ return state.previous_ticket_details;
+ },
+ getCurrentPersons(state) {
+ return state.ticket.currentPersons ?? [];
+ },
getActionIcons(state) {
return state.action_icons;
},
- getDistinctAddressesHistory(state) {
- return state.ticket.history;
+ getSinceCreated: (state) => (currentTime: Date) => {
+ if (!state.ticket.createdAt) {
+ return "";
+ }
+ return getSinceCreated(state.ticket.createdAt.datetime, currentTime);
},
},
+
mutations: {
setTicket(state, ticket: Ticket) {
state.ticket = ticket;
},
+ setPreviousTickets(state, previousTickets: TicketSimple[]) {
+ state.previous_tickets = previousTickets;
+ },
+ setPreviousTicketDetails(state, ticket: Ticket) {
+ state.previous_ticket_details = ticket;
+ },
},
actions: {
async closeTicket({ commit, state }) {
@@ -87,5 +116,39 @@ export const moduleTicket: Module = {
throw error.name;
}
},
+
+ async fetchTicketsByPerson({ commit, state }) {
+ try {
+ if (state.ticket.currentPersons.length === 0) {
+ commit("setPreviousTickets", []);
+ return;
+ }
+ const { results }: { results: TicketSimple[] } = await makeFetch(
+ "GET",
+ `/api/1.0/ticket/ticket/list?byPerson=${state.ticket.currentPersons.map((person) => person.id).join(",")}`,
+ );
+ const excludeCurrentTicket = results.filter(
+ (ticket) => ticket.id !== state.ticket.id,
+ );
+ commit("setPreviousTickets", excludeCurrentTicket);
+ } catch (e: unknown) {
+ const error = e as ApiException;
+ throw error.name;
+ }
+ },
+
+ async fetchPreviousTicketDetails({ commit }, ticketId: number) {
+ try {
+ const ticket: Ticket = await makeFetch(
+ "GET",
+ `/api/1.0/ticket/ticket/${ticketId}`,
+ );
+ commit("setPreviousTicketDetails", ticket);
+ return ticket;
+ } catch (e: unknown) {
+ const error = e as ApiException;
+ throw error.name;
+ }
+ },
},
};
diff --git a/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/utils/utils.ts b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/utils/utils.ts
new file mode 100644
index 000000000..342df70a6
--- /dev/null
+++ b/src/Bundle/ChillTicketBundle/src/Resources/public/vuejs/TicketApp/utils/utils.ts
@@ -0,0 +1,94 @@
+import { ISOToDatetime } from "../../../../../../../../Bundle/ChillMainBundle/Resources/public/chill/js/date";
+import {
+ trans,
+ CHILL_TICKET_TICKET_BANNER_DAYS,
+ CHILL_TICKET_TICKET_BANNER_HOURS,
+ CHILL_TICKET_TICKET_BANNER_MINUTES,
+ CHILL_TICKET_TICKET_BANNER_SECONDS,
+ CHILL_TICKET_TICKET_BANNER_AND,
+ CHILL_TICKET_TICKET_BANNER_NO_MOTIVE,
+} from "translator";
+import { Ticket, TicketSimple } from "../../../types";
+
+/**
+ * Calcule et formate le temps écoulé depuis une date de création
+ * @param createdAt La date de création au format ISO
+ * @param currentTime La date actuelle
+ * @returns Une chaîne formatée représentant le temps écoulé
+ */
+export function getSinceCreated(createdAt: string, currentTime: Date): string {
+ const date = ISOToDatetime(createdAt);
+ if (date == null) {
+ return "";
+ }
+
+ const timeDiff = Math.abs(currentTime.getTime() - date.getTime());
+ const daysDiff = Math.floor(timeDiff / (1000 * 3600 * 24));
+ const hoursDiff = Math.floor((timeDiff % (1000 * 3600 * 24)) / (1000 * 3600));
+ const minutesDiff = Math.floor((timeDiff % (1000 * 3600)) / (1000 * 60));
+ const secondsDiff = Math.floor((timeDiff % (1000 * 60)) / 1000);
+
+ // On construit la liste des parties à afficher
+ const parts: string[] = [];
+ if (daysDiff > 0) {
+ parts.push(trans(CHILL_TICKET_TICKET_BANNER_DAYS, { count: daysDiff }));
+ }
+ if (hoursDiff > 0 || daysDiff > 0) {
+ parts.push(
+ trans(CHILL_TICKET_TICKET_BANNER_HOURS, {
+ count: hoursDiff,
+ }),
+ );
+ }
+ if (minutesDiff > 0 || hoursDiff > 0 || daysDiff > 0) {
+ parts.push(
+ trans(CHILL_TICKET_TICKET_BANNER_MINUTES, {
+ count: minutesDiff,
+ }),
+ );
+ }
+ if (parts.length === 0) {
+ return trans(CHILL_TICKET_TICKET_BANNER_SECONDS, {
+ count: secondsDiff,
+ });
+ }
+ if (parts.length > 1) {
+ const last = parts.pop();
+ return (
+ parts.join(", ") +
+ " " +
+ trans(CHILL_TICKET_TICKET_BANNER_AND) +
+ " " +
+ last
+ );
+ }
+ return parts[0];
+}
+
+export function localizeTranslatableString(
+ translatableString: Record | string,
+): string {
+ // This would be implemented based on your localization logic
+ if (typeof translatableString === "string") {
+ return translatableString;
+ }
+ // Assuming it's an object with locale keys
+ return translatableString?.fr || translatableString?.en || "Unknown";
+}
+
+export function formatDateTime(
+ dateTime: string,
+ dateStyle: string,
+ timeStyle: string,
+): string {
+ return new Date(dateTime).toLocaleString("fr-FR", {
+ dateStyle: dateStyle as "short" | "medium" | "long" | "full",
+ timeStyle: timeStyle as "short" | "medium" | "long" | "full",
+ });
+}
+export function getTicketTitle(ticket: Ticket | TicketSimple): string {
+ if (ticket.currentMotive) {
+ return `#${ticket.id} ${localizeTranslatableString(ticket.currentMotive.label)}`;
+ }
+ return `#${ticket.id} ${trans(CHILL_TICKET_TICKET_BANNER_NO_MOTIVE)}`;
+}
diff --git a/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php b/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php
index e306efbd0..ef02ce5eb 100644
--- a/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php
+++ b/src/Bundle/ChillTicketBundle/src/Serializer/Normalizer/TicketNormalizer.php
@@ -45,6 +45,7 @@ final class TicketNormalizer implements NormalizerInterface, NormalizerAwareInte
'type' => 'ticket_ticket',
'id' => $object->getId(),
'externalRef' => $object->getExternalRef(),
+ 'createdAt' => $this->normalizer->normalize($object->getCreatedAt(), $format, $context),
'currentPersons' => $this->normalizer->normalize($object->getPersons(), $format, [
'groups' => 'read',
]),
@@ -65,7 +66,6 @@ final class TicketNormalizer implements NormalizerInterface, NormalizerAwareInte
$data += [
'type_extended' => 'ticket_ticket:extended',
'history' => array_values($this->serializeHistory($object, $format, ['groups' => 'read'])),
- 'createdAt' => $this->normalizer->normalize($object->getCreatedAt(), $format, $context),
'updatedAt' => $this->normalizer->normalize($object->getUpdatedAt(), $format, $context),
'updatedBy' => $this->normalizer->normalize($object->getUpdatedBy(), $format, $context),
'createdBy' => $this->normalizer->normalize($object->getCreatedBy(), $format, $context),
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 9386de9db..72a47e95d 100644
--- a/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml
+++ b/src/Bundle/ChillTicketBundle/src/translations/messages+intl-icu.fr.yml
@@ -1,6 +1,8 @@
chill_ticket:
list:
title: Tickets
+ title_previous_tickets: "{name, select, other {Précédent ticket de {name}} undefined {Précédent ticket}}"
+ no_tickets: "Aucun ticket"
filter:
to_me: Tickets qui me sont attribués
in_alert: Tickets en alerte (délai de résolution dépassé)
@@ -51,9 +53,9 @@ chill_ticket:
success: "Appelants et usagers mis à jour"
error: "Aucun usager sélectionné"
banner:
- concerned_usager: "Usagers concernés"
- speaker: "Attribué à"
- caller: "Appelant"
+ person: "{count, plural, =0 {Aucun usager concerné} =1 {Usager concerné} other {Usagers concernés}}"
+ speaker: "{count, plural, =0 {Aucun intervenant} =1 {Attribué à} other {Attribués à}}"
+ caller: "{count, plural, =0 {Aucun appelant} =1 {Appelant} other {Appelants}}"
open: "Ouvert"
closed: "Fermé"
since: "Depuis {time}"
diff --git a/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php b/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php
index 2fd983a05..764182871 100644
--- a/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php
+++ b/src/Bundle/ChillTicketBundle/tests/Serializer/Normalizer/TicketNormalizerTest.php
@@ -282,12 +282,12 @@ class TicketNormalizerTest extends KernelTestCase
'currentState',
'emergency',
'caller',
+ 'createdAt',
];
// Keys that should not be present in read:simple normalization
$unexpectedKeys = [
'history',
- 'createdAt',
'updatedAt',
'updatedBy',
'createdBy',