mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-09-28 01:25:00 +00:00
Refactor third-party type imports and update related components
- Changed import path for ThirdParty type in TypeThirdParty.vue and updated its usage. - Refactored PersonText.vue to import Person and AltName types from ChillPersonAssets. - Updated types.ts in ChillThirdPartyBundle to include a new 'type' field in the Thirdparty interface. - Modified TicketBundle types to accommodate Thirdparty type in CallerState. - Adjusted AddresseeSelectorComponent.vue to use 'thirdparty' instead of 'third_party'. - Refined BannerComponent.vue to improve readability and maintainability. - Updated CallerSelectorComponent.vue to reflect changes in entity types. - Enhanced TicketHistoryListComponent.vue to handle both Person and Thirdparty types. - Refactored TicketHistoryPersonComponent.vue to accept both Person and Thirdparty entities.
This commit is contained in:
@@ -1,17 +1,17 @@
|
||||
import {
|
||||
DateTime,
|
||||
TranslatableString,
|
||||
User,
|
||||
UserGroupOrUser,
|
||||
DateTime,
|
||||
TranslatableString,
|
||||
User,
|
||||
UserGroupOrUser,
|
||||
} from "ChillMainAssets/types";
|
||||
import { Person } from "ChillPersonAssets/types";
|
||||
import {Thirdparty} from "../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
import { Thirdparty } from "../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
export interface Motive {
|
||||
type: "ticket_motive";
|
||||
id: number;
|
||||
active: boolean;
|
||||
label: TranslatableString;
|
||||
type: "ticket_motive";
|
||||
id: number;
|
||||
active: boolean;
|
||||
label: TranslatableString;
|
||||
}
|
||||
|
||||
export type TicketState = "open" | "closed";
|
||||
@@ -19,134 +19,135 @@ export type TicketState = "open" | "closed";
|
||||
export type TicketEmergencyState = "yes" | "no";
|
||||
|
||||
interface TicketHistory<T extends string, D extends object> {
|
||||
event_type: T;
|
||||
at: DateTime;
|
||||
by: User;
|
||||
data: D;
|
||||
event_type: T;
|
||||
at: DateTime;
|
||||
by: User;
|
||||
data: D;
|
||||
}
|
||||
|
||||
export interface PersonHistory {
|
||||
type: "ticket_person_history";
|
||||
id: number;
|
||||
startDate: DateTime;
|
||||
endDate: null | DateTime;
|
||||
person: Person;
|
||||
removedBy: null;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
type: "ticket_person_history";
|
||||
id: number;
|
||||
startDate: DateTime;
|
||||
endDate: null | DateTime;
|
||||
person: Person;
|
||||
removedBy: null;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
}
|
||||
|
||||
export interface MotiveHistory {
|
||||
type: "ticket_motive_history";
|
||||
id: number;
|
||||
startDate: null;
|
||||
endDate: null | DateTime;
|
||||
motive: Motive;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
type: "ticket_motive_history";
|
||||
id: number;
|
||||
startDate: null;
|
||||
endDate: null | DateTime;
|
||||
motive: Motive;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
}
|
||||
|
||||
export interface Comment {
|
||||
type: "ticket_comment";
|
||||
id: number;
|
||||
content: string;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
type: "ticket_comment";
|
||||
id: number;
|
||||
content: string;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
}
|
||||
|
||||
export interface AddresseeHistory {
|
||||
type: "ticket_addressee_history";
|
||||
id: number;
|
||||
startDate: DateTime | null;
|
||||
addressee: UserGroupOrUser;
|
||||
endDate: DateTime | null;
|
||||
removedBy: User | null;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
type: "ticket_addressee_history";
|
||||
id: number;
|
||||
startDate: DateTime | null;
|
||||
addressee: UserGroupOrUser;
|
||||
endDate: DateTime | null;
|
||||
removedBy: User | null;
|
||||
createdBy: User | null;
|
||||
createdAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
}
|
||||
|
||||
export interface AddresseeState {
|
||||
addressees: UserGroupOrUser[];
|
||||
addressees: UserGroupOrUser[];
|
||||
}
|
||||
|
||||
export interface PersonsState {
|
||||
persons: Person[];
|
||||
persons: Person[];
|
||||
}
|
||||
export interface CallerState {
|
||||
new_caller: Person | null;
|
||||
new_caller: Person | Thirdparty | null;
|
||||
}
|
||||
|
||||
export interface StateChange {
|
||||
new_state: TicketState;
|
||||
new_state: TicketState;
|
||||
}
|
||||
|
||||
export interface EmergencyChange {
|
||||
new_emergency: TicketEmergencyState;
|
||||
new_emergency: TicketEmergencyState;
|
||||
}
|
||||
|
||||
export interface CreateTicketState {
|
||||
by: User;
|
||||
by: User;
|
||||
}
|
||||
|
||||
export type AddCommentEvent = TicketHistory<"add_comment", Comment>;
|
||||
export type SetMotiveEvent = TicketHistory<"set_motive", MotiveHistory>;
|
||||
export type AddPersonEvent = TicketHistory<"add_person", PersonHistory>;
|
||||
export type AddresseesStateEvent = TicketHistory<
|
||||
"addressees_state",
|
||||
AddresseeState
|
||||
"addressees_state",
|
||||
AddresseeState
|
||||
>;
|
||||
export type CreateTicketEvent = TicketHistory<
|
||||
"create_ticket",
|
||||
CreateTicketState
|
||||
"create_ticket",
|
||||
CreateTicketState
|
||||
>;
|
||||
export type PersonStateEvent = TicketHistory<"persons_state", PersonsState>;
|
||||
export type ChangeStateEvent = TicketHistory<"state_change", StateChange>;
|
||||
export type EmergencyStateEvent = TicketHistory<
|
||||
"emergency_change",
|
||||
EmergencyChange
|
||||
"emergency_change",
|
||||
EmergencyChange
|
||||
>;
|
||||
export type CallerStateEvent = TicketHistory<"set_caller", CallerState>;
|
||||
|
||||
export type TicketHistoryLine =
|
||||
| AddPersonEvent
|
||||
| CreateTicketEvent
|
||||
| AddCommentEvent
|
||||
| SetMotiveEvent
|
||||
| AddresseesStateEvent
|
||||
| PersonStateEvent
|
||||
| ChangeStateEvent
|
||||
| EmergencyStateEvent
|
||||
| CallerStateEvent;
|
||||
| AddPersonEvent
|
||||
| CreateTicketEvent
|
||||
| AddCommentEvent
|
||||
| SetMotiveEvent
|
||||
| AddresseesStateEvent
|
||||
| PersonStateEvent
|
||||
| ChangeStateEvent
|
||||
| EmergencyStateEvent
|
||||
| CallerStateEvent;
|
||||
|
||||
interface BaseTicket<T extends "ticket_ticket:simple"|"ticket_ticket:extended" = "ticket_ticket:simple"> {
|
||||
type_extended: T;
|
||||
type: "ticket_ticket";
|
||||
id: number;
|
||||
externalRef: string;
|
||||
currentAddressees: UserGroupOrUser[];
|
||||
currentPersons: Person[];
|
||||
currentMotive: null | Motive;
|
||||
currentState: TicketState | null;
|
||||
emergency: TicketEmergencyState | null;
|
||||
caller: Person | Thirdparty | null;
|
||||
}
|
||||
|
||||
export interface SimpleTicket extends BaseTicket<"ticket_ticket:simple"> {
|
||||
interface BaseTicket<
|
||||
T extends
|
||||
| "ticket_ticket:simple"
|
||||
| "ticket_ticket:extended" = "ticket_ticket:simple",
|
||||
> {
|
||||
type_extended: T;
|
||||
type: "ticket_ticket";
|
||||
id: number;
|
||||
externalRef: string;
|
||||
currentAddressees: UserGroupOrUser[];
|
||||
currentPersons: Person[];
|
||||
currentMotive: null | Motive;
|
||||
currentState: TicketState | null;
|
||||
emergency: TicketEmergencyState | null;
|
||||
caller: Person | Thirdparty | null;
|
||||
}
|
||||
|
||||
export interface TicketSimple extends BaseTicket<"ticket_ticket:simple"> {
|
||||
type_extended: "ticket_ticket:simple";
|
||||
type_extended: "ticket_ticket:simple";
|
||||
}
|
||||
|
||||
export interface Ticket extends BaseTicket<"ticket_ticket:extended"> {
|
||||
type_extended: "ticket_ticket:extended";
|
||||
createdAt: DateTime | null;
|
||||
createdBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
history: TicketHistoryLine[];
|
||||
type_extended: "ticket_ticket:extended";
|
||||
createdAt: DateTime | null;
|
||||
createdBy: User | null;
|
||||
updatedAt: DateTime | null;
|
||||
updatedBy: User | null;
|
||||
history: TicketHistoryLine[];
|
||||
}
|
||||
|
@@ -1,20 +1,20 @@
|
||||
<template>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<pick-entity
|
||||
uniqid="ticket-addressee-selector"
|
||||
:types="['user', 'user_group', 'third_party']"
|
||||
:picked="selectedEntities"
|
||||
:suggested="suggestedValues"
|
||||
: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>
|
||||
<div class="row">
|
||||
<div class="col-12">
|
||||
<pick-entity
|
||||
uniqid="ticket-addressee-selector"
|
||||
:types="['user', 'user_group', 'thirdparty']"
|
||||
:picked="selectedEntities"
|
||||
:suggested="suggestedValues"
|
||||
: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>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script lang="ts" setup>
|
||||
@@ -28,13 +28,13 @@ import { Entities } from "ChillPersonAssets/types";
|
||||
|
||||
// Translations
|
||||
import {
|
||||
CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL,
|
||||
trans,
|
||||
CHILL_TICKET_TICKET_ADD_ADDRESSEE_USER_LABEL,
|
||||
trans,
|
||||
} from "translator";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: Entities[];
|
||||
suggested: Entities[];
|
||||
modelValue: Entities[];
|
||||
suggested: Entities[];
|
||||
}>();
|
||||
|
||||
const emit = defineEmits<(e: "update:modelValue", value: Entities[]) => void>();
|
||||
@@ -42,53 +42,46 @@ const emit = defineEmits<(e: "update:modelValue", value: Entities[]) => void>();
|
||||
const selectedEntities = ref<Entities[]>([...props.modelValue]);
|
||||
const suggestedValues = ref<Entities[]>([...props.suggested]);
|
||||
watch(
|
||||
() => [props.suggested, props.modelValue],
|
||||
() => {
|
||||
const modelValue = props.modelValue ?? [];
|
||||
() => [props.suggested, props.modelValue],
|
||||
() => {
|
||||
const modelValue = props.modelValue ?? [];
|
||||
|
||||
suggestedValues.value = props.suggested.filter(
|
||||
(suggested: Entities) => {
|
||||
return !modelValue.some((selected: Entities) => {
|
||||
if (
|
||||
suggested.type == "user_group" &&
|
||||
selected.type == "user_group"
|
||||
) {
|
||||
switch (selected.excludeKey) {
|
||||
case "level":
|
||||
return suggested.excludeKey === "level";
|
||||
case "":
|
||||
return (
|
||||
suggested.excludeKey === "" &&
|
||||
suggested.id === selected.id
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
suggested.type === selected.type &&
|
||||
suggested.id === selected.id
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
);
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
suggestedValues.value = props.suggested.filter((suggested: Entities) => {
|
||||
return !modelValue.some((selected: Entities) => {
|
||||
if (suggested.type == "user_group" && selected.type == "user_group") {
|
||||
switch (selected.excludeKey) {
|
||||
case "level":
|
||||
return suggested.excludeKey === "level";
|
||||
case "":
|
||||
return (
|
||||
suggested.excludeKey === "" && suggested.id === selected.id
|
||||
);
|
||||
default:
|
||||
return false;
|
||||
}
|
||||
} else {
|
||||
return (
|
||||
suggested.type === selected.type && suggested.id === selected.id
|
||||
);
|
||||
}
|
||||
});
|
||||
});
|
||||
},
|
||||
{ immediate: true, deep: true },
|
||||
);
|
||||
|
||||
function addNewEntity({ entity }: { entity: Entities }) {
|
||||
selectedEntities.value.push(entity);
|
||||
emit("update:modelValue", selectedEntities.value);
|
||||
selectedEntities.value.push(entity);
|
||||
emit("update:modelValue", selectedEntities.value);
|
||||
}
|
||||
|
||||
function removeEntity({ entity }: { entity: Entities }) {
|
||||
const index = selectedEntities.value.findIndex(
|
||||
(selectedEntity) => selectedEntity === entity,
|
||||
);
|
||||
if (index !== -1) {
|
||||
selectedEntities.value.splice(index, 1);
|
||||
}
|
||||
emit("update:modelValue", selectedEntities.value);
|
||||
const index = selectedEntities.value.findIndex(
|
||||
(selectedEntity) => selectedEntity === entity,
|
||||
);
|
||||
if (index !== -1) {
|
||||
selectedEntities.value.splice(index, 1);
|
||||
}
|
||||
emit("update:modelValue", selectedEntities.value);
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,109 +1,97 @@
|
||||
<template>
|
||||
<Teleport to="#header-ticket-main">
|
||||
<div class="container-xxl text-primary">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-sm-12 ps-md-5 ps-xxl-0">
|
||||
<h1 v-if="ticket.currentMotive">
|
||||
#{{ ticket.id }} {{ ticket.currentMotive.label.fr }}
|
||||
</h1>
|
||||
<p class="chill-no-data-statement" v-else>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_NO_MOTIVE) }}
|
||||
</p>
|
||||
<h2 v-if="ticket.currentPersons.length">
|
||||
{{
|
||||
ticket.currentPersons
|
||||
.map((person) => person.text)
|
||||
.join(", ")
|
||||
}}
|
||||
</h2>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<div class="d-flex justify-content-end">
|
||||
<toggle-flags />
|
||||
|
||||
<span
|
||||
class="badge text-bg-chill-green text-white"
|
||||
style="font-size: 1rem"
|
||||
v-if="isOpen"
|
||||
>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_OPEN) }}
|
||||
</span>
|
||||
<span
|
||||
class="badge text-bg-chill-red text-white"
|
||||
style="font-size: 1rem"
|
||||
v-else
|
||||
>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<p class="created-at-timespan" v-if="ticket.createdAt">
|
||||
{{
|
||||
trans(CHILL_TICKET_TICKET_BANNER_SINCE, {
|
||||
time: since,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<Teleport to="#header-ticket-main">
|
||||
<div class="container-xxl text-primary">
|
||||
<div class="row">
|
||||
<div class="col-md-6 col-sm-12 ps-md-5 ps-xxl-0">
|
||||
<h1 v-if="ticket.currentMotive">
|
||||
#{{ ticket.id }} {{ ticket.currentMotive.label.fr }}
|
||||
</h1>
|
||||
<p class="chill-no-data-statement" v-else>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_NO_MOTIVE) }}
|
||||
</p>
|
||||
<h2 v-if="ticket.currentPersons.length">
|
||||
{{ ticket.currentPersons.map((person) => person.text).join(", ") }}
|
||||
</h2>
|
||||
</div>
|
||||
</Teleport>
|
||||
<Teleport to="#header-ticket-details">
|
||||
<div class="container-xxl">
|
||||
<div class="row justify-content-between">
|
||||
<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">
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER) }}
|
||||
</h3>
|
||||
<on-the-fly
|
||||
v-for="person in ticket.currentPersons"
|
||||
:key="person.id"
|
||||
:type="person.type"
|
||||
:id="person.id"
|
||||
:buttonText="person.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">
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_SPEAKER) }}
|
||||
</h3>
|
||||
<addressee-component
|
||||
:addressees="ticket.currentAddressees"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="col-md-6 col-sm-12">
|
||||
<div class="d-flex justify-content-end">
|
||||
<toggle-flags />
|
||||
|
||||
<span
|
||||
class="badge text-bg-chill-green text-white"
|
||||
style="font-size: 1rem"
|
||||
v-if="isOpen"
|
||||
>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_OPEN) }}
|
||||
</span>
|
||||
<span
|
||||
class="badge text-bg-chill-red text-white"
|
||||
style="font-size: 1rem"
|
||||
v-else
|
||||
>
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CLOSED) }}
|
||||
</span>
|
||||
</div>
|
||||
<div class="d-flex justify-content-end">
|
||||
<p class="created-at-timespan" v-if="ticket.createdAt">
|
||||
{{
|
||||
trans(CHILL_TICKET_TICKET_BANNER_SINCE, {
|
||||
time: since,
|
||||
})
|
||||
}}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
<Teleport to="#header-ticket-details">
|
||||
<div class="container-xxl">
|
||||
<div class="row justify-content-between">
|
||||
<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.text"
|
||||
: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">
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER) }}
|
||||
</h3>
|
||||
<on-the-fly
|
||||
v-for="person in ticket.currentPersons"
|
||||
:key="person.id"
|
||||
:type="person.type"
|
||||
:id="person.id"
|
||||
:buttonText="person.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">
|
||||
{{ trans(CHILL_TICKET_TICKET_BANNER_SPEAKER) }}
|
||||
</h3>
|
||||
<addressee-component :addressees="ticket.currentAddressees" />
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</Teleport>
|
||||
</template>
|
||||
|
||||
<style lang="scss">
|
||||
.created-at-timespan {
|
||||
font-weight: 600;
|
||||
font-variant: all-petite-caps;
|
||||
font-weight: 600;
|
||||
font-variant: all-petite-caps;
|
||||
}
|
||||
</style>
|
||||
|
||||
@@ -121,26 +109,26 @@ import { ISOToDatetime } from "../../../../../../../ChillMainBundle/Resources/pu
|
||||
|
||||
// Translations
|
||||
import {
|
||||
trans,
|
||||
CHILL_TICKET_TICKET_BANNER_NO_MOTIVE,
|
||||
CHILL_TICKET_TICKET_BANNER_OPEN,
|
||||
CHILL_TICKET_TICKET_BANNER_CLOSED,
|
||||
CHILL_TICKET_TICKET_BANNER_SINCE,
|
||||
CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER,
|
||||
CHILL_TICKET_TICKET_BANNER_SPEAKER,
|
||||
CHILL_TICKET_TICKET_BANNER_DAYS,
|
||||
CHILL_TICKET_TICKET_BANNER_HOURS,
|
||||
CHILL_TICKET_TICKET_BANNER_MINUTES,
|
||||
CHILL_TICKET_TICKET_BANNER_SECONDS,
|
||||
CHILL_TICKET_TICKET_BANNER_AND,
|
||||
CHILL_TICKET_TICKET_BANNER_CALLER,
|
||||
trans,
|
||||
CHILL_TICKET_TICKET_BANNER_NO_MOTIVE,
|
||||
CHILL_TICKET_TICKET_BANNER_OPEN,
|
||||
CHILL_TICKET_TICKET_BANNER_CLOSED,
|
||||
CHILL_TICKET_TICKET_BANNER_SINCE,
|
||||
CHILL_TICKET_TICKET_BANNER_CONCERNED_USAGER,
|
||||
CHILL_TICKET_TICKET_BANNER_SPEAKER,
|
||||
CHILL_TICKET_TICKET_BANNER_DAYS,
|
||||
CHILL_TICKET_TICKET_BANNER_HOURS,
|
||||
CHILL_TICKET_TICKET_BANNER_MINUTES,
|
||||
CHILL_TICKET_TICKET_BANNER_SECONDS,
|
||||
CHILL_TICKET_TICKET_BANNER_AND,
|
||||
CHILL_TICKET_TICKET_BANNER_CALLER,
|
||||
} from "translator";
|
||||
|
||||
// Store
|
||||
import { useStore } from "vuex";
|
||||
|
||||
const props = defineProps<{
|
||||
ticket: Ticket;
|
||||
ticket: Ticket;
|
||||
}>();
|
||||
|
||||
const store = useStore();
|
||||
@@ -148,59 +136,55 @@ const today = ref(new Date());
|
||||
const createdAt = ref(props.ticket.createdAt);
|
||||
|
||||
setInterval(() => {
|
||||
today.value = new Date();
|
||||
today.value = new Date();
|
||||
}, 5000);
|
||||
|
||||
const isOpen = computed(() => store.getters.isOpen);
|
||||
|
||||
const since = computed(() => {
|
||||
if (createdAt.value == null) {
|
||||
return "";
|
||||
}
|
||||
const date = ISOToDatetime(createdAt.value.datetime);
|
||||
if (createdAt.value == null) {
|
||||
return "";
|
||||
}
|
||||
const date = ISOToDatetime(createdAt.value.datetime);
|
||||
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
if (date == null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
const timeDiff = Math.abs(today.value.getTime() - date.getTime());
|
||||
const daysDiff = Math.floor(timeDiff / (1000 * 3600 * 24));
|
||||
const hoursDiff = Math.floor(
|
||||
(timeDiff % (1000 * 3600 * 24)) / (1000 * 3600),
|
||||
const timeDiff = Math.abs(today.value.getTime() - date.getTime());
|
||||
const daysDiff = Math.floor(timeDiff / (1000 * 3600 * 24));
|
||||
const hoursDiff = Math.floor((timeDiff % (1000 * 3600 * 24)) / (1000 * 3600));
|
||||
const minutesDiff = Math.floor((timeDiff % (1000 * 3600)) / (1000 * 60));
|
||||
const secondsDiff = Math.floor((timeDiff % (1000 * 60)) / 1000);
|
||||
|
||||
// On construit la liste des parties à afficher
|
||||
const parts: string[] = [];
|
||||
if (daysDiff > 0) {
|
||||
parts.push(trans(CHILL_TICKET_TICKET_BANNER_DAYS, { count: daysDiff }));
|
||||
}
|
||||
if (hoursDiff > 0 || daysDiff > 0) {
|
||||
parts.push(trans(CHILL_TICKET_TICKET_BANNER_HOURS, { count: hoursDiff }));
|
||||
}
|
||||
if (minutesDiff > 0 || hoursDiff > 0 || daysDiff > 0) {
|
||||
parts.push(
|
||||
trans(CHILL_TICKET_TICKET_BANNER_MINUTES, { count: minutesDiff }),
|
||||
);
|
||||
const minutesDiff = Math.floor((timeDiff % (1000 * 3600)) / (1000 * 60));
|
||||
const secondsDiff = Math.floor((timeDiff % (1000 * 60)) / 1000);
|
||||
|
||||
// On construit la liste des parties à afficher
|
||||
const parts: string[] = [];
|
||||
if (daysDiff > 0) {
|
||||
parts.push(trans(CHILL_TICKET_TICKET_BANNER_DAYS, { count: daysDiff }));
|
||||
}
|
||||
if (hoursDiff > 0 || daysDiff > 0) {
|
||||
parts.push(
|
||||
trans(CHILL_TICKET_TICKET_BANNER_HOURS, { count: hoursDiff }),
|
||||
);
|
||||
}
|
||||
if (minutesDiff > 0 || hoursDiff > 0 || daysDiff > 0) {
|
||||
parts.push(
|
||||
trans(CHILL_TICKET_TICKET_BANNER_MINUTES, { count: minutesDiff }),
|
||||
);
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return trans(CHILL_TICKET_TICKET_BANNER_SECONDS, {
|
||||
count: secondsDiff,
|
||||
});
|
||||
}
|
||||
if (parts.length > 1) {
|
||||
const last = parts.pop();
|
||||
return (
|
||||
parts.join(", ") +
|
||||
" " +
|
||||
trans(CHILL_TICKET_TICKET_BANNER_AND) +
|
||||
" " +
|
||||
last
|
||||
);
|
||||
}
|
||||
return parts[0];
|
||||
}
|
||||
if (parts.length === 0) {
|
||||
return trans(CHILL_TICKET_TICKET_BANNER_SECONDS, {
|
||||
count: secondsDiff,
|
||||
});
|
||||
}
|
||||
if (parts.length > 1) {
|
||||
const last = parts.pop();
|
||||
return (
|
||||
parts.join(", ") +
|
||||
" " +
|
||||
trans(CHILL_TICKET_TICKET_BANNER_AND) +
|
||||
" " +
|
||||
last
|
||||
);
|
||||
}
|
||||
return parts[0];
|
||||
});
|
||||
</script>
|
||||
|
@@ -1,16 +1,16 @@
|
||||
<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"
|
||||
/>
|
||||
<pick-entity
|
||||
uniqid="ticket-person-selector"
|
||||
:types="['person', 'thirdparty']"
|
||||
: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">
|
||||
@@ -24,62 +24,62 @@ import { Entities } from "ChillPersonAssets/types";
|
||||
|
||||
// Translations
|
||||
import {
|
||||
trans,
|
||||
CHILL_TICKET_TICKET_SET_PERSONS_CALLER_LABEL,
|
||||
trans,
|
||||
CHILL_TICKET_TICKET_SET_PERSONS_CALLER_LABEL,
|
||||
} from "translator";
|
||||
|
||||
const props = defineProps<{
|
||||
modelValue: Entities | null;
|
||||
suggested: Entities[];
|
||||
modelValue: Entities | null;
|
||||
suggested: Entities[];
|
||||
}>();
|
||||
const emit =
|
||||
defineEmits<(event: "update:modelValue", value: Entities | null) => void>();
|
||||
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 },
|
||||
() => [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);
|
||||
selectedEntity.value = entity;
|
||||
emit("update:modelValue", selectedEntity.value);
|
||||
}
|
||||
|
||||
function removeEntity() {
|
||||
selectedEntity.value = null;
|
||||
emit("update:modelValue", null);
|
||||
selectedEntity.value = null;
|
||||
emit("update:modelValue", null);
|
||||
}
|
||||
</script>
|
||||
<style scoped lang="scss">
|
||||
ul.person-list {
|
||||
list-style-type: none;
|
||||
list-style-type: none;
|
||||
|
||||
& > li {
|
||||
display: inline-block;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
& > li {
|
||||
display: inline-block;
|
||||
border: 1px solid transparent;
|
||||
border-radius: 6px;
|
||||
|
||||
button.remove-person {
|
||||
opacity: 10%;
|
||||
}
|
||||
button.remove-person {
|
||||
opacity: 10%;
|
||||
}
|
||||
}
|
||||
|
||||
& > li:hover {
|
||||
border: 1px solid white;
|
||||
& > li:hover {
|
||||
border: 1px solid white;
|
||||
|
||||
button.remove-person {
|
||||
opacity: 100%;
|
||||
}
|
||||
button.remove-person {
|
||||
opacity: 100%;
|
||||
}
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
@@ -1,79 +1,75 @@
|
||||
<template>
|
||||
<div
|
||||
class="card my-2 bg-light"
|
||||
v-for="history_line in history.filter(
|
||||
(line) => line.event_type != 'add_person',
|
||||
)"
|
||||
:key="history.indexOf(history_line)"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div
|
||||
class="history-header d-flex align-items-center justify-content-between"
|
||||
>
|
||||
<div class="d-flex align-items-center fw-bold">
|
||||
<i
|
||||
:class="`${actionIcons[history_line.event_type]} me-1`"
|
||||
></i>
|
||||
<span>{{ explainSentence(history_line) }}</span>
|
||||
<TicketHistoryStateComponent
|
||||
:new_state="history_line.data.new_state"
|
||||
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>
|
||||
<span class="badge-user">
|
||||
<user-render-box-badge
|
||||
:user="history_line.by"
|
||||
></user-render-box-badge>
|
||||
</span>
|
||||
<span class="fst-italic mx-2">
|
||||
{{ formatDate(history_line.at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="card my-2 bg-light"
|
||||
v-for="history_line in history.filter(
|
||||
(line) => line.event_type != 'add_person',
|
||||
)"
|
||||
:key="history.indexOf(history_line)"
|
||||
>
|
||||
<div class="card-header">
|
||||
<div
|
||||
class="history-header d-flex align-items-center justify-content-between"
|
||||
>
|
||||
<div class="d-flex align-items-center fw-bold">
|
||||
<i :class="`${actionIcons[history_line.event_type]} me-1`"></i>
|
||||
<span>{{ explainSentence(history_line) }}</span>
|
||||
<TicketHistoryStateComponent
|
||||
:new_state="history_line.data.new_state"
|
||||
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
|
||||
class="card-body row"
|
||||
v-if="
|
||||
!['state_change', 'emergency_change'].includes(
|
||||
history_line.event_type,
|
||||
)
|
||||
"
|
||||
>
|
||||
<ticket-history-person-component
|
||||
:persons="history_line.data.persons"
|
||||
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
|
||||
: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
|
||||
:addresseeState="history_line.data"
|
||||
v-else-if="history_line.event_type == 'addressees_state'"
|
||||
/>
|
||||
<ticket-history-create-component
|
||||
:by="history_line.by"
|
||||
v-else-if="history_line.event_type == 'create_ticket'"
|
||||
/>
|
||||
<div>
|
||||
<span class="badge-user">
|
||||
<user-render-box-badge
|
||||
:user="history_line.by"
|
||||
></user-render-box-badge>
|
||||
</span>
|
||||
<span class="fst-italic mx-2">
|
||||
{{ formatDate(history_line.at) }}
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
class="card-body row"
|
||||
v-if="
|
||||
!['state_change', 'emergency_change'].includes(history_line.event_type)
|
||||
"
|
||||
>
|
||||
<ticket-history-person-component
|
||||
:entities="history_line.data.persons"
|
||||
v-if="history_line.event_type == 'persons_state'"
|
||||
/>
|
||||
<ticket-history-person-component
|
||||
:entities="
|
||||
history_line.data.new_caller
|
||||
? ([history_line.data.new_caller] as Person[] | Thirdparty[])
|
||||
: []
|
||||
"
|
||||
v-if="history_line.event_type == 'set_caller'"
|
||||
/>
|
||||
<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
|
||||
:addresseeState="history_line.data"
|
||||
v-else-if="history_line.event_type == 'addressees_state'"
|
||||
/>
|
||||
<ticket-history-create-component
|
||||
:by="history_line.by"
|
||||
v-else-if="history_line.event_type == 'create_ticket'"
|
||||
/>
|
||||
</div>
|
||||
</div>
|
||||
</template>
|
||||
<script setup lang="ts">
|
||||
import { ref } from "vue";
|
||||
@@ -82,6 +78,8 @@ import { useStore } from "vuex";
|
||||
// Types
|
||||
import { DateTime } from "../../../../../../../ChillMainBundle/Resources/public/types";
|
||||
import { TicketHistoryLine } from "../../../types";
|
||||
import { Person } from "ChillPersonAssets/types";
|
||||
import { Thirdparty } from "src/Bundle/ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
// Components
|
||||
import TicketHistoryPersonComponent from "./TicketHistoryPersonComponent.vue";
|
||||
@@ -99,15 +97,15 @@ import { ISOToDatetime } from "../../../../../../../ChillMainBundle/Resources/pu
|
||||
|
||||
// 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,
|
||||
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[] }>();
|
||||
|
||||
@@ -116,36 +114,36 @@ const store = useStore();
|
||||
const actionIcons = ref(store.getters.getActionIcons);
|
||||
|
||||
function explainSentence(history: TicketHistoryLine): string {
|
||||
switch (history.event_type) {
|
||||
case "add_comment":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT);
|
||||
case "addressees_state":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE);
|
||||
case "persons_state":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE);
|
||||
case "set_motive":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_SET_MOTIVE);
|
||||
case "create_ticket":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_CREATE_TICKET);
|
||||
case "state_change":
|
||||
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:
|
||||
return "";
|
||||
}
|
||||
switch (history.event_type) {
|
||||
case "add_comment":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADD_COMMENT);
|
||||
case "addressees_state":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_ADDRESSEES_STATE);
|
||||
case "persons_state":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_PERSONS_STATE);
|
||||
case "set_motive":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_SET_MOTIVE);
|
||||
case "create_ticket":
|
||||
return trans(CHILL_TICKET_TICKET_HISTORY_CREATE_TICKET);
|
||||
case "state_change":
|
||||
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:
|
||||
return "";
|
||||
}
|
||||
}
|
||||
|
||||
function formatDate(d: DateTime): string {
|
||||
const date = ISOToDatetime(d.datetime);
|
||||
const date = ISOToDatetime(d.datetime);
|
||||
|
||||
if (date === null) {
|
||||
return "";
|
||||
}
|
||||
if (date === null) {
|
||||
return "";
|
||||
}
|
||||
|
||||
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()}`;
|
||||
}
|
||||
</script>
|
||||
|
@@ -1,18 +1,18 @@
|
||||
<template>
|
||||
<div class="col-12">
|
||||
<ul class="persons-list" v-if="persons.length > 0">
|
||||
<li v-for="person in persons" :key="person.id">
|
||||
<on-the-fly
|
||||
:type="person.type"
|
||||
:id="person.id"
|
||||
:buttonText="person.textAge"
|
||||
:displayBadge="true"
|
||||
action="show"
|
||||
></on-the-fly>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else class="text-muted">Aucune personne concernée</div>
|
||||
</div>
|
||||
<div class="col-12">
|
||||
<ul class="persons-list" v-if="entities.length > 0">
|
||||
<li v-for="entity in entities" :key="entity.text">
|
||||
<on-the-fly
|
||||
:type="entity.type"
|
||||
:id="entity.id"
|
||||
:buttonText="entity.text"
|
||||
:displayBadge="true"
|
||||
action="show"
|
||||
></on-the-fly>
|
||||
</li>
|
||||
</ul>
|
||||
<div v-else class="text-muted">Aucune personne concernée</div>
|
||||
</div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -20,17 +20,18 @@ import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||
|
||||
// Types
|
||||
import { Person } from "ChillPersonAssets/types";
|
||||
import { Thirdparty } from "src/Bundle/ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
defineProps<{ persons: Person[] }>();
|
||||
defineProps<{ entities: Person[] | Thirdparty[] }>();
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
ul.persons-list {
|
||||
list-style-type: none;
|
||||
list-style-type: none;
|
||||
|
||||
& > li {
|
||||
display: inline-block;
|
||||
margin: 0 0.15rem;
|
||||
}
|
||||
& > li {
|
||||
display: inline-block;
|
||||
margin: 0 0.15rem;
|
||||
}
|
||||
}
|
||||
</style>
|
||||
|
Reference in New Issue
Block a user