mirror of
https://gitlab.com/Chill-Projet/chill-bundles.git
synced 2025-12-18 16:15:43 +00:00
Merge branch 'ticket-app-master' into 1849-1848-1920-1921-fix-bugs
This commit is contained in:
@@ -11,7 +11,6 @@
|
||||
"@hotwired/stimulus": "^3.0.0",
|
||||
"@luminateone/eslint-baseline": "^1.0.9",
|
||||
"@symfony/stimulus-bridge": "^3.2.0",
|
||||
"@symfony/ux-translator": "file:vendor/symfony/ux-translator/assets",
|
||||
"@symfony/webpack-encore": "^4.1.0",
|
||||
"@tsconfig/node20": "^20.1.4",
|
||||
"@types/dompurify": "^3.0.5",
|
||||
|
||||
@@ -49,9 +49,7 @@
|
||||
</div>
|
||||
<div class="col-8">
|
||||
<div v-if="actionIsLoading === true">
|
||||
<i
|
||||
class="chill-green fa fa-circle-o-notch fa-spin fa-lg"
|
||||
></i>
|
||||
<i class="chill-green fa fa-circle-o-notch fa-spin fa-lg"></i>
|
||||
</div>
|
||||
|
||||
<span
|
||||
@@ -64,8 +62,7 @@
|
||||
<template
|
||||
v-else-if="
|
||||
socialActionsList.length > 0 &&
|
||||
(socialIssuesSelected.length ||
|
||||
socialActionsSelected.length)
|
||||
(socialIssuesSelected.length || socialActionsSelected.length)
|
||||
"
|
||||
>
|
||||
<div
|
||||
@@ -88,9 +85,7 @@
|
||||
</template>
|
||||
|
||||
<span
|
||||
v-else-if="
|
||||
actionAreLoaded && socialActionsList.length === 0
|
||||
"
|
||||
v-else-if="actionAreLoaded && socialActionsList.length === 0"
|
||||
class="inline-choice chill-no-data-statement mt-3"
|
||||
>
|
||||
{{ trans(ACTIVITY_SOCIAL_ACTION_LIST_EMPTY) }}
|
||||
@@ -190,8 +185,7 @@ export default {
|
||||
/* Add in list the issues already associated (if not yet listed) */
|
||||
this.socialIssuesSelected.forEach((issue) => {
|
||||
if (
|
||||
this.socialIssuesList.filter((i) => i.id === issue.id)
|
||||
.length !== 1
|
||||
this.socialIssuesList.filter((i) => i.id === issue.id).length !== 1
|
||||
) {
|
||||
this.$store.commit("addIssueInList", issue);
|
||||
}
|
||||
|
||||
@@ -47,7 +47,8 @@ span.badge {
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
display: inline-block;
|
||||
max-width: 100%;margin-bottom: 5px;
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 1em;
|
||||
text-align: left;
|
||||
line-height: 1.2em;
|
||||
|
||||
@@ -45,8 +45,10 @@ span.badge {
|
||||
word-wrap: break-word;
|
||||
word-break: break-word;
|
||||
display: inline-block;
|
||||
max-width: 100%;margin-bottom: 5px;
|
||||
margin-right: 1em;text-align: left;
|
||||
max-width: 100%;
|
||||
margin-bottom: 5px;
|
||||
margin-right: 1em;
|
||||
text-align: left;
|
||||
|
||||
&::before {
|
||||
position: absolute;
|
||||
|
||||
@@ -61,11 +61,7 @@
|
||||
<label class="input-group-text" for="slotDuration"
|
||||
>Durée des créneaux</label
|
||||
>
|
||||
<select
|
||||
v-model="slotDuration"
|
||||
id="slotDuration"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
||||
<option value="00:05:00">5 minutes</option>
|
||||
<option value="00:10:00">10 minutes</option>
|
||||
<option value="00:15:00">15 minutes</option>
|
||||
@@ -74,11 +70,7 @@
|
||||
<option value="00:60:00">60 minutes</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMinTime">De</label>
|
||||
<select
|
||||
v-model="slotMinTime"
|
||||
id="slotMinTime"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
||||
<option value="00:00:00">0h</option>
|
||||
<option value="01:00:00">1h</option>
|
||||
<option value="02:00:00">2h</option>
|
||||
@@ -94,11 +86,7 @@
|
||||
<option value="12:00:00">12h</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||
<select
|
||||
v-model="slotMaxTime"
|
||||
id="slotMaxTime"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
||||
<option value="12:00:00">12h</option>
|
||||
<option value="13:00:00">13h</option>
|
||||
<option value="14:00:00">14h</option>
|
||||
@@ -126,9 +114,7 @@
|
||||
v-model="hideWeekends"
|
||||
/>
|
||||
</span>
|
||||
<label
|
||||
for="showHideWE"
|
||||
class="form-check-label input-group-text"
|
||||
<label for="showHideWE" class="form-check-label input-group-text"
|
||||
>Week-ends</label
|
||||
>
|
||||
</div>
|
||||
@@ -144,9 +130,7 @@
|
||||
<b v-else-if="arg.event.extendedProps.is === 'range'"
|
||||
>{{ arg.timeText }}
|
||||
{{ arg.event.extendedProps.locationName }}
|
||||
<small>{{
|
||||
arg.event.extendedProps.userLabel
|
||||
}}</small></b
|
||||
<small>{{ arg.event.extendedProps.userLabel }}</small></b
|
||||
>
|
||||
<b v-else-if="arg.event.extendedProps.is === 'current'"
|
||||
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||
@@ -154,9 +138,7 @@
|
||||
<b v-else-if="arg.event.extendedProps.is === 'local'">{{
|
||||
arg.event.title
|
||||
}}</b>
|
||||
<b v-else
|
||||
>{{ arg.timeText }} {{ $t("current_selected") }}
|
||||
</b>
|
||||
<b v-else>{{ arg.timeText }} {{ $t("current_selected") }} </b>
|
||||
</span>
|
||||
</template>
|
||||
</FullCalendar>
|
||||
@@ -270,9 +252,7 @@ export default {
|
||||
this.$store.state.activity.endDate !== null)
|
||||
) {
|
||||
if (
|
||||
!window.confirm(
|
||||
this.$t("change_main_user_will_reset_event_data"),
|
||||
)
|
||||
!window.confirm(this.$t("change_main_user_will_reset_event_data"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
@@ -280,13 +260,9 @@ export default {
|
||||
|
||||
// add the previous user, if any, in the previous user list (in use for suggestion)
|
||||
if (null !== this.$store.getters.getMainUser) {
|
||||
const suggestedUids = new Set(
|
||||
this.$data.previousUser.map((u) => u.id),
|
||||
);
|
||||
const suggestedUids = new Set(this.$data.previousUser.map((u) => u.id));
|
||||
if (!suggestedUids.has(this.$store.getters.getMainUser.id)) {
|
||||
this.$data.previousUser.push(
|
||||
this.$store.getters.getMainUser,
|
||||
);
|
||||
this.$data.previousUser.push(this.$store.getters.getMainUser);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -316,8 +292,7 @@ export default {
|
||||
// show an alert if changing mainUser
|
||||
if (
|
||||
(this.$store.getters.getMainUser !== null &&
|
||||
this.$store.state.me.id !==
|
||||
this.$store.getters.getMainUser.id) ||
|
||||
this.$store.state.me.id !== this.$store.getters.getMainUser.id) ||
|
||||
this.$store.getters.getMainUser === null
|
||||
) {
|
||||
if (!window.confirm(this.$t("will_change_main_user_for_me"))) {
|
||||
@@ -361,9 +336,7 @@ export default {
|
||||
this.$store.getters.getMainUser.id
|
||||
) {
|
||||
if (
|
||||
!window.confirm(
|
||||
this.$t("this_calendar_range_will_change_main_user"),
|
||||
)
|
||||
!window.confirm(this.$t("this_calendar_range_will_change_main_user"))
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -23,11 +23,7 @@
|
||||
<label class="input-group-text" for="slotDuration"
|
||||
>Durée des créneaux</label
|
||||
>
|
||||
<select
|
||||
v-model="slotDuration"
|
||||
id="slotDuration"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotDuration" id="slotDuration" class="form-select">
|
||||
<option value="00:05:00">5 minutes</option>
|
||||
<option value="00:10:00">10 minutes</option>
|
||||
<option value="00:15:00">15 minutes</option>
|
||||
@@ -36,11 +32,7 @@
|
||||
<option value="00:60:00">60 minutes</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMinTime">De</label>
|
||||
<select
|
||||
v-model="slotMinTime"
|
||||
id="slotMinTime"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotMinTime" id="slotMinTime" class="form-select">
|
||||
<option value="00:00:00">0h</option>
|
||||
<option value="01:00:00">1h</option>
|
||||
<option value="02:00:00">2h</option>
|
||||
@@ -56,11 +48,7 @@
|
||||
<option value="12:00:00">12h</option>
|
||||
</select>
|
||||
<label class="input-group-text" for="slotMaxTime">À</label>
|
||||
<select
|
||||
v-model="slotMaxTime"
|
||||
id="slotMaxTime"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="slotMaxTime" id="slotMaxTime" class="form-select">
|
||||
<option value="12:00:00">12h</option>
|
||||
<option value="13:00:00">13h</option>
|
||||
<option value="14:00:00">14h</option>
|
||||
@@ -88,9 +76,7 @@
|
||||
v-model="showWeekends"
|
||||
/>
|
||||
</span>
|
||||
<label
|
||||
for="showHideWE"
|
||||
class="form-check-label input-group-text"
|
||||
<label for="showHideWE" class="form-check-label input-group-text"
|
||||
>Week-ends</label
|
||||
>
|
||||
</div>
|
||||
@@ -100,9 +86,7 @@
|
||||
<FullCalendar :options="calendarOptions" ref="calendarRef">
|
||||
<template v-slot:eventContent="{ event }: { event: EventApi }">
|
||||
<span :class="eventClasses">
|
||||
<b v-if="event.extendedProps.is === 'remote'">{{
|
||||
event.title
|
||||
}}</b>
|
||||
<b v-if="event.extendedProps.is === 'remote'">{{ event.title }}</b>
|
||||
<b v-else-if="event.extendedProps.is === 'range'"
|
||||
>{{ formatDate(event.startStr, "time") }} -
|
||||
{{ formatDate(event.endStr, "time") }}:
|
||||
@@ -132,11 +116,7 @@
|
||||
<h6 class="chill-red">{{ $t("copy_range_from_to") }}</h6>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-9 col-md-2">
|
||||
<select
|
||||
v-model="dayOrWeek"
|
||||
id="dayOrWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<select v-model="dayOrWeek" id="dayOrWeek" class="form-select">
|
||||
<option value="day">{{ $t("from_day_to_day") }}</option>
|
||||
<option value="week">
|
||||
{{ $t("from_week_to_week") }}
|
||||
@@ -145,27 +125,16 @@
|
||||
</div>
|
||||
<template v-if="dayOrWeek === 'day'">
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<input
|
||||
class="form-control"
|
||||
type="date"
|
||||
v-model="copyFrom"
|
||||
/>
|
||||
<input class="form-control" type="date" v-model="copyFrom" />
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-1 col-md-1 copy-chevron">
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<input
|
||||
class="form-control"
|
||||
type="date"
|
||||
v-model="copyTo"
|
||||
/>
|
||||
<input class="form-control" type="date" v-model="copyTo" />
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||
<button
|
||||
class="btn btn-action float-end"
|
||||
@click="copyDay"
|
||||
>
|
||||
<button class="btn btn-action float-end" @click="copyDay">
|
||||
{{ $t("copy_range") }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -177,11 +146,7 @@
|
||||
id="copyFromWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="w in lastWeeks"
|
||||
:value="w.value"
|
||||
:key="w.value"
|
||||
>
|
||||
<option v-for="w in lastWeeks" :value="w.value" :key="w.value">
|
||||
{{ w.text }}
|
||||
</option>
|
||||
</select>
|
||||
@@ -190,25 +155,14 @@
|
||||
<i class="fa fa-angle-double-right"></i>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-3 col-md-3">
|
||||
<select
|
||||
v-model="copyToWeek"
|
||||
id="copyToWeek"
|
||||
class="form-select"
|
||||
>
|
||||
<option
|
||||
v-for="w in nextWeeks"
|
||||
:value="w.value"
|
||||
:key="w.value"
|
||||
>
|
||||
<select v-model="copyToWeek" id="copyToWeek" class="form-select">
|
||||
<option v-for="w in nextWeeks" :value="w.value" :key="w.value">
|
||||
{{ w.text }}
|
||||
</option>
|
||||
</select>
|
||||
</div>
|
||||
<div class="col-xs-12 col-sm-5 col-md-1">
|
||||
<button
|
||||
class="btn btn-action float-end"
|
||||
@click="copyWeek"
|
||||
>
|
||||
<button class="btn btn-action float-end" @click="copyWeek">
|
||||
{{ $t("copy_range") }}
|
||||
</button>
|
||||
</div>
|
||||
|
||||
@@ -46,8 +46,7 @@ export interface StoredObjectVersionCreated extends StoredObjectVersion {
|
||||
persisted: false;
|
||||
}
|
||||
|
||||
export interface StoredObjectVersionPersisted
|
||||
extends StoredObjectVersionCreated {
|
||||
export interface StoredObjectVersionPersisted extends StoredObjectVersionCreated {
|
||||
version: number;
|
||||
id: number;
|
||||
createdAt: DateTime | null;
|
||||
@@ -61,8 +60,7 @@ export interface StoredObjectStatusChange {
|
||||
type: string;
|
||||
}
|
||||
|
||||
export interface StoredObjectVersionWithPointInTime
|
||||
extends StoredObjectVersionPersisted {
|
||||
export interface StoredObjectVersionWithPointInTime extends StoredObjectVersionPersisted {
|
||||
"point-in-times": StoredObjectPointInTime[];
|
||||
"from-restored": StoredObjectVersionPersisted | null;
|
||||
}
|
||||
|
||||
@@ -49,8 +49,7 @@ const isRestored = computed<boolean>(
|
||||
);
|
||||
|
||||
const isDuplicated = computed<boolean>(
|
||||
() =>
|
||||
props.version.version === 0 && null !== props.version["from-restored"],
|
||||
() => props.version.version === 0 && null !== props.version["from-restored"],
|
||||
);
|
||||
|
||||
const classes = computed<{
|
||||
@@ -70,16 +69,9 @@ const classes = computed<{
|
||||
<div :class="classes">
|
||||
<div
|
||||
class="col-12 tags"
|
||||
v-if="
|
||||
isCurrent ||
|
||||
isKeptBeforeConversion ||
|
||||
isRestored ||
|
||||
isDuplicated
|
||||
"
|
||||
>
|
||||
<span class="badge bg-success" v-if="isCurrent"
|
||||
>Version actuelle</span
|
||||
v-if="isCurrent || isKeptBeforeConversion || isRestored || isDuplicated"
|
||||
>
|
||||
<span class="badge bg-success" v-if="isCurrent">Version actuelle</span>
|
||||
<span class="badge bg-info" v-if="isKeptBeforeConversion"
|
||||
>Conservée avant conversion dans un autre format</span
|
||||
>
|
||||
@@ -96,21 +88,17 @@ const classes = computed<{
|
||||
<span
|
||||
><strong> #{{ version.version + 1 }} </strong></span
|
||||
>
|
||||
<template
|
||||
v-if="version.createdBy !== null && version.createdAt !== null"
|
||||
<template v-if="version.createdBy !== null && version.createdAt !== null"
|
||||
><strong v-if="version.version == 0">créé par</strong
|
||||
><strong v-else>modifié par</strong>
|
||||
<span class="badge-user"
|
||||
><UserRenderBoxBadge
|
||||
:user="version.createdBy"
|
||||
></UserRenderBoxBadge
|
||||
><UserRenderBoxBadge :user="version.createdBy"></UserRenderBoxBadge
|
||||
></span>
|
||||
<strong>à</strong>
|
||||
{{
|
||||
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
|
||||
}}</template
|
||||
><template
|
||||
v-if="version.createdBy === null && version.createdAt !== null"
|
||||
><template v-if="version.createdBy === null && version.createdAt !== null"
|
||||
><strong v-if="version.version == 0">Créé le</strong
|
||||
><strong v-else>modifié le</strong>
|
||||
{{
|
||||
|
||||
@@ -61,9 +61,7 @@ export const ISOToDatetime = (str: string | null): Date | null => {
|
||||
[time, timezone] = times.split(times.charAt(8)),
|
||||
[hours, minutes, seconds] = time.split(":").map((s) => parseInt(s));
|
||||
if ("0000" === timezone) {
|
||||
return new Date(
|
||||
Date.UTC(year, month - 1, date, hours, minutes, seconds),
|
||||
);
|
||||
return new Date(Date.UTC(year, month - 1, date, hours, minutes, seconds));
|
||||
}
|
||||
|
||||
return new Date(year, month - 1, date, hours, minutes, seconds);
|
||||
@@ -158,9 +156,7 @@ export const intervalISOToDays = (str: string | null): number | null => {
|
||||
vstring = "";
|
||||
break;
|
||||
default:
|
||||
throw Error(
|
||||
"this character should not appears: " + str.charAt(i),
|
||||
);
|
||||
throw Error("this character should not appears: " + str.charAt(i));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -180,4 +176,3 @@ export function getTimezoneOffsetString(date: Date, timeZone: string): string {
|
||||
|
||||
return `${sign}${hours}:${minutes}`;
|
||||
}
|
||||
|
||||
|
||||
@@ -3,7 +3,7 @@ import {
|
||||
Scope,
|
||||
ValidationExceptionInterface,
|
||||
ValidationProblemFromMap,
|
||||
ViolationFromMap
|
||||
ViolationFromMap,
|
||||
} from "../../types";
|
||||
|
||||
export type body = Record<string, boolean | string | number | null>;
|
||||
@@ -68,7 +68,10 @@ export class ValidationException<
|
||||
|
||||
this.byProperty = problem.violations.reduce(
|
||||
(acc, v) => {
|
||||
const key = v.propertyPath.replace('/\[\d+\]$/', "") as Extract<keyof M, string>;
|
||||
const key = v.propertyPath.replace("/\[\d+\]$/", "") as Extract<
|
||||
keyof M,
|
||||
string
|
||||
>;
|
||||
(acc[key] ||= []).push(v.title);
|
||||
return acc;
|
||||
},
|
||||
@@ -80,19 +83,18 @@ export class ValidationException<
|
||||
}
|
||||
}
|
||||
|
||||
violationsByNormalizedProperty(property: Extract<keyof M, string>): ViolationFromMap<M>[] {
|
||||
return this.violationsList.filter((v) => v.propertyPath.replace(/\[\d+\]$/, "") === property);
|
||||
violationsByNormalizedProperty(
|
||||
property: Extract<keyof M, string>,
|
||||
): ViolationFromMap<M>[] {
|
||||
return this.violationsList.filter(
|
||||
(v) => v.propertyPath.replace(/\[\d+\]$/, "") === property,
|
||||
);
|
||||
}
|
||||
|
||||
violationsByNormalizedPropertyAndParams<
|
||||
P extends Extract<keyof M, string>,
|
||||
K extends Extract<keyof M[P], string>
|
||||
>(
|
||||
property: P,
|
||||
param: K,
|
||||
param_value: M[P][K]
|
||||
): ViolationFromMap<M>[]
|
||||
{
|
||||
K extends Extract<keyof M[P], string>,
|
||||
>(property: P, param: K, param_value: M[P][K]): ViolationFromMap<M>[] {
|
||||
const list = this.violationsByNormalizedProperty(property);
|
||||
|
||||
return list.filter(
|
||||
@@ -101,7 +103,7 @@ export class ValidationException<
|
||||
// `with_parameter in v.parameters` check indexing
|
||||
param in v.parameters &&
|
||||
// the cast is safe, because we have overloading that bind the types
|
||||
(v.parameters as M[P])[param] === param_value
|
||||
(v.parameters as M[P])[param] === param_value,
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -110,9 +112,9 @@ export class ValidationException<
|
||||
* Check that the exception is a ValidationExceptionInterface
|
||||
* @param x
|
||||
*/
|
||||
export function isValidationException<M extends Record<string, Record<string, string|number>>>(
|
||||
x: unknown,
|
||||
): x is ValidationExceptionInterface<M> {
|
||||
export function isValidationException<
|
||||
M extends Record<string, Record<string, string | number>>,
|
||||
>(x: unknown): x is ValidationExceptionInterface<M> {
|
||||
return (
|
||||
x instanceof ValidationException ||
|
||||
(typeof x === "object" &&
|
||||
@@ -147,8 +149,7 @@ export interface AccessExceptionInterface extends TransportExceptionInterface {
|
||||
violations: string[];
|
||||
}
|
||||
|
||||
export interface NotFoundExceptionInterface
|
||||
extends TransportExceptionInterface {
|
||||
export interface NotFoundExceptionInterface extends TransportExceptionInterface {
|
||||
name: "NotFoundException";
|
||||
}
|
||||
|
||||
@@ -159,8 +160,7 @@ export interface ServerExceptionInterface extends TransportExceptionInterface {
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface ConflictHttpExceptionInterface
|
||||
extends TransportExceptionInterface {
|
||||
export interface ConflictHttpExceptionInterface extends TransportExceptionInterface {
|
||||
name: "ConflictHttpException";
|
||||
violations: string[];
|
||||
}
|
||||
|
||||
@@ -7,8 +7,7 @@ import {Gender, GenderTranslation} from "ChillMainAssets/types";
|
||||
* @return {GenderTranslation} Returns the gender translation string corresponding to the provided gender,
|
||||
* or "unknown" if the gender is null.
|
||||
*/
|
||||
export function toGenderTranslation(gender: Gender|null): GenderTranslation
|
||||
{
|
||||
export function toGenderTranslation(gender: Gender | null): GenderTranslation {
|
||||
if (null === gender) {
|
||||
return "unknown";
|
||||
}
|
||||
|
||||
@@ -38,7 +38,6 @@ export interface SetCivility {
|
||||
id: number;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Gender translation.
|
||||
*
|
||||
@@ -380,13 +379,16 @@ export type DynamicKeys<M extends Record<string, Record<string, unknown>>> =
|
||||
|
||||
type NormalizeKey<K extends string> = K extends `${infer B}[${number}]` ? B : K;
|
||||
|
||||
export type ViolationFromMap<M extends Record<string, Record<string, unknown>>> = {
|
||||
[K in DynamicKeys<M> & string]: { // <- note le "& string" ici
|
||||
export type ViolationFromMap<
|
||||
M extends Record<string, Record<string, unknown>>,
|
||||
> = {
|
||||
[K in DynamicKeys<M> & string]: {
|
||||
// <- note le "& string" ici
|
||||
propertyPath: K;
|
||||
title: string;
|
||||
parameters?: M[NormalizeKey<K>];
|
||||
type?: string;
|
||||
}
|
||||
};
|
||||
}[DynamicKeys<M> & string];
|
||||
|
||||
export type ValidationProblemFromMap<
|
||||
@@ -418,15 +420,17 @@ export interface ValidationExceptionInterface<
|
||||
/** Indexing by property (useful for display by field) */
|
||||
byProperty: Record<Extract<keyof M, string>, string[]>;
|
||||
|
||||
violationsByNormalizedProperty(property: Extract<keyof M, string>): ViolationFromMap<M>[];
|
||||
violationsByNormalizedProperty(
|
||||
property: Extract<keyof M, string>,
|
||||
): ViolationFromMap<M>[];
|
||||
|
||||
violationsByNormalizedPropertyAndParams<
|
||||
P extends Extract<keyof M, string>,
|
||||
K extends Extract<keyof M[P], string>
|
||||
K extends Extract<keyof M[P], string>,
|
||||
>(
|
||||
property: P,
|
||||
param: K,
|
||||
param_value: M[P][K]
|
||||
param_value: M[P][K],
|
||||
): ViolationFromMap<M>[];
|
||||
}
|
||||
|
||||
@@ -435,8 +439,7 @@ export interface AccessExceptionInterface extends TransportExceptionInterface {
|
||||
violations: string[];
|
||||
}
|
||||
|
||||
export interface NotFoundExceptionInterface
|
||||
extends TransportExceptionInterface {
|
||||
export interface NotFoundExceptionInterface extends TransportExceptionInterface {
|
||||
name: "NotFoundException";
|
||||
}
|
||||
|
||||
@@ -447,8 +450,7 @@ export interface ServerExceptionInterface extends TransportExceptionInterface {
|
||||
body: string;
|
||||
}
|
||||
|
||||
export interface ConflictHttpExceptionInterface
|
||||
extends TransportExceptionInterface {
|
||||
export interface ConflictHttpExceptionInterface extends TransportExceptionInterface {
|
||||
name: "ConflictHttpException";
|
||||
violations: string[];
|
||||
}
|
||||
@@ -496,16 +498,16 @@ export interface TabDefinition {
|
||||
counter: () => number;
|
||||
}
|
||||
|
||||
export type CreateComponentConfigGeneral = {
|
||||
action: 'create';
|
||||
export interface CreateComponentConfigGeneral {
|
||||
action: "create";
|
||||
allowedTypes: CreatableEntityType[];
|
||||
query: string;
|
||||
parent: null;
|
||||
}
|
||||
|
||||
export type CreateComponentThirdPartyAddContact = {
|
||||
action: 'addContact';
|
||||
allowedTypes: readonly ['thirdparty'];
|
||||
export interface CreateComponentThirdPartyAddContact {
|
||||
action: "addContact";
|
||||
allowedTypes: readonly ["thirdparty"];
|
||||
query: string;
|
||||
parent: ThirdpartyCompany;
|
||||
}
|
||||
@@ -513,8 +515,9 @@ export type CreateComponentThirdPartyAddContact = {
|
||||
/**
|
||||
* Configuration for the CreateModal and Create component
|
||||
*/
|
||||
export type CreateComponentConfig = CreateComponentConfigGeneral | CreateComponentThirdPartyAddContact;
|
||||
|
||||
export type CreateComponentConfig =
|
||||
| CreateComponentConfigGeneral
|
||||
| CreateComponentThirdPartyAddContact;
|
||||
|
||||
/**
|
||||
* Possible states for the WaitingScreen Component.
|
||||
|
||||
@@ -69,10 +69,9 @@ const props = withDefaults(defineProps<CreateComponentConfig>(), {
|
||||
parent: null,
|
||||
});
|
||||
|
||||
const emit =
|
||||
defineEmits<{
|
||||
(e: "onPersonCreated", payload: { person: Person }): void,
|
||||
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }): void,
|
||||
const emit = defineEmits<{
|
||||
(e: "onPersonCreated", payload: { person: Person }): void;
|
||||
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }): void;
|
||||
}>();
|
||||
|
||||
const type = ref<CreatableEntityType | null>(null);
|
||||
@@ -106,7 +105,7 @@ const containsThirdParty = computed<boolean>(() =>
|
||||
props.allowedTypes.includes("thirdparty"),
|
||||
);
|
||||
const containsPerson = computed<boolean>(() => {
|
||||
if (props.action === 'addContact') {
|
||||
if (props.action === "addContact") {
|
||||
return false;
|
||||
}
|
||||
return props.allowedTypes.includes("person");
|
||||
@@ -115,7 +114,10 @@ const containsPerson = computed<boolean>(() => {
|
||||
function save(): void {
|
||||
if (radioType.value === "person" && castPerson.value !== null) {
|
||||
castPerson.value.postPerson();
|
||||
} else if (radioType.value === "thirdparty" && castThirdparty.value !== null) {
|
||||
} else if (
|
||||
radioType.value === "thirdparty" &&
|
||||
castThirdparty.value !== null
|
||||
) {
|
||||
castThirdparty.value.postThirdParty();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -24,9 +24,13 @@ const onPersonCreated = ({person}: {person: Person}): void => {
|
||||
emit("onPersonCreated", { person });
|
||||
};
|
||||
|
||||
const onThirdPartyCreated = ({thirdParty}: {thirdParty: Thirdparty}): void => {
|
||||
const onThirdPartyCreated = ({
|
||||
thirdParty,
|
||||
}: {
|
||||
thirdParty: Thirdparty;
|
||||
}): void => {
|
||||
emit("onThirdPartyCreated", { thirdParty: thirdParty });
|
||||
}
|
||||
};
|
||||
|
||||
function save(): void {
|
||||
console.log("save from CreateModal");
|
||||
|
||||
@@ -177,14 +177,19 @@ const props = withDefaults(defineProps<OnTheFlyComponentProps>(), {
|
||||
query: "",
|
||||
});
|
||||
|
||||
const emit = defineEmits<{
|
||||
(e: "saveFormOnTheFly", payload: { type: string | undefined; data: any }): void;
|
||||
}>();
|
||||
const emit =
|
||||
defineEmits<
|
||||
(
|
||||
e: "saveFormOnTheFly",
|
||||
payload: { type: string | undefined; data: any },
|
||||
) => void
|
||||
>();
|
||||
|
||||
type castEditPersonType = InstanceType<typeof PersonEdit>;
|
||||
type castEditThirdPartyType = InstanceType<typeof ThirdPartyEdit>;
|
||||
const castEditPerson = useTemplateRef<castEditPersonType>('castEditPerson')
|
||||
const castEditThirdParty = useTemplateRef<castEditThirdPartyType>('castEditThirdParty');
|
||||
const castEditPerson = useTemplateRef<castEditPersonType>("castEditPerson");
|
||||
const castEditThirdParty =
|
||||
useTemplateRef<castEditThirdPartyType>("castEditThirdParty");
|
||||
|
||||
const modal = ref<{ showModal: boolean; modalDialogClass: string }>({
|
||||
showModal: false,
|
||||
@@ -234,35 +239,35 @@ const titleAction = computed<string>(() => {
|
||||
|
||||
const titleCreate = computed<string>(() => {
|
||||
if (typeof props.allowedTypes === "undefined") {
|
||||
return trans(ONTHEFLY_CREATE_TITLE_DEFAULT)
|
||||
return trans(ONTHEFLY_CREATE_TITLE_DEFAULT);
|
||||
}
|
||||
return props.allowedTypes.every((t: EntityType) => t === "person")
|
||||
? (trans(ONTHEFLY_CREATE_TITLE_PERSON))
|
||||
? trans(ONTHEFLY_CREATE_TITLE_PERSON)
|
||||
: props.allowedTypes.every((t: EntityType) => t === "thirdparty")
|
||||
? (trans(ONTHEFLY_CREATE_TITLE_THIRDPARTY))
|
||||
: (trans(ONTHEFLY_CREATE_TITLE_DEFAULT));
|
||||
? trans(ONTHEFLY_CREATE_TITLE_THIRDPARTY)
|
||||
: trans(ONTHEFLY_CREATE_TITLE_DEFAULT);
|
||||
});
|
||||
|
||||
const titleModal = computed<string>(() => {
|
||||
switch (props.action) {
|
||||
case "show":
|
||||
if (props.type == "person") {
|
||||
return trans(ONTHEFLY_SHOW_PERSON)
|
||||
return trans(ONTHEFLY_SHOW_PERSON);
|
||||
} else if (props.type == "thirdparty") {
|
||||
return trans(ONTHEFLY_SHOW_THIRDPARTY)
|
||||
return trans(ONTHEFLY_SHOW_THIRDPARTY);
|
||||
}
|
||||
break;
|
||||
case "edit":
|
||||
if (props.type == "person") {
|
||||
return trans(ONTHEFLY_EDIT_PERSON)
|
||||
return trans(ONTHEFLY_EDIT_PERSON);
|
||||
} else if (props.type == "thirdparty") {
|
||||
return trans(ONTHEFLY_EDIT_THIRDPARTY)
|
||||
return trans(ONTHEFLY_EDIT_THIRDPARTY);
|
||||
}
|
||||
break;
|
||||
case "create":
|
||||
return titleCreate.value;
|
||||
case "addContact":
|
||||
return trans(THIRDPARTY_ADDCONTACT_TITLE)
|
||||
return trans(THIRDPARTY_ADDCONTACT_TITLE);
|
||||
default:
|
||||
break;
|
||||
}
|
||||
@@ -311,7 +316,10 @@ function openModal(): void {
|
||||
modal.value.showModal = true;
|
||||
}
|
||||
|
||||
function buildLocation(id: string | number | undefined, type: EntityType | undefined): string | undefined {
|
||||
function buildLocation(
|
||||
id: string | number | undefined,
|
||||
type: EntityType | undefined,
|
||||
): string | undefined {
|
||||
if (type === "person") {
|
||||
return encodeURI(`/fr/person/${id}/general${getReturnPath.value}`);
|
||||
} else if (type === "thirdparty") {
|
||||
@@ -324,17 +332,16 @@ async function saveAction() {
|
||||
if (props.type === "person") {
|
||||
const person = await castEditPerson.value?.postPerson();
|
||||
if (null !== person) {
|
||||
emit("saveFormOnTheFly", {type: props.type, data: person})
|
||||
emit("saveFormOnTheFly", { type: props.type, data: person });
|
||||
}
|
||||
} else if (props.type === 'thirdparty') {
|
||||
} else if (props.type === "thirdparty") {
|
||||
const thirdParty = await castEditThirdParty.value?.postThirdParty();
|
||||
if (null !== thirdParty) {
|
||||
emit("saveFormOnTheFly", {type: props.type, data: thirdParty })
|
||||
emit("saveFormOnTheFly", { type: props.type, data: thirdParty });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
defineExpose({
|
||||
openModal,
|
||||
closeModal,
|
||||
|
||||
@@ -19,7 +19,8 @@
|
||||
>
|
||||
{{ p.text }}
|
||||
</span>
|
||||
<span v-else
|
||||
<span
|
||||
v-else
|
||||
:class="getBadgeClass(p)"
|
||||
class="chill_denomination"
|
||||
:style="getBadgeStyle(p)"
|
||||
@@ -61,12 +62,14 @@
|
||||
@click="addNewSuggested(s)"
|
||||
style="margin: 0"
|
||||
>
|
||||
<span v-if="!isEntityHousehold(s)" :class="getBadgeClass(s)" :style="getBadgeStyle(s)">
|
||||
<span
|
||||
v-if="!isEntityHousehold(s)"
|
||||
:class="getBadgeClass(s)"
|
||||
:style="getBadgeStyle(s)"
|
||||
>
|
||||
{{ s.text }}
|
||||
</span>
|
||||
<span v-else>
|
||||
Ménage n°{{ s.id }}
|
||||
</span>
|
||||
<span v-else> Ménage n°{{ s.id }} </span>
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
@@ -85,7 +88,8 @@ import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
||||
import {
|
||||
Entities,
|
||||
EntitiesOrMe,
|
||||
EntityType, isEntityHousehold,
|
||||
EntityType,
|
||||
isEntityHousehold,
|
||||
SearchOptions,
|
||||
Suggestion,
|
||||
} from "ChillPersonAssets/types";
|
||||
|
||||
@@ -47,9 +47,7 @@ const canRemove = computed<boolean>((): boolean => {
|
||||
</p>
|
||||
<div v-else class="flex-table">
|
||||
<div v-for="a in notNullAttachments" :key="a.id" class="item-bloc">
|
||||
<generic-doc-item-box
|
||||
:generic-doc="a.genericDoc"
|
||||
></generic-doc-item-box>
|
||||
<generic-doc-item-box :generic-doc="a.genericDoc"></generic-doc-item-box>
|
||||
<div class="item-row separator">
|
||||
<ul class="record_actions">
|
||||
<li>
|
||||
|
||||
@@ -49,9 +49,8 @@ onMounted(async () => {
|
||||
|
||||
genericDocs.value = fetchedGenericDocs.filter(
|
||||
(doc) =>
|
||||
!documentClasses.includes(
|
||||
props.workflow?.relatedEntityClass || "",
|
||||
) || props.workflow?.relatedEntityId !== doc.identifiers.id,
|
||||
!documentClasses.includes(props.workflow?.relatedEntityClass || "") ||
|
||||
props.workflow?.relatedEntityId !== doc.identifiers.id,
|
||||
);
|
||||
loaded.value = true;
|
||||
});
|
||||
@@ -124,9 +123,7 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
return false;
|
||||
}
|
||||
|
||||
return needles.every((n: string) =>
|
||||
title.toLowerCase().includes(n),
|
||||
);
|
||||
return needles.every((n: string) => title.toLowerCase().includes(n));
|
||||
})
|
||||
.filter((genericDoc: GenericDocForAccompanyingPeriod) => {
|
||||
if (placesFilter.value.length === 0) {
|
||||
@@ -167,8 +164,7 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
aria-controls="filterOrderCollapse"
|
||||
>
|
||||
<strong
|
||||
><i class="fa fa-fw fa-filter"></i>Filtrer la
|
||||
liste</strong
|
||||
><i class="fa fa-fw fa-filter"></i>Filtrer la liste</strong
|
||||
>
|
||||
</button>
|
||||
</h2>
|
||||
@@ -193,10 +189,7 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
placeholder="Chercher dans la liste"
|
||||
class="form-control"
|
||||
/>
|
||||
<button
|
||||
type="submit"
|
||||
class="btn btn-misc"
|
||||
>
|
||||
<button type="submit" class="btn btn-misc">
|
||||
<i class="fa fa-search"></i>
|
||||
</button>
|
||||
</div>
|
||||
@@ -204,9 +197,7 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
</div>
|
||||
|
||||
<div class="row my-2">
|
||||
<legend
|
||||
class="col-form-label col-sm-4 required"
|
||||
>
|
||||
<legend class="col-form-label col-sm-4 required">
|
||||
Date du document
|
||||
</legend>
|
||||
<div class="col-sm-8 pt-1">
|
||||
@@ -232,15 +223,9 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
</div>
|
||||
|
||||
<div class="row my-2">
|
||||
<div class="col-sm-4 col-form-label">
|
||||
Filtrer par
|
||||
</div>
|
||||
<div class="col-sm-4 col-form-label">Filtrer par</div>
|
||||
<div class="col-sm-8 pt-2">
|
||||
<div
|
||||
class="form-check"
|
||||
v-for="p in availablePlaces"
|
||||
:key="p"
|
||||
>
|
||||
<div class="form-check" v-for="p in availablePlaces" :key="p">
|
||||
<input
|
||||
type="checkbox"
|
||||
v-model="placesFilter"
|
||||
@@ -248,9 +233,7 @@ const filteredDocuments = computed<GenericDocForAccompanyingPeriod[]>(() => {
|
||||
class="form-check-input"
|
||||
:value="p"
|
||||
/>
|
||||
<label class="form-check-label">{{
|
||||
placeTrans(p)
|
||||
}}</label>
|
||||
<label class="form-check-label">{{ placeTrans(p) }}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -100,8 +100,8 @@ defineExpose({ openModal, closeModal });
|
||||
@click="onConfirm"
|
||||
>
|
||||
<template v-if="numberOfPicked > 1">
|
||||
<i class="fa fa-plus"></i> Ajouter
|
||||
{{ numberOfPicked }} pièces jointes
|
||||
<i class="fa fa-plus"></i> Ajouter {{ numberOfPicked }} pièces
|
||||
jointes
|
||||
</template>
|
||||
<template v-else>
|
||||
<i class="fa fa-plus"></i> Ajouter une pièce jointe
|
||||
|
||||
@@ -5,10 +5,7 @@
|
||||
:class="{ active: subscriberFinal }"
|
||||
type="button"
|
||||
@click="
|
||||
subscribeTo(
|
||||
subscriberFinal ? 'unsubscribe' : 'subscribe',
|
||||
'final',
|
||||
)
|
||||
subscribeTo(subscriberFinal ? 'unsubscribe' : 'subscribe', 'final')
|
||||
"
|
||||
>
|
||||
<i
|
||||
@@ -21,12 +18,7 @@
|
||||
class="btn btn-outline-primary text-start d-flex align-items-center"
|
||||
:class="{ active: subscriberStep }"
|
||||
type="button"
|
||||
@click="
|
||||
subscribeTo(
|
||||
subscriberStep ? 'unsubscribe' : 'subscribe',
|
||||
'step',
|
||||
)
|
||||
"
|
||||
@click="subscribeTo(subscriberStep ? 'unsubscribe' : 'subscribe', 'step')"
|
||||
>
|
||||
<i
|
||||
class="fa fa-fw me-2"
|
||||
|
||||
@@ -23,10 +23,7 @@
|
||||
<slot name="body"></slot>
|
||||
</div>
|
||||
<div class="modal-footer" v-if="!hideFooter">
|
||||
<button
|
||||
class="btn btn-cancel"
|
||||
@click="emits('close')"
|
||||
>
|
||||
<button class="btn btn-cancel" @click="emits('close')">
|
||||
{{ trans(MODAL_ACTION_CLOSE) }}
|
||||
</button>
|
||||
<slot name="footer"></slot>
|
||||
@@ -53,10 +50,10 @@ import { trans, MODAL_ACTION_CLOSE } from "translator";
|
||||
import { defineProps } from "vue";
|
||||
|
||||
defineSlots<{
|
||||
header?: () => any,
|
||||
body?: () => any,
|
||||
footer?: () => any,
|
||||
"body-head"?: () => any,
|
||||
header?: () => any;
|
||||
body?: () => any;
|
||||
footer?: () => any;
|
||||
"body-head"?: () => any;
|
||||
}>();
|
||||
|
||||
export interface ModalProps {
|
||||
|
||||
@@ -1,7 +1,9 @@
|
||||
import { ref } from "vue";
|
||||
import { ValidationExceptionInterface } from "ChillMainAssets/types";
|
||||
|
||||
export function useViolationList<T extends Record<string, Record<string, string>>>() {
|
||||
export function useViolationList<
|
||||
T extends Record<string, Record<string, string>>,
|
||||
>() {
|
||||
type ViolationKey = Extract<keyof T, string>;
|
||||
const violationsList = ref<ValidationExceptionInterface<T> | null>(null);
|
||||
|
||||
@@ -9,15 +11,15 @@ export function useViolationList<T extends Record<string, Record<string, string>
|
||||
if (null === violationsList.value) {
|
||||
return [];
|
||||
}
|
||||
const r = violationsList.value.violationsByNormalizedProperty(property).map((v) => v.title);
|
||||
|
||||
const r = violationsList.value
|
||||
.violationsByNormalizedProperty(property)
|
||||
.map((v) => v.title);
|
||||
|
||||
return r;
|
||||
|
||||
}
|
||||
function violationTitlesWithParameter<
|
||||
P extends ViolationKey,
|
||||
Param extends Extract<keyof T[P], string>
|
||||
Param extends Extract<keyof T[P], string>,
|
||||
>(
|
||||
property: P,
|
||||
with_parameter: Param,
|
||||
@@ -26,26 +28,38 @@ export function useViolationList<T extends Record<string, Record<string, string>
|
||||
if (violationsList.value === null) {
|
||||
return [];
|
||||
}
|
||||
return violationsList.value.violationsByNormalizedPropertyAndParams(property, with_parameter, with_parameter_value)
|
||||
return violationsList.value
|
||||
.violationsByNormalizedPropertyAndParams(
|
||||
property,
|
||||
with_parameter,
|
||||
with_parameter_value,
|
||||
)
|
||||
.map((v) => v.title);
|
||||
}
|
||||
|
||||
|
||||
function hasViolation<P extends ViolationKey>(property: P): boolean {
|
||||
return violationTitles(property).length > 0;
|
||||
}
|
||||
function hasViolationWithParameter<
|
||||
P extends ViolationKey,
|
||||
Param extends Extract<keyof T[P], string>
|
||||
Param extends Extract<keyof T[P], string>,
|
||||
>(
|
||||
property: P,
|
||||
with_parameter: Param,
|
||||
with_parameter_value: T[P][Param],
|
||||
): boolean {
|
||||
return violationTitlesWithParameter(property, with_parameter, with_parameter_value).length > 0;
|
||||
return (
|
||||
violationTitlesWithParameter(
|
||||
property,
|
||||
with_parameter,
|
||||
with_parameter_value,
|
||||
).length > 0
|
||||
);
|
||||
}
|
||||
|
||||
function setValidationException<V extends ValidationExceptionInterface<T>>(validationException: V): void {
|
||||
function setValidationException<V extends ValidationExceptionInterface<T>>(
|
||||
validationException: V,
|
||||
): void {
|
||||
violationsList.value = validationException;
|
||||
}
|
||||
|
||||
@@ -53,5 +67,12 @@ export function useViolationList<T extends Record<string, Record<string, string>
|
||||
violationsList.value = null;
|
||||
}
|
||||
|
||||
return {violationTitles, violationTitlesWithParameter, setValidationException, cleanException, hasViolationWithParameter, hasViolation};
|
||||
return {
|
||||
violationTitles,
|
||||
violationTitlesWithParameter,
|
||||
setValidationException,
|
||||
cleanException,
|
||||
hasViolationWithParameter,
|
||||
hasViolation,
|
||||
};
|
||||
}
|
||||
|
||||
@@ -14,7 +14,8 @@ import {
|
||||
DateTimeWrite,
|
||||
SetGender,
|
||||
SetCenter,
|
||||
SetCivility, Gender,
|
||||
SetCivility,
|
||||
Gender,
|
||||
} from "ChillMainAssets/types";
|
||||
import { StoredObject } from "ChillDocStoreAssets/types";
|
||||
import { Thirdparty } from "../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
@@ -299,7 +300,7 @@ export interface AccompanyingPeriodWorkGoal {
|
||||
}
|
||||
|
||||
export interface AccompanyingPeriodWorkEvaluation {
|
||||
type: 'accompanying_period_work_evaluation';
|
||||
type: "accompanying_period_work_evaluation";
|
||||
accompanyingPeriodWork: AccompanyingPeriodWork | null;
|
||||
comment: string;
|
||||
createdAt: DateTime | null;
|
||||
@@ -432,7 +433,7 @@ export type EntityType =
|
||||
| "user"
|
||||
| "household";
|
||||
|
||||
export type Entities = (UserGroup | User | Person | Thirdparty | Household);
|
||||
export type Entities = UserGroup | User | Person | Thirdparty | Household;
|
||||
|
||||
export function isEntityHousehold(e: Entities): e is Household {
|
||||
return e.type === "household";
|
||||
@@ -440,25 +441,34 @@ export function isEntityHousehold(e: Entities): e is Household {
|
||||
|
||||
export type EntitiesOrMe = "me" | Entities;
|
||||
|
||||
|
||||
// Type guards to discriminate Suggestions by their result kind
|
||||
export function isSuggestionForUserGroup(s: Suggestion): s is Suggestion & { result: UserGroup } {
|
||||
export function isSuggestionForUserGroup(
|
||||
s: Suggestion,
|
||||
): s is Suggestion & { result: UserGroup } {
|
||||
return (s as any)?.result?.type === "user_group";
|
||||
}
|
||||
|
||||
export function isSuggestionForUser(s: Suggestion): s is Suggestion & { result: User } {
|
||||
export function isSuggestionForUser(
|
||||
s: Suggestion,
|
||||
): s is Suggestion & { result: User } {
|
||||
return (s as any)?.result?.type === "user";
|
||||
}
|
||||
|
||||
export function isSuggestionForPerson(s: Suggestion): s is Suggestion & { result: Person } {
|
||||
export function isSuggestionForPerson(
|
||||
s: Suggestion,
|
||||
): s is Suggestion & { result: Person } {
|
||||
return (s as any)?.result?.type === "person";
|
||||
}
|
||||
|
||||
export function isSuggestionForThirdParty(s: Suggestion): s is Suggestion & { result: Thirdparty } {
|
||||
export function isSuggestionForThirdParty(
|
||||
s: Suggestion,
|
||||
): s is Suggestion & { result: Thirdparty } {
|
||||
return (s as any)?.result?.type === "thirdparty";
|
||||
}
|
||||
|
||||
export function isSuggestionForHousehold(s: Suggestion): s is Suggestion & { result: Household } {
|
||||
export function isSuggestionForHousehold(
|
||||
s: Suggestion,
|
||||
): s is Suggestion & { result: Household } {
|
||||
return (s as any)?.result?.type === "household";
|
||||
}
|
||||
|
||||
@@ -482,7 +492,7 @@ export interface SearchPagination {
|
||||
export interface Search {
|
||||
count: number;
|
||||
pagination: SearchPagination;
|
||||
results: {relevance: number, result: Entities}[];
|
||||
results: { relevance: number; result: Entities }[];
|
||||
}
|
||||
|
||||
export interface SearchOptions {
|
||||
@@ -498,7 +508,11 @@ export interface SearchOptions {
|
||||
};
|
||||
}
|
||||
|
||||
type PersonIdentifierPresence = 'NOT_EDITABLE' | 'ON_EDIT' | 'ON_CREATION' | 'REQUIRED';
|
||||
type PersonIdentifierPresence =
|
||||
| "NOT_EDITABLE"
|
||||
| "ON_EDIT"
|
||||
| "ON_CREATION"
|
||||
| "REQUIRED";
|
||||
|
||||
export interface PersonIdentifierWorker {
|
||||
type: "person_identifier_worker";
|
||||
|
||||
@@ -42,9 +42,7 @@
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<button
|
||||
class="btn btn-save"
|
||||
@click="modal.showModal = true">
|
||||
<button class="btn btn-save" @click="modal.showModal = true">
|
||||
{{ $t("confirm.ok") }}
|
||||
</button>
|
||||
</li>
|
||||
|
||||
@@ -84,8 +84,12 @@
|
||||
<ul class="record_actions">
|
||||
<li class="add-persons">
|
||||
<add-persons
|
||||
:button-title="trans(ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON)"
|
||||
:modal-title="trans(ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON)"
|
||||
:button-title="
|
||||
trans(ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON)
|
||||
"
|
||||
:modal-title="
|
||||
trans(ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON)
|
||||
"
|
||||
:key="addPersons.key"
|
||||
:options="addPersons.options"
|
||||
@add-new-persons="addNewPersons"
|
||||
@@ -108,7 +112,10 @@ import { mapGetters, mapState } from "vuex";
|
||||
import ParticipationItem from "./PersonsAssociated/ParticipationItem.vue";
|
||||
import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
|
||||
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
|
||||
import {ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON, trans} from "translator";
|
||||
import {
|
||||
ACCOMPANYING_COURSE_PERSONS_ASSOCIATED_ADD_PERSON,
|
||||
trans,
|
||||
} from "translator";
|
||||
|
||||
export default {
|
||||
name: "PersonsAssociated",
|
||||
|
||||
@@ -55,9 +55,7 @@
|
||||
<!-- 1. Goals with results that were already selected/saved to the entity -->
|
||||
<div v-for="g in goalsPicked" :key="g.goal.id">
|
||||
<div class="item-title" @click="removeGoal(g)">
|
||||
<span class="removable">{{
|
||||
localizeString(g.goal.title)
|
||||
}}</span>
|
||||
<span class="removable">{{ localizeString(g.goal.title) }}</span>
|
||||
</div>
|
||||
<div>
|
||||
<add-result :goal="g.goal" destination="goal"></add-result>
|
||||
@@ -90,14 +88,8 @@
|
||||
|
||||
<!-- 3. Selector for objectives with results -->
|
||||
<div class="accordion" id="expandedSuggestions">
|
||||
<div
|
||||
v-if="availableForCheckGoal.length > 0"
|
||||
class="accordion-item"
|
||||
>
|
||||
<h2
|
||||
class="accordion-header"
|
||||
id="heading_expanded_suggestions"
|
||||
>
|
||||
<div v-if="availableForCheckGoal.length > 0" class="accordion-item">
|
||||
<h2 class="accordion-header" id="heading_expanded_suggestions">
|
||||
<button
|
||||
v-if="isExpanded"
|
||||
class="accordion-button"
|
||||
@@ -138,10 +130,7 @@
|
||||
</ul>
|
||||
</template>
|
||||
</div>
|
||||
<p
|
||||
v-if="goalsPicked.length === 0"
|
||||
class="chill-no-data-statement"
|
||||
>
|
||||
<p v-if="goalsPicked.length === 0" class="chill-no-data-statement">
|
||||
Aucun objectif associé
|
||||
</p>
|
||||
</div>
|
||||
@@ -188,10 +177,7 @@
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
<ul
|
||||
class="record_actions"
|
||||
v-if="evaluationsForAction.length > 0"
|
||||
>
|
||||
<ul class="record_actions" v-if="evaluationsForAction.length > 0">
|
||||
<li>
|
||||
<button
|
||||
:title="$t('add_an_evaluation')"
|
||||
@@ -223,10 +209,7 @@
|
||||
class="me-2 form-check-input"
|
||||
:id="'person_check' + p.id"
|
||||
/>
|
||||
<label
|
||||
:for="'person_check' + p.id"
|
||||
class="form-check-label"
|
||||
>
|
||||
<label :for="'person_check' + p.id" class="form-check-label">
|
||||
<person-text :person="p"></person-text>
|
||||
</label>
|
||||
</div>
|
||||
@@ -244,10 +227,7 @@
|
||||
class="me-2 form-check-input"
|
||||
:id="'person_check' + p.id"
|
||||
/>
|
||||
<label
|
||||
:for="'person_check' + p.id"
|
||||
class="form-check-label"
|
||||
>
|
||||
<label :for="'person_check' + p.id" class="form-check-label">
|
||||
<person-text :person="p"></person-text>
|
||||
</label>
|
||||
</div>
|
||||
@@ -310,9 +290,7 @@
|
||||
<add-persons
|
||||
ref="handlingThirdPartyPicker"
|
||||
v-bind:key="handlingThirdPartyPicker.key"
|
||||
v-bind:buttonTitle="
|
||||
$t('precise_handling_thirdparty')
|
||||
"
|
||||
v-bind:buttonTitle="$t('precise_handling_thirdparty')"
|
||||
v-bind:modalTitle="$t('choose_a_thirdparty')"
|
||||
v-bind:options="handlingThirdPartyPicker.options"
|
||||
@addNewPersons="setHandlingThirdParty"
|
||||
@@ -458,23 +436,16 @@
|
||||
>
|
||||
|
||||
</button>
|
||||
<ul
|
||||
class="dropdown-menu"
|
||||
aria-labelledby="btnGroupNotifyButtons"
|
||||
>
|
||||
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons">
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="goToGenerateNotification(true)"
|
||||
>{{ $t("notification_notify_referrer") }}</a
|
||||
>
|
||||
<a class="dropdown-item" @click="goToGenerateNotification(true)">{{
|
||||
$t("notification_notify_referrer")
|
||||
}}</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="goToGenerateNotification(false)"
|
||||
>{{ $t("notification_notify_any") }}</a
|
||||
>
|
||||
<a class="dropdown-item" @click="goToGenerateNotification(false)">{{
|
||||
$t("notification_notify_any")
|
||||
}}</a>
|
||||
</li>
|
||||
</ul>
|
||||
</template>
|
||||
@@ -523,8 +494,7 @@ const i18n = {
|
||||
available_goals_text:
|
||||
"Motifs, objectifs et dispositifs disponibles pour ajout :",
|
||||
results_title: "Orientations - résultats",
|
||||
results_without_objective:
|
||||
"Résultats - orientations sans objectifs",
|
||||
results_without_objective: "Résultats - orientations sans objectifs",
|
||||
add_objectif: "Ajouter un motif - objectif - dispositif",
|
||||
add_an_objective: "Ajouter un objectif",
|
||||
Evaluations: "Évaluations",
|
||||
@@ -725,10 +695,7 @@ export default {
|
||||
this.showAddEvaluation = !this.showAddEvaluation;
|
||||
},
|
||||
setHandlingThirdParty({ selected, modal }) {
|
||||
this.$store.commit(
|
||||
"setHandlingThirdParty",
|
||||
selected.shift().result,
|
||||
);
|
||||
this.$store.commit("setHandlingThirdParty", selected.shift().result);
|
||||
this.$refs.handlingThirdPartyPicker.resetSearch();
|
||||
modal.showModal = false;
|
||||
},
|
||||
@@ -840,9 +807,7 @@ export default {
|
||||
});
|
||||
},
|
||||
scrollToElement(docAnchorId) {
|
||||
const documentEl = document.getElementById(
|
||||
`document_${docAnchorId}`,
|
||||
);
|
||||
const documentEl = document.getElementById(`document_${docAnchorId}`);
|
||||
if (documentEl) {
|
||||
documentEl.scrollIntoView({ behavior: "smooth" });
|
||||
}
|
||||
|
||||
@@ -6,15 +6,11 @@
|
||||
class="item-bloc"
|
||||
v-for="(d, i) in documents"
|
||||
:key="d.id"
|
||||
:class="[
|
||||
parseInt(docAnchorId) === d.id ? 'bg-blink' : 'nothing',
|
||||
]"
|
||||
:class="[parseInt(docAnchorId) === d.id ? 'bg-blink' : 'nothing']"
|
||||
>
|
||||
<div :id="'document_' + d.id" class="item-row">
|
||||
<div class="input-group input-group-lg mb-3 row">
|
||||
<label class="col-sm-3 col-form-label"
|
||||
>Titre du document:</label
|
||||
>
|
||||
<label class="col-sm-3 col-form-label">Titre du document:</label>
|
||||
<div class="col-sm-9">
|
||||
<input
|
||||
class="form-control document-title"
|
||||
@@ -32,9 +28,7 @@
|
||||
<p v-if="d.createdBy" class="createdBy">
|
||||
Créé par {{ d.createdBy.text }}<br />
|
||||
Le
|
||||
{{
|
||||
$d(ISOToDatetime(d.createdAt.datetime), "long")
|
||||
}}
|
||||
{{ $d(ISOToDatetime(d.createdAt.datetime), "long") }}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
@@ -43,8 +37,7 @@
|
||||
<ul class="record_actions">
|
||||
<li
|
||||
v-if="
|
||||
d.workflows_availables.length > 0 ||
|
||||
d.workflows.length > 0
|
||||
d.workflows_availables.length > 0 || d.workflows.length > 0
|
||||
"
|
||||
>
|
||||
<list-workflow-modal
|
||||
@@ -52,9 +45,7 @@
|
||||
:allowCreate="true"
|
||||
relatedEntityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument"
|
||||
:relatedEntityId="d.id"
|
||||
:workflowsAvailables="
|
||||
d.workflows_availables
|
||||
"
|
||||
:workflowsAvailables="d.workflows_availables"
|
||||
:preventDefaultMoveToGenerate="true"
|
||||
:goToGenerateWorkflowPayload="{ doc: d }"
|
||||
@go-to-generate-workflow="
|
||||
@@ -66,22 +57,14 @@
|
||||
<button
|
||||
v-if="AmIRefferer"
|
||||
class="btn btn-notify"
|
||||
@click="
|
||||
$emit(
|
||||
'goToGenerateNotification',
|
||||
d,
|
||||
false,
|
||||
)
|
||||
"
|
||||
@click="$emit('goToGenerateNotification', d, false)"
|
||||
></button>
|
||||
<template v-else>
|
||||
<button
|
||||
id="btnGroupNotifyButtons"
|
||||
type="button"
|
||||
class="btn btn-notify dropdown-toggle"
|
||||
:title="
|
||||
trans(EVALUATION_NOTIFICATION_SEND)
|
||||
"
|
||||
:title="trans(EVALUATION_NOTIFICATION_SEND)"
|
||||
data-bs-toggle="dropdown"
|
||||
aria-expanded="false"
|
||||
>
|
||||
@@ -94,35 +77,17 @@
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
goToGenerateDocumentNotification(
|
||||
d,
|
||||
true,
|
||||
)
|
||||
"
|
||||
@click="goToGenerateDocumentNotification(d, true)"
|
||||
>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_NOTIFICATION_NOTIFY_REFERRER,
|
||||
)
|
||||
}}
|
||||
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_REFERRER) }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
goToGenerateDocumentNotification(
|
||||
d,
|
||||
false,
|
||||
)
|
||||
"
|
||||
@click="goToGenerateDocumentNotification(d, false)"
|
||||
>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_NOTIFICATION_NOTIFY_ANY,
|
||||
)
|
||||
}}
|
||||
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_ANY) }}
|
||||
</a>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -133,15 +98,10 @@
|
||||
:stored-object="d.storedObject"
|
||||
:filename="d.title"
|
||||
:can-edit="true"
|
||||
:execute-before-leave="
|
||||
submitBeforeLeaveToEditor
|
||||
"
|
||||
:davLink="
|
||||
d.storedObject._links?.dav_link.href
|
||||
"
|
||||
:execute-before-leave="submitBeforeLeaveToEditor"
|
||||
:davLink="d.storedObject._links?.dav_link.href"
|
||||
:davLinkExpiration="
|
||||
d.storedObject._links?.dav_link
|
||||
.expiration
|
||||
d.storedObject._links?.dav_link.expiration
|
||||
"
|
||||
@on-stored-object-status-change="
|
||||
$emit('statusDocumentChanged', $event)
|
||||
@@ -151,8 +111,7 @@
|
||||
<!--replace document-->
|
||||
<li
|
||||
v-if="
|
||||
Number.isInteger(d.id) &&
|
||||
d.storedObject._permissions.canEdit
|
||||
Number.isInteger(d.id) && d.storedObject._permissions.canEdit
|
||||
"
|
||||
>
|
||||
<drop-file-modal
|
||||
@@ -183,56 +142,28 @@
|
||||
<li v-if="d.workflows.length === 0">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
$emit('removeDocument', d)
|
||||
"
|
||||
@click="$emit('removeDocument', d)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-trash-o"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_DOCUMENT_DELETE,
|
||||
)
|
||||
}}
|
||||
<i class="fa fa-trash-o" aria-hidden="true"></i>
|
||||
{{ trans(EVALUATION_DOCUMENT_DELETE) }}
|
||||
</a>
|
||||
</li>
|
||||
<!--duplicate document-->
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
$emit(
|
||||
'duplicateDocument',
|
||||
d,
|
||||
)
|
||||
"
|
||||
@click="$emit('duplicateDocument', d)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-copy"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_DOCUMENT_DUPLICATE_HERE,
|
||||
)
|
||||
}}
|
||||
<i class="fa fa-copy" aria-hidden="true"></i>
|
||||
{{ trans(EVALUATION_DOCUMENT_DUPLICATE_HERE) }}
|
||||
</a>
|
||||
</li>
|
||||
<li>
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
prepareDocumentDuplicationToWork(
|
||||
d,
|
||||
)
|
||||
"
|
||||
@click="prepareDocumentDuplicationToWork(d)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-copy"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
<i class="fa fa-copy" aria-hidden="true"></i>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
|
||||
@@ -241,27 +172,13 @@
|
||||
>
|
||||
</li>
|
||||
<!--move document-->
|
||||
<li
|
||||
v-if="
|
||||
d.storedObject._permissions
|
||||
.canEdit
|
||||
"
|
||||
>
|
||||
<li v-if="d.storedObject._permissions.canEdit">
|
||||
<a
|
||||
class="dropdown-item"
|
||||
@click="
|
||||
prepareDocumentMoveToWork(d)
|
||||
"
|
||||
@click="prepareDocumentMoveToWork(d)"
|
||||
>
|
||||
<i
|
||||
class="fa fa-arrows"
|
||||
aria-hidden="true"
|
||||
></i>
|
||||
{{
|
||||
trans(
|
||||
EVALUATION_DOCUMENT_MOVE,
|
||||
)
|
||||
}}</a
|
||||
<i class="fa fa-arrows" aria-hidden="true"></i>
|
||||
{{ trans(EVALUATION_DOCUMENT_MOVE) }}</a
|
||||
>
|
||||
</li>
|
||||
</ul>
|
||||
@@ -427,9 +344,7 @@ async function goToGenerateDocumentNotification(document, tos) {
|
||||
buildLinkCreateNotification(
|
||||
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
|
||||
updatedDocument.id,
|
||||
tos === true
|
||||
? store.state.work.accompanyingPeriod.user?.id
|
||||
: null,
|
||||
tos === true ? store.state.work.accompanyingPeriod.user?.id : null,
|
||||
window.location.pathname +
|
||||
window.location.search +
|
||||
window.location.hash,
|
||||
|
||||
@@ -29,9 +29,7 @@
|
||||
@inputDocumentTitle="onInputDocumentTitle"
|
||||
@removeDocument="removeDocument"
|
||||
@duplicateDocument="duplicateDocument"
|
||||
@duplicate-document-to-evaluation="
|
||||
duplicateDocumentToEvaluation
|
||||
"
|
||||
@duplicate-document-to-evaluation="duplicateDocumentToEvaluation"
|
||||
@move-document-to-evaluation="moveDocumentToEvaluation"
|
||||
@statusDocumentChanged="onStatusDocumentChanged"
|
||||
@goToGenerateNotification="goToGenerateDocumentNotification"
|
||||
@@ -381,9 +379,7 @@ function goToGenerateDocumentNotification(document, tos) {
|
||||
buildLinkCreateNotification(
|
||||
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
|
||||
updatedDocument.id,
|
||||
tos === true
|
||||
? store.state.work.accompanyingPeriod.user.id
|
||||
: null,
|
||||
tos === true ? store.state.work.accompanyingPeriod.user.id : null,
|
||||
window.location.pathname +
|
||||
window.location.search +
|
||||
window.location.hash,
|
||||
|
||||
@@ -2,7 +2,8 @@ import { fetchResults, makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import { Center, Civility, Gender, SetCenter } from "ChillMainAssets/types";
|
||||
import {
|
||||
AltName,
|
||||
Person, PersonIdentifier,
|
||||
Person,
|
||||
PersonIdentifier,
|
||||
PersonIdentifierWorker,
|
||||
PersonWrite,
|
||||
} from "ChillPersonAssets/types";
|
||||
@@ -26,21 +27,43 @@ export const personToWritePerson = (person: Person): PersonWrite => {
|
||||
type: "person",
|
||||
firstName: person.firstName,
|
||||
lastName: person.lastName,
|
||||
altNames: person.altNames.map((altName) => ({key: altName.key, value: altName.label})),
|
||||
altNames: person.altNames.map((altName) => ({
|
||||
key: altName.key,
|
||||
value: altName.label,
|
||||
})),
|
||||
addressId: null,
|
||||
birthdate: null === person.birthdate ? null : {datetime: person.birthdate.datetime8601},
|
||||
deathdate: null === person.deathdate ? null : {datetime: person.deathdate.datetime8601},
|
||||
birthdate:
|
||||
null === person.birthdate
|
||||
? null
|
||||
: { datetime: person.birthdate.datetime8601 },
|
||||
deathdate:
|
||||
null === person.deathdate
|
||||
? null
|
||||
: { datetime: person.deathdate.datetime8601 },
|
||||
phonenumber: person.phonenumber,
|
||||
mobilenumber: person.mobilenumber,
|
||||
center: null === person.centers ? null : person.centers
|
||||
center:
|
||||
null === person.centers
|
||||
? null
|
||||
: person.centers
|
||||
.map((center): SetCenter => ({ id: center.id, type: "center" }))
|
||||
.find(() => true) || null,
|
||||
email: person.email,
|
||||
civility: null === person.civility ? null : {id: person.civility.id, type: "chill_main_civility"},
|
||||
gender: null === person.gender ? null : {id: person.gender.id, type: "chill_main_gender"},
|
||||
identifiers: person.identifiers.map((identifier: PersonIdentifier) => ({type: "person_identifier", definition_id: identifier.definition.id, value: identifier.value})),
|
||||
}
|
||||
}
|
||||
civility:
|
||||
null === person.civility
|
||||
? null
|
||||
: { id: person.civility.id, type: "chill_main_civility" },
|
||||
gender:
|
||||
null === person.gender
|
||||
? null
|
||||
: { id: person.gender.id, type: "chill_main_gender" },
|
||||
identifiers: person.identifiers.map((identifier: PersonIdentifier) => ({
|
||||
type: "person_identifier",
|
||||
definition_id: identifier.definition.id,
|
||||
value: identifier.value,
|
||||
})),
|
||||
};
|
||||
};
|
||||
|
||||
export const getPersonAltNames = async (): Promise<AltName[]> =>
|
||||
fetch("/api/1.0/person/config/alt_names.json").then((response) => {
|
||||
@@ -65,10 +88,12 @@ export const getPersonIdentifiers = async (): Promise<
|
||||
PersonIdentifierWorker[]
|
||||
> => fetchResults("/api/1.0/person/identifiers/workers");
|
||||
|
||||
export interface WritePersonViolationMap
|
||||
extends Record<string, Record<string, string>> {
|
||||
export interface WritePersonViolationMap extends Record<
|
||||
string,
|
||||
Record<string, string>
|
||||
> {
|
||||
firstName: {
|
||||
"{{ value }}": string
|
||||
"{{ value }}": string;
|
||||
};
|
||||
lastName: {
|
||||
"{{ value }}": string;
|
||||
@@ -96,7 +121,7 @@ export interface WritePersonViolationMap
|
||||
birthdate: {};
|
||||
identifiers: {
|
||||
"{{ value }}": string;
|
||||
"definition_id": string;
|
||||
definition_id: string;
|
||||
};
|
||||
}
|
||||
export const createPerson = async (person: PersonWrite): Promise<Person> => {
|
||||
@@ -107,10 +132,13 @@ export const createPerson = async (person: PersonWrite): Promise<Person> => {
|
||||
);
|
||||
};
|
||||
|
||||
export const editPerson = async (person: PersonWrite, personId: number): Promise<Person> => {
|
||||
export const editPerson = async (
|
||||
person: PersonWrite,
|
||||
personId: number,
|
||||
): Promise<Person> => {
|
||||
return makeFetch<PersonWrite, Person, WritePersonViolationMap>(
|
||||
"PATCH",
|
||||
`/api/1.0/person/person/${personId}.json`,
|
||||
person,
|
||||
);
|
||||
}
|
||||
};
|
||||
|
||||
@@ -15,11 +15,7 @@
|
||||
<ul class="small_in_title columns mt-1">
|
||||
<li>
|
||||
<span class="item-key">
|
||||
{{
|
||||
trans(
|
||||
ACCOMPANYING_COURSE_WORK_START_DATE,
|
||||
)
|
||||
}}
|
||||
{{ trans(ACCOMPANYING_COURSE_WORK_START_DATE) }}
|
||||
:
|
||||
</span>
|
||||
<b>{{ formatDate(eval.startDate) }}</b>
|
||||
@@ -27,9 +23,7 @@
|
||||
|
||||
<li v-if="eval.endDate">
|
||||
<span class="item-key">
|
||||
{{
|
||||
trans(ACCOMPANYING_COURSE_WORK_END_DATE)
|
||||
}}
|
||||
{{ trans(ACCOMPANYING_COURSE_WORK_END_DATE) }}
|
||||
:
|
||||
</span>
|
||||
<b>{{ formatDate(eval.endDate) }}</b>
|
||||
|
||||
@@ -34,8 +34,10 @@
|
||||
|
||||
<template #body>
|
||||
<accompanying-period-work-list
|
||||
v-if="evaluations.length === 0":accompanying-period-works="accompanyingPeriodWorks"
|
||||
v-model:selectedAcpw="selectedAcpw"/>
|
||||
v-if="evaluations.length === 0"
|
||||
:accompanying-period-works="accompanyingPeriodWorks"
|
||||
v-model:selectedAcpw="selectedAcpw"
|
||||
/>
|
||||
<accompanying-period-work-evaluation-list
|
||||
v-if="evaluations.length > 0"
|
||||
:evaluations="evaluations"
|
||||
@@ -59,9 +61,10 @@ import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
|
||||
import AccompanyingPeriodWorkList from "./AccompanyingPeriodWorkList.vue";
|
||||
import { AccompanyingPeriodWork } from "../../../types";
|
||||
import {
|
||||
trans,ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK,
|
||||
ACPW_DUPLICATE_SELECT_AN_EVALUATION,CONFIRM,
|
||||
|
||||
trans,
|
||||
ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK,
|
||||
ACPW_DUPLICATE_SELECT_AN_EVALUATION,
|
||||
CONFIRM,
|
||||
} from "translator";
|
||||
import { fetchResults } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import AccompanyingPeriodWorkEvaluationList from "ChillPersonAssets/vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkEvaluationList.vue";
|
||||
@@ -147,14 +150,14 @@ const confirmSelection = () => {
|
||||
if (!props.isEvaluationSelector) {
|
||||
if (selectedAcpw.value) {
|
||||
// only emit if something is actually selected!emit("pickWork", { work: selectedAcpw.value });
|
||||
closeModal();}
|
||||
closeModal();
|
||||
}
|
||||
// optionally show some error or warning if not selected
|
||||
return;
|
||||
}
|
||||
|
||||
if (selectedAcpw.value && props.isEvaluationSelector) {
|
||||
evaluations.value =
|
||||
selectedAcpw.value.accompanyingPeriodWorkEvaluations;
|
||||
evaluations.value = selectedAcpw.value.accompanyingPeriodWorkEvaluations;
|
||||
}
|
||||
|
||||
if (selectedEvaluation.value && props.isEvaluationSelector) {
|
||||
|
||||
@@ -25,7 +25,11 @@
|
||||
/>
|
||||
|
||||
<CreateModal
|
||||
v-if="creatableEntityTypes.length > 0 && showModalCreate && null == thirdPartyParentAddContact"
|
||||
v-if="
|
||||
creatableEntityTypes.length > 0 &&
|
||||
showModalCreate &&
|
||||
null == thirdPartyParentAddContact
|
||||
"
|
||||
action="create"
|
||||
:allowed-types="creatableEntityTypes"
|
||||
:query="query"
|
||||
@@ -62,7 +66,10 @@ import type {
|
||||
import { marked } from "marked";
|
||||
import options = marked.options;
|
||||
import CreateModal from "ChillMainAssets/vuejs/OnTheFly/components/CreateModal.vue";
|
||||
import {Thirdparty, ThirdpartyCompany} from "../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
import {
|
||||
Thirdparty,
|
||||
ThirdpartyCompany,
|
||||
} from "../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
interface AddPersonsConfig {
|
||||
suggested?: Suggestion[];
|
||||
@@ -80,13 +87,13 @@ const props = withDefaults(defineProps<AddPersonsConfig>(), {
|
||||
});
|
||||
|
||||
const emit =
|
||||
defineEmits<{
|
||||
(e: "addNewPersons", payload: { selected: Suggestion[] }): void;
|
||||
}
|
||||
defineEmits<
|
||||
(e: "addNewPersons", payload: { selected: Suggestion[] }) => void
|
||||
>();
|
||||
|
||||
type PersonChooseModalType = InstanceType<typeof PersonChooseModal>;
|
||||
const personChooseModal = useTemplateRef<PersonChooseModalType>('personChooseModal');
|
||||
const personChooseModal =
|
||||
useTemplateRef<PersonChooseModalType>("personChooseModal");
|
||||
|
||||
/**
|
||||
* Flag to show/hide the modal "choose".
|
||||
@@ -156,7 +163,7 @@ function closeModalChoose(): void {
|
||||
}
|
||||
|
||||
function closeModalCreate(): void {
|
||||
if (null !== thirdPartyParentAddContact) {
|
||||
if (null !== thirdPartyParentAddContact.value) {
|
||||
thirdPartyParentAddContact.value = null;
|
||||
}
|
||||
showModalCreate.value = false;
|
||||
@@ -165,7 +172,10 @@ function closeModalCreate(): void {
|
||||
/**
|
||||
* Called by PersonSuggestion's updateSelection event, when an element is checked/unchecked
|
||||
*/
|
||||
function updateSelected(payload: {suggestion: Suggestion, isSelected: boolean}): void {
|
||||
function updateSelected(payload: {
|
||||
suggestion: Suggestion;
|
||||
isSelected: boolean;
|
||||
}): void {
|
||||
if (payload.isSelected) {
|
||||
addSuggestionToSelected(payload.suggestion);
|
||||
} else {
|
||||
@@ -236,7 +246,7 @@ function resetSearch(): void {
|
||||
personChooseModal.value?.resetSearch();
|
||||
}
|
||||
|
||||
defineExpose({resetSearch})
|
||||
defineExpose({ resetSearch });
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -82,7 +82,11 @@
|
||||
v-if="props.allowCreate && query.length > 0"
|
||||
class="create-button"
|
||||
>
|
||||
<button type="button" class="btn btn-submit" @click="emit('onAskForCreate', { query })">
|
||||
<button
|
||||
type="button"
|
||||
class="btn btn-submit"
|
||||
@click="emit('onAskForCreate', { query })"
|
||||
>
|
||||
{{ trans(ONTHEFLY_CREATE_BUTTON, { q: query }) }}
|
||||
</button>
|
||||
</div>
|
||||
@@ -147,7 +151,10 @@ const emit = defineEmits<{
|
||||
(e: "onPickEntities"): void;
|
||||
(e: "onAskForCreate", payload: { query: string }): void;
|
||||
(e: "triggerAddContact", payload: { parent: ThirdpartyCompany }): void;
|
||||
(e: "updateSelected", payload: {suggestion: Suggestion, isSelected: boolean}): void;
|
||||
(
|
||||
e: "updateSelected",
|
||||
payload: { suggestion: Suggestion; isSelected: boolean },
|
||||
): void;
|
||||
(e: "cleanSelected"): void;
|
||||
}>();
|
||||
|
||||
@@ -181,11 +188,10 @@ const queryLength = computed(() => search.query.length);
|
||||
const suggestedCounter = computed(() => suggested.value.length);
|
||||
const selectedCounter = computed(() => props.selected.size);
|
||||
|
||||
const checkUniq = computed(() =>
|
||||
props.options.uniq ? "radio" : "checkbox",
|
||||
);
|
||||
const checkUniq = computed(() => (props.options.uniq ? "radio" : "checkbox"));
|
||||
|
||||
const selectedAndSuggested = computed<(Suggestion & {isSelected: boolean})[]>(() => {
|
||||
const selectedAndSuggested = computed<(Suggestion & { isSelected: boolean })[]>(
|
||||
() => {
|
||||
const selectedAndSuggested = [];
|
||||
|
||||
// add selected that are not in the search results
|
||||
@@ -195,13 +201,19 @@ const selectedAndSuggested = computed<(Suggestion & {isSelected: boolean})[]>(()
|
||||
}
|
||||
}
|
||||
for (const suggestion of suggested.value) {
|
||||
selectedAndSuggested.push({...suggestion, isSelected: props.selected.has(suggestion.key)})
|
||||
selectedAndSuggested.push({
|
||||
...suggestion,
|
||||
isSelected: props.selected.has(suggestion.key),
|
||||
});
|
||||
}
|
||||
|
||||
return selectedAndSuggested;
|
||||
});
|
||||
},
|
||||
);
|
||||
|
||||
const hasNoResult = computed(() => search.hasPreviousQuery && suggested.value.length === 0);
|
||||
const hasNoResult = computed(
|
||||
() => search.hasPreviousQuery && suggested.value.length === 0,
|
||||
);
|
||||
|
||||
function setQuery(q: string) {
|
||||
search.query = q;
|
||||
@@ -240,14 +252,15 @@ function setQuery(q: string) {
|
||||
}, delay);
|
||||
}
|
||||
|
||||
|
||||
function loadSuggestions(suggestedArr: {relevance: number, result: Entities}[]): void {
|
||||
function loadSuggestions(
|
||||
suggestedArr: { relevance: number; result: Entities }[],
|
||||
): void {
|
||||
suggested.value = suggestedArr.map((item) => {
|
||||
return {
|
||||
key: item.result.type + item.result.id,
|
||||
relevance: item.relevance,
|
||||
result: item.result
|
||||
}
|
||||
result: item.result,
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
@@ -267,7 +280,7 @@ function resetSearch() {
|
||||
|
||||
function selectAll() {
|
||||
suggested.value.forEach((suggestion: Suggestion) => {
|
||||
emit("updateSelected", {suggestion, isSelected: true})
|
||||
emit("updateSelected", { suggestion, isSelected: true });
|
||||
});
|
||||
}
|
||||
|
||||
@@ -279,7 +292,7 @@ function triggerAddContact(payload: {parent: ThirdpartyCompany}) {
|
||||
* Triggered when the user clicks on the "add" button.
|
||||
*/
|
||||
function pickEntities(): void {
|
||||
emit("onPickEntities", );
|
||||
emit("onPickEntities");
|
||||
search.query = "";
|
||||
emit("close");
|
||||
}
|
||||
|
||||
@@ -53,9 +53,10 @@ import SuggestionUserGroup from "./TypeUserGroup.vue";
|
||||
import {
|
||||
isSuggestionForHousehold,
|
||||
isSuggestionForPerson,
|
||||
isSuggestionForThirdParty, isSuggestionForUser,
|
||||
isSuggestionForThirdParty,
|
||||
isSuggestionForUser,
|
||||
isSuggestionForUserGroup,
|
||||
Suggestion
|
||||
Suggestion,
|
||||
} from "ChillPersonAssets/types";
|
||||
import { ThirdpartyCompany } from "../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
@@ -65,11 +66,14 @@ const props = defineProps<{
|
||||
type: "radio" | "checkbox";
|
||||
}>();
|
||||
const emit = defineEmits<{
|
||||
(e: "updateSelected", payload: {suggestion: Suggestion, isSelected: boolean}): void;
|
||||
(
|
||||
e: "updateSelected",
|
||||
payload: { suggestion: Suggestion; isSelected: boolean },
|
||||
): void;
|
||||
(e: "triggerAddContact", payload: { parent: ThirdpartyCompany }): void;
|
||||
}>();
|
||||
|
||||
const isChecked = computed<boolean>(() => props.isSelected)
|
||||
const isChecked = computed<boolean>(() => props.isSelected);
|
||||
|
||||
const onUpdateValue = (event: Event) => {
|
||||
const target = event?.target;
|
||||
@@ -77,8 +81,11 @@ const onUpdateValue = (event: Event) => {
|
||||
console.error("the value of checked is not an HTMLInputElement");
|
||||
return;
|
||||
}
|
||||
emit("updateSelected", {suggestion: props.item, isSelected: props.type === "radio" ? true : target.checked});
|
||||
}
|
||||
emit("updateSelected", {
|
||||
suggestion: props.item,
|
||||
isSelected: props.type === "radio" ? true : target.checked,
|
||||
});
|
||||
};
|
||||
|
||||
function triggerAddContact(payload: { parent: ThirdpartyCompany }) {
|
||||
emit("triggerAddContact", payload);
|
||||
|
||||
@@ -36,7 +36,7 @@ function formatDate(dateString: string | undefined, format: string) {
|
||||
}
|
||||
|
||||
const props = defineProps<{
|
||||
item: Suggestion & { result: Person },
|
||||
item: Suggestion & { result: Person };
|
||||
}>();
|
||||
|
||||
const hasBirthdate = computed(() => props.item.result.birthdate !== null);
|
||||
|
||||
@@ -1,9 +1,15 @@
|
||||
<template>
|
||||
<div class="container tpartycontainer">
|
||||
<div class="tparty-identification">
|
||||
<span v-if="(isThirdpartyChild(item.result) || isThirdpartyContact(item.result)) && item.result.profession" class="profession">{{
|
||||
<span
|
||||
v-if="
|
||||
(isThirdpartyChild(item.result) ||
|
||||
isThirdpartyContact(item.result)) &&
|
||||
item.result.profession
|
||||
}}</span>
|
||||
"
|
||||
class="profession"
|
||||
>{{ item.result.profession }}</span
|
||||
>
|
||||
<span class="name"> {{ item.result.text }} </span>
|
||||
<span class="location">
|
||||
<template v-if="hasAddress">
|
||||
@@ -12,7 +18,10 @@
|
||||
</template>
|
||||
</span>
|
||||
</div>
|
||||
<div class="tpartyparent" v-if="isThirdpartyChild(item.result) && null !== item.result.parent">
|
||||
<div
|
||||
class="tpartyparent"
|
||||
v-if="isThirdpartyChild(item.result) && null !== item.result.parent"
|
||||
>
|
||||
<span class="name"> > {{ item.result.parent.text }} </span>
|
||||
</div>
|
||||
</div>
|
||||
@@ -23,7 +32,8 @@
|
||||
v-if="item.result.type === 'thirdparty' && item.result.kind === 'company'"
|
||||
class="btn btn-tpchild"
|
||||
@click="emit('triggerAddContact', { parent: item.result })"
|
||||
><i class="bi bi-person-fill-add"></i></a>
|
||||
><i class="bi bi-person-fill-add"></i
|
||||
></a>
|
||||
<on-the-fly type="thirdparty" :id="item.result.id" action="show" />
|
||||
</div>
|
||||
</template>
|
||||
@@ -38,7 +48,8 @@ import { Result, Suggestion } from "ChillPersonAssets/types";
|
||||
import {
|
||||
isThirdpartyChild,
|
||||
isThirdpartyContact,
|
||||
Thirdparty, ThirdpartyCompany
|
||||
Thirdparty,
|
||||
ThirdpartyCompany,
|
||||
} from "./../../../../../../ChillThirdPartyBundle/Resources/public/types";
|
||||
|
||||
interface TypeThirdPartyProps {
|
||||
@@ -47,7 +58,10 @@ interface TypeThirdPartyProps {
|
||||
|
||||
const props = defineProps<TypeThirdPartyProps>();
|
||||
|
||||
const emit = defineEmits<(e: "triggerAddContact", payload: {parent: ThirdpartyCompany}) => void>();
|
||||
const emit =
|
||||
defineEmits<
|
||||
(e: "triggerAddContact", payload: { parent: ThirdpartyCompany }) => void
|
||||
>();
|
||||
|
||||
const onTheFly = ref<InstanceType<typeof OnTheFly> | null>(null);
|
||||
const toast = useToast();
|
||||
@@ -56,7 +70,10 @@ const hasAddress = computed(() => {
|
||||
if (props.item.result.address !== null) {
|
||||
return true;
|
||||
}
|
||||
if (isThirdpartyChild(props.item.result) && props.item.result.parent !== null) {
|
||||
if (
|
||||
isThirdpartyChild(props.item.result) &&
|
||||
props.item.result.parent !== null
|
||||
) {
|
||||
return props.item.result.parent.address !== null;
|
||||
}
|
||||
|
||||
@@ -67,7 +84,11 @@ const getAddress = computed(() => {
|
||||
if (props.item.result.address !== null) {
|
||||
return props.item.result.address;
|
||||
}
|
||||
if (isThirdpartyChild(props.item.result) && props.item.result.parent !== null && props.item.result.parent.address !== null) {
|
||||
if (
|
||||
isThirdpartyChild(props.item.result) &&
|
||||
props.item.result.parent !== null &&
|
||||
props.item.result.parent.address !== null
|
||||
) {
|
||||
return props.item.result.parent.address;
|
||||
}
|
||||
return null;
|
||||
|
||||
@@ -21,7 +21,6 @@ interface TypeUserProps {
|
||||
}
|
||||
|
||||
const props = defineProps<TypeUserProps>();
|
||||
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -23,9 +23,7 @@
|
||||
</div>
|
||||
|
||||
<p>
|
||||
<span
|
||||
v-if="options.addId == true"
|
||||
:title="person.personId"
|
||||
<span v-if="options.addId == true" :title="person.personId"
|
||||
><i class="bi bi-info-circle"></i> {{ person.personId }}</span
|
||||
>
|
||||
</p>
|
||||
@@ -34,10 +32,14 @@
|
||||
<gender-icon-render-box
|
||||
v-if="person.gender"
|
||||
:gender="person.gender"
|
||||
/> <span
|
||||
v-if="person.birthdate"
|
||||
>
|
||||
{{ trans(RENDERBOX_BIRTHDAY_STATEMENT, {gender: toGenderTranslation(person.gender), birthdate: ISOToDate(person.birthdate?.datetime)}) }}
|
||||
/>
|
||||
<span v-if="person.birthdate">
|
||||
{{
|
||||
trans(RENDERBOX_BIRTHDAY_STATEMENT, {
|
||||
gender: toGenderTranslation(person.gender),
|
||||
birthdate: ISOToDate(person.birthdate?.datetime),
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
<span v-if="options.addAge && person.birthdate" class="age">
|
||||
({{ trans(RENDERBOX_YEARS_OLD, { n: person.age }) }})
|
||||
@@ -45,13 +47,15 @@
|
||||
</p>
|
||||
|
||||
<p>
|
||||
<span
|
||||
v-if="person.deathdate"
|
||||
>
|
||||
{{ trans(RENDERBOX_DEATHDATE_STATEMENT, {gender: toGenderTranslation(person.gender), deathdate: ISOToDate(person.deathdate?.datetime)}) }}
|
||||
<span v-if="person.deathdate">
|
||||
{{
|
||||
trans(RENDERBOX_DEATHDATE_STATEMENT, {
|
||||
gender: toGenderTranslation(person.gender),
|
||||
deathdate: ISOToDate(person.deathdate?.datetime),
|
||||
})
|
||||
}}
|
||||
</span>
|
||||
</p>
|
||||
|
||||
</div>
|
||||
</div>
|
||||
|
||||
@@ -302,7 +306,7 @@ const props = withDefaults(defineProps<Props>(), {
|
||||
addNoData: true,
|
||||
isMultiline: true,
|
||||
isHolder: false,
|
||||
addHouseholdLink: true
|
||||
addHouseholdLink: true,
|
||||
}),
|
||||
});
|
||||
|
||||
|
||||
@@ -81,11 +81,12 @@
|
||||
value=""
|
||||
@input="onAltNameInput($event, a.key)"
|
||||
/>
|
||||
<label :for="'label_' + a.key">{{ localizeString(a.labels) }}</label>
|
||||
<label :for="'label_' + a.key">{{
|
||||
localizeString(a.labels)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<template v-if="action === 'create'">
|
||||
@@ -98,18 +99,30 @@
|
||||
<div class="form-floating">
|
||||
<input
|
||||
class="form-control form-control-lg"
|
||||
:class="{'is-invalid': violations.hasViolationWithParameter('identifiers', 'definition_id', worker.definition_id.toString())}"
|
||||
:class="{
|
||||
'is-invalid': violations.hasViolationWithParameter(
|
||||
'identifiers',
|
||||
'definition_id',
|
||||
worker.definition_id.toString(),
|
||||
),
|
||||
}"
|
||||
type="text"
|
||||
:name="'worker_' + worker.definition_id"
|
||||
:placeholder="localizeString(worker.label)"
|
||||
@input="onIdentifierInput($event, worker.definition_id)"
|
||||
/>
|
||||
<label :for="'worker_' + worker.definition_id" :class="{required: worker.presence == 'REQUIRED'}">{{
|
||||
localizeString(worker.label)
|
||||
}}</label>
|
||||
<label
|
||||
:for="'worker_' + worker.definition_id"
|
||||
:class="{ required: worker.presence == 'REQUIRED' }"
|
||||
>{{ localizeString(worker.label) }}</label
|
||||
>
|
||||
</div>
|
||||
<div
|
||||
v-for="err in violations.violationTitlesWithParameter('identifiers', 'definition_id', worker.definition_id.toString())"
|
||||
v-for="err in violations.violationTitlesWithParameter(
|
||||
'identifiers',
|
||||
'definition_id',
|
||||
worker.definition_id.toString(),
|
||||
)"
|
||||
class="invalid-feedback was-validated-force"
|
||||
>
|
||||
{{ err }}
|
||||
@@ -163,7 +176,9 @@
|
||||
{{ c.name }}
|
||||
</option>
|
||||
</select>
|
||||
<label for="center" class="required">{{ trans(PERSON_MESSAGES_PERSON_CENTER_TITLE) }}</label>
|
||||
<label for="center" class="required">{{
|
||||
trans(PERSON_MESSAGES_PERSON_CENTER_TITLE)
|
||||
}}</label>
|
||||
</div>
|
||||
<div
|
||||
v-for="err in violations.violationTitles('center')"
|
||||
@@ -190,7 +205,9 @@
|
||||
{{ localizeString(c.name) }}
|
||||
</option>
|
||||
</select>
|
||||
<label for="civility">{{ trans(PERSON_MESSAGES_PERSON_CIVILITY_TITLE) }}</label>
|
||||
<label for="civility">{{
|
||||
trans(PERSON_MESSAGES_PERSON_CIVILITY_TITLE)
|
||||
}}</label>
|
||||
</div>
|
||||
<div
|
||||
v-for="err in violations.violationTitles('civility')"
|
||||
@@ -241,7 +258,9 @@
|
||||
:aria-label="trans(PERSON_MESSAGES_PERSON_PHONENUMBER)"
|
||||
aria-describedby="phonenumber"
|
||||
/>
|
||||
<label for="phonenumber">{{ trans(PERSON_MESSAGES_PERSON_PHONENUMBER) }}</label>
|
||||
<label for="phonenumber">{{
|
||||
trans(PERSON_MESSAGES_PERSON_PHONENUMBER)
|
||||
}}</label>
|
||||
</div>
|
||||
<div
|
||||
v-for="err in violations.violationTitles('phonenumber')"
|
||||
@@ -266,7 +285,9 @@
|
||||
:aria-label="trans(PERSON_MESSAGES_PERSON_MOBILENUMBER)"
|
||||
aria-describedby="mobilenumber"
|
||||
/>
|
||||
<label for="mobilenumber">{{ trans(PERSON_MESSAGES_PERSON_MOBILENUMBER) }}</label>
|
||||
<label for="mobilenumber">{{
|
||||
trans(PERSON_MESSAGES_PERSON_MOBILENUMBER)
|
||||
}}</label>
|
||||
</div>
|
||||
<div
|
||||
v-for="err in violations.violationTitles('mobilenumber')"
|
||||
@@ -326,11 +347,8 @@
|
||||
ref="addAddress"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<div v-else>
|
||||
|
||||
</div>
|
||||
<div v-else></div>
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
@@ -338,7 +356,8 @@ import { ref, reactive, computed, onMounted } from "vue";
|
||||
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||
import {
|
||||
createPerson, editPerson,
|
||||
createPerson,
|
||||
editPerson,
|
||||
getCentersForPersonCreation,
|
||||
getCivilities,
|
||||
getGenders,
|
||||
@@ -366,22 +385,19 @@ import {
|
||||
PERSON_MESSAGES_PERSON_ADDRESS_SHOW_ADDRESS_FORM,
|
||||
PERSON_MESSAGES_PERSON_ADDRESS_WARNING,
|
||||
} from "translator";
|
||||
import {
|
||||
Center,
|
||||
Civility,
|
||||
Gender,
|
||||
} from "ChillMainAssets/types";
|
||||
import { Center, Civility, Gender } from "ChillMainAssets/types";
|
||||
import {
|
||||
AltName,
|
||||
Person,
|
||||
PersonWrite,
|
||||
PersonIdentifierWorker,
|
||||
} from "ChillPersonAssets/types";
|
||||
import {
|
||||
isValidationException,
|
||||
} from "ChillMainAssets/lib/api/apiMethods";
|
||||
import { isValidationException } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import { useToast } from "vue-toast-notification";
|
||||
import {getTimezoneOffsetString, ISOToDate} from "ChillMainAssets/chill/js/date";
|
||||
import {
|
||||
getTimezoneOffsetString,
|
||||
ISOToDate,
|
||||
} from "ChillMainAssets/chill/js/date";
|
||||
import { useViolationList } from "ChillMainAssets/vuejs/_composables/violationList";
|
||||
|
||||
interface PersonEditComponentConfig {
|
||||
@@ -486,13 +502,16 @@ const birthDate = computed({
|
||||
person.birthdate = null;
|
||||
return;
|
||||
}
|
||||
const offset = getTimezoneOffsetString(date, Intl.DateTimeFormat().resolvedOptions().timeZone);
|
||||
const offset = getTimezoneOffsetString(
|
||||
date,
|
||||
Intl.DateTimeFormat().resolvedOptions().timeZone,
|
||||
);
|
||||
if (person.birthdate) {
|
||||
person.birthdate.datetime = value + "T00:00:00" + offset;
|
||||
} else {
|
||||
person.birthdate = { datetime: value + "T00:00:00" + offset };
|
||||
}
|
||||
}
|
||||
},
|
||||
});
|
||||
const phonenumber = computed({
|
||||
get: () => person.phonenumber,
|
||||
@@ -566,7 +585,7 @@ async function loadData() {
|
||||
const w = personToWritePerson(p);
|
||||
person.firstName = w.firstName;
|
||||
person.lastName = w.lastName;
|
||||
person.altNames.push(...w.altNames)
|
||||
person.altNames.push(...w.altNames);
|
||||
person.civility = w.civility;
|
||||
person.addressId = w.addressId;
|
||||
person.birthdate = w.birthdate;
|
||||
@@ -633,7 +652,7 @@ function submitNewAddress(payload: { addressId: number }) {
|
||||
|
||||
async function postPerson(): Promise<Person> {
|
||||
try {
|
||||
if (props.action === 'create') {
|
||||
if (props.action === "create") {
|
||||
const createdPerson = await createPerson(person);
|
||||
emit("onPersonCreated", { person: createdPerson });
|
||||
|
||||
@@ -667,7 +686,7 @@ onMounted(() => {
|
||||
getPersonIdentifiers().then((identifiers) => {
|
||||
config.identifiers = identifiers.filter(
|
||||
(w: PersonIdentifierWorker) =>
|
||||
w.presence === 'ON_CREATION' || w.presence === 'REQUIRED'
|
||||
w.presence === "ON_CREATION" || w.presence === "REQUIRED",
|
||||
);
|
||||
});
|
||||
if (props.action !== "create") {
|
||||
|
||||
@@ -2,8 +2,7 @@ const personMessages = {
|
||||
fr: {
|
||||
add_persons: {
|
||||
title: "Ajouter des usagers",
|
||||
suggested_counter:
|
||||
"Pas de résultats | 1 résultat | {count} résultats",
|
||||
suggested_counter: "Pas de résultats | 1 résultat | {count} résultats",
|
||||
selected_counter: " 1 sélectionné | {count} sélectionnés",
|
||||
search_some_persons: "Rechercher des personnes..",
|
||||
},
|
||||
|
||||
@@ -2,7 +2,9 @@ import {
|
||||
Address,
|
||||
Center,
|
||||
Civility,
|
||||
DateTime, SetAddress, SetCivility,
|
||||
DateTime,
|
||||
SetAddress,
|
||||
SetCivility,
|
||||
User,
|
||||
} from "ChillMainAssets/types";
|
||||
|
||||
@@ -35,7 +37,10 @@ function isBaseThirdParty(t: unknown): t is BaseThirdParty {
|
||||
(o as any).type === "thirdparty" &&
|
||||
typeof o.id === "number" &&
|
||||
typeof o.text === "string" &&
|
||||
(o.kind === "" || o.kind === "contact" || o.kind === "child" || o.kind === "company") &&
|
||||
(o.kind === "" ||
|
||||
o.kind === "contact" ||
|
||||
o.kind === "child" ||
|
||||
o.kind === "company") &&
|
||||
typeof o.active === "boolean"
|
||||
);
|
||||
}
|
||||
@@ -51,13 +56,8 @@ export interface ThirdpartyCompany extends BaseThirdParty {
|
||||
}
|
||||
|
||||
// Type guard to distinguish a ThirdpartyCompany
|
||||
export function isThirdpartyCompany(
|
||||
t: BaseThirdParty
|
||||
): t is ThirdpartyCompany {
|
||||
return (
|
||||
t.type === "thirdparty" &&
|
||||
t.kind === "company"
|
||||
);
|
||||
export function isThirdpartyCompany(t: BaseThirdParty): t is ThirdpartyCompany {
|
||||
return t.type === "thirdparty" && t.kind === "company";
|
||||
}
|
||||
|
||||
export interface ThirdpartyChild extends BaseThirdParty {
|
||||
@@ -75,13 +75,8 @@ export interface ThirdpartyChild extends BaseThirdParty {
|
||||
}
|
||||
|
||||
// Type guard to distinguish a ThirdpartyChild
|
||||
export function isThirdpartyChild(
|
||||
t: BaseThirdParty
|
||||
): t is ThirdpartyChild {
|
||||
return (
|
||||
t.type === "thirdparty" &&
|
||||
t.kind === "child"
|
||||
);
|
||||
export function isThirdpartyChild(t: BaseThirdParty): t is ThirdpartyChild {
|
||||
return t.type === "thirdparty" && t.kind === "child";
|
||||
}
|
||||
|
||||
export interface ThirdpartyContact extends BaseThirdParty {
|
||||
@@ -99,24 +94,23 @@ export interface ThirdpartyContact extends BaseThirdParty {
|
||||
}
|
||||
|
||||
// Type guard to distinguish a ThirdpartyContact
|
||||
export function isThirdpartyContact(
|
||||
t: BaseThirdParty
|
||||
): t is ThirdpartyContact {
|
||||
return (
|
||||
t.type === "thirdparty" &&
|
||||
t.kind === "contact"
|
||||
);
|
||||
export function isThirdpartyContact(t: BaseThirdParty): t is ThirdpartyContact {
|
||||
return t.type === "thirdparty" && t.kind === "contact";
|
||||
}
|
||||
|
||||
export type Thirdparty = ThirdpartyCompany | ThirdpartyContact | ThirdpartyChild;
|
||||
|
||||
export type Thirdparty =
|
||||
| ThirdpartyCompany
|
||||
| ThirdpartyContact
|
||||
| ThirdpartyChild;
|
||||
|
||||
export function isThirdparty(t: unknown): t is Thirdparty {
|
||||
if (!isBaseThirdParty(t)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return (isThirdpartyCompany(t) || isThirdpartyContact(t) || isThirdpartyChild(t));
|
||||
return (
|
||||
isThirdpartyCompany(t) || isThirdpartyContact(t) || isThirdpartyChild(t)
|
||||
);
|
||||
}
|
||||
|
||||
interface ThirdpartyType {
|
||||
|
||||
@@ -1,7 +1,13 @@
|
||||
/*
|
||||
* GET a thirdparty by id
|
||||
*/
|
||||
import {isThirdpartyChild, isThirdpartyCompany, isThirdpartyContact, Thirdparty, ThirdPartyWrite} from '../../types';
|
||||
import {
|
||||
isThirdpartyChild,
|
||||
isThirdpartyCompany,
|
||||
isThirdpartyContact,
|
||||
Thirdparty,
|
||||
ThirdPartyWrite,
|
||||
} from "../../types";
|
||||
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
|
||||
|
||||
export const getThirdparty = async (id: number): Promise<Thirdparty> => {
|
||||
@@ -21,40 +27,41 @@ export const thirdpartyToWriteThirdParty = (t: Thirdparty): ThirdPartyWrite => {
|
||||
const isChild = isThirdpartyChild(t);
|
||||
|
||||
return {
|
||||
type: 'thirdparty',
|
||||
type: "thirdparty",
|
||||
kind: t.kind,
|
||||
civility:
|
||||
(isContact || isChild) && t.civility
|
||||
? { type: 'chill_main_civility', id: t.civility.id }
|
||||
? { type: "chill_main_civility", id: t.civility.id }
|
||||
: null,
|
||||
profession: (isContact || isChild) ? (t.profession ?? '') : '',
|
||||
firstname: isCompany ? '' : (t.firstname ?? ''),
|
||||
name: isCompany
|
||||
? (t.nameCompany ?? '')
|
||||
: (t.name ?? ''),
|
||||
email: t.email ?? '',
|
||||
telephone: t.telephone ?? '',
|
||||
telephone2: t.telephone2 ?? '',
|
||||
profession: isContact || isChild ? (t.profession ?? "") : "",
|
||||
firstname: isCompany ? "" : (t.firstname ?? ""),
|
||||
name: isCompany ? (t.nameCompany ?? "") : (t.name ?? ""),
|
||||
email: t.email ?? "",
|
||||
telephone: t.telephone ?? "",
|
||||
telephone2: t.telephone2 ?? "",
|
||||
address: null,
|
||||
comment: isChild ? (t.comment ?? '') : '',
|
||||
parent: isChild && t.parent ? { type: 'thirdparty', id: t.parent.id } : null,
|
||||
comment: isChild ? (t.comment ?? "") : "",
|
||||
parent:
|
||||
isChild && t.parent ? { type: "thirdparty", id: t.parent.id } : null,
|
||||
};
|
||||
};
|
||||
|
||||
export interface WriteThirdPartyViolationMap
|
||||
extends Record<string, Record<string, string>> {
|
||||
export interface WriteThirdPartyViolationMap extends Record<
|
||||
string,
|
||||
Record<string, string>
|
||||
> {
|
||||
email: {
|
||||
"{{ value }}": string;
|
||||
},
|
||||
};
|
||||
name: {
|
||||
"{{ value }}": string;
|
||||
},
|
||||
};
|
||||
telephone: {
|
||||
"{{ value }}": string;
|
||||
}
|
||||
};
|
||||
telephone2: {
|
||||
"{{ value }}": string;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
/*
|
||||
@@ -63,13 +70,16 @@ extends Record<string, Record<string, string>> {
|
||||
export const createThirdParty = async (body: ThirdPartyWrite) => {
|
||||
const url = `/api/1.0/thirdparty/thirdparty.json`;
|
||||
|
||||
return makeFetch<ThirdPartyWrite, Thirdparty>('POST', url, body);
|
||||
return makeFetch<ThirdPartyWrite, Thirdparty>("POST", url, body);
|
||||
};
|
||||
|
||||
/*
|
||||
* PATCH an existing thirdparty
|
||||
*/
|
||||
export const patchThirdparty = async (id: number, body: ThirdPartyWrite): Promise<Thirdparty> => {
|
||||
export const patchThirdparty = async (
|
||||
id: number,
|
||||
body: ThirdPartyWrite,
|
||||
): Promise<Thirdparty> => {
|
||||
const url = `/api/1.0/thirdparty/thirdparty/${id}.json`;
|
||||
return makeFetch('PATCH', url, body);
|
||||
return makeFetch("PATCH", url, body);
|
||||
};
|
||||
|
||||
@@ -133,13 +133,14 @@ import { computed, defineAsyncComponent } from "vue";
|
||||
import AddressRenderBox from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue";
|
||||
import Confidential from "ChillMainAssets/vuejs/_components/Confidential.vue";
|
||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||
import {isThirdpartyChild, isThirdpartyCompany, Thirdparty} from "../../../types";
|
||||
import {
|
||||
isThirdpartyChild,
|
||||
isThirdpartyCompany,
|
||||
Thirdparty,
|
||||
} from "../../../types";
|
||||
import { localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
||||
import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
|
||||
import {
|
||||
THIRDPARTY_MESSAGES_CHILD_OF,
|
||||
trans
|
||||
} from "translator";
|
||||
import { THIRDPARTY_MESSAGES_CHILD_OF, trans } from "translator";
|
||||
|
||||
// Async to avoid recursive resolution issues
|
||||
/*
|
||||
@@ -160,7 +161,9 @@ interface RenderOptions {
|
||||
|
||||
const props = defineProps<{ thirdparty: Thirdparty; options: RenderOptions }>();
|
||||
|
||||
const isMultiline = computed<boolean>(() => props.options?.isMultiline ?? false);
|
||||
const isMultiline = computed<boolean>(
|
||||
() => props.options?.isMultiline ?? false,
|
||||
);
|
||||
|
||||
const hasParent = computed<boolean>(() => {
|
||||
return isThirdpartyChild(props.thirdparty);
|
||||
|
||||
@@ -20,29 +20,34 @@
|
||||
action === 'edit' || action === 'create' || action === 'addContact'
|
||||
"
|
||||
>
|
||||
<ThirdPartyEdit :id="id" :type="type" :action="action" :query="query" :parent="parent" />
|
||||
<ThirdPartyEdit
|
||||
:id="id"
|
||||
:type="type"
|
||||
:action="action"
|
||||
:query="query"
|
||||
:parent="parent"
|
||||
/>
|
||||
</div>
|
||||
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {onMounted, ref} from 'vue'
|
||||
import ThirdPartyRenderBox from '../Entity/ThirdPartyRenderBox.vue'
|
||||
import ThirdPartyEdit from './ThirdPartyEdit.vue'
|
||||
import { getThirdparty } from '../../_api/OnTheFly'
|
||||
import {Thirdparty, ThirdpartyCompany} from '../../../types'
|
||||
import { onMounted, ref } from "vue";
|
||||
import ThirdPartyRenderBox from "../Entity/ThirdPartyRenderBox.vue";
|
||||
import ThirdPartyEdit from "./ThirdPartyEdit.vue";
|
||||
import { getThirdparty } from "../../_api/OnTheFly";
|
||||
import { Thirdparty, ThirdpartyCompany } from "../../../types";
|
||||
|
||||
type ThirdPartyProp = {
|
||||
id: number,
|
||||
type: 'thirdparty',
|
||||
action: 'show'|'edit'|'create',
|
||||
parent?: null,
|
||||
interface ThirdPartyProp {
|
||||
id: number;
|
||||
type: "thirdparty";
|
||||
action: "show" | "edit" | "create";
|
||||
parent?: null;
|
||||
}
|
||||
type ThirdPartyAddContact = {
|
||||
id: number,
|
||||
type: 'thirdparty',
|
||||
action: 'addContact',
|
||||
parent: ThirdpartyCompany,
|
||||
interface ThirdPartyAddContact {
|
||||
id: number;
|
||||
type: "thirdparty";
|
||||
action: "addContact";
|
||||
parent: ThirdpartyCompany;
|
||||
}
|
||||
|
||||
type ThirdPartyProps = ThirdPartyProp | ThirdPartyAddContact;
|
||||
@@ -58,10 +63,10 @@ async function loadData() {
|
||||
}
|
||||
|
||||
onMounted(() => {
|
||||
if (props.action === 'show' && props.id) {
|
||||
loadData()
|
||||
if (props.action === "show" && props.id) {
|
||||
loadData();
|
||||
}
|
||||
})
|
||||
});
|
||||
</script>
|
||||
|
||||
<style lang="scss" scoped>
|
||||
|
||||
@@ -4,7 +4,9 @@
|
||||
<div class="parent-info">
|
||||
<i class="fa fa-li fa-hand-o-right" />
|
||||
<b class="me-2">{{ trans(THIRDPARTY_MESSAGES_CHILD_OF) }}</b>
|
||||
<span class="chill-entity badge-thirdparty">{{ resolvedParent.text }}</span>
|
||||
<span class="chill-entity badge-thirdparty">{{
|
||||
resolvedParent.text
|
||||
}}</span>
|
||||
</div>
|
||||
</div>
|
||||
<div class="form-floating mb-3" v-else-if="props.action === 'create'">
|
||||
@@ -77,7 +79,9 @@
|
||||
{{ localizeString(civility.name) }}
|
||||
</option>
|
||||
</select>
|
||||
<label for="civility">{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY) }}</label>
|
||||
<label for="civility">{{
|
||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -93,7 +97,9 @@
|
||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)"
|
||||
aria-describedby="profession"
|
||||
/>
|
||||
<label for="profession">{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION) }}</label>
|
||||
<label for="profession">{{
|
||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
@@ -224,7 +230,9 @@
|
||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)"
|
||||
aria-describedby="email"
|
||||
/>
|
||||
<label for="email">{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL) }}</label>
|
||||
<label for="email">{{
|
||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_EMAIL)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -250,7 +258,9 @@
|
||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)"
|
||||
aria-describedby="phonenumber"
|
||||
/>
|
||||
<label for="phonenumber">{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER) }}</label>
|
||||
<label for="phonenumber">{{
|
||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -263,7 +273,9 @@
|
||||
|
||||
<div class="mb-3">
|
||||
<div class="input-group has-validation">
|
||||
<span class="input-group-text" id="phonenumber2"><i class="fa fa-fw fa-phone"/></span>
|
||||
<span class="input-group-text" id="phonenumber2"
|
||||
><i class="fa fa-fw fa-phone"
|
||||
/></span>
|
||||
<div class="form-floating">
|
||||
<input
|
||||
class="form-control form-control-lg"
|
||||
@@ -274,7 +286,9 @@
|
||||
:aria-label="trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)"
|
||||
aria-describedby="phonenumber2"
|
||||
/>
|
||||
<label for="phonenumber2">{{ trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2) }}</label>
|
||||
<label for="phonenumber2">{{
|
||||
trans(THIRDPARTY_MESSAGES_THIRDPARTY_PHONENUMBER2)
|
||||
}}</label>
|
||||
</div>
|
||||
</div>
|
||||
<div
|
||||
@@ -301,17 +315,18 @@
|
||||
</template>
|
||||
|
||||
<script setup lang="ts">
|
||||
import {ref, reactive, computed, onMounted, getCurrentInstance} from 'vue'
|
||||
import ThirdPartyRenderBox from '../Entity/ThirdPartyRenderBox.vue'
|
||||
import { ref, reactive, computed, onMounted, getCurrentInstance } from "vue";
|
||||
import ThirdPartyRenderBox from "../Entity/ThirdPartyRenderBox.vue";
|
||||
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
|
||||
import {
|
||||
createThirdParty,
|
||||
getThirdparty, patchThirdparty,
|
||||
getThirdparty,
|
||||
patchThirdparty,
|
||||
thirdpartyToWriteThirdParty,
|
||||
WriteThirdPartyViolationMap
|
||||
} from '../../_api/OnTheFly'
|
||||
import BadgeEntity from 'ChillMainAssets/vuejs/_components/BadgeEntity.vue'
|
||||
import {localizeString as _localizeString} from 'ChillMainAssets/lib/localizationHelper/localizationHelper'
|
||||
WriteThirdPartyViolationMap,
|
||||
} from "../../_api/OnTheFly";
|
||||
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
|
||||
import { localizeString as _localizeString } from "ChillMainAssets/lib/localizationHelper/localizationHelper";
|
||||
import {
|
||||
trans,
|
||||
THIRDPARTY_MESSAGES_THIRDPARTY_FIRSTNAME,
|
||||
@@ -323,11 +338,13 @@ import {
|
||||
THIRDPARTY_MESSAGES_THIRDPARTY_COMMENT,
|
||||
THIRDPARTY_MESSAGES_THIRDPARTY_PROFESSION,
|
||||
THIRDPARTY_MESSAGES_THIRDPARTY_CIVILITY,
|
||||
THIRDPARTY_MESSAGES_CHILD_OF, PERSON_EDIT_ERROR_WHILE_SAVING,
|
||||
} from 'translator'
|
||||
THIRDPARTY_MESSAGES_CHILD_OF,
|
||||
PERSON_EDIT_ERROR_WHILE_SAVING,
|
||||
} from "translator";
|
||||
import {
|
||||
createPerson,
|
||||
getCivilities, WritePersonViolationMap,
|
||||
getCivilities,
|
||||
WritePersonViolationMap,
|
||||
} from "ChillPersonAssets/vuejs/_api/OnTheFly";
|
||||
import {
|
||||
isThirdpartyChild,
|
||||
@@ -335,36 +352,41 @@ import {
|
||||
Thirdparty,
|
||||
ThirdpartyCompany,
|
||||
ThirdPartyKind,
|
||||
ThirdPartyWrite
|
||||
ThirdPartyWrite,
|
||||
} from "../../../types";
|
||||
import { Civility, SetCivility } from "ChillMainAssets/types";
|
||||
import { isValidationException } from "ChillMainAssets/lib/api/apiMethods";
|
||||
import { useViolationList } from "ChillMainAssets/vuejs/_composables/violationList";
|
||||
import { useToast } from "vue-toast-notification";
|
||||
|
||||
|
||||
interface ThirdPartyEditWriteProps {
|
||||
id?: number;
|
||||
type?: 'thirdparty';
|
||||
action: 'edit' | 'create'
|
||||
type?: "thirdparty";
|
||||
action: "edit" | "create";
|
||||
query?: string;
|
||||
parent?: null;
|
||||
}
|
||||
|
||||
interface ThirdPartyAddContactProps {
|
||||
id?: null;
|
||||
type?: 'thirdparty';
|
||||
action: 'addContact';
|
||||
type?: "thirdparty";
|
||||
action: "addContact";
|
||||
query?: "";
|
||||
parent: ThirdpartyCompany;
|
||||
}
|
||||
|
||||
type ThirdPartyEditProps = ThirdPartyAddContactProps | ThirdPartyEditWriteProps;
|
||||
|
||||
const props = withDefaults(defineProps<ThirdPartyEditProps>(), {type: 'thirdparty', query: "", parent: null});
|
||||
const props = withDefaults(defineProps<ThirdPartyEditProps>(), {
|
||||
type: "thirdparty",
|
||||
query: "",
|
||||
parent: null,
|
||||
});
|
||||
|
||||
const emit =
|
||||
defineEmits<(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }) => void>();
|
||||
defineEmits<
|
||||
(e: "onThirdPartyCreated", payload: { thirdParty: Thirdparty }) => void
|
||||
>();
|
||||
|
||||
defineExpose({ postThirdParty });
|
||||
|
||||
@@ -372,7 +394,7 @@ const toast = useToast();
|
||||
|
||||
const thirdParty = ref<ThirdPartyWrite>({
|
||||
type: "thirdparty",
|
||||
kind: 'company',
|
||||
kind: "company",
|
||||
address: null,
|
||||
civility: null,
|
||||
email: "",
|
||||
@@ -401,17 +423,17 @@ const civility = computed<number | null>({
|
||||
},
|
||||
});
|
||||
|
||||
const civilities = ref<Civility[]>([])
|
||||
const civilities = ref<Civility[]>([]);
|
||||
|
||||
const addAddress = reactive({
|
||||
options: {
|
||||
openPanesInModal: true,
|
||||
onlyButton: false,
|
||||
button: {size: 'btn-sm'},
|
||||
title: {create: 'add_an_address_title', edit: 'edit_address'},
|
||||
button: { size: "btn-sm" },
|
||||
title: { create: "add_an_address_title", edit: "edit_address" },
|
||||
},
|
||||
})
|
||||
const addAddressRef = ref<any>(null)
|
||||
});
|
||||
const addAddressRef = ref<any>(null);
|
||||
|
||||
/**
|
||||
* We need a specific computed for the kind
|
||||
@@ -421,7 +443,7 @@ const kind = computed<ThirdPartyKind>({
|
||||
return thirdParty.value.kind;
|
||||
},
|
||||
set(v) {
|
||||
thirdParty.value.kind = v
|
||||
thirdParty.value.kind = v;
|
||||
},
|
||||
});
|
||||
|
||||
@@ -431,21 +453,24 @@ const context = computed(() => {
|
||||
edit: false,
|
||||
addressId: null as number | null,
|
||||
defaults: (window as any).addaddress,
|
||||
}
|
||||
};
|
||||
if (thirdParty.value.address) {
|
||||
ctx.addressId = thirdParty.value.address.id
|
||||
ctx.edit = true
|
||||
ctx.addressId = thirdParty.value.address.id;
|
||||
ctx.edit = true;
|
||||
}
|
||||
return ctx
|
||||
})
|
||||
return ctx;
|
||||
});
|
||||
|
||||
const resolvedParent = computed<null | ThirdpartyCompany>(() => {
|
||||
if (null !== originalThirdParty.value && isThirdpartyChild(originalThirdParty.value)) {
|
||||
if (
|
||||
null !== originalThirdParty.value &&
|
||||
isThirdpartyChild(originalThirdParty.value)
|
||||
) {
|
||||
return originalThirdParty.value.parent;
|
||||
}
|
||||
|
||||
return props.parent ?? null;
|
||||
})
|
||||
});
|
||||
|
||||
/**
|
||||
* Find the query items to display for suggestion
|
||||
@@ -461,7 +486,10 @@ const queryItems = computed(() => {
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.split(" ");
|
||||
const lastNameWords = (thirdParty.value.name || "").trim().toLowerCase().split(" ");
|
||||
const lastNameWords = (thirdParty.value.name || "")
|
||||
.trim()
|
||||
.toLowerCase()
|
||||
.split(" ");
|
||||
|
||||
return words
|
||||
.filter((word) => !firstNameWords.includes(word.toLowerCase()))
|
||||
@@ -469,20 +497,19 @@ const queryItems = computed(() => {
|
||||
});
|
||||
|
||||
function localizeString(str: any) {
|
||||
return _localizeString(str)
|
||||
return _localizeString(str);
|
||||
}
|
||||
|
||||
|
||||
onMounted(() => {
|
||||
getCivilities().then((cv) => {
|
||||
civilities.value = cv;
|
||||
});
|
||||
if (props.action === "edit") {
|
||||
loadData();
|
||||
} else if (props.action === 'addContact') {
|
||||
thirdParty.value.kind = 'child';
|
||||
} else if (props.action === "addContact") {
|
||||
thirdParty.value.kind = "child";
|
||||
thirdParty.value.address = null;
|
||||
thirdParty.value.parent = {id: props.parent.id, type: 'thirdparty'};
|
||||
thirdParty.value.parent = { id: props.parent.id, type: "thirdparty" };
|
||||
}
|
||||
});
|
||||
|
||||
@@ -498,35 +525,35 @@ function submitAddress(payload: { addressId: number }) {
|
||||
thirdParty.value.address = { id: payload.addressId };
|
||||
}
|
||||
|
||||
function addQueryItem(field: 'name' | 'firstName', queryItem: string) {
|
||||
function addQueryItem(field: "name" | "firstName", queryItem: string) {
|
||||
switch (field) {
|
||||
case 'name':
|
||||
case "name":
|
||||
if (thirdParty.value.name) {
|
||||
thirdParty.value.name += ` ${queryItem}`
|
||||
thirdParty.value.name += ` ${queryItem}`;
|
||||
} else {
|
||||
thirdParty.value.name = queryItem
|
||||
thirdParty.value.name = queryItem;
|
||||
}
|
||||
break
|
||||
case 'firstName':
|
||||
thirdParty.value.firstname = queryItem
|
||||
break
|
||||
break;
|
||||
case "firstName":
|
||||
thirdParty.value.firstname = queryItem;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
function addQuery(query: string) {
|
||||
thirdParty.value.name = query
|
||||
thirdParty.value.name = query;
|
||||
}
|
||||
|
||||
const violations = useViolationList<WriteThirdPartyViolationMap>();
|
||||
|
||||
async function postThirdParty(): Promise<Thirdparty> {
|
||||
try {
|
||||
if (props.action === 'edit' && props.id) {
|
||||
if (props.action === "edit" && props.id) {
|
||||
const tp = await patchThirdparty(props.id, thirdParty.value);
|
||||
return Promise.resolve(tp);
|
||||
} else if (props.action === 'addContact' || props.action === 'create') {
|
||||
} else if (props.action === "addContact" || props.action === "create") {
|
||||
const tp = await createThirdParty(thirdParty.value);
|
||||
emit('onThirdPartyCreated', {thirdParty: tp});
|
||||
emit("onThirdPartyCreated", { thirdParty: tp });
|
||||
return Promise.resolve(tp);
|
||||
}
|
||||
} catch (e: unknown) {
|
||||
@@ -539,7 +566,6 @@ async function postThirdParty(): Promise<Thirdparty> {
|
||||
}
|
||||
throw "'action' is not edit with and id, or addContact or create";
|
||||
}
|
||||
|
||||
</script>
|
||||
|
||||
<style scoped lang="scss">
|
||||
|
||||
@@ -148,9 +148,8 @@ export type TicketHistoryLine =
|
||||
| CallerStateEvent;
|
||||
|
||||
interface BaseTicket<
|
||||
T extends
|
||||
| "ticket_ticket:simple"
|
||||
| "ticket_ticket:extended" = "ticket_ticket:simple",
|
||||
T extends "ticket_ticket:simple" | "ticket_ticket:extended" =
|
||||
"ticket_ticket:simple",
|
||||
> {
|
||||
type_extended: T;
|
||||
type: "ticket_ticket";
|
||||
|
||||
Reference in New Issue
Block a user