Add tranfert with AddPerson

This commit is contained in:
Boris Waaub 2024-05-06 16:38:56 +02:00
parent 6500c24a7f
commit 473765366a
7 changed files with 275 additions and 90 deletions

View File

@ -24,9 +24,9 @@
</div>
<div v-if="activeTab === 'transfert'">
<form @submit.prevent="setAdressees">
<form @submit.prevent="setAdressees" v-if="userGroups.length && users.length">
<addressee-selector-component v-model="addressees" :user-groups="userGroups" :users="users" />
<div class="d-flex justify-content-end p-2">
<div class="d-flex justify-content-end p-1">
<button class="btn btn-chill-green text-white float-right" type="submit">
<i class="fa fa-pencil"></i>
{{ $t("transfert.save") }}
@ -39,7 +39,7 @@
<form @submit.prevent="createMotive">
<motive-selector-component v-model="motive" :motives="motives" />
<div class="d-flex justify-content-end p-2">
<div class="d-flex justify-content-end p-1">
<button class="btn btn-chill-green text-white float-right" type="submit">
<i class="fa fa-pencil"></i>
{{ $t("motive.save") }}
@ -108,11 +108,11 @@ export default defineComponent({
const ticket = computed(() => store.getters.getTicket as Ticket);
const motives = computed(() => store.getters.getMotives as Motive[]);
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
const users = computed(() => store.getters.getUserGroups as User[]);
const users = computed(() => store.getters.getUsers as User[]);
const motive = ref(ticket.value.currentMotive ? ticket.value.currentMotive: {} as Motive);
const content = ref('' as Comment["content"]);
const addressees = ref(ticket.value.currentAddressees as Array<UserGroupOrUser>);
const addressees = ref([] as Array<UserGroupOrUser>);

View File

@ -1,23 +1,103 @@
<template>
<div class="row">
<div class="col-12 col-lg-4 col-md-6">
<vue-multiselect name="selectMotive" id="selectMotive" label="label" :custom-label="customUserGroupLabel"
track-by="id" open-direction="top" :multiple="false" :searchable="true"
:placeholder="$t('transfert.label')" :select-label="$t('multiselect.select_label')"
:deselect-label="$t('multiselect.deselect_label')" :selected-label="$t('multiselect.selected_label')"
:options="userGroups" v-model="userGroup" />
<div class="col-12 col-lg-6 col-md-6 mb-2 text-center">
<span class="m-1">
<input
type="radio"
class="btn-check"
name="options-outlined"
id="level-none"
autocomplete="off"
:value="{}"
v-model="userGroupLevel"
/>
<label :class="`btn btn-outline-primary`" for="level-none">
Aucun
</label>
</span>
<span
v-for="userGroupItem in userGroups.filter(
(userGroup) => userGroup.excludeKey == 'level'
)"
:key="userGroupItem.id"
class="m-1"
>
<input
type="radio"
class="btn-check"
name="options-outlined"
:id="`level-${userGroupItem.id}`"
autocomplete="off"
:value="userGroupItem"
v-model="userGroupLevel"
/>
<label
:class="`btn btn-${userGroupItem.id}`"
:for="`level-${userGroupItem.id}`"
:style="getUserGroupBtnColor(userGroupItem)"
>
{{ userGroupItem.label.fr }}
</label>
</span>
</div>
<div class="col-12 col-lg-6 col-md-6 mb-2 text-center">
<span
v-for="userGroupItem in userGroups.filter(
(userGroup) => userGroup.excludeKey == ''
)"
:key="userGroupItem.id"
class="m-1"
>
<input
type="checkbox"
class="btn-check"
name="options-outlined"
:id="`user-group-${userGroupItem.id}`"
autocomplete="off"
:value="userGroupItem"
v-model="userGroup"
/>
<label
:class="`btn btn-${userGroupItem.id}`"
:for="`user-group-${userGroupItem.id}`"
:style="getUserGroupBtnColor(userGroupItem)"
>
{{ userGroupItem.label.fr }}
</label>
</span>
</div>
<div class="col-12 col-lg-6 col-md-6 mb-2 text-center">
<add-persons
:options="addPersonsOptions"
key="add-person-ticket"
buttonTitle="transfert.user_label"
modalTitle="transfert.user_label"
ref="addPersons"
@addNewPersons="addNewEntity"
/>
</div>
<div class="col-12 col-lg-6 col-md-6 mb-2 mb-2 text-center">
<span class="badge text-bg-light m-1" v-for="user in users">
{{ user.username }}
</span>
</div>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent, ref, watch } from "vue";
import { PropType, computed, defineComponent, ref, watch } from "vue";
import { useI18n } from "vue-i18n";
import VueMultiselect from "vue-multiselect";
// Types
import { User, UserGroup, UserGroupOrUser } from "../../../../../../../ChillMainBundle/Resources/public/types";
import {
User,
UserGroup,
UserGroupOrUser,
} from "../../../../../../../ChillMainBundle/Resources/public/types";
// Components
import AddPersons from "../../../../../../../ChillPersonBundle/Resources/public/vuejs/_components/AddPersons.vue";
export default defineComponent({
name: "AddresseeSelectorComponent",
@ -37,29 +117,99 @@ export default defineComponent({
},
},
components: {
VueMultiselect,
AddPersons,
},
emits: ["update:modelValue"],
setup(props, ctx) {
const addressees = ref(props.modelValue as UserGroupOrUser[]);
const userGroup = ref({} as UserGroup);
// Cant use UserGroupOrUser[] because of TS2367
// TS2367: This comparison appears to be unintentional because the types '"user" | "chill_main_user_group"' and '"user_group"' have no overlap.
const addressees = ref(props.modelValue as any[]);
const userGroupLevel = ref({} as UserGroupOrUser);
const userGroup = ref([] as UserGroupOrUser[]);
const users = ref([] as User[]);
const addPersons = ref();
const { t } = useI18n();
watch(userGroup, (userGroup) => {
addressees.value.push(userGroup);
function getUserGroupBtnColor(userGroup: UserGroup) {
return [
`.btn-check:checked + .btn-${userGroup.id} {
color: ${userGroup.foregroundColor};
background-color: ${userGroup.backgroundColor};
}`,
];
}
function addNewEntity(datas: any) {
const { selected, modal } = datas;
users.value = selected.map((selected: any) => selected.result);
addressees.value = addressees.value.filter(
(addressee) => addressee.type === "user_group"
);
addressees.value = [...addressees.value, ...users.value];
ctx.emit("update:modelValue", addressees.value);
addPersons.value.resetSearch();
modal.showModal = false;
}
const addPersonsOptions = computed(() => {
return {
uniq: false,
type: ["user"],
priority: null,
button: {
size: "btn-sm",
class: "btn-submit",
},
};
});
watch(userGroupLevel, (userGroupLevelAdd, userGroupLevelRem) => {
if (userGroupLevelRem) {
addressees.value.splice(
addressees.value.indexOf(userGroupLevelRem),
1
);
}
addressees.value.push(userGroupLevelAdd);
ctx.emit("update:modelValue", addressees.value);
});
watch(userGroup, (userGroupAdd) => {
addressees.value = addressees.value.filter(
(addressee) => addressee.excludeKey !== ""
);
addressees.value = [...addressees.value, ...userGroupAdd];
ctx.emit("update:modelValue", addressees.value);
});
return {
addressees,
userGroupLevel,
userGroup,
customUserGroupLabel(userGroup: UserGroup) {
return userGroup.label ? userGroup.label.fr : t('transfert.label');
users,
addPersons,
addPersonsOptions,
addNewEntity,
getUserGroupBtnColor,
customUserGroupLabel(selectedUserGroup: UserGroup) {
return selectedUserGroup.label
? selectedUserGroup.label.fr
: t("transfert.user_group_label");
},
};
},
});
</script>
<style lang="scss" scoped></style>
<style lang="scss" scoped>
.btn-check:checked + .btn,
:not(.btn-check) + .btn:active,
.btn:first-child:active,
.btn.active,
.btn.show {
color: white;
box-shadow: 0 0 0 0.2rem var(--bs-chill-green);
outline: 0;
}
</style>

View File

@ -1,30 +0,0 @@
<template>
<div class="col-12">
<i class="fa fa-paint-brush"></i>
<span class="mx-1">
{{ $t('history.user_group.',{ user_group: addresseeHistory.addressee.label }) }}
</span>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue';
// Types
import { AddresseeHistory } from '../../../types';
export default defineComponent({
name: 'TicketHistoryAddresseeComponent',
props: {
addresseeHistory: {
type: Object as PropType<AddresseeHistory>,
required: true,
},
},
setup() {}
});
</script>
<style lang="scss" scoped></style>

View File

@ -0,0 +1,48 @@
<template>
<div class="col-12" v-if="addressee.type == 'user_group'">
<i class="fa fa-paper-plane"></i>
<span class="mx-1">
{{
$t("history.transfert_user_group", {
user_group: addressee.label.fr,
})
}}
</span>
</div>
<div class="col-12" v-if="addressee.type == 'user'">
<i class="fa fa-paper-plane"></i>
<span class="mx-1">
{{
$t("history.transfert_user", {
user: addressee.username,
})
}}
</span>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent, ref } from "vue";
// Types
import { AddresseeHistory } from "../../../types";
import { UserGroupOrUser } from "../../../../../../../ChillMainBundle/Resources/public/types";
export default defineComponent({
name: "TicketHistoryAddresseeComponent",
props: {
addresseeHistory: {
type: Object as PropType<AddresseeHistory>,
required: true,
},
},
setup(props, ctx) {
return {
addressee: ref(props.addresseeHistory.addressee as UserGroupOrUser),
};
},
});
</script>
<style lang="scss" scoped></style>

View File

@ -1,50 +1,59 @@
<template>
<div class="card my-2 bg-light" v-for="history_line in history" :key="history_line.data.id">
<div
class="card my-2 bg-light"
v-for="history_line in history"
:key="history_line.data.id"
>
<div class="card-header">
<span class="fw-bold fst-italic">
{{ formatDate(history_line.at) }}
</span>
<span class="badge bg-white text-black mx-1">{{ history_line.by.username }}</span>
<span class="badge bg-white text-black mx-1">{{
history_line.by.username
}}</span>
</div>
{{history_line.event_type}}
<div class="card-body row fst-italic">
<div class="col-12">
<i class="fa fa-eyedropper"></i>
<span class="mx-1">
{{ $t('history.user', { username: history_line.by.username }) }}
</span>
</div>
<ticket-history-person-component :personHistory="history_line.data"
v-if="history_line.event_type == 'add_person'" />
<ticket-history-motive-component :motiveHistory="history_line.data"
v-else-if="history_line.event_type == 'set_motive'" />
<ticket-history-comment-component :commentHistory="history_line.data"
v-else-if="history_line.event_type == 'add_comment'" />
<ticket-history-addressee-component :commentHistory="history_line.data"
v-else-if="history_line.event_type == 'add_addressee'" />
<ticket-history-person-component
:personHistory="history_line.data"
v-if="history_line.event_type == 'add_person'"
/>
<ticket-history-motive-component
:motiveHistory="history_line.data"
v-else-if="history_line.event_type == 'set_motive'"
/>
<ticket-history-comment-component
:commentHistory="history_line.data"
v-else-if="history_line.event_type == 'add_comment'"
/>
<ticket-history-addressee-component
:addresseeHistory="history_line.data"
v-else-if="history_line.event_type == 'add_addressee'"
/>
</div>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue';
import { DateTime } from '../../../../../../../ChillMainBundle/Resources/public/types';
import { PropType, defineComponent } from "vue";
import { DateTime } from "../../../../../../../ChillMainBundle/Resources/public/types";
// Types
import { Ticket } from '../../../types';
import { Ticket } from "../../../types";
// Components
import TicketHistoryPersonComponent from './TicketHistoryPersonComponent.vue';
import TicketHistoryMotiveComponent from './TicketHistoryMotiveComponent.vue';
import TicketHistoryCommentComponent from './TicketHistoryCommentComponent.vue';
import TicketHistoryPersonComponent from "./TicketHistoryPersonComponent.vue";
import TicketHistoryMotiveComponent from "./TicketHistoryMotiveComponent.vue";
import TicketHistoryCommentComponent from "./TicketHistoryCommentComponent.vue";
import TicketHistoryAddresseeComponent from "./TicketHistoryAddresseeComponent.vue";
export default defineComponent({
name: 'TicketHistoryListComponent',
name: "TicketHistoryListComponent",
components: {
TicketHistoryPersonComponent,
TicketHistoryMotiveComponent,
TicketHistoryCommentComponent,
TicketHistoryAddresseeComponent,
},
props: {
history: {
@ -56,12 +65,12 @@ export default defineComponent({
setup() {
function formatDate(d: DateTime) {
const date = new Date(d.datetime);
const month = date.toLocaleString('default', { month: 'long' });
return `${date.getDate()} ${month} ${date.getFullYear()}, ${date.toLocaleTimeString()}`
const month = date.toLocaleString("default", { month: "long" });
return `${date.getDate()} ${month} ${date.getFullYear()}, ${date.toLocaleTimeString()}`;
}
return { formatDate }
}
return { formatDate };
},
});
</script>

View File

@ -1,20 +1,26 @@
<template>
<div class="col-12">
<i class="fa fa-bolt" style="min-width: 16px;"></i>
<div class="col-12" v-if="personHistory.createdBy">
<i class="fa fa-eyedropper"></i>
<span class="mx-1">
{{ $t('history.person',{ person: personHistory.person.text }) }}
{{ $t("history.user", { username: personHistory.createdBy.username }) }}
</span>
</div>
<div class="col-12">
<i class="fa fa-bolt" style="min-width: 16px"></i>
<span class="mx-1">
{{ $t("history.person", { person: personHistory.person.text }) }}
</span>
</div>
</template>
<script lang="ts">
import { PropType, defineComponent } from 'vue';
import { PropType, defineComponent } from "vue";
// Type
import { PersonHistory } from '../../../types';
import { PersonHistory, Ticket } from "../../../types";
export default defineComponent({
name: 'TicketHistoryPersonComponent',
name: "TicketHistoryPersonComponent",
props: {
personHistory: {
type: Object as PropType<PersonHistory>,
@ -22,7 +28,7 @@ export default defineComponent({
},
},
setup() {}
setup() {},
});
</script>

View File

@ -10,7 +10,8 @@ const messages = {
user: "Prise en charge par {username}",
motive: "Motif indiqué: {motive}",
comment: "Commentaire: {comment}",
user_group: "Transferer au group: {user_group}",
transfert_user_group: "Transferé au groupe: {user_group}",
transfert_user: "Transferé vers l'utilisateur: {user}",
},
comment: {
title: "Commentaire",
@ -26,7 +27,8 @@ const messages = {
},
transfert: {
title: "Transfert",
label: "Transferer vers",
user_group_label: "Transferer vers un groupe",
user_label: "Transferer vers un ou plusieurs utilisateurs",
save: "Enregistrer",
success: "Transfert effectué",
},