Merge branch '1604-by-creator-and-by-user-assign-selector-for-ticket-list' into 'ticket-app-master'

[Frontend] Ajouter les sélecteur "par créateur", et "par utilisateur assigné"

See merge request Chill-Projet/chill-bundles!876
This commit is contained in:
2025-09-09 08:24:08 +00:00
committed by GitLab
5 changed files with 94 additions and 11 deletions

View File

@@ -169,6 +169,9 @@ export interface TicketFilters {
export interface TicketFilterParams { export interface TicketFilterParams {
byPerson?: number[]; byPerson?: number[];
byCreator?: number[];
byAddressee?: number[];
byAddresseeGroup?: number[];
byCurrentState?: TicketState[]; byCurrentState?: TicketState[];
byCurrentStateEmergency?: TicketEmergencyState[]; byCurrentStateEmergency?: TicketEmergencyState[];
byMotives?: number[]; byMotives?: number[];

View File

@@ -7,7 +7,7 @@
:multiple="true" :multiple="true"
:removable-if-set="true" :removable-if-set="true"
:display-picked="true" :display-picked="true"
:label="trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL)" :label="label"
@add-new-entity="addNewEntity" @add-new-entity="addNewEntity"
@remove-entity="removeEntity" @remove-entity="removeEntity"
/> />
@@ -28,10 +28,16 @@ import {
trans, trans,
} from "translator"; } from "translator";
const props = defineProps<{ const props = withDefaults(
modelValue: Entities[]; defineProps<{
suggested: Entities[]; modelValue: Entities[];
}>(); suggested: Entities[];
label?: string;
}>(),
{
label: trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL),
},
);
const emit = defineEmits<(e: "update:modelValue", value: Entities[]) => void>(); const emit = defineEmits<(e: "update:modelValue", value: Entities[]) => void>();

View File

@@ -101,6 +101,7 @@ onMounted(async () => {
await store.dispatch("getCurrentUser"); await store.dispatch("getCurrentUser");
await store.dispatch("fetchTicketList", filters); await store.dispatch("fetchTicketList", filters);
await store.dispatch("fetchMotives"); await store.dispatch("fetchMotives");
await store.dispatch("fetchUserGroups");
} finally { } finally {
isLoading.value = false; isLoading.value = false;
} }

View File

@@ -23,6 +23,31 @@
/> />
</div> </div>
<div class="col-md-6 mb-3">
<label class="form-label" for="userSelector">{{
trans(CHILL_TICKET_LIST_FILTER_CREATORS)
}}</label>
<persons-selector
v-model="selectedCreator"
:suggested="[]"
:multiple="true"
:types="['user']"
id="userSelector"
:label="trans(CHILL_TICKET_LIST_FILTER_BY_CREATOR)"
/>
</div>
<div class="col-md-6 mb-3">
<label class="form-label" for="addresseeSelector">{{
trans(CHILL_TICKET_LIST_FILTER_ADDRESSEES)
}}</label>
<addressee-selector-component
v-model="selectedAddressees"
:suggested="userGroups"
:label="trans(CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES)"
id="addresseeSelector"
/>
</div>
<div class="col-md-6"> <div class="col-md-6">
<!-- Filtre par motifs --> <!-- Filtre par motifs -->
<div class="row"> <div class="row">
@@ -193,8 +218,10 @@
<script setup lang="ts"> <script setup lang="ts">
import { ref, computed, watch } from "vue"; import { ref, computed, watch } from "vue";
import { useStore } from "vuex";
import type { Person } from "ChillPersonAssets/types"; import type { Person } from "ChillPersonAssets/types";
import type { Motive, TicketFilterParams, TicketFilters } from "../../../types"; import type { Motive, TicketFilterParams, TicketFilters } from "../../../types";
import { User, UserGroup, UserGroupOrUser } from "ChillMainAssets/types";
// Translation // Translation
import { import {
@@ -202,6 +229,10 @@ import {
CHILL_TICKET_LIST_FILTER_TITLE, CHILL_TICKET_LIST_FILTER_TITLE,
CHILL_TICKET_LIST_FILTER_PERSONS_CONCERNED, CHILL_TICKET_LIST_FILTER_PERSONS_CONCERNED,
CHILL_TICKET_LIST_FILTER_BY_PERSON, CHILL_TICKET_LIST_FILTER_BY_PERSON,
CHILL_TICKET_LIST_FILTER_CREATORS,
CHILL_TICKET_LIST_FILTER_BY_CREATOR,
CHILL_TICKET_LIST_FILTER_ADDRESSEES,
CHILL_TICKET_LIST_FILTER_BY_ADDRESSEES,
CHILL_TICKET_LIST_FILTER_BY_MOTIVES, CHILL_TICKET_LIST_FILTER_BY_MOTIVES,
CHILL_TICKET_LIST_FILTER_REMOVE, CHILL_TICKET_LIST_FILTER_REMOVE,
CHILL_TICKET_LIST_FILTER_OPEN, CHILL_TICKET_LIST_FILTER_OPEN,
@@ -221,6 +252,7 @@ import {
// Components // Components
import PersonsSelector from "../../TicketApp/components/Person/PersonsSelectorComponent.vue"; import PersonsSelector from "../../TicketApp/components/Person/PersonsSelectorComponent.vue";
import MotiveSelector from "../../TicketApp/components/Motive/MotiveSelectorComponent.vue"; import MotiveSelector from "../../TicketApp/components/Motive/MotiveSelectorComponent.vue";
import AddresseeSelectorComponent from "../../TicketApp/components/Addressee/AddresseeSelectorComponent.vue";
import ToggleComponent from "./ToggleComponent.vue"; import ToggleComponent from "./ToggleComponent.vue";
// Props // Props
@@ -235,6 +267,8 @@ const emit = defineEmits<{
"filters-changed": [filters: TicketFilterParams]; "filters-changed": [filters: TicketFilterParams];
}>(); }>();
const store = useStore();
// État réactif // État réactif
const filters = ref<TicketFilters>({ const filters = ref<TicketFilters>({
byCurrentState: ["open"], byCurrentState: ["open"],
@@ -249,6 +283,13 @@ const filters = ref<TicketFilters>({
const selectedPersons = ref<Person[]>([]); const selectedPersons = ref<Person[]>([]);
const availablePersons = ref<Person[]>(props.availablePersons || []); const availablePersons = ref<Person[]>(props.availablePersons || []);
// Sélection des utilisateur assigné
const selectedAddressees = ref<UserGroupOrUser[]>([]);
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
// Séléction des créateurs
const selectedCreator = ref<User[]>([]);
// Sélection des motifs // Sélection des motifs
const selectedMotive = ref<Motive | undefined>(); const selectedMotive = ref<Motive | undefined>();
const selectedMotives = ref<Motive[]>([]); const selectedMotives = ref<Motive[]>([]);
@@ -266,6 +307,24 @@ const selectedPersonIds = computed(() =>
selectedPersons.value.map((person) => person.id), selectedPersons.value.map((person) => person.id),
); );
// Computed pour les IDs des utilisateur ou groupes sélectionnées
const selectedUserAddresseesIds = computed(() =>
selectedAddressees.value
.filter((addressee) => addressee.type === "user")
.map((addressee) => addressee.id),
);
const selectedGroupAddresseesIds = computed(() =>
selectedAddressees.value
.filter((addressee) => addressee.type === "user_group")
.map((addressee) => addressee.id),
);
// Computed pour les IDs des créateurs
const selectedCreatorIds = computed(() =>
selectedCreator.value.map((creator) => creator.id),
);
// Computed pour les IDs des motifs sélectionnés // Computed pour les IDs des motifs sélectionnés
const selectedMotiveIds = computed(() => const selectedMotiveIds = computed(() =>
selectedMotives.value.map((motive) => motive.id), selectedMotives.value.map((motive) => motive.id),
@@ -325,7 +384,15 @@ const applyFilters = (): void => {
if (selectedPersonIds.value.length > 0) { if (selectedPersonIds.value.length > 0) {
apiFilters.byPerson = selectedPersonIds.value; apiFilters.byPerson = selectedPersonIds.value;
} }
if (selectedCreatorIds.value.length > 0) {
apiFilters.byCreator = selectedCreatorIds.value;
}
if (selectedUserAddresseesIds.value.length > 0) {
apiFilters.byAddressee = selectedUserAddresseesIds.value;
}
if (selectedGroupAddresseesIds.value.length > 0) {
apiFilters.byAddresseeGroup = selectedGroupAddresseesIds.value;
}
if (filters.value.byCurrentState.length > 0) { if (filters.value.byCurrentState.length > 0) {
apiFilters.byCurrentState = filters.value.byCurrentState; apiFilters.byCurrentState = filters.value.byCurrentState;
} }
@@ -366,6 +433,8 @@ const resetFilters = (): void => {
byAddresseeToMe: false, byAddresseeToMe: false,
}; };
selectedPersons.value = []; selectedPersons.value = [];
selectedCreator.value = [];
selectedAddressees.value = [];
selectedMotives.value = []; selectedMotives.value = [];
selectedMotive.value = undefined; selectedMotive.value = undefined;
isClosedToggled.value = true; isClosedToggled.value = true;

View File

@@ -8,17 +8,21 @@ chill_ticket:
loading_ticket_details: "Chargement de l'historique du ticket..." loading_ticket_details: "Chargement de l'historique du ticket..."
error_loading_ticket: "Erreur lors du chargement des ticket" error_loading_ticket: "Erreur lors du chargement des ticket"
load_more: "Voir plus..." load_more: "Voir plus..."
addressees: "Attribué à" addressees: "Destinataires"
persons: "Usager concernés" persons: "Usager concernés"
callers: "Appelants" callers: "Appelants"
filter: filter:
to_me: Tickets qui me sont attribués to_me: Tickets qui me sont destinés
in_alert: Tickets en alerte (délai de résolution dépassé) in_alert: Tickets en alerte (délai de résolution dépassé)
created_between: Créés entre created_between: Créés entre
state_change: État actuel state_change: État actuel
title: "Filtres des tickets" title: "Filtres des tickets"
persons_concerned: "Usagers concernés" persons_concerned: "Usagers concernés"
by_person: "Par personne" by_person: "Par personne"
creators: "Créateurs"
by_creator: "Par créateur"
addressees: "Par destinataire"
by_addressees: "Par destinataire"
by_motives: "Par motifs" by_motives: "Par motifs"
current_state: "État actuel" current_state: "État actuel"
open: "Ouvert" open: "Ouvert"
@@ -44,7 +48,7 @@ chill_ticket:
warning: "Veuillez remplir au minimum le motif et le commentaire" warning: "Veuillez remplir au minimum le motif et le commentaire"
history: history:
add_comment: "Commentaire ajouté" add_comment: "Commentaire ajouté"
addressees_state: "{count, plural, =0 {Attributions supprimées} =1 {Attribution ajoutée} other {Attributions ajoutées}}" addressees_state: "{count, plural, =0 {Destinataire supprimé} =1 {Destinataire ajouté} other {Destinataire ajoutés}}"
persons_state: "{count, plural, =0 {Usagers supprimés} =1 {Usager concerné ajouté} other {Usagers concernés ajoutés}}" persons_state: "{count, plural, =0 {Usagers supprimés} =1 {Usager concerné ajouté} other {Usagers concernés ajoutés}}"
set_caller: "{id, select, null {Appelant supprimé} other {Appelant ajouté}}" set_caller: "{id, select, null {Appelant supprimé} other {Appelant ajouté}}"
set_motive: "Motif ajouté" set_motive: "Motif ajouté"
@@ -83,7 +87,7 @@ chill_ticket:
error: "Aucun motif sélectionné" error: "Aucun motif sélectionné"
add_addressee: add_addressee:
title: "Attribuer" title: "Attribuer"
user_group_label: "Attributer à un groupe" user_group_label: "Attribuer à un groupe"
user_label: "Attribuer à un ou plusieurs utilisateurs" user_label: "Attribuer à un ou plusieurs utilisateurs"
success: "Attribution effectuée" success: "Attribution effectuée"
error: "Aucun destinataire sélectionné" error: "Aucun destinataire sélectionné"
@@ -97,7 +101,7 @@ chill_ticket:
error: "Aucun usager sélectionné" error: "Aucun usager sélectionné"
banner: banner:
person: "{count, plural, =0 {Aucun usager impliqué} =1 {Usager impliqué} other {Usagers impliqués}}" person: "{count, plural, =0 {Aucun usager impliqué} =1 {Usager impliqué} other {Usagers impliqués}}"
speaker: "{count, plural, =0 {Aucun intervenant} =1 {Intervenant attribué} other {Intervenants attribués}}" speaker: "{count, plural, =0 {Aucun destinataire} =1 {Destinataire} other {Destinataires}}"
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: "Clôturé" closed: "Clôturé"