mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-10 00:34:58 +00:00
Merge branch 'fix-and-change-from-board-78' into 'ticket-app-master'
Améliorations liées au board 78 See merge request Chill-Projet/chill-bundles!873
This commit is contained in:
@@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
<template #body>
|
<template #body>
|
||||||
<ticket-init-form-component
|
<ticket-init-form-component
|
||||||
|
:ticket="ticket"
|
||||||
:motives="motives"
|
:motives="motives"
|
||||||
:suggested-persons="suggestedPersons"
|
:suggested-persons="suggestedPersons"
|
||||||
@submit="handleFormSubmit"
|
@submit="handleFormSubmit"
|
||||||
@@ -61,6 +62,7 @@ import {
|
|||||||
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,
|
||||||
|
CHILL_TICKET_TICKET_INIT_FORM_WARNING,
|
||||||
CHILL_TICKET_LIST_LOADING_TICKET_DETAILS,
|
CHILL_TICKET_LIST_LOADING_TICKET_DETAILS,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
@@ -81,16 +83,18 @@ async function handleFormSubmit(ticketForm: TicketInitForm) {
|
|||||||
try {
|
try {
|
||||||
if (ticketForm.motive) {
|
if (ticketForm.motive) {
|
||||||
await store.dispatch("createMotive", ticketForm.motive);
|
await store.dispatch("createMotive", ticketForm.motive);
|
||||||
|
} else {
|
||||||
|
toast.warning(trans(CHILL_TICKET_TICKET_INIT_FORM_WARNING));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
if (ticketForm.content && ticketForm.content.trim() !== "") {
|
if (ticketForm.content && ticketForm.content.trim() !== "") {
|
||||||
await store.dispatch("createComment", ticketForm.content);
|
await store.dispatch("createComment", ticketForm.content);
|
||||||
|
} else {
|
||||||
|
toast.warning(trans(CHILL_TICKET_TICKET_INIT_FORM_WARNING));
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
await store.dispatch("setPersons", ticketForm.persons);
|
await store.dispatch("setPersons", ticketForm.persons);
|
||||||
|
|
||||||
// Rafraîchir les données nécessaires
|
|
||||||
await store.dispatch("fetchTicketHistory");
|
|
||||||
await store.dispatch("fetchPreviousTickets");
|
|
||||||
|
|
||||||
// Forcer le rafraîchissement des composants
|
// Forcer le rafraîchissement des composants
|
||||||
refreshKey.value++;
|
refreshKey.value++;
|
||||||
|
|
||||||
@@ -114,7 +118,7 @@ onMounted(async () => {
|
|||||||
await store.dispatch("fetchUserGroups");
|
await store.dispatch("fetchUserGroups");
|
||||||
await store.dispatch("fetchUsers");
|
await store.dispatch("fetchUsers");
|
||||||
await store.dispatch("getSuggestedPersons");
|
await store.dispatch("getSuggestedPersons");
|
||||||
showTicketInitFormModal.value = store.getters.isNewTicket;
|
showTicketInitFormModal.value = store.getters.isIncompleteTicket;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error as string);
|
toast.error(error as string);
|
||||||
} finally {
|
} finally {
|
||||||
|
@@ -29,7 +29,6 @@
|
|||||||
<form @submit.prevent="submitAction">
|
<form @submit.prevent="submitAction">
|
||||||
<comment-editor-component
|
<comment-editor-component
|
||||||
v-model="content"
|
v-model="content"
|
||||||
@supplementary-text="(value) => (supplementaryText = value)"
|
|
||||||
:motive="motive"
|
:motive="motive"
|
||||||
v-if="activeTab === 'add_comment'"
|
v-if="activeTab === 'add_comment'"
|
||||||
/>
|
/>
|
||||||
@@ -254,7 +253,6 @@ const returnPath = computed((): string => {
|
|||||||
|
|
||||||
const motive = ref(ticket.value.currentMotive as Motive);
|
const motive = ref(ticket.value.currentMotive as Motive);
|
||||||
const content = ref("" as Comment["content"]);
|
const content = ref("" as Comment["content"]);
|
||||||
const supplementaryText = ref("" as string);
|
|
||||||
const addressees = ref(ticket.value.currentAddressees as UserGroupOrUser[]);
|
const addressees = ref(ticket.value.currentAddressees as UserGroupOrUser[]);
|
||||||
const persons = ref(ticket.value.currentPersons as Person[]);
|
const persons = ref(ticket.value.currentPersons as Person[]);
|
||||||
const caller = ref(ticket.value.caller as Person);
|
const caller = ref(ticket.value.caller as Person);
|
||||||
@@ -265,12 +263,8 @@ async function submitAction() {
|
|||||||
if (!content.value) {
|
if (!content.value) {
|
||||||
toast.error(trans(CHILL_TICKET_TICKET_ADD_COMMENT_ERROR));
|
toast.error(trans(CHILL_TICKET_TICKET_ADD_COMMENT_ERROR));
|
||||||
} else {
|
} else {
|
||||||
await store.dispatch(
|
await store.dispatch("createComment", content.value);
|
||||||
"createComment",
|
|
||||||
content.value + supplementaryText.value,
|
|
||||||
);
|
|
||||||
content.value = "";
|
content.value = "";
|
||||||
supplementaryText.value = "";
|
|
||||||
activeTab.value = "";
|
activeTab.value = "";
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_ADD_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_ADD_COMMENT_SUCCESS));
|
||||||
}
|
}
|
||||||
|
@@ -10,12 +10,8 @@
|
|||||||
/>
|
/>
|
||||||
</h1>
|
</h1>
|
||||||
|
|
||||||
<h2 v-if="ticket.currentPersons.length">
|
<h2 v-if="ticket.caller">
|
||||||
{{
|
{{ ticket.caller.text }}
|
||||||
ticket.currentPersons
|
|
||||||
.map((person: Person) => person.text)
|
|
||||||
.join(", ")
|
|
||||||
}}
|
|
||||||
</h2>
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@@ -2,13 +2,34 @@
|
|||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<blockquote class="chill-user-quote">
|
<blockquote class="chill-user-quote">
|
||||||
<button
|
<button
|
||||||
class="btn btn-sm btn-edit float-end"
|
class="btn btn-sm btn-primary float-end"
|
||||||
title="Edit"
|
title="Visible"
|
||||||
|
@click="visibleComment"
|
||||||
|
v-if="commentHistory.deleted"
|
||||||
|
>
|
||||||
|
<i class="bi bi-eye"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm bg-chill-red float-end text-white"
|
||||||
|
@click="maskComment"
|
||||||
|
v-else
|
||||||
|
>
|
||||||
|
<i class="bi bi-eye-slash"></i>
|
||||||
|
</button>
|
||||||
|
<button
|
||||||
|
class="btn btn-sm btn-edit mx-2 float-end text-white"
|
||||||
@click="editCommentModal = true"
|
@click="editCommentModal = true"
|
||||||
style="top: 0.5rem; right: 0.5rem"
|
style="top: 0.5rem; right: 0.5rem"
|
||||||
v-if="canBeEdited && isOpen"
|
v-if="canBeEdited && isOpen"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<p v-html="convertMarkdownToHtml(commentHistory.content)"></p>
|
<p v-html="convertMarkdownToHtml(commentHistory.content)"></p>
|
||||||
|
<span
|
||||||
|
v-if="commentHistory.deleted"
|
||||||
|
class="ms-2 d-block text-center fst-italic text-muted"
|
||||||
|
>
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_MASK_COMMENT_HINT) }}
|
||||||
|
</span>
|
||||||
</blockquote>
|
</blockquote>
|
||||||
</div>
|
</div>
|
||||||
<Modal
|
<Modal
|
||||||
@@ -26,16 +47,6 @@
|
|||||||
<comment-editor v-model="editedComment" />
|
<comment-editor v-model="editedComment" />
|
||||||
</template>
|
</template>
|
||||||
<template #footer>
|
<template #footer>
|
||||||
<button
|
|
||||||
class="btn btn-primary"
|
|
||||||
@click="restoreComment"
|
|
||||||
v-if="commentHistory.deleted"
|
|
||||||
>
|
|
||||||
{{ trans(RESTORE) }}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-delete" @click="deleteComment" v-else>
|
|
||||||
{{ trans(DELETE) }}
|
|
||||||
</button>
|
|
||||||
<button class="btn btn-save" @click="saveComment">
|
<button class="btn btn-save" @click="saveComment">
|
||||||
{{ trans(SAVE) }}
|
{{ trans(SAVE) }}
|
||||||
</button>
|
</button>
|
||||||
@@ -59,12 +70,11 @@ import Modal from "../../../../../../../../ChillMainBundle/Resources/public/vuej
|
|||||||
import {
|
import {
|
||||||
trans,
|
trans,
|
||||||
SAVE,
|
SAVE,
|
||||||
DELETE,
|
|
||||||
RESTORE,
|
|
||||||
CHILL_TICKET_TICKET_EDIT_COMMENT_TITLE,
|
CHILL_TICKET_TICKET_EDIT_COMMENT_TITLE,
|
||||||
CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS,
|
CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS,
|
||||||
CHILL_TICKET_TICKET_DELETE_COMMENT_SUCCESS,
|
CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS,
|
||||||
CHILL_TICKET_TICKET_RESTORE_COMMENT_SUCCESS,
|
CHILL_TICKET_TICKET_MASK_COMMENT_HINT,
|
||||||
|
CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
|
|
||||||
@@ -87,16 +97,16 @@ const saveComment = () => {
|
|||||||
toast.success(trans(CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_EDIT_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
|
||||||
const deleteComment = () => {
|
const maskComment = () => {
|
||||||
store.dispatch("deleteComment", props.commentHistory.id);
|
store.dispatch("maskComment", props.commentHistory.id);
|
||||||
editCommentModal.value = false;
|
editCommentModal.value = false;
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_DELETE_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_MASK_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
|
||||||
const restoreComment = () => {
|
const visibleComment = () => {
|
||||||
store.dispatch("restoreComment", props.commentHistory.id);
|
store.dispatch("visibleComment", props.commentHistory.id);
|
||||||
editCommentModal.value = false;
|
editCommentModal.value = false;
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_RESTORE_COMMENT_SUCCESS));
|
toast.success(trans(CHILL_TICKET_TICKET_VISIBLE_COMMENT_SUCCESS));
|
||||||
};
|
};
|
||||||
|
|
||||||
const preprocess = (markdown: string): string => {
|
const preprocess = (markdown: string): string => {
|
||||||
|
@@ -26,7 +26,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { reactive, ref, watch } from "vue";
|
import { reactive, ref, watch, computed } from "vue";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import CommentEditor from "ChillMainAssets/vuejs/_components/CommentEditor/CommentEditor.vue";
|
import CommentEditor from "ChillMainAssets/vuejs/_components/CommentEditor/CommentEditor.vue";
|
||||||
@@ -45,31 +45,38 @@ const props = defineProps<{
|
|||||||
const supplementaryCommentsInput = reactive<string[]>([]);
|
const supplementaryCommentsInput = reactive<string[]>([]);
|
||||||
|
|
||||||
const emit = defineEmits<{
|
const emit = defineEmits<{
|
||||||
"update:modelValue": [value: string | undefined];
|
"update:modelValue": [value: string];
|
||||||
"show-peloton-modal": [storedObjects: StoredObject[]];
|
"show-peloton-modal": [storedObjects: StoredObject[]];
|
||||||
"supplementary-text": [value: string];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const content = ref(props.modelValue);
|
const content = ref(props.modelValue);
|
||||||
|
|
||||||
watch(
|
const aggregateSupplementaryComments = computed(() => {
|
||||||
supplementaryCommentsInput,
|
|
||||||
(value) => {
|
|
||||||
let supplementaryText = " \n\n ";
|
let supplementaryText = " \n\n ";
|
||||||
for (const index in value) {
|
if (props.motive && props.motive.supplementaryComments) {
|
||||||
if (value[index]) {
|
props.motive.supplementaryComments.forEach(
|
||||||
|
(item: { label: string }, index: number) => {
|
||||||
|
if (supplementaryCommentsInput[index]) {
|
||||||
supplementaryText +=
|
supplementaryText +=
|
||||||
`**${props.motive?.supplementaryComments[index].label}**: ${value[index]}` +
|
`**${item.label}**: ${supplementaryCommentsInput[index]}` +
|
||||||
" \n\n ";
|
" \n\n ";
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
);
|
||||||
}
|
}
|
||||||
emit("supplementary-text", supplementaryText);
|
return (content.value || "") + supplementaryText;
|
||||||
|
});
|
||||||
|
|
||||||
|
watch(
|
||||||
|
supplementaryCommentsInput,
|
||||||
|
() => {
|
||||||
|
emit("update:modelValue", aggregateSupplementaryComments.value);
|
||||||
},
|
},
|
||||||
{ deep: true },
|
{ deep: true },
|
||||||
);
|
);
|
||||||
|
|
||||||
watch(content, (value) => {
|
watch(content, () => {
|
||||||
emit("update:modelValue", value);
|
emit("update:modelValue", aggregateSupplementaryComments.value);
|
||||||
});
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -1,15 +1,13 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
|
||||||
<span
|
<span
|
||||||
class="badge rounded-pill me-1 mx-2"
|
class="badge rounded-pill me-1 mx-2"
|
||||||
:class="{
|
:class="{
|
||||||
'bg-danger': new_emergency === 'yes',
|
'bg-warning': new_emergency === 'yes',
|
||||||
'bg-secondary': new_emergency === 'no',
|
'bg-secondary': new_emergency === 'no',
|
||||||
}"
|
}"
|
||||||
>
|
>
|
||||||
{{ trans(CHILL_TICKET_TICKET_BANNER_EMERGENCY) }}
|
{{ trans(CHILL_TICKET_TICKET_BANNER_EMERGENCY) }}
|
||||||
</span>
|
</span>
|
||||||
</div>
|
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { trans, CHILL_TICKET_TICKET_BANNER_EMERGENCY } from "translator";
|
import { trans, CHILL_TICKET_TICKET_BANNER_EMERGENCY } from "translator";
|
||||||
|
@@ -3,7 +3,7 @@
|
|||||||
<button
|
<button
|
||||||
class="badge rounded-pill me-1"
|
class="badge rounded-pill me-1"
|
||||||
:class="{
|
:class="{
|
||||||
'bg-chill-red': modelValue,
|
'bg-warning': modelValue,
|
||||||
'bg-secondary': !modelValue,
|
'bg-secondary': !modelValue,
|
||||||
'no-pointer': props.disabled,
|
'no-pointer': props.disabled,
|
||||||
}"
|
}"
|
||||||
|
@@ -25,7 +25,6 @@ import {
|
|||||||
CHILL_TICKET_TICKET_BANNER_OPEN,
|
CHILL_TICKET_TICKET_BANNER_OPEN,
|
||||||
CHILL_TICKET_TICKET_BANNER_CLOSED,
|
CHILL_TICKET_TICKET_BANNER_CLOSED,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
const props = defineProps<StateChange>();
|
const props = defineProps<StateChange>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
@@ -76,7 +76,7 @@ import CommentEditorComponent from "./Comment/CommentEditorComponent.vue";
|
|||||||
import PersonsSelectorComponent from "./Person/PersonsSelectorComponent.vue";
|
import PersonsSelectorComponent from "./Person/PersonsSelectorComponent.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { Motive, TicketInitForm } from "../../../types";
|
import { Motive, Ticket, TicketInitForm } from "../../../types";
|
||||||
import { Person } from "ChillPersonAssets/types";
|
import { Person } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
// Translations
|
// Translations
|
||||||
@@ -92,7 +92,8 @@ import {
|
|||||||
CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL,
|
CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
defineProps<{
|
const props = defineProps<{
|
||||||
|
ticket: Ticket;
|
||||||
motives: Motive[];
|
motives: Motive[];
|
||||||
suggestedPersons: Person[];
|
suggestedPersons: Person[];
|
||||||
}>();
|
}>();
|
||||||
@@ -106,9 +107,9 @@ const store = useStore();
|
|||||||
|
|
||||||
const ticketForm = reactive({
|
const ticketForm = reactive({
|
||||||
content: "",
|
content: "",
|
||||||
motive: undefined as Motive | undefined,
|
motive: props.ticket.currentMotive as Motive | null,
|
||||||
persons: [] as Person[],
|
persons: props.ticket.currentPersons as Person[],
|
||||||
caller: null as Person | null,
|
caller: props.ticket.caller as Person | null,
|
||||||
} as TicketInitForm);
|
} as TicketInitForm);
|
||||||
|
|
||||||
watch(
|
watch(
|
||||||
|
@@ -64,7 +64,7 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
throw error.name;
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async deleteComment({ commit }, id: Comment["id"]) {
|
async maskComment({ commit }, id: Comment["id"]) {
|
||||||
try {
|
try {
|
||||||
const result: Comment = await makeFetch(
|
const result: Comment = await makeFetch(
|
||||||
"POST",
|
"POST",
|
||||||
@@ -77,7 +77,7 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
async restoreComment({ commit }, id: Comment["id"]) {
|
async visibleComment({ commit }, id: Comment["id"]) {
|
||||||
try {
|
try {
|
||||||
const result: Comment = await makeFetch(
|
const result: Comment = await makeFetch(
|
||||||
"POST",
|
"POST",
|
||||||
|
@@ -4,6 +4,7 @@ import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/
|
|||||||
import { Module } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
import { Ticket } from "../../../../types";
|
import { Ticket } from "../../../../types";
|
||||||
|
import { Thirdparty } from "src/Bundle/ChillThirdPartyBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
persons: Person[];
|
persons: Person[];
|
||||||
@@ -29,7 +30,6 @@ export const modulePersons: Module<State, RootState> = {
|
|||||||
id: person.id,
|
id: person.id,
|
||||||
type: person.type,
|
type: person.type,
|
||||||
}));
|
}));
|
||||||
console.log("Setting persons:", personData);
|
|
||||||
try {
|
try {
|
||||||
const result: Ticket = await makeFetch(
|
const result: Ticket = await makeFetch(
|
||||||
"POST",
|
"POST",
|
||||||
@@ -67,10 +67,14 @@ export const modulePersons: Module<State, RootState> = {
|
|||||||
async getSuggestedPersons({ commit, rootState }) {
|
async getSuggestedPersons({ commit, rootState }) {
|
||||||
try {
|
try {
|
||||||
const ticketId = rootState.ticket.ticket.id;
|
const ticketId = rootState.ticket.ticket.id;
|
||||||
const result: Person[] = await makeFetch(
|
const caller = rootState.ticket.ticket.caller;
|
||||||
|
const result: (Person | Thirdparty)[] = await makeFetch(
|
||||||
"GET",
|
"GET",
|
||||||
`/api/1.0/ticket/ticket/${ticketId}/suggest-person`,
|
`/api/1.0/ticket/ticket/${ticketId}/suggest-person`,
|
||||||
);
|
);
|
||||||
|
if (caller) {
|
||||||
|
result.push(caller);
|
||||||
|
}
|
||||||
commit("setPersons", result);
|
commit("setPersons", result);
|
||||||
} catch (e: unknown) {
|
} catch (e: unknown) {
|
||||||
const error = e as ApiException;
|
const error = e as ApiException;
|
||||||
|
@@ -38,8 +38,11 @@ export const moduleTicket: Module<State, RootState> = {
|
|||||||
isEmergency(state) {
|
isEmergency(state) {
|
||||||
return state.ticket.emergency == "yes";
|
return state.ticket.emergency == "yes";
|
||||||
},
|
},
|
||||||
isNewTicket(state) {
|
isIncompleteTicket(state) {
|
||||||
return state.ticket.history.length == 3;
|
return (
|
||||||
|
state.ticket.currentMotive === null ||
|
||||||
|
!state.ticket.history.some((item) => item.event_type == "add_comment")
|
||||||
|
);
|
||||||
},
|
},
|
||||||
getTicket(state) {
|
getTicket(state) {
|
||||||
state.ticket.history = state.ticket.history.sort((a, b) =>
|
state.ticket.history = state.ticket.history.sort((a, b) =>
|
||||||
@@ -62,6 +65,9 @@ export const moduleTicket: Module<State, RootState> = {
|
|||||||
getCurrentPersons(state) {
|
getCurrentPersons(state) {
|
||||||
return state.ticket.currentPersons;
|
return state.ticket.currentPersons;
|
||||||
},
|
},
|
||||||
|
getCaller: (state) => {
|
||||||
|
return state.ticket.caller;
|
||||||
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
mutations: {
|
mutations: {
|
||||||
|
@@ -73,14 +73,14 @@ export const moduleTicketList: Module<State, RootState> = {
|
|||||||
([, value]) =>
|
([, value]) =>
|
||||||
value !== undefined &&
|
value !== undefined &&
|
||||||
value !== null &&
|
value !== null &&
|
||||||
value !== "" &&
|
(value === true || (value !== "" && value.length > 0)),
|
||||||
value.length > 0,
|
|
||||||
),
|
),
|
||||||
);
|
);
|
||||||
params = new URLSearchParams(
|
params = new URLSearchParams(
|
||||||
filteredParams as Record<string, string>,
|
filteredParams as Record<string, string>,
|
||||||
).toString();
|
).toString();
|
||||||
}
|
}
|
||||||
|
|
||||||
const { results, pagination, count } = (await makeFetch(
|
const { results, pagination, count } = (await makeFetch(
|
||||||
"GET",
|
"GET",
|
||||||
`/api/1.0/ticket/ticket/list/?${params}`,
|
`/api/1.0/ticket/ticket/list/?${params}`,
|
||||||
@@ -99,10 +99,7 @@ export const moduleTicketList: Module<State, RootState> = {
|
|||||||
},
|
},
|
||||||
async fetchConnectedUser({ commit }) {
|
async fetchConnectedUser({ commit }) {
|
||||||
try {
|
try {
|
||||||
const user = await makeFetch(
|
const user = await makeFetch("GET", "/api/1.0/main/whoami.json");
|
||||||
"GET",
|
|
||||||
"/api/1.0/main/whoami.json",
|
|
||||||
);
|
|
||||||
commit("setUser", user);
|
commit("setUser", user);
|
||||||
return user;
|
return user;
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
|
@@ -84,7 +84,7 @@
|
|||||||
:on-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
:on-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
||||||
:off-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
:off-label="trans(CHILL_TICKET_LIST_FILTER_EMERGENCY)"
|
||||||
:classColor="{
|
:classColor="{
|
||||||
on: 'bg-chill-red',
|
on: 'bg-warning',
|
||||||
off: 'bg-secondary',
|
off: 'bg-secondary',
|
||||||
}"
|
}"
|
||||||
@update:model-value="handleEmergencyToggle"
|
@update:model-value="handleEmergencyToggle"
|
||||||
@@ -288,7 +288,7 @@ const handleEmergencyToggle = (value: boolean) => {
|
|||||||
if (value) {
|
if (value) {
|
||||||
filters.value.byCurrentStateEmergency = ["yes"];
|
filters.value.byCurrentStateEmergency = ["yes"];
|
||||||
} else {
|
} else {
|
||||||
filters.value.byCurrentStateEmergency = ["no"];
|
filters.value.byCurrentStateEmergency = [];
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -1,9 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div
|
<div
|
||||||
class="card my-2 bg-light"
|
class="card my-2 bg-light"
|
||||||
v-for="history_line in history.filter(
|
v-for="history_line in filteredHistoryLines"
|
||||||
(line) => line.event_type != 'add_person',
|
|
||||||
)"
|
|
||||||
:key="history.indexOf(history_line)"
|
:key="history.indexOf(history_line)"
|
||||||
>
|
>
|
||||||
<div class="card-header">
|
<div class="card-header">
|
||||||
@@ -20,8 +18,9 @@
|
|||||||
"
|
"
|
||||||
class="badge bg-danger ms-2"
|
class="badge bg-danger ms-2"
|
||||||
>
|
>
|
||||||
{{ trans(CHILL_TICKET_TICKET_HISTORY_DELETED) }}
|
{{ trans(CHILL_TICKET_TICKET_HISTORY_MASK_COMMENT) }}
|
||||||
</span>
|
</span>
|
||||||
|
|
||||||
<state-component
|
<state-component
|
||||||
:new_state="history_line.data.new_state"
|
:new_state="history_line.data.new_state"
|
||||||
v-if="history_line.event_type == 'state_change'"
|
v-if="history_line.event_type == 'state_change'"
|
||||||
@@ -41,14 +40,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div
|
<div class="card-body row" v-if="displayBody(history_line)">
|
||||||
class="card-body row"
|
|
||||||
v-if="
|
|
||||||
!['state_change', 'emergency_change', 'create_ticket'].includes(
|
|
||||||
history_line.event_type,
|
|
||||||
)
|
|
||||||
"
|
|
||||||
>
|
|
||||||
<person-component
|
<person-component
|
||||||
:entities="history_line.data.persons"
|
:entities="history_line.data.persons"
|
||||||
v-if="history_line.event_type == 'persons_state'"
|
v-if="history_line.event_type == 'persons_state'"
|
||||||
@@ -80,7 +72,7 @@
|
|||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { ref } from "vue";
|
import { computed, ref } from "vue";
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@@ -113,7 +105,7 @@ import {
|
|||||||
CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE,
|
CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE,
|
||||||
CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE,
|
CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE,
|
||||||
CHILL_TICKET_TICKET_HISTORY_SET_CALLER,
|
CHILL_TICKET_TICKET_HISTORY_SET_CALLER,
|
||||||
CHILL_TICKET_TICKET_HISTORY_DELETED,
|
CHILL_TICKET_TICKET_HISTORY_MASK_COMMENT,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
const props = defineProps<{ history?: TicketHistoryLine[] }>();
|
const props = defineProps<{ history?: TicketHistoryLine[] }>();
|
||||||
@@ -121,14 +113,22 @@ const history = props.history ?? [];
|
|||||||
const store = useStore();
|
const store = useStore();
|
||||||
|
|
||||||
const actionIcons = ref(store.getters.getActionIcons);
|
const actionIcons = ref(store.getters.getActionIcons);
|
||||||
const canBeDisplayed = ref(store.getters["canBeDisplayed"]);
|
const canBeDisplayed = ref(store.getters.canBeDisplayed);
|
||||||
|
|
||||||
|
const filteredHistoryLines = computed(() =>
|
||||||
|
history.filter(
|
||||||
|
(line: TicketHistoryLine) => !(line.event_type === "add_person"),
|
||||||
|
),
|
||||||
|
);
|
||||||
|
|
||||||
function explainSentence(history: TicketHistoryLine): string {
|
function explainSentence(history: TicketHistoryLine): string {
|
||||||
switch (history.event_type) {
|
switch (history.event_type) {
|
||||||
case "add_comment":
|
case "add_comment":
|
||||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT);
|
return trans(CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT);
|
||||||
case "addressees_state":
|
case "addressees_state":
|
||||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE);
|
return trans(CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE, {
|
||||||
|
count: history.data.addressees.length,
|
||||||
|
});
|
||||||
case "persons_state":
|
case "persons_state":
|
||||||
return trans(CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE, {
|
return trans(CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE, {
|
||||||
count: history.data.persons.length,
|
count: history.data.persons.length,
|
||||||
@@ -142,12 +142,29 @@ function explainSentence(history: TicketHistoryLine): string {
|
|||||||
case "emergency_change":
|
case "emergency_change":
|
||||||
return trans(CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE);
|
return trans(CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE);
|
||||||
case "set_caller":
|
case "set_caller":
|
||||||
return trans(CHILL_TICKET_TICKET_HISTORY_SET_CALLER);
|
return trans(CHILL_TICKET_TICKET_HISTORY_SET_CALLER, {
|
||||||
|
id: history.data.new_caller?.id ?? "null",
|
||||||
|
});
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function displayBody(history_line: TicketHistoryLine): boolean {
|
||||||
|
// Dont display body if no entities or if is change of state, emergency
|
||||||
|
const data = Object.values(history_line.data)[0];
|
||||||
|
if (data == null) {
|
||||||
|
return false;
|
||||||
|
} else if (Array.isArray(data) && data.length === 0) {
|
||||||
|
return false;
|
||||||
|
} else if (
|
||||||
|
["state_change", "emergency_change"].includes(history_line.event_type)
|
||||||
|
) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
function formatDate(d: DateTime): string {
|
function formatDate(d: DateTime): string {
|
||||||
const date = ISOToDatetime(d.datetime);
|
const date = ISOToDatetime(d.datetime);
|
||||||
|
|
||||||
|
@@ -14,10 +14,8 @@
|
|||||||
<div class="wh-col">
|
<div class="wh-col">
|
||||||
<emergency-component
|
<emergency-component
|
||||||
:new_emergency="ticket.emergency"
|
:new_emergency="ticket.emergency"
|
||||||
v-if="ticket.emergency"
|
v-if="ticket.emergency == 'yes'"
|
||||||
/>
|
/>
|
||||||
</div>
|
|
||||||
<div class="wh-col">
|
|
||||||
<state-component
|
<state-component
|
||||||
v-if="ticket.currentState"
|
v-if="ticket.currentState"
|
||||||
:new_state="ticket.currentState"
|
:new_state="ticket.currentState"
|
||||||
@@ -40,7 +38,7 @@
|
|||||||
|
|
||||||
<div class="card-body pt-0">
|
<div class="card-body pt-0">
|
||||||
<div class="wrap-list">
|
<div class="wrap-list">
|
||||||
<div class="wl-row">
|
<div class="wl-row" v-if="ticket.currentAddressees.length">
|
||||||
<div class="wl-col title text-end">
|
<div class="wl-col title text-end">
|
||||||
<h3>{{ trans(CHILL_TICKET_LIST_ADDRESSEES) }}</h3>
|
<h3>{{ trans(CHILL_TICKET_LIST_ADDRESSEES) }}</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -48,7 +46,7 @@
|
|||||||
<addressee-component :addressees="ticket.currentAddressees" />
|
<addressee-component :addressees="ticket.currentAddressees" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wl-row">
|
<div class="wl-row" v-if="ticket.currentPersons.length">
|
||||||
<div class="wl-col title text-end">
|
<div class="wl-col title text-end">
|
||||||
<h3>{{ trans(CHILL_TICKET_LIST_PERSONS) }}</h3>
|
<h3>{{ trans(CHILL_TICKET_LIST_PERSONS) }}</h3>
|
||||||
</div>
|
</div>
|
||||||
@@ -56,7 +54,7 @@
|
|||||||
<person-component :entities="ticket.currentPersons" />
|
<person-component :entities="ticket.currentPersons" />
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="wl-row">
|
<div class="wl-row" v-if="ticket.caller">
|
||||||
<div class="wl-col title text-end">
|
<div class="wl-col title text-end">
|
||||||
<h3>{{ trans(CHILL_TICKET_LIST_CALLERS) }}</h3>
|
<h3>{{ trans(CHILL_TICKET_LIST_CALLERS) }}</h3>
|
||||||
</div>
|
</div>
|
||||||
|
@@ -14,7 +14,7 @@
|
|||||||
:class="[
|
:class="[
|
||||||
modelValue
|
modelValue
|
||||||
? classColor?.on || 'bg-chill-green'
|
? classColor?.on || 'bg-chill-green'
|
||||||
: classColor?.off || 'bg-chill-red',
|
: classColor?.off || 'bg-danger',
|
||||||
]"
|
]"
|
||||||
:style="{
|
:style="{
|
||||||
backgroundColor: classColor
|
backgroundColor: classColor
|
||||||
|
@@ -22,7 +22,7 @@ chill_ticket:
|
|||||||
by_motives: "Par motifs"
|
by_motives: "Par motifs"
|
||||||
current_state: "État actuel"
|
current_state: "État actuel"
|
||||||
open: "Ouvert"
|
open: "Ouvert"
|
||||||
closed: "Fermé"
|
closed: "Clôturé"
|
||||||
emergency: "Urgent"
|
emergency: "Urgent"
|
||||||
no_emergency: "Non urgent"
|
no_emergency: "Non urgent"
|
||||||
created_after: "Créé après"
|
created_after: "Créé après"
|
||||||
@@ -41,30 +41,32 @@ chill_ticket:
|
|||||||
reset: "Réinitialiser"
|
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"
|
||||||
history:
|
history:
|
||||||
add_comment: "Nouveau commentaire"
|
add_comment: "Commentaire ajouté"
|
||||||
addressees_state: "Attributions"
|
addressees_state: "{count, plural, =0 {Attributions supprimées} =1 {Attribution ajoutée} other {Attributions ajoutées}}"
|
||||||
persons_state: "{count, plural, =0 {Aucun usager concerné} =1 {Usager concerné} other {Usagers concernés}}"
|
persons_state: "{count, plural, =0 {Usagers supprimés} =1 {Usager concerné ajouté} other {Usagers concernés ajoutés}}"
|
||||||
set_caller: "Appelant"
|
set_caller: "{id, select, null {Appelant supprimé} other {Appelant ajouté}}"
|
||||||
set_motive: "Nouveau motifs"
|
set_motive: "Motif ajouté"
|
||||||
create_ticket: "Ticket créé"
|
create_ticket: "Ticket créé"
|
||||||
state_change: ""
|
state_change: ""
|
||||||
emergency_change: ""
|
emergency_change: ""
|
||||||
deleted: "Supprimé"
|
mask_comment: "Masqué"
|
||||||
previous_tickets: "Précédents tickets"
|
previous_tickets: "Précédents tickets"
|
||||||
actions_toolbar:
|
actions_toolbar:
|
||||||
cancel: "Annuler"
|
cancel: "Annuler"
|
||||||
save: "Enregistrer"
|
save: "Enregistrer"
|
||||||
close: "Fermer"
|
close: "Clôturer"
|
||||||
close_success: "Ticket fermé"
|
close_success: "Ticket clôturé"
|
||||||
close_error: "Erreur lors de la fermeture du ticket"
|
close_error: "Erreur lors de la clotûre du ticket"
|
||||||
reopen: "Rouvrir"
|
reopen: "Rouvrir"
|
||||||
reopen_success: "Rouverture du ticket réussie"
|
reopen_success: "Rouverture du ticket réussie"
|
||||||
reopen_error: "Erreur lors de la rouverture du ticket"
|
reopen_error: "Erreur lors de la rouverture du ticket"
|
||||||
restore_comment:
|
visible_comment:
|
||||||
success: "Commentaire restauré"
|
success: "Commentaire visible"
|
||||||
delete_comment:
|
mask_comment:
|
||||||
success: "Commentaire supprimé"
|
success: "Commentaire masqué"
|
||||||
|
hint: "Ce commentaire est masqué; il n'est visible que par vous."
|
||||||
edit_comment:
|
edit_comment:
|
||||||
title: "Éditer le commentaire"
|
title: "Éditer le commentaire"
|
||||||
success: "Commentaire modifié"
|
success: "Commentaire modifié"
|
||||||
@@ -98,7 +100,7 @@ chill_ticket:
|
|||||||
speaker: "{count, plural, =0 {Aucun intervenant} =1 {Intervenant attribué} other {Intervenants attribués}}"
|
speaker: "{count, plural, =0 {Aucun intervenant} =1 {Intervenant attribué} other {Intervenants attribués}}"
|
||||||
caller: "{count, plural, =0 {Aucun appelant} =1 {Appelant} other {Appelants}}"
|
caller: "{count, plural, =0 {Aucun appelant} =1 {Appelant} other {Appelants}}"
|
||||||
open: "Ouvert"
|
open: "Ouvert"
|
||||||
closed: "Fermé"
|
closed: "Clôturé"
|
||||||
since: "Depuis {time}"
|
since: "Depuis {time}"
|
||||||
and: "et"
|
and: "et"
|
||||||
days: >-
|
days: >-
|
||||||
|
Reference in New Issue
Block a user