Merge branch '1849-1848-1920-1921-fix-bugs' into 'ticket-app-master'

1849 1848 1920 1921 fix bugs

See merge request Chill-Projet/chill-bundles!940
This commit is contained in:
2025-12-12 09:17:22 +00:00
6 changed files with 284 additions and 311 deletions

View File

@@ -30,7 +30,7 @@
<Modal <Modal
v-if="showTicketInitFormModal" v-if="showTicketInitFormModal"
:show="showTicketInitFormModal" :show="showTicketInitFormModal"
modal-dialog-class="modal-lg" :modal-dialog-class="modalDialogClass"
@close="closeModal" @close="closeModal"
> >
<template #header> <template #header>
@@ -41,18 +41,24 @@
<template #body> <template #body>
<ticket-init-form-component <ticket-init-form-component
v-model="ticketForm"
:ticket="ticket" :ticket="ticket"
:motives="motives" :motives="motives"
:suggested-persons="suggestedPersons" :suggested-persons="suggestedPersons"
@submit="handleFormSubmit" @submit="handleFormSubmit"
/> />
</template> </template>
<template #footer>
<button class="btn btn-primary" @click="handleFormSubmit">
{{ trans(CHILL_TICKET_TICKET_INIT_FORM_SUBMIT) }}
</button>
</template>
</Modal> </Modal>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { useToast } from "vue-toast-notification"; import { useToast } from "vue-toast-notification";
import { computed, onMounted, ref } from "vue"; import { computed, onMounted, onUnmounted, ref } from "vue";
import { useStore } from "vuex"; import { useStore } from "vuex";
// Types // Types
@@ -71,6 +77,7 @@ import ToggleComponent from "../TicketList/components/ToggleComponent.vue";
// Translations // Translations
import { import {
trans, trans,
CHILL_TICKET_TICKET_INIT_FORM_SUBMIT,
CHILL_TICKET_TICKET_INIT_FORM_TITLE, CHILL_TICKET_TICKET_INIT_FORM_TITLE,
CHILL_TICKET_TICKET_INIT_FORM_SUCCESS, CHILL_TICKET_TICKET_INIT_FORM_SUCCESS,
CHILL_TICKET_TICKET_INIT_FORM_ERROR, CHILL_TICKET_TICKET_INIT_FORM_ERROR,
@@ -96,26 +103,49 @@ const showTicketInitFormModal = ref(false);
const loading = ref(true); const loading = ref(true);
const refreshKey = ref(0); const refreshKey = ref(0);
async function handleFormSubmit(ticketForm: TicketInitForm) { // ticketForm réactif pour v-model
const ticketForm = ref({
content: "",
addressees: ticket.value?.currentAddressees,
motive: ticket.value?.currentMotive,
persons: ticket.value?.currentPersons,
caller: ticket.value?.caller,
emergency: ticket.value?.emergency,
} as TicketInitForm);
const modalDialogClass = ref(
window.innerWidth < 990 ? "modal-fullscreen" : "modal-lg",
);
function updateModalClass() {
modalDialogClass.value =
window.innerWidth < 990 ? "modal-fullscreen" : "modal-lg";
}
window.addEventListener("resize", updateModalClass);
async function handleFormSubmit() {
try { try {
if (!ticketForm.motive || ticketForm.content.trim() === "") { if (!ticketForm.value.motive || ticketForm.value.content.trim() === "") {
toast.warning(trans(CHILL_TICKET_TICKET_INIT_FORM_WARNING)); toast.warning(trans(CHILL_TICKET_TICKET_INIT_FORM_WARNING));
return; return;
} }
if (ticketForm.motive) { if (ticketForm.value.motive) {
await store.dispatch("createMotive", ticketForm.motive); await store.dispatch("createMotive", ticketForm.value.motive);
} }
if (ticketForm.content.trim() !== "") { if (ticketForm.value.content.trim() !== "") {
await store.dispatch("createComment", ticketForm.content); await store.dispatch("createComment", ticketForm.value.content);
} }
// Ne pas mettre à jour emergency si le motif force l'état d'urgence // Ne pas mettre à jour emergency si le motif force l'état d'urgence
if (ticketForm.motive && !ticketForm.motive.makeTicketEmergency) { if (
await store.dispatch("setEmergency", ticketForm.emergency); ticketForm.value.motive &&
!ticketForm.value.motive.makeTicketEmergency
) {
await store.dispatch("setEmergency", ticketForm.value.emergency);
} }
await store.dispatch("setAddressees", ticketForm.addressees); await store.dispatch("setAddressees", ticketForm.value.addressees);
await store.dispatch("setPersons", ticketForm.persons); await store.dispatch("setPersons", ticketForm.value.persons);
// Forcer le rafraîchissement des composants // Forcer le rafraîchissement des composants
refreshKey.value++; refreshKey.value++;
@@ -147,6 +177,10 @@ onMounted(() => {
loading.value = false; loading.value = false;
} }
}); });
onUnmounted(() => {
window.removeEventListener("resize", updateModalClass);
});
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -7,7 +7,6 @@
class="btn btn-link p-0" class="btn btn-link p-0"
style=" style="
position: absolute; position: absolute;
top: 0.5rem;
right: 0.5rem; right: 0.5rem;
font-size: 2rem; font-size: 2rem;
line-height: 1; line-height: 1;
@@ -26,7 +25,7 @@
</label> </label>
</div> </div>
<form @submit.prevent="submitAction"> <form class="p-2" @submit.prevent="submitAction">
<comment-editor-component <comment-editor-component
v-model="content" v-model="content"
:motive="motive" :motive="motive"

View File

@@ -18,7 +18,7 @@
<select <select
v-model="selectedStoredObject" v-model="selectedStoredObject"
class="form-select" class="form-select"
@change="onSelectionChange" @change="fetchDocument"
style="max-width: 400px" style="max-width: 400px"
> >
<option <option
@@ -125,22 +125,7 @@ const isLoading = ref<boolean>(false);
const error = ref<string>(""); const error = ref<string>("");
const showPelotonsModal = ref<boolean>(false); const showPelotonsModal = ref<boolean>(false);
watch( async function fetchDocument() {
() => props.storedObjects,
(newStoredObjects) => {
if (
newStoredObjects &&
newStoredObjects.length > 0 &&
!selectedStoredObject.value
) {
selectedStoredObject.value = newStoredObjects[0];
onSelectionChange();
}
},
{ immediate: true },
);
async function onSelectionChange() {
if (!selectedStoredObject.value) { if (!selectedStoredObject.value) {
cleanupPrevious(); cleanupPrevious();
documentType.value = ""; documentType.value = "";
@@ -162,7 +147,6 @@ async function onSelectionChange() {
selectedStoredObject.value, selectedStoredObject.value,
selectedStoredObject.value.currentVersion, selectedStoredObject.value.currentVersion,
); );
console.log("downloadInfo", downloadInfo);
const rawResponse = await window.fetch(downloadInfo.url); const rawResponse = await window.fetch(downloadInfo.url);
if (!rawResponse.ok) { if (!rawResponse.ok) {
@@ -228,22 +212,22 @@ function cleanupPrevious() {
documentUrl.value = ""; documentUrl.value = "";
} }
} }
function handleClick() { function handleClick() {
fetchDocument();
showPelotonsModal.value = true; showPelotonsModal.value = true;
if (
!selectedStoredObject.value &&
props.storedObjects &&
props.storedObjects.length > 0
) {
selectedStoredObject.value = props.storedObjects[0];
onSelectionChange();
}
} }
function closeModal() { function closeModal() {
showPelotonsModal.value = false; showPelotonsModal.value = false;
} }
watch(
() => props.storedObjects,
(newStoredObjects) => {
selectedStoredObject.value = newStoredObjects ? newStoredObjects[0] : null;
},
{ immediate: true },
);
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -1,7 +1,6 @@
<template> <template>
<div class="card mb-4"> <div class="card mb-4">
<div class="card-body"> <div class="card-body">
<form @submit.prevent="submitForm">
<div class="mb-3"> <div class="mb-3">
<label class="form-label pe-2" for="emergency"> <label class="form-label pe-2" for="emergency">
{{ trans(CHILL_TICKET_LIST_FILTER_EMERGENCY) }} {{ trans(CHILL_TICKET_LIST_FILTER_EMERGENCY) }}
@@ -69,16 +68,6 @@
:suggested="userGroups" :suggested="userGroups"
/> />
</div> </div>
<!-- Boutons d'action -->
<div class="d-flex justify-content-end gap-2 mt-4">
<button type="button" class="btn btn-secondary" @click="resetForm">
{{ trans(CHILL_TICKET_TICKET_INIT_FORM_RESET) }}
</button>
<button type="submit" class="btn btn-primary">
{{ trans(CHILL_TICKET_TICKET_INIT_FORM_SUBMIT) }}
</button>
</div>
</form>
</div> </div>
</div> </div>
</template> </template>
@@ -94,20 +83,12 @@ import PersonsSelectorComponent from "./Person/PersonsSelectorComponent.vue";
import AddresseeSelectorComponent from "./Addressee/AddresseeSelectorComponent.vue"; import AddresseeSelectorComponent from "./Addressee/AddresseeSelectorComponent.vue";
import EmergencyToggleComponent from "./Emergency/EmergencyToggleComponent.vue"; import EmergencyToggleComponent from "./Emergency/EmergencyToggleComponent.vue";
// Types // Types
import { import { Motive, TicketInitForm } from "../../../types";
Motive,
MotiveWithParent,
Ticket,
TicketEmergencyState,
TicketInitForm,
} from "../../../types";
import { Person } from "ChillPersonAssets/types"; import { Person } from "ChillPersonAssets/types";
// Translations // Translations
import { import {
trans, trans,
CHILL_TICKET_TICKET_INIT_FORM_SUBMIT,
CHILL_TICKET_TICKET_INIT_FORM_RESET,
CHILL_TICKET_TICKET_SET_MOTIVE_TITLE, CHILL_TICKET_TICKET_SET_MOTIVE_TITLE,
CHILL_TICKET_TICKET_ADD_COMMENT_TITLE, CHILL_TICKET_TICKET_ADD_COMMENT_TITLE,
CHILL_TICKET_TICKET_SET_PERSONS_TITLE_CALLER, CHILL_TICKET_TICKET_SET_PERSONS_TITLE_CALLER,
@@ -117,32 +98,23 @@ import {
CHILL_TICKET_LIST_FILTER_EMERGENCY, CHILL_TICKET_LIST_FILTER_EMERGENCY,
CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE, CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE,
} from "translator"; } from "translator";
import { UserGroup, UserGroupOrUser } from "ChillMainAssets/types"; import { UserGroup } from "ChillMainAssets/types";
const props = defineProps<{ const props = defineProps<{
ticket: Ticket; modelValue: TicketInitForm;
motives: Motive[]; motives: Motive[];
suggestedPersons: Person[]; suggestedPersons: Person[];
}>(); }>();
const emit = defineEmits<{ const emit = defineEmits<{
"update:modelValue": [value: TicketInitForm]; "update:modelValue": [value: TicketInitForm];
submit: [formData: TicketInitForm];
}>(); }>();
const store = useStore(); const store = useStore();
const ticketForm = reactive({ const ticketForm = reactive({ ...props.modelValue });
content: "",
addressees: props.ticket.currentAddressees as UserGroupOrUser[],
motive: props.ticket.currentMotive as MotiveWithParent | null,
persons: props.ticket.currentPersons as Person[],
caller: props.ticket.caller as Person | null,
emergency: props.ticket.emergency as TicketEmergencyState,
} as TicketInitForm);
const isEmergency = ref<boolean>( const isEmergency = ref<boolean>(
props.ticket.emergency == "yes" ? true : false, props.modelValue.emergency == "yes" ? true : false,
); );
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]); const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
@@ -155,23 +127,16 @@ watch(
}, },
); );
function submitForm() { watch(
emit("submit", { ticketForm,
content: ticketForm.content, (newVal) => {
motive: ticketForm.motive, emit("update:modelValue", {
addressees: [...ticketForm.addressees], ...newVal,
persons: [...ticketForm.persons],
caller: ticketForm.caller,
emergency: isEmergency.value ? "yes" : "no", emergency: isEmergency.value ? "yes" : "no",
}); });
} },
function resetForm() { { deep: true },
ticketForm.content = ""; );
ticketForm.motive = null;
ticketForm.persons = [];
ticketForm.caller = null;
ticketForm.emergency = props.ticket.emergency as TicketEmergencyState;
}
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@@ -3,13 +3,7 @@
<div class="card-body"> <div class="card-body">
<div class="wrap-header"> <div class="wrap-header">
<div class="row align-items-top"> <div class="row align-items-top">
<div <div class="col-6">
v-if="
null !== ticket.currentMotive &&
null !== ticket.currentMotive.parent
"
class="col-6"
>
<div class="small text-muted"> <div class="small text-muted">
{{ motiveHierarchyLabel(ticket.currentMotive) }} {{ motiveHierarchyLabel(ticket.currentMotive) }}
</div> </div>
@@ -100,8 +94,6 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { defineProps, defineEmits } from "vue";
// Types // Types
import { TicketSimple } from "../../../types"; import { TicketSimple } from "../../../types";
import { Person } from "ChillPersonAssets/types"; import { Person } from "ChillPersonAssets/types";

View File

@@ -47,7 +47,6 @@ chill_ticket:
init_form: init_form:
title: "Ajouter des informations sur le ticket" title: "Ajouter des informations sur le ticket"
submit: "Mettre à jour le ticket" submit: "Mettre à jour le ticket"
reset: "Réinitialiser"
success: "Ticket mis à jour avec succès" success: "Ticket mis à jour avec succès"
error: "Veuillez remplir tous les champs obligatoires" error: "Veuillez remplir tous les champs obligatoires"
warning: "Veuillez remplir au minimum le motif et le commentaire" warning: "Veuillez remplir au minimum le motif et le commentaire"