mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-07-08 09:56:14 +00:00
Afficher les patients suggérés et ajouter un sélecteur urgent/non urgent
This commit is contained in:
parent
06e8264dde
commit
3df4043eb9
@ -10,6 +10,11 @@ export interface Civility {
|
|||||||
// TODO
|
// TODO
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface Household {
|
||||||
|
type: "household";
|
||||||
|
id: number;
|
||||||
|
}
|
||||||
|
|
||||||
export interface Job {
|
export interface Job {
|
||||||
id: number;
|
id: number;
|
||||||
type: "user_job";
|
type: "user_job";
|
||||||
@ -48,16 +53,10 @@ export interface User {
|
|||||||
label: string;
|
label: string;
|
||||||
// todo: mainCenter; mainJob; etc..
|
// todo: mainCenter; mainJob; etc..
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO : Add missing household properties
|
|
||||||
export interface Household {
|
|
||||||
type: "household";
|
|
||||||
id: number;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface ThirdParty {
|
export interface ThirdParty {
|
||||||
type: "thirdparty";
|
type: "thirdparty";
|
||||||
id: number;
|
id: number;
|
||||||
|
text: string;
|
||||||
firstname: string;
|
firstname: string;
|
||||||
name: string;
|
name: string;
|
||||||
email: string;
|
email: string;
|
||||||
@ -228,3 +227,61 @@ export interface WorkflowAttachment {
|
|||||||
export interface PrivateCommentEmbeddable {
|
export interface PrivateCommentEmbeddable {
|
||||||
comments: Record<number, string>;
|
comments: Record<number, string>;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// API Exception types
|
||||||
|
export interface TransportExceptionInterface {
|
||||||
|
name: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ValidationExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
|
name: "ValidationException";
|
||||||
|
error: object;
|
||||||
|
violations: string[];
|
||||||
|
titles: string[];
|
||||||
|
propertyPaths: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface AccessExceptionInterface extends TransportExceptionInterface {
|
||||||
|
name: "AccessException";
|
||||||
|
violations: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface NotFoundExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
|
name: "NotFoundException";
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ServerExceptionInterface extends TransportExceptionInterface {
|
||||||
|
name: "ServerException";
|
||||||
|
message: string;
|
||||||
|
code: number;
|
||||||
|
body: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ConflictHttpExceptionInterface
|
||||||
|
extends TransportExceptionInterface {
|
||||||
|
name: "ConflictHttpException";
|
||||||
|
violations: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type ApiException =
|
||||||
|
| ValidationExceptionInterface
|
||||||
|
| AccessExceptionInterface
|
||||||
|
| NotFoundExceptionInterface
|
||||||
|
| ServerExceptionInterface
|
||||||
|
| ConflictHttpExceptionInterface;
|
||||||
|
|
||||||
|
export interface Modal {
|
||||||
|
showModal: boolean;
|
||||||
|
modalDialogClass: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface Selected {
|
||||||
|
result: UserGroupOrUser;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface addNewEntities {
|
||||||
|
selected: Selected[];
|
||||||
|
modal: Modal;
|
||||||
|
}
|
||||||
|
@ -1,7 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<div class="grey-card">
|
||||||
<ul :class="listClasses" v-if="picked.length && displayPicked">
|
<ul :class="listClasses" v-if="picked.length && displayPicked">
|
||||||
<li v-for="p in picked" @click="removeEntity(p)" :key="p.type + p.id">
|
<li
|
||||||
<span class="chill_denomination">{{ p.text }}</span>
|
v-for="p in picked"
|
||||||
|
@click="removeEntity(p)"
|
||||||
|
:key="p.type + p.id"
|
||||||
|
>
|
||||||
|
<span
|
||||||
|
:class="getBadgeClass(p)"
|
||||||
|
class="chill_denomination"
|
||||||
|
:style="getBadgeStyle(p)"
|
||||||
|
>
|
||||||
|
{{ p.text }}
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="record_actions">
|
<ul class="record_actions">
|
||||||
@ -11,132 +22,251 @@
|
|||||||
:key="uniqid"
|
:key="uniqid"
|
||||||
:buttonTitle="translatedListOfTypes"
|
:buttonTitle="translatedListOfTypes"
|
||||||
:modalTitle="translatedListOfTypes"
|
:modalTitle="translatedListOfTypes"
|
||||||
ref="addPersons"
|
|
||||||
@addNewPersons="addNewEntity"
|
@addNewPersons="addNewEntity"
|
||||||
>
|
>
|
||||||
</add-persons>
|
</add-persons>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
<ul class="list-suggest add-items inline">
|
|
||||||
|
<ul class="badge-suggest add-items inline" style="float: right">
|
||||||
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)">
|
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)">
|
||||||
<span>{{ s.text }}</span>
|
<span :class="getBadgeClass(s)" :style="getBadgeStyle(s)">
|
||||||
|
{{ s.text }}
|
||||||
|
</span>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script>
|
<script lang="ts" setup>
|
||||||
|
import { ref, computed, defineProps, defineEmits, defineComponent } from "vue";
|
||||||
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
||||||
import { appMessages } from "./i18n";
|
import { Entities, EntityType, SearchOptions } from "ChillPersonAssets/types";
|
||||||
|
import {
|
||||||
|
PICK_ENTITY_MODAL_TITLE,
|
||||||
|
PICK_ENTITY_USER,
|
||||||
|
PICK_ENTITY_USER_GROUP,
|
||||||
|
PICK_ENTITY_PERSON,
|
||||||
|
PICK_ENTITY_THIRDPARTY,
|
||||||
|
trans,
|
||||||
|
} from "translator";
|
||||||
|
import { addNewEntities } from "ChillMainAssets/types";
|
||||||
|
|
||||||
export default {
|
defineComponent({
|
||||||
name: "PickEntity",
|
|
||||||
props: {
|
|
||||||
multiple: {
|
|
||||||
type: Boolean,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
types: {
|
|
||||||
type: Array,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
picked: {
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
uniqid: {
|
|
||||||
type: String,
|
|
||||||
required: true,
|
|
||||||
},
|
|
||||||
removableIfSet: {
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
displayPicked: {
|
|
||||||
// display picked entities.
|
|
||||||
type: Boolean,
|
|
||||||
default: true,
|
|
||||||
},
|
|
||||||
suggested: {
|
|
||||||
type: Array,
|
|
||||||
default: [],
|
|
||||||
},
|
|
||||||
label: {
|
|
||||||
type: String,
|
|
||||||
required: false,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
emits: ["addNewEntity", "removeEntity", "addNewEntityProcessEnded"],
|
|
||||||
components: {
|
components: {
|
||||||
AddPersons,
|
AddPersons,
|
||||||
},
|
},
|
||||||
data() {
|
});
|
||||||
return {
|
const props = defineProps<{
|
||||||
key: "",
|
multiple: boolean;
|
||||||
};
|
types: EntityType[];
|
||||||
},
|
picked: Entities[];
|
||||||
computed: {
|
uniqid: string;
|
||||||
addPersonsOptions() {
|
removableIfSet?: boolean;
|
||||||
return {
|
displayPicked?: boolean;
|
||||||
uniq: !this.multiple,
|
suggested?: Entities[];
|
||||||
type: this.types,
|
label?: string;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const emits = defineEmits<{
|
||||||
|
(e: "addNewEntity", payload: { entity: Entities }): void;
|
||||||
|
(e: "removeEntity", payload: { entity: Entities }): void;
|
||||||
|
(e: "addNewEntityProcessEnded"): void;
|
||||||
|
}>();
|
||||||
|
|
||||||
|
const addPersons = ref();
|
||||||
|
|
||||||
|
const addPersonsOptions = computed(
|
||||||
|
() =>
|
||||||
|
({
|
||||||
|
uniq: !props.multiple,
|
||||||
|
type: props.types,
|
||||||
priority: null,
|
priority: null,
|
||||||
button: {
|
button: {
|
||||||
size: "btn-sm",
|
size: "btn-sm",
|
||||||
class: "btn-submit",
|
class: "btn-submit",
|
||||||
},
|
},
|
||||||
};
|
}) as SearchOptions,
|
||||||
},
|
);
|
||||||
translatedListOfTypes() {
|
|
||||||
if (this.label !== "") {
|
const translatedListOfTypes = computed(() => {
|
||||||
return this.label;
|
if (props.label !== undefined && props.label !== "") {
|
||||||
|
return props.label;
|
||||||
}
|
}
|
||||||
|
|
||||||
let trans = [];
|
const translatedTypes = props.types.map((type: EntityType) => {
|
||||||
this.types.forEach((t) => {
|
switch (type) {
|
||||||
if (this.$props.multiple) {
|
case "user":
|
||||||
trans.push(appMessages.fr.pick_entity[t].toLowerCase());
|
return trans(PICK_ENTITY_USER, {
|
||||||
} else {
|
count: props.multiple ? 2 : 1,
|
||||||
trans.push(
|
});
|
||||||
appMessages.fr.pick_entity[t + "_one"].toLowerCase(),
|
case "person":
|
||||||
);
|
return trans(PICK_ENTITY_PERSON, {
|
||||||
|
count: props.multiple ? 2 : 1,
|
||||||
|
});
|
||||||
|
case "third_party":
|
||||||
|
return trans(PICK_ENTITY_THIRDPARTY, {
|
||||||
|
count: props.multiple ? 2 : 1,
|
||||||
|
});
|
||||||
|
case "user_group":
|
||||||
|
return trans(PICK_ENTITY_USER_GROUP, {
|
||||||
|
count: props.multiple ? 2 : 1,
|
||||||
|
});
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
if (this.$props.multiple) {
|
return `${trans(PICK_ENTITY_MODAL_TITLE, {
|
||||||
return (
|
count: props.multiple ? 2 : 1,
|
||||||
appMessages.fr.pick_entity.modal_title + trans.join(", ")
|
})} ${translatedTypes.join(", ")}`;
|
||||||
);
|
});
|
||||||
} else {
|
|
||||||
return (
|
const listClasses = computed(() => ({
|
||||||
appMessages.fr.pick_entity.modal_title_one +
|
"badge-suggest": true,
|
||||||
trans.join(", ")
|
"remove-items": props.removableIfSet !== false,
|
||||||
);
|
inline: true,
|
||||||
}
|
}));
|
||||||
},
|
|
||||||
listClasses() {
|
function addNewSuggested(entity: Entities) {
|
||||||
return {
|
emits("addNewEntity", { entity });
|
||||||
"list-suggest": true,
|
}
|
||||||
"remove-items": this.$props.removableIfSet,
|
|
||||||
};
|
function addNewEntity({ selected }: addNewEntities) {
|
||||||
},
|
Object.values(selected).forEach((item) => {
|
||||||
},
|
emits("addNewEntity", { entity: item.result });
|
||||||
methods: {
|
});
|
||||||
addNewSuggested(entity) {
|
addPersons.value?.resetSearch();
|
||||||
this.$emit("addNewEntity", { entity: entity });
|
|
||||||
},
|
emits("addNewEntityProcessEnded");
|
||||||
addNewEntity({ selected, modal }) {
|
}
|
||||||
selected.forEach((item) => {
|
|
||||||
this.$emit("addNewEntity", { entity: item.result });
|
function removeEntity(entity: Entities) {
|
||||||
}, this);
|
if (props.removableIfSet === false) {
|
||||||
this.$refs.addPersons.resetSearch(); // to cast child method
|
|
||||||
modal.showModal = false;
|
|
||||||
this.$emit("addNewEntityProcessEnded");
|
|
||||||
},
|
|
||||||
removeEntity(entity) {
|
|
||||||
if (!this.$props.removableIfSet) {
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.$emit("removeEntity", { entity: entity });
|
emits("removeEntity", { entity });
|
||||||
},
|
}
|
||||||
},
|
|
||||||
};
|
function getBadgeClass(entities: Entities) {
|
||||||
|
if (entities.type !== "user_group") {
|
||||||
|
return entities.type;
|
||||||
|
}
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
function getBadgeStyle(entities: Entities) {
|
||||||
|
if (entities.type === "user_group") {
|
||||||
|
return [
|
||||||
|
`ul.badge-suggest li > span {
|
||||||
|
color: ${entities.foregroundColor}!important;
|
||||||
|
border-bottom-color: ${entities.backgroundColor};
|
||||||
|
}`,
|
||||||
|
];
|
||||||
|
}
|
||||||
|
return [];
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
.grey-card {
|
||||||
|
background: #f8f9fa;
|
||||||
|
border-radius: 8px;
|
||||||
|
padding: 1.5rem;
|
||||||
|
min-height: 160px;
|
||||||
|
}
|
||||||
|
|
||||||
|
.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;
|
||||||
|
}
|
||||||
|
|
||||||
|
.as-user-group {
|
||||||
|
display: inline-block;
|
||||||
|
}
|
||||||
|
ul.badge-suggest {
|
||||||
|
list-style-type: none;
|
||||||
|
padding-left: 0;
|
||||||
|
margin-bottom: 0px;
|
||||||
|
}
|
||||||
|
ul.badge-suggest li > span {
|
||||||
|
white-space: normal;
|
||||||
|
text-align: start;
|
||||||
|
margin-bottom: 3px;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.badge-suggest.inline li {
|
||||||
|
display: inline-block;
|
||||||
|
margin-right: 0.2em;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.add-items li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.add-items li span {
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.add-items li span:hover {
|
||||||
|
color: #ced4da;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.add-items li > span:before {
|
||||||
|
font: normal normal normal 13px ForkAwesome;
|
||||||
|
margin-right: 1.8em;
|
||||||
|
content: "\f067";
|
||||||
|
color: var(--bs-success);
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 50%;
|
||||||
|
left: 0.75rem;
|
||||||
|
-webkit-transform: translateY(-50%);
|
||||||
|
-moz-transform: translateY(-50%);
|
||||||
|
-ms-transform: translateY(-50%);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
ul.badge-suggest.remove-items li {
|
||||||
|
position: relative;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.remove-items li span {
|
||||||
|
cursor: pointer;
|
||||||
|
padding-left: 2rem;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.remove-items li span:hover {
|
||||||
|
color: #ced4da;
|
||||||
|
}
|
||||||
|
ul.badge-suggest.remove-items li > span:before {
|
||||||
|
font: normal normal normal 13px ForkAwesome;
|
||||||
|
margin-right: 1.8em;
|
||||||
|
content: "\f1f8";
|
||||||
|
color: var(--bs-danger);
|
||||||
|
position: absolute;
|
||||||
|
display: block;
|
||||||
|
top: 50%;
|
||||||
|
left: 0.75rem;
|
||||||
|
-webkit-transform: translateY(-50%);
|
||||||
|
-moz-transform: translateY(-50%);
|
||||||
|
-ms-transform: translateY(-50%);
|
||||||
|
transform: translateY(-50%);
|
||||||
|
}
|
||||||
|
ul.badge-suggest li > span {
|
||||||
|
margin: 0.2rem 0.1rem;
|
||||||
|
display: inline-block;
|
||||||
|
padding: 0 1em 0 2.2em !important;
|
||||||
|
background-color: #fff;
|
||||||
|
border: 1px solid #dee2e6;
|
||||||
|
border-bottom-width: 3px;
|
||||||
|
border-bottom-style: solid;
|
||||||
|
border-radius: 6px;
|
||||||
|
font-size: 0.75em;
|
||||||
|
font-weight: 700;
|
||||||
|
}
|
||||||
|
|
||||||
|
ul.badge-suggest li > span.person {
|
||||||
|
border-bottom-color: #43b29d;
|
||||||
|
}
|
||||||
|
ul.badge-suggest li > span.thirdparty {
|
||||||
|
border-bottom-color: rgb(198.9, 72, 98.1);
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
@ -156,3 +156,31 @@ renderbox:
|
|||||||
no_current_address: "Sans adresse actuellement"
|
no_current_address: "Sans adresse actuellement"
|
||||||
new_household: "Nouveau ménage"
|
new_household: "Nouveau ménage"
|
||||||
no_members_yet: "Aucun membre actuellement"
|
no_members_yet: "Aucun membre actuellement"
|
||||||
|
|
||||||
|
pick_entity:
|
||||||
|
add: "Ajouter"
|
||||||
|
modal_title: >-
|
||||||
|
{count, plural,
|
||||||
|
one {Indiquer un}
|
||||||
|
other {Ajouter des}
|
||||||
|
}
|
||||||
|
user: >-
|
||||||
|
{count, plural,
|
||||||
|
one {Utilisateur}
|
||||||
|
other {Utilisateurs}
|
||||||
|
}
|
||||||
|
user_group: >-
|
||||||
|
{count, plural,
|
||||||
|
one {Groupe d'utilisateur}
|
||||||
|
other {Groupes d'utilisateurs}
|
||||||
|
}
|
||||||
|
person: >-
|
||||||
|
{count, plural,
|
||||||
|
one {Usager}
|
||||||
|
other {Usagers}
|
||||||
|
}
|
||||||
|
thirdparty: >-
|
||||||
|
{count, plural,
|
||||||
|
one {Tiers}
|
||||||
|
other {Tiers}
|
||||||
|
}
|
||||||
|
@ -1,21 +1,18 @@
|
|||||||
import { StoredObject } from "ChillDocStoreAssets/types";
|
import { StoredObject } from "ChillDocStoreAssets/types";
|
||||||
import {
|
import {
|
||||||
Address,
|
Address,
|
||||||
Scope,
|
|
||||||
Center,
|
Center,
|
||||||
Civility,
|
Civility,
|
||||||
DateTime,
|
DateTime,
|
||||||
User,
|
User,
|
||||||
WorkflowAvailable,
|
|
||||||
Job,
|
|
||||||
Household,
|
|
||||||
User,
|
|
||||||
UserGroup,
|
UserGroup,
|
||||||
WorkflowAvailable,
|
Household,
|
||||||
ThirdParty,
|
ThirdParty,
|
||||||
|
WorkflowAvailable,
|
||||||
|
Scope,
|
||||||
|
Job,
|
||||||
PrivateCommentEmbeddable,
|
PrivateCommentEmbeddable,
|
||||||
} from "ChillMainAssets/types";
|
} from "../../../ChillMainBundle/Resources/public/types";
|
||||||
import { StoredObject } from "ChillDocStoreAssets/types";
|
|
||||||
import { Thirdparty } from "../../../ChillThirdPartyBundle/Resources/public/types";
|
import { Thirdparty } from "../../../ChillThirdPartyBundle/Resources/public/types";
|
||||||
import { Calendar } from "../../../ChillCalendarBundle/Resources/public/types";
|
import { Calendar } from "../../../ChillCalendarBundle/Resources/public/types";
|
||||||
|
|
||||||
@ -76,19 +73,6 @@ export interface AccompanyingPeriod {
|
|||||||
| "DRAFT";
|
| "DRAFT";
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface AccompanyingPeriodWorkEvaluationDocument {
|
|
||||||
id: number;
|
|
||||||
type: "accompanying_period_work_evaluation_document";
|
|
||||||
storedObject: StoredObject;
|
|
||||||
title: string;
|
|
||||||
createdAt: DateTime | null;
|
|
||||||
createdBy: User | null;
|
|
||||||
updatedAt: DateTime | null;
|
|
||||||
updatedBy: User | null;
|
|
||||||
workflows_availables: WorkflowAvailable[];
|
|
||||||
workflows: object[];
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AccompanyingPeriodWork {
|
export interface AccompanyingPeriodWork {
|
||||||
id: number;
|
id: number;
|
||||||
accompanyingPeriod?: AccompanyingPeriod;
|
accompanyingPeriod?: AccompanyingPeriod;
|
||||||
@ -113,7 +97,7 @@ export interface AccompanyingPeriodWork {
|
|||||||
version: number;
|
version: number;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface SocialAction {
|
export interface SocialAction {
|
||||||
id: number;
|
id: number;
|
||||||
parent?: SocialAction | null;
|
parent?: SocialAction | null;
|
||||||
children: SocialAction[];
|
children: SocialAction[];
|
||||||
@ -195,18 +179,6 @@ export interface Goal {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface Result {
|
|
||||||
id: number;
|
|
||||||
accompanyingPeriodWorks: AccompanyingPeriodWork[];
|
|
||||||
accompanyingPeriodWorkGoals: AccompanyingPeriodWorkGoal[];
|
|
||||||
goals: Goal[];
|
|
||||||
socialActions: SocialAction[];
|
|
||||||
title: {
|
|
||||||
fr: string;
|
|
||||||
};
|
|
||||||
desactivationDate?: string | null;
|
|
||||||
}
|
|
||||||
|
|
||||||
export interface AccompanyingPeriodWorkGoal {
|
export interface AccompanyingPeriodWorkGoal {
|
||||||
id: number;
|
id: number;
|
||||||
accompanyingPeriodWork: AccompanyingPeriodWork;
|
accompanyingPeriodWork: AccompanyingPeriodWork;
|
||||||
@ -258,6 +230,26 @@ export interface AccompanyingPeriodWorkReferrerHistory {
|
|||||||
updatedBy: User | null;
|
updatedBy: User | null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export interface AccompanyingPeriodWorkEvaluationDocument {
|
||||||
|
id: number;
|
||||||
|
type: "accompanying_period_work_evaluation_document";
|
||||||
|
storedObject: StoredObject;
|
||||||
|
title: string;
|
||||||
|
createdAt: DateTime | null;
|
||||||
|
createdBy: User | null;
|
||||||
|
updatedAt: DateTime | null;
|
||||||
|
updatedBy: User | null;
|
||||||
|
workflows_availables: WorkflowAvailable[];
|
||||||
|
workflows: object[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export type EntityType =
|
||||||
|
| "user_group"
|
||||||
|
| "user"
|
||||||
|
| "person"
|
||||||
|
| "third_party"
|
||||||
|
| "household";
|
||||||
|
|
||||||
export type Entities = (UserGroup | User | Person | ThirdParty | Household) & {
|
export type Entities = (UserGroup | User | Person | ThirdParty | Household) & {
|
||||||
address?: Address | null;
|
address?: Address | null;
|
||||||
kind?: string;
|
kind?: string;
|
||||||
|
@ -37,7 +37,9 @@
|
|||||||
id="search-persons"
|
id="search-persons"
|
||||||
name="query"
|
name="query"
|
||||||
v-model="query"
|
v-model="query"
|
||||||
:placeholder="trans(ADD_PERSONS_SEARCH_SOME_PERSONS)"
|
:placeholder="
|
||||||
|
trans(ADD_PERSONS_SEARCH_SOME_PERSONS)
|
||||||
|
"
|
||||||
ref="searchRef"
|
ref="searchRef"
|
||||||
/>
|
/>
|
||||||
<i class="fa fa-search fa-lg" />
|
<i class="fa fa-search fa-lg" />
|
||||||
@ -54,7 +56,10 @@
|
|||||||
<a v-if="suggestedCounter > 2" @click="selectAll">
|
<a v-if="suggestedCounter > 2" @click="selectAll">
|
||||||
{{ trans(ACTION_CHECK_ALL) }}
|
{{ trans(ACTION_CHECK_ALL) }}
|
||||||
</a>
|
</a>
|
||||||
<a v-if="selectedCounter > 0" @click="resetSelection">
|
<a
|
||||||
|
v-if="selectedCounter > 0"
|
||||||
|
@click="resetSelection"
|
||||||
|
>
|
||||||
<i v-if="suggestedCounter > 2"> • </i>
|
<i v-if="suggestedCounter > 2"> • </i>
|
||||||
{{ trans(ACTION_RESET) }}
|
{{ trans(ACTION_RESET) }}
|
||||||
</a>
|
</a>
|
||||||
@ -90,7 +95,9 @@
|
|||||||
(options.type.includes('person') ||
|
(options.type.includes('person') ||
|
||||||
options.type.includes('thirdparty'))
|
options.type.includes('thirdparty'))
|
||||||
"
|
"
|
||||||
:button-text="trans(ONTHEFLY_CREATE_BUTTON, { q: query })"
|
:button-text="
|
||||||
|
trans(ONTHEFLY_CREATE_BUTTON, { q: query })
|
||||||
|
"
|
||||||
:allowed-types="options.type"
|
:allowed-types="options.type"
|
||||||
:query="query"
|
:query="query"
|
||||||
action="create"
|
action="create"
|
||||||
@ -106,7 +113,9 @@
|
|||||||
class="btn btn-create"
|
class="btn btn-create"
|
||||||
@click.prevent="
|
@click.prevent="
|
||||||
() => {
|
() => {
|
||||||
$emit('addNewPersons', { selected: selectedComputed });
|
$emit('addNewPersons', {
|
||||||
|
selected: selectedComputed,
|
||||||
|
});
|
||||||
query = '';
|
query = '';
|
||||||
closeModal();
|
closeModal();
|
||||||
}
|
}
|
||||||
@ -272,7 +281,10 @@ function setQuery(q: string) {
|
|||||||
loadSuggestions(suggested.results);
|
loadSuggestions(suggested.results);
|
||||||
})
|
})
|
||||||
.catch((error: DOMException) => {
|
.catch((error: DOMException) => {
|
||||||
if (error instanceof DOMException && error.name === "AbortError") {
|
if (
|
||||||
|
error instanceof DOMException &&
|
||||||
|
error.name === "AbortError"
|
||||||
|
) {
|
||||||
// Request was aborted, ignore
|
// Request was aborted, ignore
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -15,7 +15,7 @@ export interface Motive {
|
|||||||
|
|
||||||
export type TicketState = "open" | "closed";
|
export type TicketState = "open" | "closed";
|
||||||
|
|
||||||
export type TicketEmergencyState = "yes"|"no";
|
export type TicketEmergencyState = "yes" | "no";
|
||||||
|
|
||||||
interface TicketHistory<T extends string, D extends object> {
|
interface TicketHistory<T extends string, D extends object> {
|
||||||
event_type: T;
|
event_type: T;
|
||||||
@ -75,42 +75,52 @@ export interface AddresseeState {
|
|||||||
export interface PersonsState {
|
export interface PersonsState {
|
||||||
persons: Person[];
|
persons: Person[];
|
||||||
}
|
}
|
||||||
|
export interface CallerState {
|
||||||
|
new_caller: Person | null;
|
||||||
|
}
|
||||||
|
|
||||||
export interface StateChange {
|
export interface StateChange {
|
||||||
new_state: TicketState;
|
new_state: TicketState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface StateChange {
|
export interface EmergencyChange {
|
||||||
new_state: TicketState;
|
new_emergency: TicketEmergencyState;
|
||||||
}
|
}
|
||||||
|
|
||||||
export interface CreateTicketState {
|
export interface CreateTicketState {
|
||||||
by: User;
|
by: User;
|
||||||
}
|
}
|
||||||
|
|
||||||
interface AddPersonEvent extends TicketHistory<"add_person", PersonHistory> {}
|
|
||||||
export type AddCommentEvent = TicketHistory<"add_comment", Comment>;
|
export type AddCommentEvent = TicketHistory<"add_comment", Comment>;
|
||||||
export type SetMotiveEvent = TicketHistory<"set_motive", MotiveHistory>;
|
export type SetMotiveEvent = TicketHistory<"set_motive", MotiveHistory>;
|
||||||
//interface AddAddressee extends TicketHistory<"add_addressee", AddresseeHistory> {};
|
export type AddPersonEvent = TicketHistory<"add_person", PersonHistory>;
|
||||||
//interface RemoveAddressee extends TicketHistory<"remove_addressee", AddresseeHistory> {};
|
export type AddresseesStateEvent = TicketHistory<
|
||||||
export interface AddresseesStateEvent
|
"addressees_state",
|
||||||
extends TicketHistory<"addressees_state", AddresseeState> {}
|
AddresseeState
|
||||||
export interface CreateTicketEvent
|
>;
|
||||||
extends TicketHistory<"create_ticket", CreateTicketState> {}
|
export type CreateTicketEvent = TicketHistory<
|
||||||
export interface PersonStateEvent
|
"create_ticket",
|
||||||
extends TicketHistory<"persons_state", PersonsState> {}
|
CreateTicketState
|
||||||
export interface ChangeStateEvent
|
>;
|
||||||
extends TicketHistory<"state_change", StateChange> {}
|
export type PersonStateEvent = TicketHistory<"persons_state", PersonsState>;
|
||||||
|
export type ChangeStateEvent = TicketHistory<"state_change", StateChange>;
|
||||||
|
export type EmergencyStateEvent = TicketHistory<
|
||||||
|
"emergency_change",
|
||||||
|
EmergencyChange
|
||||||
|
>;
|
||||||
|
export type CallerStateEvent = TicketHistory<"set_caller", CallerState>;
|
||||||
|
|
||||||
// TODO : Remove add_persont event from TicketHistoryLine
|
// TODO : Remove add_person event from TicketHistoryLine
|
||||||
export type TicketHistoryLine =
|
export type TicketHistoryLine =
|
||||||
| AddPersonEvent
|
| AddPersonEvent
|
||||||
| CreateTicketEvent
|
| CreateTicketEvent
|
||||||
| AddCommentEvent
|
| AddCommentEvent
|
||||||
| SetMotiveEvent /*AddAddressee | RemoveAddressee | */
|
| SetMotiveEvent
|
||||||
| AddresseesStateEvent
|
| AddresseesStateEvent
|
||||||
| PersonStateEvent
|
| PersonStateEvent
|
||||||
| ChangeStateEvent;
|
| ChangeStateEvent
|
||||||
|
| EmergencyStateEvent
|
||||||
|
| CallerStateEvent;
|
||||||
|
|
||||||
export interface Ticket {
|
export interface Ticket {
|
||||||
type: "ticket_ticket";
|
type: "ticket_ticket";
|
||||||
@ -124,16 +134,5 @@ export interface Ticket {
|
|||||||
updatedBy: User | null;
|
updatedBy: User | null;
|
||||||
currentState: TicketState | null;
|
currentState: TicketState | null;
|
||||||
emergency: TicketEmergencyState | null;
|
emergency: TicketEmergencyState | null;
|
||||||
}
|
caller: Person | null;
|
||||||
|
|
||||||
export interface addNewPersons {
|
|
||||||
selected: Selected[];
|
|
||||||
modal: Modal;
|
|
||||||
}
|
|
||||||
export interface Modal {
|
|
||||||
showModal: boolean;
|
|
||||||
modalDialogClass: string;
|
|
||||||
}
|
|
||||||
export interface Selected {
|
|
||||||
result: User;
|
|
||||||
}
|
}
|
||||||
|
@ -34,6 +34,7 @@ onMounted(async () => {
|
|||||||
await store.dispatch("fetchMotives");
|
await store.dispatch("fetchMotives");
|
||||||
await store.dispatch("fetchUserGroups");
|
await store.dispatch("fetchUserGroups");
|
||||||
await store.dispatch("fetchUsers");
|
await store.dispatch("fetchUsers");
|
||||||
|
await store.dispatch("getSuggestedPersons");
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error as string);
|
toast.error(error as string);
|
||||||
}
|
}
|
||||||
|
@ -2,25 +2,38 @@
|
|||||||
<div class="fixed-bottom">
|
<div class="fixed-bottom">
|
||||||
<div class="footer-ticket-details" v-if="activeTab">
|
<div class="footer-ticket-details" v-if="activeTab">
|
||||||
<div class="tab-content p-2">
|
<div class="tab-content p-2">
|
||||||
<div>
|
<button
|
||||||
|
type="button"
|
||||||
|
class="btn btn-link p-0"
|
||||||
|
style="
|
||||||
|
position: absolute;
|
||||||
|
top: 0.5rem;
|
||||||
|
right: 0.5rem;
|
||||||
|
font-size: 2rem;
|
||||||
|
line-height: 1;
|
||||||
|
color: #888;
|
||||||
|
text-decoration: none;
|
||||||
|
"
|
||||||
|
@click="closeAllActions"
|
||||||
|
aria-label="Fermer"
|
||||||
|
title="Fermer"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
|
<div v-if="activeTabTitle">
|
||||||
<label class="col-form-label">
|
<label class="col-form-label">
|
||||||
{{ activeTabTitle }}
|
{{ activeTabTitle }}
|
||||||
</label>
|
</label>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<form
|
<form @submit.prevent="submitAction">
|
||||||
v-if="activeTab !== 'persons_state'"
|
|
||||||
@submit.prevent="submitAction"
|
|
||||||
>
|
|
||||||
<add-comment-component
|
<add-comment-component
|
||||||
v-model="content"
|
v-model="content"
|
||||||
v-if="activeTab === 'add_comment'"
|
v-if="activeTab === 'add_comment'"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
<addressee-selector-component
|
<addressee-selector-component
|
||||||
v-model="addressees"
|
v-model="addressees"
|
||||||
:user-groups="userGroups"
|
:suggested="userGroups"
|
||||||
:users="users"
|
|
||||||
v-if="activeTab === 'addressees_state'"
|
v-if="activeTab === 'addressees_state'"
|
||||||
/>
|
/>
|
||||||
|
|
||||||
@ -29,20 +42,40 @@
|
|||||||
:motives="motives"
|
:motives="motives"
|
||||||
v-if="activeTab === 'set_motive'"
|
v-if="activeTab === 'set_motive'"
|
||||||
/>
|
/>
|
||||||
|
<div v-if="activeTab === 'persons_state'">
|
||||||
<ul class="record_actions sticky-form-buttons">
|
<div class="row">
|
||||||
<li class="cancel">
|
<label class="col col-form-label">
|
||||||
<button
|
|
||||||
@click="activeTab = ''"
|
|
||||||
class="btn btn-cancel"
|
|
||||||
>
|
|
||||||
{{
|
{{
|
||||||
trans(
|
trans(
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CANCEL,
|
CHILL_TICKET_TICKET_SET_PERSONS_TITLE_CALLER,
|
||||||
)
|
)
|
||||||
}}
|
}}
|
||||||
</button>
|
</label>
|
||||||
</li>
|
<label class="col col-form-label">
|
||||||
|
{{
|
||||||
|
trans(
|
||||||
|
CHILL_TICKET_TICKET_SET_PERSONS_TITLE_PERSON,
|
||||||
|
)
|
||||||
|
}}
|
||||||
|
</label>
|
||||||
|
</div>
|
||||||
|
<div class="row">
|
||||||
|
<div class="col">
|
||||||
|
<caller-selector-component
|
||||||
|
v-model="caller"
|
||||||
|
:suggested="[]"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
<div class="col">
|
||||||
|
<persons-selector-component
|
||||||
|
v-model="persons"
|
||||||
|
:suggested="suggestedPersons"
|
||||||
|
/>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<ul class="record_actions sticky-form-buttons">
|
||||||
<li>
|
<li>
|
||||||
<button class="btn btn-save" type="submit">
|
<button class="btn btn-save" type="submit">
|
||||||
{{
|
{{
|
||||||
@ -54,11 +87,6 @@
|
|||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
</form>
|
</form>
|
||||||
<template v-else>
|
|
||||||
<persons-selector-component
|
|
||||||
@closeRequested="closeAllActions()"
|
|
||||||
/>
|
|
||||||
</template>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
<div class="footer-ticket-main">
|
<div class="footer-ticket-main">
|
||||||
@ -67,8 +95,16 @@
|
|||||||
<a :href="returnPath" class="btn btn-cancel">Annuler</a>
|
<a :href="returnPath" class="btn btn-cancel">Annuler</a>
|
||||||
</li>
|
</li>
|
||||||
<li v-else class="nav-item p-2 go-back">
|
<li v-else class="nav-item p-2 go-back">
|
||||||
<a href="/fr/ticket/ticket/list" class="btn btn-cancel"
|
<button
|
||||||
>Annuler</a
|
type="button"
|
||||||
|
class="btn btn-link p-0"
|
||||||
|
style="font-size: 1.5rem; line-height: 1; color: #888"
|
||||||
|
@click="closeAllActions"
|
||||||
|
aria-label="Fermer"
|
||||||
|
title="Fermer"
|
||||||
|
>
|
||||||
|
<span aria-hidden="true">×</span>
|
||||||
|
</button>
|
||||||
>
|
>
|
||||||
</li>
|
</li>
|
||||||
<li
|
<li
|
||||||
@ -114,7 +150,7 @@
|
|||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, ref } from "vue";
|
import { computed, ref, watch } from "vue";
|
||||||
import { useStore } from "vuex";
|
import { useStore } from "vuex";
|
||||||
import { useToast } from "vue-toast-notification";
|
import { useToast } from "vue-toast-notification";
|
||||||
|
|
||||||
@ -123,6 +159,7 @@ import MotiveSelectorComponent from "./MotiveSelectorComponent.vue";
|
|||||||
import AddresseeSelectorComponent from "./AddresseeSelectorComponent.vue";
|
import AddresseeSelectorComponent from "./AddresseeSelectorComponent.vue";
|
||||||
import AddCommentComponent from "./AddCommentComponent.vue";
|
import AddCommentComponent from "./AddCommentComponent.vue";
|
||||||
import PersonsSelectorComponent from "./PersonsSelectorComponent.vue";
|
import PersonsSelectorComponent from "./PersonsSelectorComponent.vue";
|
||||||
|
import CallerSelectorComponent from "./CallerSelectorComponent.vue";
|
||||||
|
|
||||||
// Translations
|
// Translations
|
||||||
import {
|
import {
|
||||||
@ -136,8 +173,10 @@ import {
|
|||||||
CHILL_TICKET_TICKET_SET_MOTIVE_TITLE,
|
CHILL_TICKET_TICKET_SET_MOTIVE_TITLE,
|
||||||
CHILL_TICKET_TICKET_SET_MOTIVE_ERROR,
|
CHILL_TICKET_TICKET_SET_MOTIVE_ERROR,
|
||||||
CHILL_TICKET_TICKET_SET_MOTIVE_SUCCESS,
|
CHILL_TICKET_TICKET_SET_MOTIVE_SUCCESS,
|
||||||
|
CHILL_TICKET_TICKET_SET_PERSONS_TITLE_PERSON,
|
||||||
|
CHILL_TICKET_TICKET_SET_PERSONS_TITLE_CALLER,
|
||||||
CHILL_TICKET_TICKET_SET_PERSONS_TITLE,
|
CHILL_TICKET_TICKET_SET_PERSONS_TITLE,
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CANCEL,
|
CHILL_TICKET_TICKET_SET_PERSONS_SUCCESS,
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_SAVE,
|
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_SAVE,
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE,
|
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE,
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_SUCCESS,
|
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CLOSE_SUCCESS,
|
||||||
@ -149,11 +188,11 @@ import {
|
|||||||
|
|
||||||
// Types
|
// Types
|
||||||
import {
|
import {
|
||||||
User,
|
|
||||||
UserGroup,
|
UserGroup,
|
||||||
UserGroupOrUser,
|
UserGroupOrUser,
|
||||||
} from "../../../../../../../ChillMainBundle/Resources/public/types";
|
} from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import { Comment, Motive, Ticket } from "../../../types";
|
import { Comment, Motive, Ticket } from "../../../types";
|
||||||
|
import { Person } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
const toast = useToast();
|
const toast = useToast();
|
||||||
@ -169,8 +208,6 @@ const activeTabTitle = computed((): string => {
|
|||||||
return trans(CHILL_TICKET_TICKET_SET_MOTIVE_TITLE);
|
return trans(CHILL_TICKET_TICKET_SET_MOTIVE_TITLE);
|
||||||
case "addressees_state":
|
case "addressees_state":
|
||||||
return trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE);
|
return trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_TITLE);
|
||||||
case "persons_state":
|
|
||||||
return trans(CHILL_TICKET_TICKET_SET_PERSONS_TITLE);
|
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
@ -207,8 +244,8 @@ const ticket = computed(() => store.getters.getTicket as Ticket);
|
|||||||
const isOpen = computed(() => store.getters.isOpen);
|
const isOpen = computed(() => store.getters.isOpen);
|
||||||
const motives = computed(() => store.getters.getMotives as Motive[]);
|
const motives = computed(() => store.getters.getMotives as Motive[]);
|
||||||
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
|
const userGroups = computed(() => store.getters.getUserGroups as UserGroup[]);
|
||||||
const users = computed(() => store.getters.getUsers as User[]);
|
const suggestedPersons = computed(() => store.getters.getPersons as Person[]);
|
||||||
|
console.log("suggestedPersons", suggestedPersons.value);
|
||||||
const hasReturnPath = computed((): boolean => {
|
const hasReturnPath = computed((): boolean => {
|
||||||
const params = new URL(document.location.toString()).searchParams;
|
const params = new URL(document.location.toString()).searchParams;
|
||||||
return params.has("returnPath");
|
return params.has("returnPath");
|
||||||
@ -232,6 +269,8 @@ const motive = ref(
|
|||||||
);
|
);
|
||||||
const content = ref("" as Comment["content"]);
|
const content = ref("" as Comment["content"]);
|
||||||
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 caller = ref(ticket.value.caller as Person);
|
||||||
|
|
||||||
async function submitAction() {
|
async function submitAction() {
|
||||||
try {
|
try {
|
||||||
@ -279,6 +318,13 @@ async function submitAction() {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
case "persons_state":
|
||||||
|
await store.dispatch("setPersons", {
|
||||||
|
persons: persons.value,
|
||||||
|
});
|
||||||
|
activeTab.value = "";
|
||||||
|
toast.success(trans(CHILL_TICKET_TICKET_SET_PERSONS_SUCCESS));
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
toast.error(error as string);
|
toast.error(error as string);
|
||||||
@ -311,6 +357,11 @@ async function reopenTicket() {
|
|||||||
function closeAllActions() {
|
function closeAllActions() {
|
||||||
activeTab.value = "";
|
activeTab.value = "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
watch(caller, async (newCaller) => {
|
||||||
|
await store.dispatch("setCaller", { caller: newCaller });
|
||||||
|
await store.dispatch("getSuggestedPersons");
|
||||||
|
});
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -20,12 +20,8 @@
|
|||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
<div v-if="users.length > 0" class="col-12">
|
<div v-if="users.length > 0" class="col-12">
|
||||||
<span class="badge-user">
|
<span class="badge-user" v-for="user in users" :key="user.id">
|
||||||
<user-render-box-badge
|
<user-render-box-badge :user="user" />
|
||||||
v-for="user in users"
|
|
||||||
:key="user.id"
|
|
||||||
:user="user"
|
|
||||||
></user-render-box-badge>
|
|
||||||
</span>
|
</span>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
@ -1,90 +1,18 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-12 col-lg-6 col-md-6 text-center">
|
<div class="col-12">
|
||||||
<div class="mb-5 level-line">
|
<pick-entity
|
||||||
<span
|
uniqid="ticket-addressee-selector"
|
||||||
v-for="userGroupItem in userGroups.filter(
|
:types="['user', 'user_group', 'third_party']"
|
||||||
(userGroup) => userGroup.excludeKey == 'level',
|
:picked="selectedEntities"
|
||||||
)"
|
|
||||||
:key="userGroupItem.id"
|
|
||||||
class="m-2 as-user-group"
|
|
||||||
>
|
|
||||||
<input
|
|
||||||
type="radio"
|
|
||||||
class="btn-check"
|
|
||||||
name="options-outlined"
|
|
||||||
:id="`level-${userGroupItem.id}`"
|
|
||||||
autocomplete="off"
|
|
||||||
:value="userGroupItem"
|
|
||||||
v-model="userGroupLevel"
|
|
||||||
@click="
|
|
||||||
Object.values(userGroupLevel).includes(
|
|
||||||
userGroupItem.id,
|
|
||||||
)
|
|
||||||
? (userGroupLevel = {})
|
|
||||||
: (userGroupLevel = userGroupItem)
|
|
||||||
"
|
|
||||||
/>
|
|
||||||
<label
|
|
||||||
:class="`btn btn-${userGroupItem.id}`"
|
|
||||||
:for="`level-${userGroupItem.id}`"
|
|
||||||
:style="getUserGroupBtnColor(userGroupItem)"
|
|
||||||
>
|
|
||||||
{{ userGroupItem.label.fr }}
|
|
||||||
</label>
|
|
||||||
</span>
|
|
||||||
</div>
|
|
||||||
<div class="mb-2 level-line">
|
|
||||||
<span
|
|
||||||
v-for="userGroupItem in userGroups.filter(
|
|
||||||
(userGroup) => userGroup.excludeKey == '',
|
|
||||||
)"
|
|
||||||
:key="userGroupItem.id"
|
|
||||||
class="m-2"
|
|
||||||
>
|
|
||||||
<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>
|
|
||||||
|
|
||||||
<div class="col-12 col-lg-6 col-md-6 mb-2 mb-2 text-center">
|
|
||||||
<add-persons
|
|
||||||
:options="addPersonsOptions"
|
|
||||||
key="add-person-ticket"
|
|
||||||
:buttonTitle="
|
|
||||||
trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL)
|
|
||||||
"
|
|
||||||
:modalTitle="
|
|
||||||
trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL)
|
|
||||||
"
|
|
||||||
:selected="selectedValues"
|
|
||||||
:suggested="suggestedValues"
|
:suggested="suggestedValues"
|
||||||
@addNewPersons="addNewEntity"
|
:multiple="true"
|
||||||
|
:removable-if-set="true"
|
||||||
|
:display-picked="true"
|
||||||
|
:label="trans(CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL)"
|
||||||
|
@add-new-entity="addNewEntity"
|
||||||
|
@remove-entity="removeEntity"
|
||||||
/>
|
/>
|
||||||
<div class="p-2">
|
|
||||||
<ul class="list-suggest inline remove-items">
|
|
||||||
<li v-for="user in users" :key="user.id">
|
|
||||||
<span :title="user.username" @click="removeUser(user)">
|
|
||||||
{{ user.username }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
@ -93,12 +21,10 @@
|
|||||||
import { ref, watch, defineProps, defineEmits } from "vue";
|
import { ref, watch, defineProps, defineEmits } from "vue";
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
import PickEntity from "ChillMainAssets/vuejs/PickEntity/PickEntity.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import type { User, UserGroup, UserGroupOrUser } from "ChillMainAssets/types";
|
import { Entities } from "ChillPersonAssets/types";
|
||||||
import { SearchOptions, Suggestion } from "ChillPersonAssets/types";
|
|
||||||
import type { addNewPersons } from "../../../types";
|
|
||||||
|
|
||||||
// Translations
|
// Translations
|
||||||
import {
|
import {
|
||||||
@ -107,117 +33,62 @@ import {
|
|||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
const props = defineProps<{
|
const props = defineProps<{
|
||||||
modelValue?: UserGroupOrUser[];
|
modelValue: Entities[];
|
||||||
userGroups: UserGroup[];
|
suggested: Entities[];
|
||||||
users: User[];
|
|
||||||
}>();
|
}>();
|
||||||
|
|
||||||
const selectedValues = ref<Suggestion[]>([]);
|
const emit = defineEmits<(e: "update:modelValue", value: Entities[]) => void>();
|
||||||
const suggestedValues = ref<Suggestion[]>([]);
|
|
||||||
|
|
||||||
const emit =
|
const selectedEntities = ref<Entities[]>([...props.modelValue]);
|
||||||
defineEmits<(e: "update:modelValue", value: UserGroupOrUser[]) => void>();
|
const suggestedValues = ref<Entities[]>([...props.suggested]);
|
||||||
|
watch(
|
||||||
|
() => [props.suggested, props.modelValue],
|
||||||
|
() => {
|
||||||
|
const modelValue = props.modelValue ?? [];
|
||||||
|
|
||||||
const addressees = ref<UserGroupOrUser[]>([...(props.modelValue ?? [])]);
|
suggestedValues.value = props.suggested.filter(
|
||||||
|
(suggested: Entities) => {
|
||||||
const userGroupsInit = [
|
return !modelValue.some((selected: Entities) => {
|
||||||
...(props.modelValue ?? []).filter(
|
if (
|
||||||
(addressee: UserGroupOrUser) => addressee.type == "user_group",
|
suggested.type == "user_group" &&
|
||||||
),
|
selected.type == "user_group"
|
||||||
] as UserGroup[];
|
) {
|
||||||
|
switch (selected.excludeKey) {
|
||||||
const userGroupLevel = ref<UserGroup | Record<string, never>>(
|
case "level":
|
||||||
(userGroupsInit.filter(
|
return suggested.excludeKey === "level";
|
||||||
(userGroup: UserGroup) => userGroup.excludeKey == "level",
|
case "":
|
||||||
)[0] as UserGroup) ?? {},
|
return (
|
||||||
);
|
suggested.excludeKey === "" &&
|
||||||
|
suggested.id === selected.id
|
||||||
const userGroup = ref<UserGroup[]>(
|
|
||||||
userGroupsInit.filter(
|
|
||||||
(userGroup: UserGroup) => userGroup.excludeKey == "",
|
|
||||||
) as UserGroup[],
|
|
||||||
);
|
|
||||||
|
|
||||||
const users = ref<User[]>([
|
|
||||||
...(props.modelValue ?? []).filter(
|
|
||||||
(addressee: UserGroupOrUser) => addressee.type == "user",
|
|
||||||
),
|
|
||||||
] as User[]);
|
|
||||||
|
|
||||||
const addPersonsOptions = {
|
|
||||||
uniq: false,
|
|
||||||
type: ["user"],
|
|
||||||
priority: null,
|
|
||||||
button: {
|
|
||||||
size: "btn-sm",
|
|
||||||
class: "btn-submit",
|
|
||||||
},
|
|
||||||
} as SearchOptions;
|
|
||||||
|
|
||||||
function getUserGroupBtnColor(userGroup: UserGroup) {
|
|
||||||
return [
|
|
||||||
`color: ${userGroup.foregroundColor};
|
|
||||||
.btn-check:checked + .btn-${userGroup.id} {
|
|
||||||
color: ${userGroup.foregroundColor};
|
|
||||||
background-color: ${userGroup.backgroundColor};
|
|
||||||
}`,
|
|
||||||
];
|
|
||||||
}
|
|
||||||
|
|
||||||
function addNewEntity(datas: addNewPersons) {
|
|
||||||
const { selected } = datas;
|
|
||||||
users.value = selected.map((selected) => selected.result);
|
|
||||||
addressees.value = addressees.value.filter(
|
|
||||||
(addressee) => addressee.type === "user_group",
|
|
||||||
);
|
);
|
||||||
addressees.value = [...addressees.value, ...users.value];
|
default:
|
||||||
emit("update:modelValue", addressees.value);
|
return false;
|
||||||
selectedValues.value = [];
|
|
||||||
suggestedValues.value = [];
|
|
||||||
}
|
|
||||||
|
|
||||||
function removeUser(user: User) {
|
|
||||||
users.value.splice(users.value.indexOf(user), 1);
|
|
||||||
addressees.value = addressees.value.filter(
|
|
||||||
(addressee) => addressee.id !== user.id,
|
|
||||||
);
|
|
||||||
emit("update:modelValue", addressees.value);
|
|
||||||
}
|
|
||||||
|
|
||||||
watch(userGroupLevel, (userGroupLevelAdd, userGroupLevelRem) => {
|
|
||||||
const index = addressees.value.indexOf(userGroupLevelRem as UserGroup);
|
|
||||||
if (index !== -1) {
|
|
||||||
addressees.value.splice(index, 1);
|
|
||||||
}
|
}
|
||||||
addressees.value.push(userGroupLevelAdd as UserGroup);
|
} else {
|
||||||
emit("update:modelValue", addressees.value);
|
return (
|
||||||
});
|
suggested.type === selected.type &&
|
||||||
|
suggested.id === selected.id
|
||||||
|
);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
},
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
watch(userGroup, (userGroupAdd) => {
|
function addNewEntity({ entity }: { entity: Entities }) {
|
||||||
const userGroupLevelArr = addressees.value.filter(
|
selectedEntities.value.push(entity);
|
||||||
(addressee) =>
|
emit("update:modelValue", selectedEntities.value);
|
||||||
addressee.type == "user_group" && addressee.excludeKey == "level",
|
}
|
||||||
) as UserGroup[];
|
|
||||||
const usersArr = addressees.value.filter(
|
function removeEntity({ entity }: { entity: Entities }) {
|
||||||
(addressee) => addressee.type == "user",
|
const index = selectedEntities.value.findIndex(
|
||||||
) as User[];
|
(selectedEntity) => selectedEntity === entity,
|
||||||
addressees.value = [...usersArr, ...userGroupLevelArr, ...userGroupAdd];
|
);
|
||||||
emit("update:modelValue", addressees.value);
|
if (index !== -1) {
|
||||||
});
|
selectedEntities.value.splice(index, 1);
|
||||||
|
}
|
||||||
|
emit("update:modelValue", selectedEntities.value);
|
||||||
|
}
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<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;
|
|
||||||
}
|
|
||||||
|
|
||||||
.as-user-group {
|
|
||||||
display: inline-block;
|
|
||||||
}
|
|
||||||
</style>
|
|
||||||
|
@ -3,17 +3,25 @@
|
|||||||
<div class="container-xxl text-primary">
|
<div class="container-xxl text-primary">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<div class="col-md-6 col-sm-12 ps-md-5 ps-xxl-0">
|
<div class="col-md-6 col-sm-12 ps-md-5 ps-xxl-0">
|
||||||
<h2>#{{ ticket.id }}</h2>
|
|
||||||
<h1 v-if="ticket.currentMotive">
|
<h1 v-if="ticket.currentMotive">
|
||||||
{{ ticket.currentMotive.label.fr }}
|
#{{ ticket.id }} {{ ticket.currentMotive.label.fr }}
|
||||||
</h1>
|
</h1>
|
||||||
<p class="chill-no-data-statement" v-else>
|
<p class="chill-no-data-statement" v-else>
|
||||||
{{ trans(CHILL_TICKET_TICKET_BANNER_NO_MOTIVE) }}
|
{{ trans(CHILL_TICKET_TICKET_BANNER_NO_MOTIVE) }}
|
||||||
</p>
|
</p>
|
||||||
|
<h2 v-if="ticket.currentPersons.length">
|
||||||
|
{{
|
||||||
|
ticket.currentPersons
|
||||||
|
.map((person) => person.text)
|
||||||
|
.join(", ")
|
||||||
|
}}
|
||||||
|
</h2>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<div class="col-md-6 col-sm-12">
|
<div class="col-md-6 col-sm-12">
|
||||||
<div class="d-flex justify-content-end">
|
<div class="d-flex justify-content-end">
|
||||||
|
<toggle-flags />
|
||||||
|
|
||||||
<span
|
<span
|
||||||
class="badge text-bg-chill-green text-white"
|
class="badge text-bg-chill-green text-white"
|
||||||
style="font-size: 1rem"
|
style="font-size: 1rem"
|
||||||
@ -45,7 +53,25 @@
|
|||||||
<Teleport to="#header-ticket-details">
|
<Teleport to="#header-ticket-details">
|
||||||
<div class="container-xxl">
|
<div class="container-xxl">
|
||||||
<div class="row justify-content-between">
|
<div class="row justify-content-between">
|
||||||
<div class="col-md-6 col-sm-12 ps-md-5 ps-xxl-0">
|
<div
|
||||||
|
class="col-md-4 col-sm-12 d-flex flex-column align-items-start"
|
||||||
|
>
|
||||||
|
<h3 class="text-primary">
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_BANNER_CALLER) }}
|
||||||
|
</h3>
|
||||||
|
<on-the-fly
|
||||||
|
v-if="ticket.caller"
|
||||||
|
:key="ticket.caller.id"
|
||||||
|
:type="ticket.caller.type"
|
||||||
|
:id="ticket.caller.id"
|
||||||
|
:buttonText="ticket.caller.textAge"
|
||||||
|
:displayBadge="'true' === 'true'"
|
||||||
|
action="show"
|
||||||
|
></on-the-fly>
|
||||||
|
</div>
|
||||||
|
<div
|
||||||
|
class="col-md-4 col-sm-12 d-flex flex-column align-items-start"
|
||||||
|
>
|
||||||
<h3 class="text-primary">
|
<h3 class="text-primary">
|
||||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER) }}
|
{{ trans(CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER) }}
|
||||||
</h3>
|
</h3>
|
||||||
@ -59,7 +85,9 @@
|
|||||||
action="show"
|
action="show"
|
||||||
></on-the-fly>
|
></on-the-fly>
|
||||||
</div>
|
</div>
|
||||||
<div class="col-md-6 col-sm-12">
|
<div
|
||||||
|
class="col-md-4 col-sm-12 d-flex flex-column align-items-start"
|
||||||
|
>
|
||||||
<h3 class="text-primary">
|
<h3 class="text-primary">
|
||||||
{{ trans(CHILL_TICKET_TICKET_BANNER_SPEAKER) }}
|
{{ trans(CHILL_TICKET_TICKET_BANNER_SPEAKER) }}
|
||||||
</h3>
|
</h3>
|
||||||
@ -84,6 +112,7 @@ import { ref, computed } from "vue";
|
|||||||
|
|
||||||
// Components
|
// Components
|
||||||
import AddresseeComponent from "./AddresseeComponent.vue";
|
import AddresseeComponent from "./AddresseeComponent.vue";
|
||||||
|
import ToggleFlags from "./ToggleFlags.vue";
|
||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
@ -104,6 +133,7 @@ import {
|
|||||||
CHILL_TICKET_TICKET_BANNER_MINUTES,
|
CHILL_TICKET_TICKET_BANNER_MINUTES,
|
||||||
CHILL_TICKET_TICKET_BANNER_SECONDS,
|
CHILL_TICKET_TICKET_BANNER_SECONDS,
|
||||||
CHILL_TICKET_TICKET_BANNER_AND,
|
CHILL_TICKET_TICKET_BANNER_AND,
|
||||||
|
CHILL_TICKET_TICKET_BANNER_CALLER,
|
||||||
} from "translator";
|
} from "translator";
|
||||||
|
|
||||||
// Store
|
// Store
|
||||||
|
@ -0,0 +1,85 @@
|
|||||||
|
<template>
|
||||||
|
<pick-entity
|
||||||
|
uniqid="ticket-person-selector"
|
||||||
|
:types="['person', 'third_party']"
|
||||||
|
:picked="selectedEntity ? [selectedEntity] : []"
|
||||||
|
:suggested="suggestedValues"
|
||||||
|
:multiple="false"
|
||||||
|
:removable-if-set="true"
|
||||||
|
:display-picked="true"
|
||||||
|
:label="trans(CHILL_TICKET_TICKET_SET_PERSONS_CALLER_LABEL)"
|
||||||
|
@add-new-entity="addNewEntity"
|
||||||
|
@remove-entity="removeEntity"
|
||||||
|
/>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { ref, watch, defineProps, defineEmits } from "vue";
|
||||||
|
|
||||||
|
// Components
|
||||||
|
import PickEntity from "ChillMainAssets/vuejs/PickEntity/PickEntity.vue";
|
||||||
|
|
||||||
|
// Types
|
||||||
|
import { Entities } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
|
// Translations
|
||||||
|
import {
|
||||||
|
trans,
|
||||||
|
CHILL_TICKET_TICKET_SET_PERSONS_CALLER_LABEL,
|
||||||
|
} from "translator";
|
||||||
|
|
||||||
|
const props = defineProps<{
|
||||||
|
modelValue: Entities | null;
|
||||||
|
suggested: Entities[];
|
||||||
|
}>();
|
||||||
|
const emit =
|
||||||
|
defineEmits<(event: "update:modelValue", value: Entities | null) => void>();
|
||||||
|
|
||||||
|
const selectedEntity = ref<Entities | null>(props.modelValue);
|
||||||
|
const suggestedValues = ref<Entities[]>([...props.suggested]);
|
||||||
|
|
||||||
|
watch(
|
||||||
|
() => [props.suggested, props.modelValue],
|
||||||
|
() => {
|
||||||
|
suggestedValues.value = props.suggested.filter(
|
||||||
|
(suggested: Entities) =>
|
||||||
|
suggested.id === selectedEntity.value?.id &&
|
||||||
|
suggested.type === selectedEntity.value?.type,
|
||||||
|
);
|
||||||
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
|
function addNewEntity({ entity }: { entity: Entities }) {
|
||||||
|
selectedEntity.value = entity;
|
||||||
|
emit("update:modelValue", selectedEntity.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
function removeEntity() {
|
||||||
|
selectedEntity.value = null;
|
||||||
|
emit("update:modelValue", null);
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
<style scoped lang="scss">
|
||||||
|
ul.person-list {
|
||||||
|
list-style-type: none;
|
||||||
|
|
||||||
|
& > li {
|
||||||
|
display: inline-block;
|
||||||
|
border: 1px solid transparent;
|
||||||
|
border-radius: 6px;
|
||||||
|
|
||||||
|
button.remove-person {
|
||||||
|
opacity: 10%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
& > li:hover {
|
||||||
|
border: 1px solid white;
|
||||||
|
|
||||||
|
button.remove-person {
|
||||||
|
opacity: 100%;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -1,135 +1,70 @@
|
|||||||
<template>
|
<template>
|
||||||
<div>
|
<pick-entity
|
||||||
<div style="display: flex; flex-direction: column; align-items: center">
|
uniqid="ticket-person-selector"
|
||||||
<add-persons
|
:types="['person']"
|
||||||
:options="addPersonsOptions"
|
:picked="selectedEntities"
|
||||||
key="add-person-selector"
|
|
||||||
:buttonTitle="trans(CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL)"
|
|
||||||
:modalTitle="trans(CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL)"
|
|
||||||
:selected="selectedValues"
|
|
||||||
:suggested="suggestedValues"
|
:suggested="suggestedValues"
|
||||||
@addNewPersons="addNewEntity"
|
:multiple="false"
|
||||||
|
:removable-if-set="true"
|
||||||
|
:display-picked="true"
|
||||||
|
:label="trans(CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL)"
|
||||||
|
@add-new-entity="addNewEntity"
|
||||||
|
@remove-entity="removeEntity"
|
||||||
/>
|
/>
|
||||||
<div class="p-2">
|
|
||||||
<ul class="list-suggest inline remove-items">
|
|
||||||
<li v-for="person in currentPersons" :key="person.id">
|
|
||||||
<span
|
|
||||||
:title="`${person.firstName} ${person.lastName}`"
|
|
||||||
@click="removePerson(person)"
|
|
||||||
>
|
|
||||||
{{ `${person.firstName} ${person.lastName}` }}
|
|
||||||
</span>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
<ul class="record_actions">
|
|
||||||
<li class="cancel">
|
|
||||||
<button
|
|
||||||
class="btn btn-cancel"
|
|
||||||
type="button"
|
|
||||||
@click="emit('closeRequested')"
|
|
||||||
>
|
|
||||||
{{ trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CANCEL) }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
<li>
|
|
||||||
<button class="btn btn-save" type="submit" @click.prevent="save">
|
|
||||||
{{ trans(CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_SAVE) }}
|
|
||||||
</button>
|
|
||||||
</li>
|
|
||||||
</ul>
|
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
import { computed, inject, reactive, ref } from "vue";
|
import { ref, watch, defineProps, defineEmits } from "vue";
|
||||||
import { useStore } from "vuex";
|
|
||||||
import { ToastPluginApi } from "vue-toast-notification";
|
|
||||||
|
|
||||||
// Components
|
// Components
|
||||||
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
import PickEntity from "ChillMainAssets/vuejs/PickEntity/PickEntity.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { SearchOptions, Suggestion, Person } from "ChillPersonAssets/types";
|
import { Entities } from "ChillPersonAssets/types";
|
||||||
import { Ticket } from "../../../types";
|
|
||||||
|
|
||||||
// Translations
|
// Translations
|
||||||
import {
|
import { trans, CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL } from "translator";
|
||||||
trans,
|
|
||||||
CHILL_TICKET_TICKET_SET_PERSONS_USER_LABEL,
|
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_CANCEL,
|
|
||||||
CHILL_TICKET_TICKET_ACTIONS_TOOLBAR_SAVE,
|
|
||||||
CHILL_TICKET_TICKET_SET_PERSONS_SUCCESS,
|
|
||||||
} from "translator";
|
|
||||||
|
|
||||||
const emit = defineEmits<(e: "closeRequested") => void>();
|
const props = defineProps<{
|
||||||
|
modelValue: Entities[];
|
||||||
|
suggested: Entities[];
|
||||||
|
}>();
|
||||||
|
const emit = defineEmits<{
|
||||||
|
"update:modelValue": [value: Entities[]];
|
||||||
|
}>();
|
||||||
|
|
||||||
const store = useStore();
|
const selectedEntities = ref<Entities[]>([...props.modelValue]);
|
||||||
const toast = inject("toast") as ToastPluginApi;
|
const suggestedValues = ref<Entities[]>([...props.suggested]);
|
||||||
const ticket = computed<Ticket>(() => store.getters.getTicket);
|
|
||||||
const persons = computed(() => ticket.value.currentPersons);
|
|
||||||
|
|
||||||
const addPersonsOptions = {
|
watch(
|
||||||
uniq: false,
|
() => [props.suggested, props.modelValue],
|
||||||
type: ["person"],
|
() => {
|
||||||
priority: null,
|
suggestedValues.value = props.suggested.filter(
|
||||||
button: {
|
(suggested: Entities) =>
|
||||||
size: "btn-sm",
|
!props.modelValue.some(
|
||||||
class: "btn-submit",
|
(selected: Entities) =>
|
||||||
},
|
suggested.id === selected.id &&
|
||||||
} as SearchOptions;
|
suggested.type === selected.type,
|
||||||
|
),
|
||||||
const selectedValues = ref<Suggestion[]>([]);
|
|
||||||
const suggestedValues = ref<Suggestion[]>([]);
|
|
||||||
|
|
||||||
const added: Person[] = reactive([]);
|
|
||||||
const removed: Person[] = reactive([]);
|
|
||||||
|
|
||||||
const computeCurrentPersons = (
|
|
||||||
initial: Person[],
|
|
||||||
added: Person[],
|
|
||||||
removed: Person[],
|
|
||||||
): Person[] => {
|
|
||||||
for (let p of added) {
|
|
||||||
if (initial.findIndex((element) => element.id === p.id) === -1) {
|
|
||||||
initial.push(p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return initial.filter(
|
|
||||||
(p) => removed.findIndex((element) => element.id === p.id) === -1,
|
|
||||||
);
|
);
|
||||||
};
|
},
|
||||||
|
{ immediate: true, deep: true },
|
||||||
|
);
|
||||||
|
|
||||||
const currentPersons = computed((): Person[] => {
|
function addNewEntity({ entity }: { entity: Entities }) {
|
||||||
return computeCurrentPersons(persons.value, added, removed);
|
selectedEntities.value.push(entity);
|
||||||
});
|
emit("update:modelValue", selectedEntities.value);
|
||||||
|
}
|
||||||
|
|
||||||
const removePerson = (p: Person) => {
|
function removeEntity({ entity }: { entity: Entities }) {
|
||||||
removed.push(p);
|
const index = selectedEntities.value.findIndex(
|
||||||
};
|
(selectedEntity) => selectedEntity === entity,
|
||||||
|
);
|
||||||
const addNewEntity = (n: { selected: { result: Person }[] }) => {
|
if (index !== -1) {
|
||||||
for (let p of n.selected) {
|
selectedEntities.value.splice(index, 1);
|
||||||
added.push(p.result);
|
|
||||||
}
|
}
|
||||||
selectedValues.value = [];
|
emit("update:modelValue", selectedEntities.value);
|
||||||
suggestedValues.value = [];
|
}
|
||||||
};
|
|
||||||
|
|
||||||
const save = async function (): Promise<void> {
|
|
||||||
try {
|
|
||||||
await store.dispatch("setPersons", {
|
|
||||||
persons: computeCurrentPersons(persons.value, added, removed),
|
|
||||||
});
|
|
||||||
toast.success(trans(CHILL_TICKET_TICKET_SET_PERSONS_SUCCESS));
|
|
||||||
} catch (error) {
|
|
||||||
toast.error((error as Error).message);
|
|
||||||
return Promise.resolve();
|
|
||||||
}
|
|
||||||
emit("closeRequested");
|
|
||||||
};
|
|
||||||
</script>
|
</script>
|
||||||
<style scoped lang="scss">
|
<style scoped lang="scss">
|
||||||
ul.person-list {
|
ul.person-list {
|
||||||
|
@ -0,0 +1,18 @@
|
|||||||
|
<template>
|
||||||
|
<div>
|
||||||
|
<span
|
||||||
|
class="badge rounded-pill me-1 mx-2"
|
||||||
|
:class="{
|
||||||
|
'bg-danger': new_emergency === 'yes',
|
||||||
|
'bg-secondary': new_emergency === 'no',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_BANNER_EMERGENCY) }}
|
||||||
|
</span>
|
||||||
|
</div>
|
||||||
|
</template>
|
||||||
|
<script setup lang="ts">
|
||||||
|
import { trans, CHILL_TICKET_TICKET_BANNER_EMERGENCY } from "translator";
|
||||||
|
|
||||||
|
defineProps<{ new_emergency: string }>();
|
||||||
|
</script>
|
@ -19,6 +19,10 @@
|
|||||||
: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'"
|
||||||
/>
|
/>
|
||||||
|
<TicketHistoryEmergencyComponent
|
||||||
|
v-if="history_line.event_type == 'emergency_change'"
|
||||||
|
:new_emergency="history_line.data.new_emergency"
|
||||||
|
/>
|
||||||
</div>
|
</div>
|
||||||
<div>
|
<div>
|
||||||
<span class="badge-user">
|
<span class="badge-user">
|
||||||
@ -34,12 +38,24 @@
|
|||||||
</div>
|
</div>
|
||||||
<div
|
<div
|
||||||
class="card-body row"
|
class="card-body row"
|
||||||
v-if="history_line.event_type != 'state_change'"
|
v-if="
|
||||||
|
!['state_change', 'emergency_change'].includes(
|
||||||
|
history_line.event_type,
|
||||||
|
)
|
||||||
|
"
|
||||||
>
|
>
|
||||||
<ticket-history-person-component
|
<ticket-history-person-component
|
||||||
:personHistory="history_line.data"
|
:persons="history_line.data.persons"
|
||||||
v-if="history_line.event_type == 'persons_state'"
|
v-if="history_line.event_type == 'persons_state'"
|
||||||
/>
|
/>
|
||||||
|
<ticket-history-person-component
|
||||||
|
:persons="
|
||||||
|
history_line.data.new_caller
|
||||||
|
? [history_line.data.new_caller]
|
||||||
|
: []
|
||||||
|
"
|
||||||
|
v-if="history_line.event_type == 'set_caller'"
|
||||||
|
/>
|
||||||
<ticket-history-motive-component
|
<ticket-history-motive-component
|
||||||
:motiveHistory="history_line.data"
|
:motiveHistory="history_line.data"
|
||||||
v-else-if="history_line.event_type == 'set_motive'"
|
v-else-if="history_line.event_type == 'set_motive'"
|
||||||
@ -74,11 +90,25 @@ import TicketHistoryCommentComponent from "./TicketHistoryCommentComponent.vue";
|
|||||||
import TicketHistoryAddresseeComponent from "./TicketHistoryAddresseeComponent.vue";
|
import TicketHistoryAddresseeComponent from "./TicketHistoryAddresseeComponent.vue";
|
||||||
import TicketHistoryCreateComponent from "./TicketHistoryCreateComponent.vue";
|
import TicketHistoryCreateComponent from "./TicketHistoryCreateComponent.vue";
|
||||||
import TicketHistoryStateComponent from "./TicketHistoryStateComponent.vue";
|
import TicketHistoryStateComponent from "./TicketHistoryStateComponent.vue";
|
||||||
|
import TicketHistoryEmergencyComponent from "./TicketHistoryEmergencyComponent.vue";
|
||||||
|
|
||||||
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
|
||||||
|
|
||||||
// Utils
|
// Utils
|
||||||
import { ISOToDatetime } from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
import { ISOToDatetime } from "../../../../../../../ChillMainBundle/Resources/public/chill/js/date";
|
||||||
|
|
||||||
|
// Translations
|
||||||
|
import {
|
||||||
|
trans,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_SET_MOTIVE,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_CREATE_TICKET,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE,
|
||||||
|
CHILL_TICKET_TICKET_HISTORY_SET_CALLER,
|
||||||
|
} from "translator";
|
||||||
defineProps<{ history: TicketHistoryLine[] }>();
|
defineProps<{ history: TicketHistoryLine[] }>();
|
||||||
|
|
||||||
const store = useStore();
|
const store = useStore();
|
||||||
@ -88,17 +118,21 @@ const actionIcons = ref(store.getters.getActionIcons);
|
|||||||
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 "Nouveau commentaire";
|
return trans(CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT);
|
||||||
case "addressees_state":
|
case "addressees_state":
|
||||||
return "Attributions";
|
return trans(CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE);
|
||||||
case "persons_state":
|
case "persons_state":
|
||||||
return "Usagés concernés";
|
return trans(CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE);
|
||||||
case "set_motive":
|
case "set_motive":
|
||||||
return "Nouveau motifs";
|
return trans(CHILL_TICKET_TICKET_HISTORY_SET_MOTIVE);
|
||||||
case "create_ticket":
|
case "create_ticket":
|
||||||
return "Ticket créé";
|
return trans(CHILL_TICKET_TICKET_HISTORY_CREATE_TICKET);
|
||||||
case "state_change":
|
case "state_change":
|
||||||
return "Status du ticket modifié";
|
return trans(CHILL_TICKET_TICKET_HISTORY_STATE_CHANGE);
|
||||||
|
case "emergency_change":
|
||||||
|
return trans(CHILL_TICKET_TICKET_HISTORY_EMERGENCY_CHANGE);
|
||||||
|
case "set_caller":
|
||||||
|
return trans(CHILL_TICKET_TICKET_HISTORY_SET_CALLER);
|
||||||
default:
|
default:
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<template>
|
<template>
|
||||||
<div class="col-12">
|
<div class="col-12">
|
||||||
<ul class="persons-list">
|
<ul class="persons-list" v-if="persons.length > 0">
|
||||||
<li v-for="person in personHistory.persons" :key="person.id">
|
<li v-for="person in persons" :key="person.id">
|
||||||
<on-the-fly
|
<on-the-fly
|
||||||
:type="person.type"
|
:type="person.type"
|
||||||
:id="person.id"
|
:id="person.id"
|
||||||
@ -11,6 +11,7 @@
|
|||||||
></on-the-fly>
|
></on-the-fly>
|
||||||
</li>
|
</li>
|
||||||
</ul>
|
</ul>
|
||||||
|
<div v-else class="text-muted">Aucune personne concernée</div>
|
||||||
</div>
|
</div>
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
@ -18,9 +19,9 @@
|
|||||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||||
|
|
||||||
// Types
|
// Types
|
||||||
import { PersonsState } from "../../../types";
|
import { Person } from "ChillPersonAssets/types";
|
||||||
|
|
||||||
defineProps<{ personHistory: PersonsState }>();
|
defineProps<{ persons: Person[] }>();
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<style lang="scss" scoped>
|
<style lang="scss" scoped>
|
||||||
|
@ -1,4 +1,19 @@
|
|||||||
<template>
|
<template>
|
||||||
|
<span
|
||||||
|
class="badge rounded-pill me-1 mx-2"
|
||||||
|
:class="{
|
||||||
|
'bg-chill-red': props.new_state == 'closed',
|
||||||
|
'bg-chill-green': props.new_state == 'open',
|
||||||
|
}"
|
||||||
|
>
|
||||||
|
<template v-if="props.new_state == 'open'">
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_BANNER_OPEN) }}
|
||||||
|
</template>
|
||||||
|
<template v-else-if="props.new_state == 'closed'">
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }}
|
||||||
|
</template>
|
||||||
|
</span>
|
||||||
|
<!--
|
||||||
<span
|
<span
|
||||||
class="text-chill-green mx-2"
|
class="text-chill-green mx-2"
|
||||||
style="
|
style="
|
||||||
@ -22,7 +37,7 @@
|
|||||||
v-else-if="props.new_state == 'closed'"
|
v-else-if="props.new_state == 'closed'"
|
||||||
>
|
>
|
||||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }}
|
{{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }}
|
||||||
</span>
|
</span> -->
|
||||||
</template>
|
</template>
|
||||||
|
|
||||||
<script setup lang="ts">
|
<script setup lang="ts">
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
<template>
|
||||||
|
<span class="d-block d-sm-inline-block ms-sm-3 ms-md-0">
|
||||||
|
<button
|
||||||
|
class="badge rounded-pill me-1"
|
||||||
|
:class="{
|
||||||
|
'bg-danger': isEmergency,
|
||||||
|
'bg-secondary': !isEmergency,
|
||||||
|
}"
|
||||||
|
@click="toggleEmergency"
|
||||||
|
>
|
||||||
|
{{ trans(CHILL_TICKET_TICKET_BANNER_EMERGENCY) }}
|
||||||
|
</button>
|
||||||
|
</span>
|
||||||
|
</template>
|
||||||
|
|
||||||
|
<script lang="ts" setup>
|
||||||
|
import { computed } from "vue";
|
||||||
|
import { useStore } from "vuex";
|
||||||
|
import { useToast } from "vue-toast-notification";
|
||||||
|
import { trans, CHILL_TICKET_TICKET_BANNER_EMERGENCY } from "translator";
|
||||||
|
|
||||||
|
const store = useStore();
|
||||||
|
const toast = useToast();
|
||||||
|
|
||||||
|
const isEmergency = computed(() => store.getters.isEmergency);
|
||||||
|
|
||||||
|
// Methods
|
||||||
|
function toggleEmergency() {
|
||||||
|
store
|
||||||
|
.dispatch("toggleEmergency", isEmergency.value ? "no" : "yes")
|
||||||
|
.catch(({ name, violations }) => {
|
||||||
|
if (name === "ValidationException" || name === "AccessException") {
|
||||||
|
violations.forEach((violation: string) =>
|
||||||
|
toast.open({ message: violation }),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
toast.open({ message: "An error occurred" });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
</script>
|
||||||
|
|
||||||
|
<style lang="scss" scoped>
|
||||||
|
a.flag-toggle {
|
||||||
|
color: white;
|
||||||
|
cursor: pointer;
|
||||||
|
&:hover {
|
||||||
|
color: white;
|
||||||
|
text-decoration: underline;
|
||||||
|
border-radius: 20px;
|
||||||
|
}
|
||||||
|
i {
|
||||||
|
margin: auto 0.4em;
|
||||||
|
}
|
||||||
|
span.on {
|
||||||
|
font-weight: bolder;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
button.badge {
|
||||||
|
&.bg-secondary {
|
||||||
|
opacity: 0.5;
|
||||||
|
&:hover {
|
||||||
|
opacity: 0.7;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
</style>
|
@ -7,6 +7,7 @@ import { Module } from "vuex";
|
|||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
|
|
||||||
import {
|
import {
|
||||||
|
ApiException,
|
||||||
User,
|
User,
|
||||||
UserGroup,
|
UserGroup,
|
||||||
UserGroupOrUser,
|
UserGroupOrUser,
|
||||||
@ -46,8 +47,9 @@ export const moduleAddressee: Module<State, RootState> = {
|
|||||||
commit("setUserGroups", results);
|
commit("setUserGroups", results);
|
||||||
},
|
},
|
||||||
);
|
);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
fetchUsers({ commit }) {
|
fetchUsers({ commit }) {
|
||||||
@ -55,8 +57,9 @@ export const moduleAddressee: Module<State, RootState> = {
|
|||||||
fetchResults("/api/1.0/main/user.json").then((results) => {
|
fetchResults("/api/1.0/main/user.json").then((results) => {
|
||||||
commit("setUsers", results);
|
commit("setUsers", results);
|
||||||
});
|
});
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -76,8 +79,9 @@ export const moduleAddressee: Module<State, RootState> = {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
commit("setTicket", result);
|
commit("setTicket", result);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,10 @@
|
|||||||
import {
|
import { makeFetch } from "../../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
fetchResults,
|
|
||||||
makeFetch,
|
|
||||||
} from "../../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
|
||||||
|
|
||||||
import { Module } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
|
|
||||||
import { Comment } from "../../../../types";
|
import { Comment } from "../../../../types";
|
||||||
|
import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
comments: Comment[];
|
comments: Comment[];
|
||||||
@ -31,8 +29,9 @@ export const moduleComment: Module<State, RootState> = {
|
|||||||
{ content },
|
{ content },
|
||||||
);
|
);
|
||||||
commit("setTicket", result);
|
commit("setTicket", result);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@ import { Module } from "vuex";
|
|||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
|
|
||||||
import { Motive } from "../../../../types";
|
import { Motive } from "../../../../types";
|
||||||
|
import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
motives: Motive[];
|
motives: Motive[];
|
||||||
@ -33,8 +34,9 @@ export const moduleMotive: Module<State, RootState> = {
|
|||||||
"/api/1.0/ticket/motive.json",
|
"/api/1.0/ticket/motive.json",
|
||||||
)) as Motive[];
|
)) as Motive[];
|
||||||
commit("setMotives", results);
|
commit("setMotives", results);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
@ -55,8 +57,9 @@ export const moduleMotive: Module<State, RootState> = {
|
|||||||
},
|
},
|
||||||
);
|
);
|
||||||
commit("setTicket", result);
|
commit("setTicket", result);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,12 +1,28 @@
|
|||||||
import { makeFetch } from "../../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
import { makeFetch } from "../../../../../../../../ChillMainBundle/Resources/public/lib/api/apiMethods";
|
||||||
import { Person } from "../../../../../../../../ChillPersonBundle/Resources/public/types";
|
import { Person } from "../../../../../../../../ChillPersonBundle/Resources/public/types";
|
||||||
|
import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
import { Module } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
import { Ticket } from "../../../../types";
|
import { Ticket } from "../../../../types";
|
||||||
|
|
||||||
export interface State {}
|
export interface State {
|
||||||
|
persons: Person[];
|
||||||
|
}
|
||||||
|
|
||||||
export const modulePersons: Module<State, RootState> = {
|
export const modulePersons: Module<State, RootState> = {
|
||||||
|
state: () => ({
|
||||||
|
persons: [] as Person[],
|
||||||
|
}),
|
||||||
|
getters: {
|
||||||
|
getPersons(state) {
|
||||||
|
return state.persons;
|
||||||
|
},
|
||||||
|
},
|
||||||
|
mutations: {
|
||||||
|
setPersons(state, persons: Person[]) {
|
||||||
|
state.persons = persons;
|
||||||
|
},
|
||||||
|
},
|
||||||
actions: {
|
actions: {
|
||||||
async setPersons(
|
async setPersons(
|
||||||
{ commit, rootState: RootState },
|
{ commit, rootState: RootState },
|
||||||
@ -25,8 +41,45 @@ export const modulePersons: Module<State, RootState> = {
|
|||||||
commit("setTicket", result);
|
commit("setTicket", result);
|
||||||
|
|
||||||
return Promise.resolve();
|
return Promise.resolve();
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async setCaller(
|
||||||
|
{ commit, rootState: RootState },
|
||||||
|
payload: { caller: Person | null },
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const caller = payload.caller
|
||||||
|
? {
|
||||||
|
id: payload.caller.id,
|
||||||
|
type: payload.caller.type,
|
||||||
|
}
|
||||||
|
: null;
|
||||||
|
const result: Ticket = await makeFetch(
|
||||||
|
"POST",
|
||||||
|
`/api/1.0/ticket/ticket/${RootState.ticket.ticket.id}/set-caller`,
|
||||||
|
{ caller },
|
||||||
|
);
|
||||||
|
commit("setTicket", result as Ticket);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
async getSuggestedPersons({ commit, rootState: RootState }) {
|
||||||
|
try {
|
||||||
|
const ticketId = RootState.ticket.ticket.id;
|
||||||
|
const result: Person[] = await makeFetch(
|
||||||
|
"GET",
|
||||||
|
`/api/1.0/ticket/ticket/${ticketId}/suggest-person`,
|
||||||
|
);
|
||||||
|
commit("setPersons", result);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -1,8 +1,9 @@
|
|||||||
import { Module } from "vuex";
|
import { Module } from "vuex";
|
||||||
import { RootState } from "..";
|
import { RootState } from "..";
|
||||||
|
|
||||||
import { Ticket } from "../../../../types";
|
import { Ticket, TicketEmergencyState } from "../../../../types";
|
||||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||||
|
import { ApiException } from "../../../../../../../../ChillMainBundle/Resources/public/types";
|
||||||
|
|
||||||
export interface State {
|
export interface State {
|
||||||
ticket: Ticket;
|
ticket: Ticket;
|
||||||
@ -13,18 +14,23 @@ export const moduleTicket: Module<State, RootState> = {
|
|||||||
state: () => ({
|
state: () => ({
|
||||||
ticket: {} as Ticket,
|
ticket: {} as Ticket,
|
||||||
action_icons: {
|
action_icons: {
|
||||||
add_person: "fa fa-eyedropper",
|
add_person: "fa fa-user-plus",
|
||||||
add_comment: "fa fa-comment",
|
add_comment: "fa fa-comment",
|
||||||
set_motive: "fa fa-paint-brush",
|
set_motive: "fa fa-paint-brush",
|
||||||
addressees_state: "fa fa-paper-plane",
|
addressees_state: "fa fa-paper-plane",
|
||||||
persons_state: "fa fa-eyedropper",
|
persons_state: "fa fa-user",
|
||||||
state_change: "fa fa-bolt",
|
set_caller: "fa fa-phone",
|
||||||
|
state_change: "",
|
||||||
|
emergency_change: "",
|
||||||
},
|
},
|
||||||
}),
|
}),
|
||||||
getters: {
|
getters: {
|
||||||
isOpen(state) {
|
isOpen(state) {
|
||||||
return state.ticket.currentState === "open";
|
return state.ticket.currentState === "open";
|
||||||
},
|
},
|
||||||
|
isEmergency(state) {
|
||||||
|
return state.ticket.emergency == "yes" ? true : false;
|
||||||
|
},
|
||||||
getTicket(state) {
|
getTicket(state) {
|
||||||
state.ticket.history = state.ticket.history.sort((a, b) =>
|
state.ticket.history = state.ticket.history.sort((a, b) =>
|
||||||
b.at.datetime.localeCompare(a.at.datetime),
|
b.at.datetime.localeCompare(a.at.datetime),
|
||||||
@ -52,8 +58,9 @@ export const moduleTicket: Module<State, RootState> = {
|
|||||||
`/api/1.0/ticket/ticket/${state.ticket.id}/close`,
|
`/api/1.0/ticket/ticket/${state.ticket.id}/close`,
|
||||||
);
|
);
|
||||||
commit("setTicket", result as Ticket);
|
commit("setTicket", result as Ticket);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
async reopenTicket({ commit, state }) {
|
async reopenTicket({ commit, state }) {
|
||||||
@ -63,8 +70,24 @@ export const moduleTicket: Module<State, RootState> = {
|
|||||||
`/api/1.0/ticket/ticket/${state.ticket.id}/open`,
|
`/api/1.0/ticket/ticket/${state.ticket.id}/open`,
|
||||||
);
|
);
|
||||||
commit("setTicket", result as Ticket);
|
commit("setTicket", result as Ticket);
|
||||||
} catch (e: any) {
|
} catch (e: unknown) {
|
||||||
throw e.name;
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
|
}
|
||||||
|
},
|
||||||
|
async toggleEmergency(
|
||||||
|
{ commit, state },
|
||||||
|
emergency: TicketEmergencyState,
|
||||||
|
) {
|
||||||
|
try {
|
||||||
|
const result: Ticket = await makeFetch(
|
||||||
|
"POST",
|
||||||
|
`/api/1.0/ticket/ticket/${state.ticket.id}/emergency/${emergency}`,
|
||||||
|
);
|
||||||
|
commit("setTicket", result as Ticket);
|
||||||
|
} catch (e: unknown) {
|
||||||
|
const error = e as ApiException;
|
||||||
|
throw error.name;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -6,6 +6,15 @@ chill_ticket:
|
|||||||
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
|
||||||
ticket:
|
ticket:
|
||||||
|
history:
|
||||||
|
add_comment: "Nouveau commentaire"
|
||||||
|
addressees_state: "Attributions"
|
||||||
|
persons_state: "Usagé(s) concerné(s)"
|
||||||
|
set_caller: "Appelant Concerné"
|
||||||
|
set_motive: "Nouveau motifs"
|
||||||
|
create_ticket: "Ticket créé"
|
||||||
|
state_change: ""
|
||||||
|
emergency_change: ""
|
||||||
previous_tickets: "Précédents tickets"
|
previous_tickets: "Précédents tickets"
|
||||||
actions_toolbar:
|
actions_toolbar:
|
||||||
cancel: "Annuler"
|
cancel: "Annuler"
|
||||||
@ -34,13 +43,17 @@ chill_ticket:
|
|||||||
success: "Attribution effectuée"
|
success: "Attribution effectuée"
|
||||||
error: "Aucun destinataire sélectionné"
|
error: "Aucun destinataire sélectionné"
|
||||||
set_persons:
|
set_persons:
|
||||||
title: "Usagers concernés"
|
title: "Appelant et usager(s)"
|
||||||
|
title_person: "Usager(s)"
|
||||||
|
title_caller: "Appelant"
|
||||||
user_label: "Ajouter un usager"
|
user_label: "Ajouter un usager"
|
||||||
success: "Usager ajouté"
|
caller_label: "Ajouter un appelant"
|
||||||
|
success: "Appelants et usagers mis à jour"
|
||||||
error: "Aucun usager sélectionné"
|
error: "Aucun usager sélectionné"
|
||||||
banner:
|
banner:
|
||||||
concerned_usager: "Usagers concernés"
|
concerned_usager: "Usagers concernés"
|
||||||
speaker: "Attribué à"
|
speaker: "Attribué à"
|
||||||
|
caller: "Appelant"
|
||||||
open: "Ouvert"
|
open: "Ouvert"
|
||||||
closed: "Fermé"
|
closed: "Fermé"
|
||||||
since: "Depuis {time}"
|
since: "Depuis {time}"
|
||||||
@ -70,3 +83,4 @@ chill_ticket:
|
|||||||
other {# secondes}
|
other {# secondes}
|
||||||
}
|
}
|
||||||
no_motive: "Pas de motif"
|
no_motive: "Pas de motif"
|
||||||
|
emergency: "URGENT"
|
||||||
|
Loading…
x
Reference in New Issue
Block a user