This commit is contained in:
2025-08-21 09:55:52 +02:00
parent d62dd4396e
commit 3abb76d268
14 changed files with 1029 additions and 940 deletions

View File

@@ -3,50 +3,50 @@ import AccompanyingPeriodWorkSelectorModal from "../../vuejs/_components/Accompa
import { AccompanyingPeriodWork } from "../../types"; import { AccompanyingPeriodWork } from "../../types";
document.addEventListener("DOMContentLoaded", () => { document.addEventListener("DOMContentLoaded", () => {
const elements = document.querySelectorAll<HTMLDivElement>( const elements = document.querySelectorAll<HTMLDivElement>(
'div[data-pick-entities-type="acpw"]', 'div[data-pick-entities-type="acpw"]',
);
elements.forEach((el) => {
const uniqid = el.dataset.inputUniqid;
if (undefined === uniqid) {
throw "Uniqid not found on this element";
}
const input = document.querySelector<HTMLInputElement>(
`input[data-input-uniqid="${uniqid}"]`,
); );
elements.forEach((el) => {
const uniqid = el.dataset.inputUniqid;
if (null === input) { if (undefined === uniqid) {
throw "Element with uniqid not found: " + uniqid; throw "Uniqid not found on this element";
} }
const accompanyingPeriodIdAsString = input.dataset.accompanyingPeriodId; const input = document.querySelector<HTMLInputElement>(
`input[data-input-uniqid="${uniqid}"]`,
);
if (undefined === accompanyingPeriodIdAsString) { if (null === input) {
throw "accompanying period id not found"; throw "Element with uniqid not found: " + uniqid;
} }
const accompanyingPeriodId = Number.parseInt( const accompanyingPeriodIdAsString = input.dataset.accompanyingPeriodId;
accompanyingPeriodIdAsString,
);
const app = createApp({ if (undefined === accompanyingPeriodIdAsString) {
template: throw "accompanying period id not found";
'<accompanying-period-work-selector-modal :accompanying-period-id="accompanyingPeriodId" @pickWork="pickWork"></accompanying-period-work-selector-modal>', }
components: { AccompanyingPeriodWorkSelectorModal },
data() {
return { accompanyingPeriodId };
},
methods: {
pickWork: function (payload: { work: AccompanyingPeriodWork }) {
console.log("payload", payload);
input.value = payload.work.id?.toString() ?? ''; const accompanyingPeriodId = Number.parseInt(
}, accompanyingPeriodIdAsString,
}, );
const app = createApp({
template:
'<accompanying-period-work-selector-modal :accompanying-period-id="accompanyingPeriodId" @pickWork="pickWork"></accompanying-period-work-selector-modal>',
components: { AccompanyingPeriodWorkSelectorModal },
data() {
return { accompanyingPeriodId };
},
methods: {
pickWork: function (payload: { work: AccompanyingPeriodWork }) {
console.log("payload", payload);
input.value = payload.work.id?.toString() ?? "";
},
},
});
app.mount(el);
}); });
app.mount(el);
});
}); });

View File

@@ -84,170 +84,170 @@ export interface AccompanyingPeriodWorkEvaluationDocument {
} }
export interface AccompanyingPeriodWork { export interface AccompanyingPeriodWork {
id?: number; id?: number;
accompanyingPeriod?: AccompanyingPeriod; accompanyingPeriod?: AccompanyingPeriod;
accompanyingPeriodWorkEvaluations: AccompanyingPeriodWorkEvaluation[]; accompanyingPeriodWorkEvaluations: AccompanyingPeriodWorkEvaluation[];
createdAt?: string; createdAt?: string;
createdAutomatically: boolean; createdAutomatically: boolean;
createdAutomaticallyReason: string; createdAutomaticallyReason: string;
createdBy: User; createdBy: User;
endDate?: string; endDate?: string;
goals: AccompanyingPeriodWorkGoal[]; goals: AccompanyingPeriodWorkGoal[];
handlingThierParty?: Thirdparty; handlingThierParty?: Thirdparty;
note: string; note: string;
persons: Person[]; persons: Person[];
privateComment: PrivateCommentEmbeddable; privateComment: PrivateCommentEmbeddable;
referrersHistory: AccompanyingPeriodWorkReferrerHistory[]; referrersHistory: AccompanyingPeriodWorkReferrerHistory[];
results: Result[]; results: Result[];
socialAction?: SocialAction; socialAction?: SocialAction;
startDate?: string; startDate?: string;
thirdParties: Thirdparty[]; thirdParties: Thirdparty[];
updatedAt?: string; updatedAt?: string;
updatedBy: User; updatedBy: User;
version: number; version: number;
} }
interface SocialAction { interface SocialAction {
id: number; id: number;
parent?: SocialAction | null; parent?: SocialAction | null;
children: SocialAction[]; children: SocialAction[];
issue?: SocialIssue | null; issue?: SocialIssue | null;
ordering: number; ordering: number;
title: { title: {
fr: string; fr: string;
}; };
defaultNotificationDelay?: string | null; defaultNotificationDelay?: string | null;
desactivationDate?: string | null; desactivationDate?: string | null;
evaluations: Evaluation[]; evaluations: Evaluation[];
goals: Goal[]; goals: Goal[];
results: Result[]; results: Result[];
} }
export interface AccompanyingPeriodResource { export interface AccompanyingPeriodResource {
id: number; id: number;
accompanyingPeriod: AccompanyingPeriod; accompanyingPeriod: AccompanyingPeriod;
comment?: string | null; comment?: string | null;
person?: Person | null; person?: Person | null;
thirdParty?: Thirdparty | null; thirdParty?: Thirdparty | null;
} }
export interface Origin { export interface Origin {
id: number; id: number;
label: { label: {
fr: string; fr: string;
}; };
noActiveAfter: DateTime; noActiveAfter: DateTime;
} }
export interface ClosingMotive { export interface ClosingMotive {
id: number; id: number;
active: boolean; active: boolean;
name: { name: {
fr: string; fr: string;
}; };
ordering: number; ordering: number;
isCanceledAccompanyingPeriod: boolean; isCanceledAccompanyingPeriod: boolean;
parent?: ClosingMotive | null; parent?: ClosingMotive | null;
children: ClosingMotive[]; children: ClosingMotive[];
} }
export interface AccompanyingPeriodParticipation { export interface AccompanyingPeriodParticipation {
id: number; id: number;
startDate: DateTime; startDate: DateTime;
endDate?: DateTime | null; endDate?: DateTime | null;
accompanyingPeriod: AccompanyingPeriod; accompanyingPeriod: AccompanyingPeriod;
person: Person; person: Person;
} }
export interface AccompanyingPeriodLocationHistory { export interface AccompanyingPeriodLocationHistory {
id: number; id: number;
startDate: DateTime; startDate: DateTime;
endDate?: DateTime | null; endDate?: DateTime | null;
addressLocation?: Address | null; addressLocation?: Address | null;
period: AccompanyingPeriod; period: AccompanyingPeriod;
personLocation?: Person | null; personLocation?: Person | null;
} }
export interface SocialIssue { export interface SocialIssue {
id: number; id: number;
parent?: SocialIssue | null; parent?: SocialIssue | null;
children: SocialIssue[]; children: SocialIssue[];
socialActions?: SocialAction[] | null; socialActions?: SocialAction[] | null;
ordering: number; ordering: number;
title: { title: {
fr: string; fr: string;
}; };
desactivationDate?: string | null; desactivationDate?: string | null;
} }
export interface Goal { export interface Goal {
id: number; id: number;
results: Result[]; results: Result[];
socialActions?: SocialAction[] | null; socialActions?: SocialAction[] | null;
title: { title: {
fr: string; fr: string;
}; };
} }
export interface Result { export interface Result {
id: number; id: number;
accompanyingPeriodWorks: AccompanyingPeriodWork[]; accompanyingPeriodWorks: AccompanyingPeriodWork[];
accompanyingPeriodWorkGoals: AccompanyingPeriodWorkGoal[]; accompanyingPeriodWorkGoals: AccompanyingPeriodWorkGoal[];
goals: Goal[]; goals: Goal[];
socialActions: SocialAction[]; socialActions: SocialAction[];
title: { title: {
fr: string; fr: string;
}; };
desactivationDate?: string | null; desactivationDate?: string | null;
} }
export interface AccompanyingPeriodWorkGoal { export interface AccompanyingPeriodWorkGoal {
id: number; id: number;
accompanyingPeriodWork: AccompanyingPeriodWork; accompanyingPeriodWork: AccompanyingPeriodWork;
goal: Goal; goal: Goal;
note: string; note: string;
results: Result[]; results: Result[];
} }
export interface AccompanyingPeriodWorkEvaluation { export interface AccompanyingPeriodWorkEvaluation {
accompanyingPeriodWork: AccompanyingPeriodWork | null; accompanyingPeriodWork: AccompanyingPeriodWork | null;
comment: string; comment: string;
createdAt: DateTime | null; createdAt: DateTime | null;
createdBy: User | null; createdBy: User | null;
documents: AccompanyingPeriodWorkEvaluationDocument[]; documents: AccompanyingPeriodWorkEvaluationDocument[];
endDate: DateTime | null; endDate: DateTime | null;
evaluation: Evaluation | null; evaluation: Evaluation | null;
id: number | null; id: number | null;
// eslint-disable-next-line @typescript-eslint/no-explicit-any // eslint-disable-next-line @typescript-eslint/no-explicit-any
key: any; key: any;
maxDate: DateTime | null; maxDate: DateTime | null;
startDate: DateTime | null; startDate: DateTime | null;
updatedAt: DateTime | null; updatedAt: DateTime | null;
updatedBy: User | null; updatedBy: User | null;
warningInterval: string | null; warningInterval: string | null;
timeSpent: number | null; timeSpent: number | null;
} }
export interface Evaluation { export interface Evaluation {
id: number; id: number;
url: string; url: string;
socialActions: SocialAction[]; socialActions: SocialAction[];
title: { title: {
fr: string; fr: string;
}; };
active: boolean; active: boolean;
delay: string; delay: string;
notificationDelay: string; notificationDelay: string;
} }
export interface AccompanyingPeriodWorkReferrerHistory { export interface AccompanyingPeriodWorkReferrerHistory {
id: number; id: number;
accompanyingPeriodWork: AccompanyingPeriodWork; accompanyingPeriodWork: AccompanyingPeriodWork;
user: User; user: User;
startDate: DateTime; startDate: DateTime;
endDate: DateTime | null; endDate: DateTime | null;
createdAt: DateTime; createdAt: DateTime;
updatedAt: DateTime | null; updatedAt: DateTime | null;
createdBy: User; createdBy: User;
updatedBy: User | null; updatedBy: User | null;
} }

View File

@@ -1,19 +1,19 @@
<template> <template>
<div class="row mb-3"> <div class="row mb-3">
<label class="col-sm-4 col-form-label visually-hidden">{{ <label class="col-sm-4 col-form-label visually-hidden">{{
trans(EVALUATION_PUBLIC_COMMENT) trans(EVALUATION_PUBLIC_COMMENT)
}}</label> }}</label>
<div class="col-sm-12"> <div class="col-sm-12">
<ckeditor <ckeditor
:editor="ClassicEditor" :editor="ClassicEditor"
:config="classicEditorConfig" :config="classicEditorConfig"
:placeholder="trans(EVALUATION_COMMENT_PLACEHOLDER)" :placeholder="trans(EVALUATION_COMMENT_PLACEHOLDER)"
:value="comment" :value="comment"
@input="$emit('update:comment', $event)" @input="$emit('update:comment', $event)"
tag-name="textarea" tag-name="textarea"
></ckeditor> ></ckeditor>
</div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
@@ -21,9 +21,9 @@ import { Ckeditor } from "@ckeditor/ckeditor5-vue";
import { ClassicEditor } from "ckeditor5"; import { ClassicEditor } from "ckeditor5";
import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config"; import classicEditorConfig from "ChillMainAssets/module/ckeditor5/editor_config";
import { import {
EVALUATION_PUBLIC_COMMENT, EVALUATION_PUBLIC_COMMENT,
EVALUATION_COMMENT_PLACEHOLDER, EVALUATION_COMMENT_PLACEHOLDER,
trans, trans,
} from "translator"; } from "translator";
defineProps(["comment"]); defineProps(["comment"]);

View File

@@ -1,71 +1,71 @@
<template> <template>
<div class="row mb-3"> <div class="row mb-3">
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label"> <label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
{{ trans(EVALUATION_STARTDATE) }} {{ trans(EVALUATION_STARTDATE) }}
</label> </label>
<div class="col-8 col-sm-4 col-md-8 col-lg-4"> <div class="col-8 col-sm-4 col-md-8 col-lg-4">
<input <input
class="form-control form-control-sm" class="form-control form-control-sm"
type="date" type="date"
:value="startDate" :value="startDate"
@input="$emit('update:startDate', $event.target.value)" @input="$emit('update:startDate', $event.target.value)"
/> />
</div>
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
{{ trans(EVALUATION_ENDDATE) }}
</label>
<div class="col-8 col-sm-4 col-md-8 col-lg-4">
<input
class="form-control form-control-sm"
type="date"
:value="endDate"
@input="$emit('update:endDate', $event.target.value)"
/>
</div>
</div> </div>
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label"> <div class="row mb-3">
{{ trans(EVALUATION_ENDDATE) }} <label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
</label> {{ trans(EVALUATION_MAXDATE) }}
<div class="col-8 col-sm-4 col-md-8 col-lg-4"> </label>
<input <div class="col-8 col-sm-4 col-md-8 col-lg-4">
class="form-control form-control-sm" <input
type="date" class="form-control form-control-sm"
:value="endDate" type="date"
@input="$emit('update:endDate', $event.target.value)" :value="maxDate"
/> @input="$emit('update:maxDate', $event.target.value)"
</div> />
</div> </div>
<div class="row mb-3"> <label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label"> {{ trans(EVALUATION_WARNING_INTERVAL) }}
{{ trans(EVALUATION_MAXDATE) }} </label>
</label> <div class="col-8 col-sm-4 col-md-8 col-lg-4">
<div class="col-8 col-sm-4 col-md-8 col-lg-4"> <input
<input class="form-control form-control-sm"
class="form-control form-control-sm" type="number"
type="date" :value="warningInterval"
:value="maxDate" @input="$emit('update:warningInterval', $event.target.value)"
@input="$emit('update:maxDate', $event.target.value)" />
/> </div>
</div> </div>
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
{{ trans(EVALUATION_WARNING_INTERVAL) }}
</label>
<div class="col-8 col-sm-4 col-md-8 col-lg-4">
<input
class="form-control form-control-sm"
type="number"
:value="warningInterval"
@input="$emit('update:warningInterval', $event.target.value)"
/>
</div>
</div>
</template> </template>
<script setup> <script setup>
import { import {
EVALUATION_STARTDATE, EVALUATION_STARTDATE,
EVALUATION_ENDDATE, EVALUATION_ENDDATE,
EVALUATION_MAXDATE, EVALUATION_MAXDATE,
EVALUATION_WARNING_INTERVAL, EVALUATION_WARNING_INTERVAL,
trans, trans,
} from "translator"; } from "translator";
defineProps(["startDate", "endDate", "maxDate", "warningInterval"]); defineProps(["startDate", "endDate", "maxDate", "warningInterval"]);
defineEmits([ defineEmits([
"update:startDate", "update:startDate",
"update:endDate", "update:endDate",
"update:maxDate", "update:maxDate",
"update:warningInterval", "update:warningInterval",
]); ]);
</script> </script>

View File

@@ -1,43 +1,43 @@
<template> <template>
<div class="row mb-3"> <div class="row mb-3">
<h6>{{ trans(EVALUATION_DOCUMENT_ADD) }} :</h6> <h6>{{ trans(EVALUATION_DOCUMENT_ADD) }} :</h6>
<pick-template <pick-template
entityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation" entityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluation"
:id="evaluation.id" :id="evaluation.id"
:templates="templates" :templates="templates"
:preventDefaultMoveToGenerate="true" :preventDefaultMoveToGenerate="true"
@go-to-generate-document="$emit('submitBeforeGenerate', $event)" @go-to-generate-document="$emit('submitBeforeGenerate', $event)"
> >
<template v-slot:title> <template v-slot:title>
<label class="col-form-label">{{ <label class="col-form-label">{{
trans(EVALUATION_GENERATE_A_DOCUMENT) trans(EVALUATION_GENERATE_A_DOCUMENT)
}}</label> }}</label>
</template> </template>
</pick-template> </pick-template>
<div> <div>
<label class="col-form-label">{{ <label class="col-form-label">{{
trans(EVALUATION_DOCUMENT_UPLOAD) trans(EVALUATION_DOCUMENT_UPLOAD)
}}</label> }}</label>
<ul class="record_actions document-upload"> <ul class="record_actions document-upload">
<li> <li>
<drop-file-modal <drop-file-modal
:allow-remove="false" :allow-remove="false"
@add-document="$emit('addDocument', $event)" @add-document="$emit('addDocument', $event)"
></drop-file-modal> ></drop-file-modal>
</li> </li>
</ul> </ul>
</div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue"; import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
import DropFileModal from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileModal.vue"; import DropFileModal from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileModal.vue";
import { import {
EVALUATION_DOCUMENT_ADD, EVALUATION_DOCUMENT_ADD,
EVALUATION_DOCUMENT_UPLOAD, EVALUATION_DOCUMENT_UPLOAD,
EVALUATION_GENERATE_A_DOCUMENT, EVALUATION_GENERATE_A_DOCUMENT,
trans, trans,
} from "translator"; } from "translator";
defineProps(["evaluation", "templates"]); defineProps(["evaluation", "templates"]);
@@ -46,6 +46,6 @@ defineEmits(["addDocument", "submitBeforeGenerate"]);
<style scoped> <style scoped>
ul.document-upload { ul.document-upload {
justify-content: flex-start; justify-content: flex-start;
} }
</style> </style>

View File

@@ -1,178 +1,239 @@
<template> <template>
<div class="row mb-3"> <div class="row mb-3">
<h5>{{ trans(EVALUATION_DOCUMENTS) }} :</h5> <h5>{{ trans(EVALUATION_DOCUMENTS) }} :</h5>
<div class="flex-table"> <div class="flex-table">
<div <div
class="item-bloc" class="item-bloc"
v-for="(d, i) in documents" v-for="(d, i) in documents"
:key="d.id" :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> <div :id="'document_' + d.id" class="item-row">
<div class="col-sm-9"> <div class="input-group input-group-lg mb-3 row">
<input <label class="col-sm-3 col-form-label"
class="form-control document-title" >Titre du document:</label
type="text" >
:value="d.title" <div class="col-sm-9">
:id="d.id" <input
:data-key="i" class="form-control document-title"
@input="$emit('inputDocumentTitle', $event)" type="text"
/> :value="d.title"
</div> :id="d.id"
</div> :data-key="i"
</div> @input="$emit('inputDocumentTitle', $event)"
<div class="item-row"> />
<div class="item-col item-meta"> </div>
<p v-if="d.createdBy" class="createdBy"> </div>
Créé par {{ d.createdBy.text }}<br />
Le {{ $d(ISOToDatetime(d.createdAt.datetime), "long") }}
</p>
</div>
</div>
<div class="item-row">
<div class="item-col">
<ul class="record_actions">
<li
v-if="
d.workflows_availables.length > 0 || d.workflows.length > 0
"
>
<list-workflow-modal
:workflows="d.workflows"
:allowCreate="true"
relatedEntityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument"
:relatedEntityId="d.id"
:workflowsAvailables="d.workflows_availables"
:preventDefaultMoveToGenerate="true"
:goToGenerateWorkflowPayload="{ doc: d }"
@go-to-generate-workflow="
$emit('goToGenerateWorkflow', $event)
"
></list-workflow-modal>
</li>
<li>
<button
v-if="AmIRefferer"
class="btn btn-notify"
@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)"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</button>
<ul
class="dropdown-menu"
aria-labelledby="btnGroupNotifyButtons"
>
<li>
<a
class="dropdown-item"
@click="$emit('goToGenerateNotification', d, true)"
>
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_REFERRER) }}
</a>
</li>
<li>
<a
class="dropdown-item"
@click="$emit('goToGenerateNotification', d, false)"
>
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_ANY) }}
</a>
</li>
</ul>
</template>
</li>
<li>
<document-action-buttons-group
:stored-object="d.storedObject"
:filename="d.title"
:can-edit="true"
:execute-before-leave="submitBeforeLeaveToEditor"
:davLink="d.storedObject._links?.dav_link.href"
:davLinkExpiration="
d.storedObject._links?.dav_link.expiration
"
@on-stored-object-status-change="
$emit('statusDocumentChanged', $event)
"
></document-action-buttons-group>
</li>
<li v-if="Number.isInteger(d.id)">
<div class="duplicate-dropdown">
<button
class="btn btn-duplicate dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{ trans(EVALUATION_DOCUMENT_DUPLICATE) }}
</button>
<ul class="dropdown-menu">
<li>
<a
class="dropdown-item"
@click="$emit('duplicateDocument', d)"
>{{ trans(EVALUATION_DOCUMENT_DUPLICATE_HERE) }}</a
>
</li>
<li>
<a
class="dropdown-item"
@click="prepareDocumentDuplicationToWork(d)"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
)
}}</a
>
</li>
</ul>
</div> </div>
</li> <div class="item-row">
<li v-if="d.storedObject._permissions.canEdit"> <div class="item-col item-meta">
<drop-file-modal <p v-if="d.createdBy" class="createdBy">
:existing-doc="d.storedObject" Créé par {{ d.createdBy.text }}<br />
:allow-remove="false" Le
@add-document=" {{
(arg) => $d(ISOToDatetime(d.createdAt.datetime), "long")
$emit( }}
'replaceDocument', </p>
d, </div>
arg.stored_object, </div>
arg.stored_object_version, <div class="item-row">
) <div class="item-col">
" <ul class="record_actions">
></drop-file-modal> <li
</li> v-if="
<li v-if="d.workflows.length === 0"> d.workflows_availables.length > 0 ||
<a class="btn btn-delete" @click="$emit('removeDocument', d)"> d.workflows.length > 0
</a> "
</li> >
</ul> <list-workflow-modal
</div> :workflows="d.workflows"
:allowCreate="true"
relatedEntityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument"
:relatedEntityId="d.id"
:workflowsAvailables="
d.workflows_availables
"
:preventDefaultMoveToGenerate="true"
:goToGenerateWorkflowPayload="{ doc: d }"
@go-to-generate-workflow="
$emit('goToGenerateWorkflow', $event)
"
></list-workflow-modal>
</li>
<li>
<button
v-if="AmIRefferer"
class="btn btn-notify"
@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)
"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</button>
<ul
class="dropdown-menu"
aria-labelledby="btnGroupNotifyButtons"
>
<li>
<a
class="dropdown-item"
@click="
$emit(
'goToGenerateNotification',
d,
true,
)
"
>
{{
trans(
EVALUATION_NOTIFICATION_NOTIFY_REFERRER,
)
}}
</a>
</li>
<li>
<a
class="dropdown-item"
@click="
$emit(
'goToGenerateNotification',
d,
false,
)
"
>
{{
trans(
EVALUATION_NOTIFICATION_NOTIFY_ANY,
)
}}
</a>
</li>
</ul>
</template>
</li>
<li>
<document-action-buttons-group
:stored-object="d.storedObject"
:filename="d.title"
:can-edit="true"
:execute-before-leave="
submitBeforeLeaveToEditor
"
:davLink="
d.storedObject._links?.dav_link.href
"
:davLinkExpiration="
d.storedObject._links?.dav_link
.expiration
"
@on-stored-object-status-change="
$emit('statusDocumentChanged', $event)
"
></document-action-buttons-group>
</li>
<li v-if="Number.isInteger(d.id)">
<div class="duplicate-dropdown">
<button
class="btn btn-duplicate dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{
trans(EVALUATION_DOCUMENT_DUPLICATE)
}}
</button>
<ul class="dropdown-menu">
<li>
<a
class="dropdown-item"
@click="
$emit(
'duplicateDocument',
d,
)
"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_HERE,
)
}}</a
>
</li>
<li>
<a
class="dropdown-item"
@click="
prepareDocumentDuplicationToWork(
d,
)
"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
)
}}</a
>
</li>
</ul>
</div>
</li>
<li v-if="d.storedObject._permissions.canEdit">
<drop-file-modal
:existing-doc="d.storedObject"
:allow-remove="false"
@add-document="
(arg) =>
$emit(
'replaceDocument',
d,
arg.stored_object,
arg.stored_object_version,
)
"
></drop-file-modal>
</li>
<li v-if="d.workflows.length === 0">
<a
class="btn btn-delete"
@click="$emit('removeDocument', d)"
>
</a>
</li>
</ul>
</div>
</div>
</div>
</div> </div>
</div>
</div> </div>
</div>
<AccompanyingPeriodWorkSelectorModal <AccompanyingPeriodWorkSelectorModal
v-if="showAccompanyingPeriodSelector" v-if="showAccompanyingPeriodSelector"
v-model:selectedAcpw="selectedAcpw" v-model:selectedAcpw="selectedAcpw"
:accompanying-period-id="accompanyingPeriodId" :accompanying-period-id="accompanyingPeriodId"
:is-evaluation-selector="true" :is-evaluation-selector="true"
@close-modal="showAccompanyingPeriodSelector = false" @close-modal="showAccompanyingPeriodSelector = false"
@update:selectedEvaluation="selectedEvaluation = $event" @update:selectedEvaluation="selectedEvaluation = $event"
/> />
</template> </template>
<script setup> <script setup>
@@ -181,27 +242,27 @@ import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue"; import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
import DropFileModal from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileModal.vue"; import DropFileModal from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileModal.vue";
import { import {
EVALUATION_NOTIFICATION_NOTIFY_REFERRER, EVALUATION_NOTIFICATION_NOTIFY_REFERRER,
EVALUATION_NOTIFICATION_NOTIFY_ANY, EVALUATION_NOTIFICATION_NOTIFY_ANY,
EVALUATION_NOTIFICATION_SEND, EVALUATION_NOTIFICATION_SEND,
EVALUATION_DOCUMENTS, EVALUATION_DOCUMENTS,
EVALUATION_DOCUMENT_DUPLICATE, EVALUATION_DOCUMENT_DUPLICATE,
EVALUATION_DOCUMENT_DUPLICATE_HERE, EVALUATION_DOCUMENT_DUPLICATE_HERE,
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION, EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
trans, trans,
} from "translator"; } from "translator";
import { ref, watch } from "vue"; import { ref, watch } from "vue";
import AccompanyingPeriodWorkSelectorModal from "ChillPersonAssets/vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkSelectorModal.vue"; import AccompanyingPeriodWorkSelectorModal from "ChillPersonAssets/vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkSelectorModal.vue";
defineProps(["documents", "docAnchorId", "accompanyingPeriodId"]); defineProps(["documents", "docAnchorId", "accompanyingPeriodId"]);
const emit = defineEmits([ const emit = defineEmits([
"inputDocumentTitle", "inputDocumentTitle",
"removeDocument", "removeDocument",
"duplicateDocument", "duplicateDocument",
"statusDocumentChanged", "statusDocumentChanged",
"goToGenerateWorkflow", "goToGenerateWorkflow",
"goToGenerateNotification", "goToGenerateNotification",
"duplicateDocumentToWork", "duplicateDocumentToWork",
]); ]);
const showAccompanyingPeriodSelector = ref(false); const showAccompanyingPeriodSelector = ref(false);
@@ -209,14 +270,14 @@ const selectedEvaluation = ref(null);
const selectedDocument = ref(null); const selectedDocument = ref(null);
const prepareDocumentDuplicationToWork = (d) => { const prepareDocumentDuplicationToWork = (d) => {
selectedDocument.value = d; selectedDocument.value = d;
showAccompanyingPeriodSelector.value = true; showAccompanyingPeriodSelector.value = true;
}; };
watch(selectedEvaluation, (val) => { watch(selectedEvaluation, (val) => {
emit("duplicateDocumentToEvaluation", { emit("duplicateDocumentToEvaluation", {
evaluation: val, evaluation: val,
document: selectedDocument.value, document: selectedDocument.value,
}); });
}); });
</script> </script>

View File

@@ -1,47 +1,49 @@
<template> <template>
<div> <div>
<div class="m-md-3"> <div class="m-md-3">
<DateInputs <DateInputs
:startDate="startDate" :startDate="startDate"
:endDate="endDate" :endDate="endDate"
:maxDate="maxDate" :maxDate="maxDate"
:warningInterval="warningInterval" :warningInterval="warningInterval"
@update:startDate="updateStartDate" @update:startDate="updateStartDate"
@update:endDate="updateEndDate" @update:endDate="updateEndDate"
@update:maxDate="updateMaxDate" @update:maxDate="updateMaxDate"
@update:warningInterval="updateWarningInterval" @update:warningInterval="updateWarningInterval"
/> />
<TimeSpentInput <TimeSpentInput
:timeSpent="timeSpent" :timeSpent="timeSpent"
:timeSpentChoices="timeSpentChoices" :timeSpentChoices="timeSpentChoices"
@update:timeSpent="updateTimeSpent" @update:timeSpent="updateTimeSpent"
/> />
<CommentInput :comment="comment" @update:comment="updateComment" /> <CommentInput :comment="comment" @update:comment="updateComment" />
<DocumentsList <DocumentsList
v-if="evaluation.documents.length > 0" v-if="evaluation.documents.length > 0"
:documents="evaluation.documents" :documents="evaluation.documents"
:docAnchorId="docAnchorId" :docAnchorId="docAnchorId"
:accompanyingPeriodId="store.state.work.accompanyingPeriod.id" :accompanyingPeriodId="store.state.work.accompanyingPeriod.id"
@inputDocumentTitle="onInputDocumentTitle" @inputDocumentTitle="onInputDocumentTitle"
@removeDocument="removeDocument" @removeDocument="removeDocument"
@duplicateDocument="duplicateDocument" @duplicateDocument="duplicateDocument"
@duplicate-document-to-evaluation="duplicateDocumentToEvaluation" @duplicate-document-to-evaluation="
@statusDocumentChanged="onStatusDocumentChanged" duplicateDocumentToEvaluation
@goToGenerateWorkflow="goToGenerateWorkflowEvaluationDocument" "
@goToGenerateNotification="goToGenerateDocumentNotification" @statusDocumentChanged="onStatusDocumentChanged"
/> @goToGenerateWorkflow="goToGenerateWorkflowEvaluationDocument"
@goToGenerateNotification="goToGenerateDocumentNotification"
/>
<DocumentActions <DocumentActions
:evaluation="evaluation" :evaluation="evaluation"
:templates="getTemplatesAvailables" :templates="getTemplatesAvailables"
@addDocument="addDocument" @addDocument="addDocument"
@submitBeforeGenerate="submitBeforeGenerate" @submitBeforeGenerate="submitBeforeGenerate"
/> />
</div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>
@@ -52,10 +54,7 @@ import TimeSpentInput from "./TimeSpentInput.vue";
import CommentInput from "./CommentInput.vue"; import CommentInput from "./CommentInput.vue";
import DocumentsList from "./DocumentsList.vue"; import DocumentsList from "./DocumentsList.vue";
import DocumentActions from "./DocumentActions.vue"; import DocumentActions from "./DocumentActions.vue";
import { import { trans, EVALUATION_DOCUMENT_DUPLICATE_SUCCESS } from "translator";
trans,
EVALUATION_DOCUMENT_DUPLICATE_SUCCESS
} from "translator";
import { useToast } from "vue-toast-notification"; import { useToast } from "vue-toast-notification";
const props = defineProps(["evaluation", "docAnchorId"]); const props = defineProps(["evaluation", "docAnchorId"]);
@@ -64,279 +63,284 @@ const store = useStore();
const $toast = useToast(); const $toast = useToast();
const timeSpentChoices = [ const timeSpentChoices = [
{ text: "1 minute", value: 60 }, { text: "1 minute", value: 60 },
{ text: "2 minutes", value: 120 }, { text: "2 minutes", value: 120 },
{ text: "3 minutes", value: 180 }, { text: "3 minutes", value: 180 },
{ text: "4 minutes", value: 240 }, { text: "4 minutes", value: 240 },
{ text: "5 minutes", value: 300 }, { text: "5 minutes", value: 300 },
{ text: "10 minutes", value: 600 }, { text: "10 minutes", value: 600 },
{ text: "15 minutes", value: 900 }, { text: "15 minutes", value: 900 },
{ text: "20 minutes", value: 1200 }, { text: "20 minutes", value: 1200 },
{ text: "25 minutes", value: 1500 }, { text: "25 minutes", value: 1500 },
{ text: "30 minutes", value: 1800 }, { text: "30 minutes", value: 1800 },
{ text: "45 minutes", value: 2700 }, { text: "45 minutes", value: 2700 },
{ text: "1 hour", value: 3600 }, { text: "1 hour", value: 3600 },
{ text: "1 hour 15 minutes", value: 4500 }, { text: "1 hour 15 minutes", value: 4500 },
{ text: "1 hour 30 minutes", value: 5400 }, { text: "1 hour 30 minutes", value: 5400 },
{ text: "1 hour 45 minutes", value: 6300 }, { text: "1 hour 45 minutes", value: 6300 },
{ text: "2 hours", value: 7200 }, { text: "2 hours", value: 7200 },
{ text: "2 hours 30 minutes", value: 9000 }, { text: "2 hours 30 minutes", value: 9000 },
{ text: "3 hours", value: 10800 }, { text: "3 hours", value: 10800 },
{ text: "3 hours 30 minutes", value: 12600 }, { text: "3 hours 30 minutes", value: 12600 },
{ text: "4 hours", value: 14400 }, { text: "4 hours", value: 14400 },
{ text: "4 hours 30 minutes", value: 16200 }, { text: "4 hours 30 minutes", value: 16200 },
{ text: "5 hours", value: 18000 }, { text: "5 hours", value: 18000 },
{ text: "5 hours 30 minutes", value: 19800 }, { text: "5 hours 30 minutes", value: 19800 },
{ text: "6 hours", value: 21600 }, { text: "6 hours", value: 21600 },
{ text: "6 hours 30 minutes", value: 23400 }, { text: "6 hours 30 minutes", value: 23400 },
{ text: "7 hours", value: 25200 }, { text: "7 hours", value: 25200 },
{ text: "7 hours 30 minutes", value: 27000 }, { text: "7 hours 30 minutes", value: 27000 },
{ text: "8 hours", value: 28800 }, { text: "8 hours", value: 28800 },
]; ];
const startDate = computed({ const startDate = computed({
get() { get() {
return props.evaluation.startDate; return props.evaluation.startDate;
}, },
set(v) { set(v) {
store.commit("setEvaluationStartDate", { store.commit("setEvaluationStartDate", {
key: props.evaluation.key, key: props.evaluation.key,
date: v, date: v,
}); });
}, },
}); });
const endDate = computed({ const endDate = computed({
get() { get() {
return props.evaluation.endDate; return props.evaluation.endDate;
}, },
set(v) { set(v) {
store.commit("setEvaluationEndDate", { store.commit("setEvaluationEndDate", {
key: props.evaluation.key, key: props.evaluation.key,
date: v, date: v,
}); });
}, },
}); });
const maxDate = computed({ const maxDate = computed({
get() { get() {
return props.evaluation.maxDate; return props.evaluation.maxDate;
}, },
set(v) { set(v) {
store.commit("setEvaluationMaxDate", { store.commit("setEvaluationMaxDate", {
key: props.evaluation.key, key: props.evaluation.key,
date: v, date: v,
}); });
}, },
}); });
const warningInterval = computed({ const warningInterval = computed({
get() { get() {
return props.evaluation.warningInterval; return props.evaluation.warningInterval;
}, },
set(v) { set(v) {
store.commit("setEvaluationWarningInterval", { store.commit("setEvaluationWarningInterval", {
key: props.evaluation.key, key: props.evaluation.key,
days: v, days: v,
}); });
}, },
}); });
const timeSpent = computed({ const timeSpent = computed({
get() { get() {
return props.evaluation.timeSpent; return props.evaluation.timeSpent;
}, },
set(v) { set(v) {
store.commit("setEvaluationTimeSpent", { store.commit("setEvaluationTimeSpent", {
key: props.evaluation.key, key: props.evaluation.key,
time: v, time: v,
}); });
}, },
}); });
const comment = computed({ const comment = computed({
get() { get() {
return props.evaluation.comment; return props.evaluation.comment;
}, },
set(v) { set(v) {
store.commit("setEvaluationComment", { store.commit("setEvaluationComment", {
key: props.evaluation.key, key: props.evaluation.key,
comment: v, comment: v,
}); });
}, },
}); });
const getTemplatesAvailables = computed(() => { const getTemplatesAvailables = computed(() => {
return store.getters.getTemplatesAvailablesForEvaluation( return store.getters.getTemplatesAvailablesForEvaluation(
props.evaluation.evaluation, props.evaluation.evaluation,
); );
}); });
// const getAccompanyingPeriod = computed(() => store.work) // const getAccompanyingPeriod = computed(() => store.work)
function updateStartDate(value) { function updateStartDate(value) {
startDate.value = value; startDate.value = value;
} }
function updateEndDate(value) { function updateEndDate(value) {
endDate.value = value; endDate.value = value;
} }
function updateMaxDate(value) { function updateMaxDate(value) {
maxDate.value = value; maxDate.value = value;
} }
function updateWarningInterval(value) { function updateWarningInterval(value) {
warningInterval.value = value; warningInterval.value = value;
} }
function updateTimeSpent(value) { function updateTimeSpent(value) {
timeSpent.value = value; timeSpent.value = value;
} }
function updateComment(value) { function updateComment(value) {
comment.value = value; comment.value = value;
} }
function onInputDocumentTitle(event) { function onInputDocumentTitle(event) {
const id = Number(event.target.id); const id = Number(event.target.id);
const key = Number(event.target.dataset.key) + 1; const key = Number(event.target.dataset.key) + 1;
const title = event.target.value; const title = event.target.value;
store.commit("updateDocumentTitle", { store.commit("updateDocumentTitle", {
id: id, id: id,
key: key, key: key,
evaluationKey: props.evaluation.key, evaluationKey: props.evaluation.key,
title: title, title: title,
}); });
} }
function addDocument({ stored_object, stored_object_version }) { function addDocument({ stored_object, stored_object_version }) {
let document = { let document = {
type: "accompanying_period_work_evaluation_document", type: "accompanying_period_work_evaluation_document",
storedObject: stored_object, storedObject: stored_object,
title: "Nouveau document", title: "Nouveau document",
}; };
store.commit("addDocument", { store.commit("addDocument", {
key: props.evaluation.key, key: props.evaluation.key,
document, document,
stored_object_version, stored_object_version,
}); });
} }
function removeDocument(document) { function removeDocument(document) {
if ( if (
window.confirm( window.confirm(
'Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre "' + 'Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre "' +
document.title + document.title +
'" ?', '" ?',
) )
) { ) {
store.commit("removeDocument", { store.commit("removeDocument", {
key: props.evaluation.key, key: props.evaluation.key,
document: document, document: document,
}); });
} }
} }
function duplicateDocument(document) { function duplicateDocument(document) {
store.dispatch("duplicateDocument", { store.dispatch("duplicateDocument", {
evaluation_key: props.evaluation.key, evaluation_key: props.evaluation.key,
document: document, document: document,
}) });
} }
function duplicateDocumentToEvaluation({ evaluation, document }) { function duplicateDocumentToEvaluation({ evaluation, document }) {
store.dispatch("duplicateDocumentToEvaluation", { store
evaluation: evaluation, .dispatch("duplicateDocumentToEvaluation", {
document: document, evaluation: evaluation,
}) document: document,
.then(() => { })
$toast.open({ message: trans(EVALUATION_DOCUMENT_DUPLICATE_SUCCESS) }); .then(() => {
}) $toast.open({
.catch((e) => { message: trans(EVALUATION_DOCUMENT_DUPLICATE_SUCCESS),
console.log(e); });
}); })
.catch((e) => {
console.log(e);
});
} }
function onStatusDocumentChanged(newStatus) { function onStatusDocumentChanged(newStatus) {
store.commit("statusDocumentChanged", { store.commit("statusDocumentChanged", {
key: props.evaluation.key, key: props.evaluation.key,
newStatus: newStatus, newStatus: newStatus,
}); });
} }
function goToGenerateWorkflowEvaluationDocument({ workflowName, payload }) { function goToGenerateWorkflowEvaluationDocument({ workflowName, payload }) {
const callback = (data) => { const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find( let evaluation = data.accompanyingPeriodWorkEvaluations.find(
(e) => e.key === props.evaluation.key, (e) => e.key === props.evaluation.key,
); );
let updatedDocument = evaluation.documents.find( let updatedDocument = evaluation.documents.find(
(d) => d.key === payload.doc.key, (d) => d.key === payload.doc.key,
); );
window.location.assign( window.location.assign(
buildLinkCreate( buildLinkCreate(
workflowName, workflowName,
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument", "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
updatedDocument.id, updatedDocument.id,
), ),
); );
}; };
store.dispatch("submit", callback).catch((e) => { store.dispatch("submit", callback).catch((e) => {
console.log(e); console.log(e);
throw e; throw e;
}); });
} }
function goToGenerateDocumentNotification(document, tos) { function goToGenerateDocumentNotification(document, tos) {
const callback = (data) => { const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find( let evaluation = data.accompanyingPeriodWorkEvaluations.find(
(e) => e.key === props.evaluation.key, (e) => e.key === props.evaluation.key,
); );
let updatedDocument = evaluation.documents.find( let updatedDocument = evaluation.documents.find(
(d) => d.key === document.key, (d) => d.key === document.key,
); );
window.location.assign( window.location.assign(
buildLinkCreateNotification( buildLinkCreateNotification(
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument", "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
updatedDocument.id, updatedDocument.id,
tos === true ? store.state.work.accompanyingPeriod.user.id : null, tos === true
window.location.pathname + ? store.state.work.accompanyingPeriod.user.id
window.location.search + : null,
window.location.hash, window.location.pathname +
), window.location.search +
); window.location.hash,
}; ),
store.dispatch("submit", callback).catch((e) => { );
console.log(e); };
throw e; store.dispatch("submit", callback).catch((e) => {
}); console.log(e);
throw e;
});
} }
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
input.document-title { input.document-title {
font-weight: bold; font-weight: bold;
font-size: 1rem; font-size: 1rem;
} }
.bg-blink { .bg-blink {
color: #050000; color: #050000;
padding: 10px; padding: 10px;
display: inline-block; display: inline-block;
border-radius: 5px; border-radius: 5px;
animation: blinkingBackground 2.2s infinite; animation: blinkingBackground 2.2s infinite;
animation-iteration-count: 2; animation-iteration-count: 2;
} }
@keyframes blinkingBackground { @keyframes blinkingBackground {
0% { 0% {
background-color: #ed776d; background-color: #ed776d;
} }
50% { 50% {
background-color: #ffffff; background-color: #ffffff;
} }
100% { 100% {
background-color: #ed776d; background-color: #ed776d;
} }
} }
</style> </style>

View File

@@ -1,25 +1,27 @@
<template> <template>
<div class="row mb-3"> <div class="row mb-3">
<label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label"> <label class="col-4 col-sm-2 col-md-4 col-lg-2 col-form-label">
{{ trans(EVALUATION_TIME_SPENT) }} {{ trans(EVALUATION_TIME_SPENT) }}
</label> </label>
<div class="col-8 col-sm-4 col-md-8 col-lg-4"> <div class="col-8 col-sm-4 col-md-8 col-lg-4">
<select <select
class="form-control form-control-sm" class="form-control form-control-sm"
:value="timeSpent" :value="timeSpent"
@input="$emit('update:timeSpent', $event.target.value)" @input="$emit('update:timeSpent', $event.target.value)"
> >
<option disabled value="">{{ trans(EVALUATION_TIME_SPENT) }}</option> <option disabled value="">
<option {{ trans(EVALUATION_TIME_SPENT) }}
v-for="time in timeSpentChoices" </option>
:value="time.value" <option
:key="time.value" v-for="time in timeSpentChoices"
> :value="time.value"
{{ time.text }} :key="time.value"
</option> >
</select> {{ time.text }}
</option>
</select>
</div>
</div> </div>
</div>
</template> </template>
<script setup> <script setup>

View File

@@ -11,11 +11,11 @@ export const duplicate = async (
}; };
export const duplicateDocumentToEvaluation = async ( export const duplicateDocumentToEvaluation = async (
document_id: number, document_id: number,
evaluation_id: number, evaluation_id: number,
): Promise<AccompanyingPeriodWorkEvaluationDocument> => { ): Promise<AccompanyingPeriodWorkEvaluationDocument> => {
return makeFetch<null, AccompanyingPeriodWorkEvaluationDocument>( return makeFetch<null, AccompanyingPeriodWorkEvaluationDocument>(
"POST", "POST",
`/api/1.0/person/accompanying-course-work-evaluation-document/${document_id}/evaluation/${evaluation_id}/duplicate`, `/api/1.0/person/accompanying-course-work-evaluation-document/${document_id}/evaluation/${evaluation_id}/duplicate`,
); );
}; };

View File

@@ -1,45 +1,53 @@
<template> <template>
<div class="container"> <div class="container">
<div class="item-bloc"> <div class="item-bloc">
<div class="item-row"> <div class="item-row">
<h2 class="badge-title"> <h2 class="badge-title">
<span class="title_label"></span> <span class="title_label"></span>
<span class="title_action"> <span class="title_action">
<span> <span>
{{ trans(EVALUATION) }}: {{ trans(EVALUATION) }}:
<span class="badge bg-light text-dark"> <span class="badge bg-light text-dark">
{{ eval?.evaluation?.title.fr }} {{ eval?.evaluation?.title.fr }}
</span> </span>
</span> </span>
<ul class="small_in_title columns mt-1"> <ul class="small_in_title columns mt-1">
<li> <li>
<span class="item-key"> <span class="item-key">
{{ trans(ACCOMPANYING_COURSE_WORK_START_DATE) }} : {{
</span> trans(
<b>{{ formatDate(eval.startDate) }}</b> ACCOMPANYING_COURSE_WORK_START_DATE,
</li> )
}}
:
</span>
<b>{{ formatDate(eval.startDate) }}</b>
</li>
<li v-if="eval.endDate"> <li v-if="eval.endDate">
<span class="item-key"> <span class="item-key">
{{ trans(ACCOMPANYING_COURSE_WORK_END_DATE) }} : {{
</span> trans(ACCOMPANYING_COURSE_WORK_END_DATE)
<b>{{ formatDate(eval.endDate) }}</b> }}
</li> :
</ul> </span>
</span> <b>{{ formatDate(eval.endDate) }}</b>
</h2> </li>
</div> </ul>
</span>
</h2>
</div>
</div>
</div> </div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { import {
ACCOMPANYING_COURSE_WORK_END_DATE, ACCOMPANYING_COURSE_WORK_END_DATE,
ACCOMPANYING_COURSE_WORK_START_DATE, ACCOMPANYING_COURSE_WORK_START_DATE,
EVALUATION, EVALUATION,
trans, trans,
} from "translator"; } from "translator";
import { ISOToDate } from "ChillMainAssets/chill/js/date"; import { ISOToDate } from "ChillMainAssets/chill/js/date";
import { DateTime } from "ChillMainAssets/types"; import { DateTime } from "ChillMainAssets/types";
@@ -48,15 +56,15 @@ import { AccompanyingPeriodWorkEvaluation } from "../../../types";
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const props = defineProps<{ eval: AccompanyingPeriodWorkEvaluation }>(); const props = defineProps<{ eval: AccompanyingPeriodWorkEvaluation }>();
const formatDate = (dateObject: DateTime) => { const formatDate = (dateObject: DateTime) => {
if (dateObject) { if (dateObject) {
const parsedDate = ISOToDate(dateObject.datetime); const parsedDate = ISOToDate(dateObject.datetime);
if (parsedDate) { if (parsedDate) {
return new Intl.DateTimeFormat("default", { dateStyle: "short" }).format( return new Intl.DateTimeFormat("default", {
parsedDate, dateStyle: "short",
); }).format(parsedDate);
} else { } else {
return ""; return "";
}
} }
}
}; };
</script> </script>

View File

@@ -1,24 +1,24 @@
<template> <template>
<div class="results"> <div class="results">
<div <div
v-for="evaluation in evaluations" v-for="evaluation in evaluations"
:key="evaluation.id" :key="evaluation.id"
class="list-item" class="list-item"
> >
<label class="acpw-item"> <label class="acpw-item">
<div> <div>
<input <input
type="radio" type="radio"
:value="evaluation" :value="evaluation"
v-model="selectedEvaluation" v-model="selectedEvaluation"
name="item" name="item"
/> />
</div> </div>
<accompanying-period-work-evaluation-item :eval="evaluation" /> <accompanying-period-work-evaluation-item :eval="evaluation" />
</label> </label>
</div>
</div> </div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -28,7 +28,7 @@ import AccompanyingPeriodWorkEvaluationItem from "ChillPersonAssets/vuejs/_compo
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const props = defineProps<{ const props = defineProps<{
evaluations: AccompanyingPeriodWorkEvaluation[]; evaluations: AccompanyingPeriodWorkEvaluation[];
}>(); }>();
const selectedEvaluation = ref<AccompanyingPeriodWorkEvaluation | null>(null); const selectedEvaluation = ref<AccompanyingPeriodWorkEvaluation | null>(null);
@@ -36,12 +36,12 @@ const selectedEvaluation = ref<AccompanyingPeriodWorkEvaluation | null>(null);
const emit = defineEmits(); const emit = defineEmits();
watch(selectedEvaluation, (newValue) => { watch(selectedEvaluation, (newValue) => {
emit("update:selectedEvaluation", newValue); emit("update:selectedEvaluation", newValue);
}); });
</script> </script>
<style> <style>
.acpw-item { .acpw-item {
display: flex; display: flex;
} }
</style> </style>

View File

@@ -54,15 +54,15 @@ import { AccompanyingPeriodWork } from "../../../types";
// eslint-disable-next-line @typescript-eslint/no-unused-vars // eslint-disable-next-line @typescript-eslint/no-unused-vars
const props = defineProps<{ acpw: AccompanyingPeriodWork }>(); const props = defineProps<{ acpw: AccompanyingPeriodWork }>();
const formatDate = (dateObject: DateTime) => { const formatDate = (dateObject: DateTime) => {
if (dateObject) { if (dateObject) {
const parsedDate = ISOToDate(dateObject.datetime); const parsedDate = ISOToDate(dateObject.datetime);
if (parsedDate) { if (parsedDate) {
return new Intl.DateTimeFormat("default", { dateStyle: "short" }).format( return new Intl.DateTimeFormat("default", {
parsedDate, dateStyle: "short",
); }).format(parsedDate);
} else { } else {
return ""; return "";
}
} }
}
}; };
</script> </script>

View File

@@ -1,24 +1,24 @@
<template> <template>
<div class="results"> <div class="results">
<div <div
v-for="acpw in accompanyingPeriodWorks" v-for="acpw in accompanyingPeriodWorks"
:key="acpw.id" :key="acpw.id"
class="list-item" class="list-item"
> >
<label class="acpw-item"> <label class="acpw-item">
<div> <div>
<input <input
type="radio" type="radio"
:value="acpw" :value="acpw"
v-model="selectedAcpw" v-model="selectedAcpw"
name="item" name="item"
/> />
</div> </div>
<accompanying-period-work-item :acpw="acpw" /> <accompanying-period-work-item :acpw="acpw" />
</label> </label>
</div>
</div> </div>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -26,31 +26,32 @@ import AccompanyingPeriodWorkItem from "./AccompanyingPeriodWorkItem.vue";
import { AccompanyingPeriodWork } from "../../../types"; import { AccompanyingPeriodWork } from "../../../types";
import { defineProps, ref, watch } from "vue"; import { defineProps, ref, watch } from "vue";
// eslint-disable-next-line @typescript-eslint/no-unused-vars
const props = defineProps<{ const props = defineProps<{
accompanyingPeriodWorks: AccompanyingPeriodWork[]; accompanyingPeriodWorks: AccompanyingPeriodWork[];
selectedAcpw?: AccompanyingPeriodWork | null; selectedAcpw?: AccompanyingPeriodWork | null;
}>(); }>();
const selectedAcpw = ref<AccompanyingPeriodWork | null>(props.selectedAcpw ?? null); const selectedAcpw = ref<AccompanyingPeriodWork | null>(
props.selectedAcpw ?? null,
);
// eslint-disable-next-line vue/valid-define-emits
const emit = defineEmits<{ const emit = defineEmits<{
'update:selectedAcpw': [value: AccompanyingPeriodWork | null]; "update:selectedAcpw": [value: AccompanyingPeriodWork | null];
}>(); }>();
watch(() => props.selectedAcpw, (val) => { watch(
selectedAcpw.value = val ?? null; () => props.selectedAcpw,
}); (val) => {
selectedAcpw.value = val ?? null;
},
);
watch(selectedAcpw, (newValue) => { watch(selectedAcpw, (newValue) => {
emit("update:selectedAcpw", newValue); emit("update:selectedAcpw", newValue);
}); });
</script> </script>
<style> <style>
.acpw-item { .acpw-item {
display: flex; display: flex;
} }
</style> </style>

View File

@@ -1,56 +1,68 @@
<template> <template>
<div> <div>
<div class="row justify-content-end" v-if="!isEvaluationSelector"> <div class="row justify-content-end" v-if="!isEvaluationSelector">
<div class="col-md-6 col-sm-10" v-if="selectedAcpw"> <div class="col-md-6 col-sm-10" v-if="selectedAcpw">
<ul class="list-suggest remove-items"> <ul class="list-suggest remove-items">
<li> <li>
<span @click="selectedAcpw = null" class="chill-denomination">{{ <span
selectedAcpw?.socialAction?.title.fr @click="selectedAcpw = null"
}}</span> class="chill-denomination"
</li> >{{ selectedAcpw?.socialAction?.title.fr }}</span
>
</li>
</ul>
</div>
</div>
<ul v-if="!showModal" class="record_actions">
<li>
<a class="btn btn-sm btn-create mt-3" @click="openModal">
{{ trans(ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK) }}
</a>
</li>
</ul> </ul>
</div>
<teleport to="body">
<modal
v-if="showModal"
@close="closeModal"
modal-dialog-class="modal-dialog-scrollable modal-xl"
>
<template #header>
<h3>
{{
trans(
ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK,
)
}}
</h3>
</template>
<template #body>
<accompanying-period-work-list
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"
v-model:selectedEvaluation="selectedEvaluation"
/>
</template>
<template #footer>
<button
type="button"
class="btn btn-save"
@click="confirmSelection"
>
{{ trans(CONFIRM) }}
</button>
</template>
</modal>
</teleport>
</div> </div>
<ul v-if="!showModal" class="record_actions">
<li>
<a class="btn btn-sm btn-create mt-3" @click="openModal">
{{ trans(ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK) }}
</a>
</li>
</ul>
<teleport to="body">
<modal
v-if="showModal"
@close="closeModal"
modal-dialog-class="modal-dialog-scrollable modal-xl"
>
<template #header>
<h3>{{ trans(ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK) }}</h3>
</template>
<template #body>
<accompanying-period-work-list
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"
v-model:selectedEvaluation="selectedEvaluation"
/>
</template>
<template #footer>
<button type="button" class="btn btn-save" @click="confirmSelection">
{{ trans(CONFIRM) }}
</button>
</template>
</modal>
</teleport>
</div>
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
@@ -59,9 +71,9 @@ import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import AccompanyingPeriodWorkList from "./AccompanyingPeriodWorkList.vue"; import AccompanyingPeriodWorkList from "./AccompanyingPeriodWorkList.vue";
import { AccompanyingPeriodWork } from "../../../types"; import { AccompanyingPeriodWork } from "../../../types";
import { import {
trans, trans,
ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK, ACPW_DUPLICATE_SELECT_ACCOMPANYING_PERIOD_WORK,
CONFIRM, CONFIRM,
} from "translator"; } from "translator";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods"; import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
import AccompanyingPeriodWorkEvaluationList from "ChillPersonAssets/vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkEvaluationList.vue"; import AccompanyingPeriodWorkEvaluationList from "ChillPersonAssets/vuejs/_components/AccompanyingPeriodWorkSelector/AccompanyingPeriodWorkEvaluationList.vue";
@@ -74,88 +86,89 @@ const accompanyingPeriodWorks = ref<AccompanyingPeriodWork[]>([]);
const evaluations = ref<AccompanyingPeriodWorkEvaluation[]>([]); const evaluations = ref<AccompanyingPeriodWorkEvaluation[]>([]);
const props = defineProps({ const props = defineProps({
accompanyingPeriodId: String, accompanyingPeriodId: String,
isEvaluationSelector: Boolean, isEvaluationSelector: Boolean,
}); });
const emit = defineEmits<{ const emit = defineEmits<{
pickWork: [payload: { work: AccompanyingPeriodWork | null }]; pickWork: [payload: { work: AccompanyingPeriodWork | null }];
closeModal: []; closeModal: [];
"update:selectedEvaluation": [evaluation: AccompanyingPeriodWorkEvaluation]; "update:selectedEvaluation": [evaluation: AccompanyingPeriodWorkEvaluation];
}>(); }>();
onMounted(() => { onMounted(() => {
if (props.accompanyingPeriodId) { if (props.accompanyingPeriodId) {
getAccompanyingPeriodWorks(parseInt(props.accompanyingPeriodId)); getAccompanyingPeriodWorks(parseInt(props.accompanyingPeriodId));
} else { } else {
console.error("No accompanyingperiod id was given"); console.error("No accompanyingperiod id was given");
} }
showModal.value = true; showModal.value = true;
}); });
const getAccompanyingPeriodWorks = (periodId: number) => { const getAccompanyingPeriodWorks = (periodId: number) => {
const url = `/api/1.0/person/accompanying-course/${periodId}/works.json`; const url = `/api/1.0/person/accompanying-course/${periodId}/works.json`;
makeFetch<number, {results: AccompanyingPeriodWork[]}>("GET", url) makeFetch<number, { results: AccompanyingPeriodWork[] }>("GET", url)
.then((response) => { .then((response) => {
if (props.isEvaluationSelector) { if (props.isEvaluationSelector) {
accompanyingPeriodWorks.value = response.results.filter( accompanyingPeriodWorks.value = response.results.filter(
(acpw) => acpw.accompanyingPeriodWorkEvaluations.length > 0, (acpw) => acpw.accompanyingPeriodWorkEvaluations.length > 0,
); );
} else { } else {
accompanyingPeriodWorks.value = response.results; accompanyingPeriodWorks.value = response.results;
} }
}) })
.catch((error) => { .catch((error) => {
console.log(error); console.log(error);
}); });
}; };
watch(selectedAcpw, (newValue) => { watch(selectedAcpw, (newValue) => {
const inputField = document.getElementById( const inputField = document.getElementById(
"find_accompanying_period_work_acpw", "find_accompanying_period_work_acpw",
) as HTMLInputElement; ) as HTMLInputElement;
if (inputField) { if (inputField) {
inputField.value = String(newValue?.id || ''); inputField.value = String(newValue?.id || "");
} }
/* if (!props.isEvaluationSelector) { /* if (!props.isEvaluationSelector) {
console.log("Emitting from watch:", { work: newValue }); console.log("Emitting from watch:", { work: newValue });
emit("pickWork", { work: newValue }); emit("pickWork", { work: newValue });
}*/ }*/
}); });
const openModal = () => { const openModal = () => {
showModal.value = true; showModal.value = true;
}; };
const closeModal = () => { const closeModal = () => {
showModal.value = false; showModal.value = false;
selectedEvaluation.value = null; selectedEvaluation.value = null;
// selectedAcpw.value = null; // selectedAcpw.value = null;
emit("closeModal"); emit("closeModal");
}; };
const confirmSelection = () => { const confirmSelection = () => {
selectedAcpw.value = selectedAcpw.value; selectedAcpw.value = selectedAcpw.value;
console.log('selectedAcpw', selectedAcpw.value) console.log("selectedAcpw", selectedAcpw.value);
if (!props.isEvaluationSelector) { if (!props.isEvaluationSelector) {
if (selectedAcpw.value) { // only emit if something is actually selected! if (selectedAcpw.value) {
emit("pickWork", { work: selectedAcpw.value }); // only emit if something is actually selected!
closeModal(); emit("pickWork", { work: selectedAcpw.value });
closeModal();
}
// optionally show some error or warning if not selected
return;
} }
// optionally show some error or warning if not selected
return;
} if (selectedAcpw.value && props.isEvaluationSelector) {
evaluations.value =
selectedAcpw.value.accompanyingPeriodWorkEvaluations;
}
if (selectedAcpw.value && props.isEvaluationSelector) { if (selectedEvaluation.value && props.isEvaluationSelector) {
evaluations.value = selectedAcpw.value.accompanyingPeriodWorkEvaluations; // console.log('evaluation log in modal', selectedEvaluation.value)
} emit("update:selectedEvaluation", selectedEvaluation.value);
closeModal();
if (selectedEvaluation.value && props.isEvaluationSelector) { }
// console.log('evaluation log in modal', selectedEvaluation.value)
emit("update:selectedEvaluation", selectedEvaluation.value);
closeModal();
}
}; };
</script> </script>