mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-06-12 13:24:25 +00:00
Update ticket history interface and functionality
Reworked the ticket history interface and added new functionalities. The history interface now supports multiple patients and shows changes in patients' state. Additionally, new ticket creation is now displayed in the history line, along with the creator information. Some minor textual changes were made to reflect support for multiple patients. Implemented code cleanup and removed debug statements for a cleaner codebase.
This commit is contained in:
parent
166a6fde20
commit
e45af94c78
@ -44,8 +44,6 @@ final readonly class SetPersonsController
|
||||
|
||||
$command = $this->serializer->deserialize($request->getContent(), SetPersonsCommand::class, 'json', [AbstractNormalizer::GROUPS => ['read']]);
|
||||
|
||||
dump($command);
|
||||
|
||||
return $this->registerSetPersons($command, $ticket);
|
||||
}
|
||||
|
||||
|
@ -68,14 +68,28 @@ export interface AddresseeState {
|
||||
addressees: UserGroupOrUser[],
|
||||
}
|
||||
|
||||
interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {};
|
||||
interface AddCommentEvent extends TicketHistory<"add_comment", Comment> {};
|
||||
interface SetMotiveEvent extends TicketHistory<"set_motive", MotiveHistory> {};
|
||||
export interface PersonsState {
|
||||
persons: Person[]
|
||||
}
|
||||
|
||||
export interface CreateTicketState {}
|
||||
|
||||
//interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {};
|
||||
export interface AddCommentEvent extends TicketHistory<"add_comment", Comment> {};
|
||||
export interface SetMotiveEvent extends TicketHistory<"set_motive", MotiveHistory> {};
|
||||
//interface AddAddressee extends TicketHistory<"add_addressee", AddresseeHistory> {};
|
||||
//interface RemoveAddressee extends TicketHistory<"remove_addressee", AddresseeHistory> {};
|
||||
interface AddresseesStateEvent extends TicketHistory<"addressees_state", AddresseeState> {};
|
||||
export interface AddresseesStateEvent extends TicketHistory<"addressees_state", AddresseeState> {};
|
||||
export interface CreateTicketEvent extends TicketHistory<"create_ticket", CreateTicketState> {};
|
||||
export interface PersonStateEvent extends TicketHistory<"persons_state", PersonsState> {};
|
||||
|
||||
export type TicketHistoryLine = AddPersonEvent | AddCommentEvent | SetMotiveEvent | /*AddAddressee | RemoveAddressee | */ AddresseesStateEvent;
|
||||
export type TicketHistoryLine =
|
||||
/* AddPersonEvent */
|
||||
CreateTicketEvent |
|
||||
AddCommentEvent |
|
||||
SetMotiveEvent | /*AddAddressee | RemoveAddressee | */
|
||||
AddresseesStateEvent |
|
||||
PersonStateEvent;
|
||||
|
||||
export interface Ticket {
|
||||
type: "ticket_ticket",
|
||||
|
@ -0,0 +1,18 @@
|
||||
<script setup lang="ts">
|
||||
import {User} from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||
|
||||
interface TicketHistoryCreateComponentConfig {
|
||||
by: User
|
||||
}
|
||||
|
||||
const props = defineProps<TicketHistoryCreateComponentConfig>();
|
||||
|
||||
</script>
|
||||
|
||||
<template>
|
||||
<p>Ticket créé par {{ props.by.text }}</p>
|
||||
</template>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
</style>
|
@ -25,7 +25,7 @@
|
||||
<div class="card-body row">
|
||||
<ticket-history-person-component
|
||||
:personHistory="history_line.data"
|
||||
v-if="history_line.event_type == 'add_person'"
|
||||
v-if="history_line.event_type == 'persons_state'"
|
||||
/>
|
||||
<ticket-history-motive-component
|
||||
:motiveHistory="history_line.data"
|
||||
@ -39,6 +39,10 @@
|
||||
:addressees="history_line.data.addressees"
|
||||
v-else-if="history_line.event_type == 'addressees_state'"
|
||||
/>
|
||||
<ticket-history-create-component
|
||||
:by="history_line.by"
|
||||
v-else-if="history_line.event_type == 'create_ticket'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
@ -49,13 +53,14 @@ import { useStore } from "vuex";
|
||||
|
||||
// Types
|
||||
import { DateTime } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||
import {Ticket, TicketHistoryLine} from "../../../types";
|
||||
import {TicketHistoryLine} from "../../../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 UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||
import {ISOToDatetime} from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||
|
||||
@ -67,6 +72,7 @@ export default defineComponent({
|
||||
TicketHistoryMotiveComponent,
|
||||
TicketHistoryCommentComponent,
|
||||
TicketHistoryAddresseeComponent,
|
||||
TicketHistoryCreateComponent,
|
||||
},
|
||||
props: {
|
||||
history: {
|
||||
@ -84,10 +90,12 @@ export default defineComponent({
|
||||
return "Nouveau commentaire";
|
||||
case "addressees_state":
|
||||
return "Attributions";
|
||||
case "add_person":
|
||||
case "persons_state":
|
||||
return "Patients concernés";
|
||||
case "set_motive":
|
||||
return "Nouveau motifs";
|
||||
case "create_ticket":
|
||||
return "Ticket créé";
|
||||
}
|
||||
};
|
||||
|
||||
|
@ -1,57 +1,43 @@
|
||||
<template>
|
||||
<div class="col-12" v-if="personHistory.createdBy">
|
||||
<span class="mx-1">
|
||||
{{ $t("history.user") }}
|
||||
<span class="badge bg-primary m-1">
|
||||
{{ personHistory.createdBy.username }}
|
||||
</span>
|
||||
</span>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<span class="mx-1">
|
||||
{{ $t("history.person") }}
|
||||
</span>
|
||||
<person-render-box
|
||||
render="badge"
|
||||
:key="personHistory.person.id"
|
||||
:person="personHistory.person"
|
||||
:options="{
|
||||
addLink: true,
|
||||
addId: false,
|
||||
addAltNames: false,
|
||||
addEntity: true,
|
||||
addInfo: true,
|
||||
hLevel: 3,
|
||||
isMultiline: true,
|
||||
isConfidential: false,
|
||||
}"
|
||||
/>
|
||||
<ul class="persons-list">
|
||||
<li v-for="person in personHistory.persons" :key="person.id">
|
||||
<on-the-fly :type="person.type" :id="person.id" :buttonText="person.textAge" :displayBadge="'true' === 'true'" action="show"></on-the-fly>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts">
|
||||
import { PropType, defineComponent } from "vue";
|
||||
|
||||
// Components
|
||||
import PersonRenderBox from "../../../../../../../ChillPersonBundle/Resources/public/vuejs/_components/Entity/PersonRenderBox.vue";
|
||||
|
||||
// Type
|
||||
import { PersonHistory } from "../../../types";
|
||||
import {PersonsState} from "../../../types";
|
||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||
|
||||
export default defineComponent({
|
||||
name: "TicketHistoryPersonComponent",
|
||||
props: {
|
||||
personHistory: {
|
||||
type: Object as PropType<PersonHistory>,
|
||||
type: Object as PropType<PersonsState>,
|
||||
required: true,
|
||||
},
|
||||
},
|
||||
components: {
|
||||
PersonRenderBox,
|
||||
OnTheFly,
|
||||
},
|
||||
|
||||
setup() {},
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped></style>
|
||||
<style lang="scss" scoped>
|
||||
ul.persons-list {
|
||||
list-style-type: none;
|
||||
|
||||
& > li {
|
||||
display: inline-block;
|
||||
margin: 0 0.15rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@ -38,7 +38,7 @@ const messages = {
|
||||
user_label: "Ajouter un patient",
|
||||
},
|
||||
banner: {
|
||||
concerned_patient: "Patient concerné",
|
||||
concerned_patient: "Patients concernés",
|
||||
speaker: "Attribué à",
|
||||
open: "Ouvert",
|
||||
since: "Depuis {time}",
|
||||
|
@ -12,12 +12,14 @@ export const moduleTicket: Module<State, RootState> = {
|
||||
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",
|
||||
},
|
||||
toto: "toto",
|
||||
}),
|
||||
@ -37,7 +39,7 @@ export const moduleTicket: Module<State, RootState> = {
|
||||
(result, item) => {
|
||||
const { datetime } = item.at;
|
||||
if (
|
||||
!["add_addressee", "remove_addressee"].includes(
|
||||
!["add_addressee", "remove_addressee", "add_person"].includes(
|
||||
item.event_type
|
||||
)
|
||||
) {
|
||||
|
@ -46,7 +46,7 @@
|
||||
<div class="wrap-list">
|
||||
{% if ticket.persons|length > 0 %}
|
||||
<div class="wl-row">
|
||||
<div class="wl-col title"><h3 class="mb-2">Patient concerné</h3></div>
|
||||
<div class="wl-col title"><h3 class="mb-2">Patients concernés</h3></div>
|
||||
<div class="wl-col list">
|
||||
{% for p in ticket.persons %}
|
||||
{% include '@ChillMain/OnTheFly/_insert_vue_onthefly.html.twig' with {
|
||||
|
@ -13,6 +13,7 @@ namespace Chill\TicketBundle\Serializer\Normalizer;
|
||||
|
||||
use Chill\MainBundle\Entity\User;
|
||||
use Chill\MainBundle\Entity\UserGroup;
|
||||
use Chill\PersonBundle\Entity\Person;
|
||||
use Chill\TicketBundle\Entity\AddresseeHistory;
|
||||
use Chill\TicketBundle\Entity\Comment;
|
||||
use Chill\TicketBundle\Entity\MotiveHistory;
|
||||
@ -107,8 +108,19 @@ final class TicketNormalizer implements NormalizerInterface, NormalizerAwareInte
|
||||
),
|
||||
*/
|
||||
...$this->addresseesStates($ticket),
|
||||
...$this->personStates($ticket),
|
||||
];
|
||||
|
||||
if (null !== $ticket->getCreatedBy() && null !== $ticket->getCreatedAt()) {
|
||||
$events[] =
|
||||
[
|
||||
'event_type' => 'create_ticket',
|
||||
'at' => $ticket->getCreatedAt()->sub(new \DateInterval('PT1S')), // TODO hack to avoid collision with creation of the ticket event,
|
||||
'by' => $ticket->getCreatedBy(),
|
||||
'data' => [],
|
||||
];
|
||||
}
|
||||
|
||||
usort(
|
||||
$events,
|
||||
static function (array $a, array $b): int {
|
||||
@ -176,4 +188,54 @@ final class TicketNormalizer implements NormalizerInterface, NormalizerAwareInte
|
||||
|
||||
return $steps;
|
||||
}
|
||||
|
||||
private function personStates(Ticket $ticket): array
|
||||
{
|
||||
/** @var array{string, array{added: list<PersonHistory>, removed: list<PersonHistory>}} $changes */
|
||||
$changes = [];
|
||||
$dateFormat = 'Y-m-d-m-Y-H-i-s';
|
||||
|
||||
foreach ($ticket->getPersonHistories() as $history) {
|
||||
$changes[$history->getStartDate()->format($dateFormat)]['added'][] = $history;
|
||||
if (null !== $history->getEndDate()) {
|
||||
$changes[$history->getEndDate()->format($dateFormat)]['removed'][] = $history;
|
||||
}
|
||||
}
|
||||
|
||||
ksort($changes);
|
||||
|
||||
$currents = [];
|
||||
$steps = [];
|
||||
foreach ($changes as $change) {
|
||||
$historiesAdded = $change['added'] ?? [];
|
||||
$historiesRemoved = $change['removed'] ?? [];
|
||||
|
||||
if (0 < count($historiesAdded)) {
|
||||
$at = $historiesAdded[0]->getStartDate();
|
||||
$by = $historiesAdded[0]->getCreatedBy();
|
||||
} elseif (0 < count($historiesRemoved)) {
|
||||
$at = $historiesRemoved[0]->getEndDate();
|
||||
$by = $historiesRemoved[0]->getRemovedBy();
|
||||
} else {
|
||||
throw new \LogicException('it should have at least one history');
|
||||
}
|
||||
|
||||
$removed = array_map(fn (PersonHistory $history) => $history->getPerson(), $historiesRemoved);
|
||||
$currents = array_filter($currents, fn (Person $a) => !in_array($a, $removed, true));
|
||||
foreach ($historiesAdded as $history) {
|
||||
$currents[] = $history->getPerson();
|
||||
}
|
||||
|
||||
$steps[] = [
|
||||
'event_type' => 'persons_state',
|
||||
'at' => $at,
|
||||
'by' => $by,
|
||||
'data' => [
|
||||
'persons' => array_values($currents),
|
||||
],
|
||||
];
|
||||
}
|
||||
|
||||
return $steps;
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user