Apply prettier to files

This commit is contained in:
Julie Lenaerts 2024-12-11 10:49:11 +01:00
parent a6aa2a81c2
commit ebfd48e41f
31 changed files with 4889 additions and 3883 deletions

View File

@ -1,23 +1,58 @@
<template> <template>
<div v-if="isButtonGroupDisplayable" class="btn-group"> <div v-if="isButtonGroupDisplayable" class="btn-group">
<button :class="Object.assign({'btn': true, 'btn-outline-primary': true, 'dropdown-toggle': true, 'btn-sm': props.small})" type="button" data-bs-toggle="dropdown" aria-expanded="false"> <button
:class="
Object.assign({
btn: true,
'btn-outline-primary': true,
'dropdown-toggle': true,
'btn-sm': props.small,
})
"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Actions Actions
</button> </button>
<ul class="dropdown-menu"> <ul class="dropdown-menu">
<li v-if="isEditableOnline"> <li v-if="isEditableOnline">
<wopi-edit-button :stored-object="props.storedObject" :classes="{'dropdown-item': true}" :execute-before-leave="props.executeBeforeLeave"></wopi-edit-button> <wopi-edit-button
:stored-object="props.storedObject"
:classes="{ 'dropdown-item': true }"
:execute-before-leave="props.executeBeforeLeave"
></wopi-edit-button>
</li> </li>
<li v-if="isEditableOnDesktop"> <li v-if="isEditableOnDesktop">
<desktop-edit-button :classes="{'dropdown-item': true}" :edit-link="props.davLink" :expiration-link="props.davLinkExpiration"></desktop-edit-button> <desktop-edit-button
:classes="{ 'dropdown-item': true }"
:edit-link="props.davLink"
:expiration-link="props.davLinkExpiration"
></desktop-edit-button>
</li> </li>
<li v-if="isConvertibleToPdf"> <li v-if="isConvertibleToPdf">
<convert-button :stored-object="props.storedObject" :filename="filename" :classes="{'dropdown-item': true}"></convert-button> <convert-button
:stored-object="props.storedObject"
:filename="filename"
:classes="{ 'dropdown-item': true }"
></convert-button>
</li> </li>
<li v-if="isDownloadable"> <li v-if="isDownloadable">
<download-button :stored-object="props.storedObject" :at-version="props.storedObject.currentVersion" :filename="filename" :classes="{'dropdown-item': true}" :display-action-string-in-button="true"></download-button> <download-button
:stored-object="props.storedObject"
:at-version="props.storedObject.currentVersion"
:filename="filename"
:classes="{ 'dropdown-item': true }"
:display-action-string-in-button="true"
></download-button>
</li> </li>
<li v-if="isHistoryViewable"> <li v-if="isHistoryViewable">
<history-button :stored-object="props.storedObject" :can-edit="canEdit && props.storedObject._permissions.canEdit"></history-button> <history-button
:stored-object="props.storedObject"
:can-edit="
canEdit && props.storedObject._permissions.canEdit
"
></history-button>
</li> </li>
</ul> </ul>
</div> </div>
@ -27,31 +62,34 @@
<div v-else-if="'failure' === props.storedObject.status"> <div v-else-if="'failure' === props.storedObject.status">
<div class="btn btn-outline-danger">La génération a échoué</div> <div class="btn btn-outline-danger">La génération a échoué</div>
</div> </div>
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import { computed, onMounted } from "vue"; import { computed, onMounted } from "vue";
import ConvertButton from "./StoredObjectButton/ConvertButton.vue"; import ConvertButton from "./StoredObjectButton/ConvertButton.vue";
import DownloadButton from "./StoredObjectButton/DownloadButton.vue"; import DownloadButton from "./StoredObjectButton/DownloadButton.vue";
import WopiEditButton from "./StoredObjectButton/WopiEditButton.vue"; import WopiEditButton from "./StoredObjectButton/WopiEditButton.vue";
import {is_extension_editable, is_extension_viewable, is_object_ready} from "./StoredObjectButton/helpers"; import {
is_extension_editable,
is_extension_viewable,
is_object_ready,
} from "./StoredObjectButton/helpers";
import { import {
StoredObject, StoredObject,
StoredObjectStatusChange, StoredObjectVersion, StoredObjectStatusChange,
WopiEditButtonExecutableBeforeLeaveFunction StoredObjectVersion,
WopiEditButtonExecutableBeforeLeaveFunction,
} from "../types"; } from "../types";
import DesktopEditButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DesktopEditButton.vue"; import DesktopEditButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/DesktopEditButton.vue";
import HistoryButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton.vue"; import HistoryButton from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton.vue";
interface DocumentActionButtonsGroupConfig { interface DocumentActionButtonsGroupConfig {
storedObject: StoredObject, storedObject: StoredObject;
small?: boolean, small?: boolean;
canEdit?: boolean, canEdit?: boolean;
canDownload?: boolean, canDownload?: boolean;
canConvertPdf?: boolean, canConvertPdf?: boolean;
returnPath?: string, returnPath?: string;
/** /**
* Will be the filename displayed to the user when he·she download the document * Will be the filename displayed to the user when he·she download the document
@ -59,34 +97,41 @@ interface DocumentActionButtonsGroupConfig {
* *
* If not set, 'document' will be used. * If not set, 'document' will be used.
*/ */
filename?: string, filename?: string;
/** /**
* If set, will execute this function before leaving to the editor * If set, will execute this function before leaving to the editor
*/ */
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction, executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction;
/** /**
* a link to download and edit file using webdav * a link to download and edit file using webdav
*/ */
davLink?: string, davLink?: string;
/** /**
* the expiration date of the download, as a unix timestamp * the expiration date of the download, as a unix timestamp
*/ */
davLinkExpiration?: number, davLinkExpiration?: number;
} }
const emit = defineEmits<{ const emit =
(e: 'onStoredObjectStatusChange', newStatus: StoredObjectStatusChange): void defineEmits<
}>(); (
e: "onStoredObjectStatusChange",
newStatus: StoredObjectStatusChange,
) => void
>();
const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), { const props = withDefaults(defineProps<DocumentActionButtonsGroupConfig>(), {
small: false, small: false,
canEdit: true, canEdit: true,
canDownload: true, canDownload: true,
canConvertPdf: true, canConvertPdf: true,
returnPath: window.location.pathname + window.location.search + window.location.hash returnPath:
window.location.pathname +
window.location.search +
window.location.hash,
}); });
/** /**
@ -100,22 +145,32 @@ let tryiesForReady = 0;
const maxTryiesForReady = 120; const maxTryiesForReady = 120;
const isButtonGroupDisplayable = computed<boolean>(() => { const isButtonGroupDisplayable = computed<boolean>(() => {
return isDownloadable.value || isEditableOnline.value || isEditableOnDesktop.value || isConvertibleToPdf.value; return (
isDownloadable.value ||
isEditableOnline.value ||
isEditableOnDesktop.value ||
isConvertibleToPdf.value
);
}); });
const isDownloadable = computed<boolean>(() => { const isDownloadable = computed<boolean>(() => {
return props.storedObject.status === 'ready' return (
props.storedObject.status === "ready" ||
// happens when the stored object version is just added, but not persisted // happens when the stored object version is just added, but not persisted
|| (props.storedObject.currentVersion !== null && props.storedObject.status === 'empty') (props.storedObject.currentVersion !== null &&
props.storedObject.status === "empty")
);
}); });
const isEditableOnline = computed<boolean>(() => { const isEditableOnline = computed<boolean>(() => {
return props.storedObject.status === 'ready' return (
&& props.storedObject._permissions.canEdit props.storedObject.status === "ready" &&
&& props.canEdit props.storedObject._permissions.canEdit &&
&& props.storedObject.currentVersion !== null props.canEdit &&
&& is_extension_editable(props.storedObject.currentVersion.type) props.storedObject.currentVersion !== null &&
&& props.storedObject.currentVersion.persisted !== false; is_extension_editable(props.storedObject.currentVersion.type) &&
props.storedObject.currentVersion.persisted !== false
);
}); });
const isEditableOnDesktop = computed<boolean>(() => { const isEditableOnDesktop = computed<boolean>(() => {
@ -123,26 +178,28 @@ const isEditableOnDesktop = computed<boolean>(() => {
}); });
const isConvertibleToPdf = computed<boolean>(() => { const isConvertibleToPdf = computed<boolean>(() => {
return props.storedObject.status === 'ready' return (
&& props.storedObject._permissions.canSee props.storedObject.status === "ready" &&
&& props.canConvertPdf props.storedObject._permissions.canSee &&
&& props.storedObject.currentVersion !== null props.canConvertPdf &&
&& is_extension_viewable(props.storedObject.currentVersion.type) props.storedObject.currentVersion !== null &&
&& props.storedObject.currentVersion.type !== 'application/pdf' is_extension_viewable(props.storedObject.currentVersion.type) &&
&& props.storedObject.currentVersion.persisted !== false; props.storedObject.currentVersion.type !== "application/pdf" &&
props.storedObject.currentVersion.persisted !== false
);
}); });
const isHistoryViewable = computed<boolean>(() => { const isHistoryViewable = computed<boolean>(() => {
return props.storedObject.status === 'ready'; return props.storedObject.status === "ready";
}); });
const checkForReady = function (): void { const checkForReady = function (): void {
if ( if (
'ready' === props.storedObject.status "ready" === props.storedObject.status ||
|| 'empty' === props.storedObject.status "empty" === props.storedObject.status ||
|| 'failure' === props.storedObject.status "failure" === props.storedObject.status ||
// stop reloading if the page stays opened for a long time // stop reloading if the page stays opened for a long time
|| tryiesForReady > maxTryiesForReady tryiesForReady > maxTryiesForReady
) { ) {
return; return;
} }
@ -153,20 +210,19 @@ const checkForReady = function(): void {
}; };
const onObjectNewStatusCallback = async function (): Promise<void> { const onObjectNewStatusCallback = async function (): Promise<void> {
if (props.storedObject.status === "stored_object_created") {
if (props.storedObject.status === 'stored_object_created') {
return Promise.resolve(); return Promise.resolve();
} }
const new_status = await is_object_ready(props.storedObject); const new_status = await is_object_ready(props.storedObject);
if (props.storedObject.status !== new_status.status) { if (props.storedObject.status !== new_status.status) {
emit('onStoredObjectStatusChange', new_status); emit("onStoredObjectStatusChange", new_status);
return Promise.resolve(); return Promise.resolve();
} else if ('failure' === new_status.status) { } else if ("failure" === new_status.status) {
return Promise.resolve(); return Promise.resolve();
} }
if ('ready' !== new_status.status) { if ("ready" !== new_status.status) {
// we check for new status, unless it is ready // we check for new status, unless it is ready
checkForReady(); checkForReady();
} }
@ -176,9 +232,7 @@ const onObjectNewStatusCallback = async function(): Promise<void> {
onMounted(() => { onMounted(() => {
checkForReady(); checkForReady();
}) });
</script> </script>
<style scoped> <style scoped></style>
</style>

View File

@ -27,7 +27,9 @@
</modal> </modal>
</teleport> </teleport>
<div class="col-12 m-auto sticky-top"> <div class="col-12 m-auto sticky-top">
<div class="row justify-content-center border-bottom pdf-tools d-md-none"> <div
class="row justify-content-center border-bottom pdf-tools d-md-none"
>
<div class="col-5 text-center turn-page"> <div class="col-5 text-center turn-page">
<select <select
class="form-select form-select-sm" class="form-select form-select-sm"
@ -89,7 +91,10 @@
class="col-5 p-0 text-center turnSignature" class="col-5 p-0 text-center turnSignature"
> >
<button <button
:disabled="userSignatureZone === null || userSignatureZone?.index < 1" :disabled="
userSignatureZone === null ||
userSignatureZone?.index < 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(-1)" @click="turnSignature(-1)"
> >
@ -97,7 +102,9 @@
</button> </button>
<span>|</span> <span>|</span>
<button <button
:disabled="userSignatureZone?.index >= signature.zones.length - 1" :disabled="
userSignatureZone?.index >= signature.zones.length - 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(1)" @click="turnSignature(1)"
> >
@ -135,7 +142,10 @@
:title="$t('add_sign_zone')" :title="$t('add_sign_zone')"
> >
<template v-if="canvasEvent === 'add'"> <template v-if="canvasEvent === 'add'">
<div class="spinner-border spinner-border-sm" role="status"> <div
class="spinner-border spinner-border-sm"
role="status"
>
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</template> </template>
@ -190,7 +200,10 @@
class="col-4 d-xl-none text-center turnSignature p-0" class="col-4 d-xl-none text-center turnSignature p-0"
> >
<button <button
:disabled="userSignatureZone === null || userSignatureZone?.index < 1" :disabled="
userSignatureZone === null ||
userSignatureZone?.index < 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(-1)" @click="turnSignature(-1)"
> >
@ -198,7 +211,9 @@
</button> </button>
<span>|</span> <span>|</span>
<button <button
:disabled="userSignatureZone?.index >= signature.zones.length - 1" :disabled="
userSignatureZone?.index >= signature.zones.length - 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(1)" @click="turnSignature(1)"
> >
@ -210,7 +225,10 @@
class="col-4 d-none d-xl-flex p-0 text-center turnSignature" class="col-4 d-none d-xl-flex p-0 text-center turnSignature"
> >
<button <button
:disabled="userSignatureZone === null || userSignatureZone?.index < 1" :disabled="
userSignatureZone === null ||
userSignatureZone?.index < 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(-1)" @click="turnSignature(-1)"
> >
@ -218,7 +236,9 @@
</button> </button>
<span>|</span> <span>|</span>
<button <button
:disabled="userSignatureZone?.index >= signature.zones.length - 1" :disabled="
userSignatureZone?.index >= signature.zones.length - 1
"
class="btn btn-light btn-sm" class="btn btn-light btn-sm"
@click="turnSignature(1)" @click="turnSignature(1)"
> >
@ -259,7 +279,10 @@
</template> </template>
<template v-else> <template v-else>
{{ $t("click_on_document") }} {{ $t("click_on_document") }}
<div class="spinner-border spinner-border-sm" role="status"> <div
class="spinner-border spinner-border-sm"
role="status"
>
<span class="visually-hidden">Loading...</span> <span class="visually-hidden">Loading...</span>
</div> </div>
</template> </template>
@ -336,7 +359,10 @@ console.log(PdfWorker); // incredible but this is needed
// pdfjsLib.GlobalWorkerOptions.workerSrc = PdfWorker; // pdfjsLib.GlobalWorkerOptions.workerSrc = PdfWorker;
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue"; import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import {download_and_decrypt_doc, download_doc_as_pdf} from "../StoredObjectButton/helpers"; import {
download_and_decrypt_doc,
download_doc_as_pdf,
} from "../StoredObjectButton/helpers";
pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs"; pdfjsLib.GlobalWorkerOptions.workerSrc = "pdfjs-dist/build/pdf.worker.mjs";
@ -479,12 +505,18 @@ const addCanvasEvents = () => {
canvas.addEventListener( canvas.addEventListener(
"pointerup", "pointerup",
(e) => canvasClick(e, canvas), (e) => canvasClick(e, canvas),
false false,
); );
}); });
} else { } else {
const canvas = document.querySelectorAll("canvas")[0] as HTMLCanvasElement; const canvas = document.querySelectorAll(
canvas.addEventListener("pointerup", (e) => canvasClick(e, canvas), false); "canvas",
)[0] as HTMLCanvasElement;
canvas.addEventListener(
"pointerup",
(e) => canvasClick(e, canvas),
false,
);
} }
}; };
@ -511,7 +543,7 @@ const scaleYToCanvas = (h: number, canvasHeight: number, PDFHeight: number) =>
const hitSignature = ( const hitSignature = (
zone: SignatureZone, zone: SignatureZone,
xy: number[], xy: number[],
canvas: HTMLCanvasElement canvas: HTMLCanvasElement,
) => ) =>
scaleXToCanvas(zone.x, canvas.width, zone.PDFPage.width) < xy[0] && scaleXToCanvas(zone.x, canvas.width, zone.PDFPage.width) < xy[0] &&
xy[0] < xy[0] <
@ -520,7 +552,11 @@ const hitSignature = (
scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) < scaleYToCanvas(zone.y, canvas.height, zone.PDFPage.height) <
xy[1] && xy[1] &&
xy[1] < xy[1] <
scaleYToCanvas(zone.height - zone.y, canvas.height, zone.PDFPage.height) + scaleYToCanvas(
zone.height - zone.y,
canvas.height,
zone.PDFPage.height,
) +
zone.PDFPage.height * zoom.value; zone.PDFPage.height * zoom.value;
const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => { const selectZone = async (z: SignatureZone, canvas: HTMLCanvasElement) => {
@ -536,8 +572,9 @@ const selectZoneEvent = (e: PointerEvent, canvas: HTMLCanvasElement) =>
signature.zones signature.zones
.filter( .filter(
(z) => (z) =>
(z.PDFPage.index + 1 === getCanvasId(canvas) && multiPage.value) || (z.PDFPage.index + 1 === getCanvasId(canvas) &&
(z.PDFPage.index + 1 === page.value && !multiPage.value) multiPage.value) ||
(z.PDFPage.index + 1 === page.value && !multiPage.value),
) )
.map((z) => { .map((z) => {
if (hitSignature(z, [e.offsetX, e.offsetY], canvas)) { if (hitSignature(z, [e.offsetX, e.offsetY], canvas)) {
@ -590,7 +627,7 @@ const drawZone = (
zone: SignatureZone, zone: SignatureZone,
ctx: CanvasRenderingContext2D, ctx: CanvasRenderingContext2D,
canvasWidth: number, canvasWidth: number,
canvasHeight: number canvasHeight: number,
) => { ) => {
const unselectedBlue = "#007bff"; const unselectedBlue = "#007bff";
const selectedBlue = "#034286"; const selectedBlue = "#034286";
@ -605,7 +642,7 @@ const drawZone = (
zone.PDFPage.height * zoom.value - zone.PDFPage.height * zoom.value -
scaleYToCanvas(zone.y, canvasHeight, zone.PDFPage.height), scaleYToCanvas(zone.y, canvasHeight, zone.PDFPage.height),
scaleXToCanvas(zone.width, canvasWidth, zone.PDFPage.width), scaleXToCanvas(zone.width, canvasWidth, zone.PDFPage.width),
scaleYToCanvas(zone.height, canvasHeight, zone.PDFPage.height) scaleYToCanvas(zone.height, canvasHeight, zone.PDFPage.height),
); );
ctx.font = `bold ${16 * zoom.value}px serif`; ctx.font = `bold ${16 * zoom.value}px serif`;
ctx.textAlign = "center"; ctx.textAlign = "center";
@ -633,7 +670,7 @@ const drawAllZones = () => {
.filter( .filter(
(z) => (z) =>
multiPage.value || multiPage.value ||
(z.PDFPage.index + 1 === page.value && !multiPage.value) (z.PDFPage.index + 1 === page.value && !multiPage.value),
) )
.map((z) => { .map((z) => {
const canvas = getCanvas(z.PDFPage.index + 1); const canvas = getCanvas(z.PDFPage.index + 1);
@ -663,7 +700,7 @@ const checkSignature = () => {
signedState.value = "error"; signedState.value = "error";
console.log("Error while checking the signature", error); console.log("Error while checking the signature", error);
$toast.error( $toast.error(
`Erreur lors de la vérification de la signature: ${error.txt}` `Erreur lors de la vérification de la signature: ${error.txt}`,
); );
}); });
}; };
@ -682,7 +719,7 @@ const checkForReady = () => {
tryForReady = 0; tryForReady = 0;
console.log("Reached the maximum number of tentative to try signing"); console.log("Reached the maximum number of tentative to try signing");
$toast.error( $toast.error(
"Le nombre maximum de tentatives pour essayer de signer est atteint" "Le nombre maximum de tentatives pour essayer de signer est atteint",
); );
} }
if (signedState.value === "rejected") { if (signedState.value === "rejected") {
@ -724,7 +761,7 @@ const confirmSign = () => {
console.log("Error while posting the signature", error); console.log("Error while posting the signature", error);
stopTrySigning(); stopTrySigning();
$toast.error( $toast.error(
`Erreur lors de la soumission de la signature: ${error.txt}` `Erreur lors de la soumission de la signature: ${error.txt}`,
); );
}); });
}; };
@ -780,8 +817,8 @@ const addZoneEvent = async (e: PointerEvent, canvas: HTMLCanvasElement) => {
const getReturnPath = () => const getReturnPath = () =>
window.location.search window.location.search
? window.location.search.split("?returnPath=")[1] ?? ? (window.location.search.split("?returnPath=")[1] ??
window.location.pathname window.location.pathname)
: window.location.pathname; : window.location.pathname;
init(); init();
@ -842,4 +879,3 @@ div.signature-modal-body {
height: 8rem; height: 8rem;
} }
</style> </style>

View File

@ -1,19 +1,31 @@
<script setup lang="ts"> <script setup lang="ts">
import { StoredObject, StoredObjectVersionCreated } from "../../types"; import { StoredObject, StoredObjectVersionCreated } from "../../types";
import {encryptFile, fetchNewStoredObject, uploadVersion} from "../../js/async-upload/uploader"; import {
encryptFile,
fetchNewStoredObject,
uploadVersion,
} from "../../js/async-upload/uploader";
import { computed, ref, Ref } from "vue"; import { computed, ref, Ref } from "vue";
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue"; import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
interface DropFileConfig { interface DropFileConfig {
existingDoc?: StoredObject, existingDoc?: StoredObject;
} }
const props = withDefaults(defineProps<DropFileConfig>(), {existingDoc: null}); const props = withDefaults(defineProps<DropFileConfig>(), {
existingDoc: null,
});
const emit = defineEmits<{ const emit =
(e: 'addDocument', {stored_object_version: StoredObjectVersionCreated, stored_object: StoredObject}): void, defineEmits<
}>(); (
e: "addDocument",
{
stored_object_version: StoredObjectVersionCreated,
stored_object: StoredObject,
},
) => void
>();
const is_dragging: Ref<boolean> = ref(false); const is_dragging: Ref<boolean> = ref(false);
const uploading: Ref<boolean> = ref(false); const uploading: Ref<boolean> = ref(false);
@ -27,13 +39,13 @@ const onDragOver = (e: Event) => {
e.preventDefault(); e.preventDefault();
is_dragging.value = true; is_dragging.value = true;
} };
const onDragLeave = (e: Event) => { const onDragLeave = (e: Event) => {
e.preventDefault(); e.preventDefault();
is_dragging.value = false; is_dragging.value = false;
} };
const onDrop = (e: DragEvent) => { const onDrop = (e: DragEvent) => {
e.preventDefault(); e.preventDefault();
@ -49,8 +61,8 @@ const onDrop = (e: DragEvent) => {
return; return;
} }
handleFile(files[0]) handleFile(files[0]);
} };
const onZoneClick = (e: Event) => { const onZoneClick = (e: Event) => {
e.stopPropagation(); e.stopPropagation();
@ -61,21 +73,21 @@ const onZoneClick = (e: Event) => {
input.addEventListener("change", onFileChange); input.addEventListener("change", onFileChange);
input.click(); input.click();
} };
const onFileChange = async (event: Event): Promise<void> => { const onFileChange = async (event: Event): Promise<void> => {
const input = event.target as HTMLInputElement; const input = event.target as HTMLInputElement;
if (input.files && input.files[0]) { if (input.files && input.files[0]) {
console.log('file added', input.files[0]); console.log("file added", input.files[0]);
const file = input.files[0]; const file = input.files[0];
await handleFile(file); await handleFile(file);
return Promise.resolve(); return Promise.resolve();
} }
throw 'No file given'; throw "No file given";
} };
const handleFile = async (file: File): Promise<void> => { const handleFile = async (file: File): Promise<void> => {
uploading.value = true; uploading.value = true;
@ -100,25 +112,39 @@ const handleFile = async (file: File): Promise<void> => {
keyInfos: jsonWebKey, keyInfos: jsonWebKey,
type: type, type: type,
persisted: false, persisted: false,
} };
emit('addDocument', {stored_object, stored_object_version}); emit("addDocument", { stored_object, stored_object_version });
uploading.value = false; uploading.value = false;
} };
</script> </script>
<template> <template>
<div class="drop-file"> <div class="drop-file">
<div v-if="!uploading" :class="{ area: true, dragging: is_dragging}" @click="onZoneClick" @dragover="onDragOver" @dragleave="onDragLeave" @drop="onDrop"> <div
v-if="!uploading"
:class="{ area: true, dragging: is_dragging }"
@click="onZoneClick"
@dragover="onDragOver"
@dragleave="onDragLeave"
@drop="onDrop"
>
<p v-if="has_existing_doc" class="file-icon"> <p v-if="has_existing_doc" class="file-icon">
<file-icon :type="props.existingDoc?.type"></file-icon> <file-icon :type="props.existingDoc?.type"></file-icon>
</p> </p>
<p v-if="display_filename !== null" class="display-filename">{{ display_filename }}</p> <p v-if="display_filename !== null" class="display-filename">
{{ display_filename }}
</p>
<!-- todo i18n --> <!-- todo i18n -->
<p v-if="has_existing_doc">Déposez un document ou cliquez ici pour remplacer le document existant</p> <p v-if="has_existing_doc">
<p v-else>Déposez un document ou cliquez ici pour ouvrir le navigateur de fichier</p> Déposez un document ou cliquez ici pour remplacer le document
existant
</p>
<p v-else>
Déposez un document ou cliquez ici pour ouvrir le navigateur de
fichier
</p>
</div> </div>
<div v-else class="waiting"> <div v-else class="waiting">
<i class="fa fa-cog fa-spin fa-3x fa-fw"></i> <i class="fa fa-cog fa-spin fa-3x fa-fw"></i>
@ -140,7 +166,8 @@ const handleFile = async (file: File): Promise<void> => {
font-weight: 200; font-weight: 200;
} }
& > .area, & > .waiting { & > .area,
& > .waiting {
width: 100%; width: 100%;
height: 10rem; height: 10rem;
@ -163,5 +190,4 @@ const handleFile = async (file: File): Promise<void> => {
} }
} }
} }
</style> </style>

View File

@ -1,14 +1,13 @@
<script setup lang="ts"> <script setup lang="ts">
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue"; import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import { StoredObject, StoredObjectVersion } from "../../types"; import { StoredObject, StoredObjectVersion } from "../../types";
import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue"; import DropFileWidget from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFileWidget.vue";
import { computed, reactive } from "vue"; import { computed, reactive } from "vue";
import {useToast} from 'vue-toast-notification'; import { useToast } from "vue-toast-notification";
interface DropFileConfig { interface DropFileConfig {
allowRemove: boolean, allowRemove: boolean;
existingDoc?: StoredObject, existingDoc?: StoredObject;
} }
const props = withDefaults(defineProps<DropFileConfig>(), { const props = withDefaults(defineProps<DropFileConfig>(), {
@ -16,8 +15,14 @@ const props = withDefaults(defineProps<DropFileConfig>(), {
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'addDocument', {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void, (
(e: 'removeDocument'): void e: "addDocument",
{
stored_object: StoredObject,
stored_object_version: StoredObjectVersion,
},
): void;
(e: "removeDocument"): void;
}>(); }>();
const $toast = useToast(); const $toast = useToast();
@ -26,23 +31,30 @@ const state = reactive({showModal: false});
const modalClasses = { "modal-dialog-centered": true, "modal-md": true }; const modalClasses = { "modal-dialog-centered": true, "modal-md": true };
const buttonState = computed<'add'|'replace'>(() => { const buttonState = computed<"add" | "replace">(() => {
if (props.existingDoc === undefined || props.existingDoc === null) { if (props.existingDoc === undefined || props.existingDoc === null) {
return 'add'; return "add";
} }
return 'replace'; return "replace";
}) });
function onAddDocument({stored_object, stored_object_version}: {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void { function onAddDocument({
const message = buttonState.value === 'add' ? "Document ajouté" : "Document remplacé"; stored_object,
stored_object_version,
}: {
stored_object: StoredObject;
stored_object_version: StoredObjectVersion;
}): void {
const message =
buttonState.value === "add" ? "Document ajouté" : "Document remplacé";
$toast.success(message); $toast.success(message);
emit('addDocument', {stored_object_version, stored_object}); emit("addDocument", { stored_object_version, stored_object });
state.showModal = false; state.showModal = false;
} }
function onRemoveDocument(): void { function onRemoveDocument(): void {
emit('removeDocument'); emit("removeDocument");
} }
function openModal(): void { function openModal(): void {
@ -55,15 +67,30 @@ function closeModal(): void {
</script> </script>
<template> <template>
<button v-if="buttonState === 'add'" @click="openModal" class="btn btn-create">Ajouter un document</button> <button
<button v-else @click="openModal" class="btn btn-edit">Remplacer le document</button> v-if="buttonState === 'add'"
<modal v-if="state.showModal" :modal-dialog-class="modalClasses" @close="closeModal"> @click="openModal"
class="btn btn-create"
>
Ajouter un document
</button>
<button v-else @click="openModal" class="btn btn-edit">
Remplacer le document
</button>
<modal
v-if="state.showModal"
:modal-dialog-class="modalClasses"
@close="closeModal"
>
<template v-slot:body> <template v-slot:body>
<drop-file-widget :existing-doc="existingDoc" :allow-remove="allowRemove" @add-document="onAddDocument" @remove-document="onRemoveDocument" ></drop-file-widget> <drop-file-widget
:existing-doc="existingDoc"
:allow-remove="allowRemove"
@add-document="onAddDocument"
@remove-document="onRemoveDocument"
></drop-file-widget>
</template> </template>
</modal> </modal>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,13 +1,12 @@
<script setup lang="ts"> <script setup lang="ts">
import { StoredObject, StoredObjectVersion } from "../../types"; import { StoredObject, StoredObjectVersion } from "../../types";
import { computed, ref, Ref } from "vue"; import { computed, ref, Ref } from "vue";
import DropFile from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFile.vue"; import DropFile from "ChillDocStoreAssets/vuejs/DropFileWidget/DropFile.vue";
import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue"; import DocumentActionButtonsGroup from "ChillDocStoreAssets/vuejs/DocumentActionButtonsGroup.vue";
interface DropFileConfig { interface DropFileConfig {
allowRemove: boolean, allowRemove: boolean;
existingDoc?: StoredObject, existingDoc?: StoredObject;
} }
const props = withDefaults(defineProps<DropFileConfig>(), { const props = withDefaults(defineProps<DropFileConfig>(), {
@ -15,8 +14,14 @@ const props = withDefaults(defineProps<DropFileConfig>(), {
}); });
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'addDocument', {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void, (
(e: 'removeDocument'): void e: "addDocument",
{
stored_object: StoredObject,
stored_object_version: StoredObjectVersion,
},
): void;
(e: "removeDocument"): void;
}>(); }>();
const has_existing_doc = computed<boolean>(() => { const has_existing_doc = computed<boolean>(() => {
@ -27,7 +32,7 @@ const dav_link_expiration = computed<number|undefined>(() => {
if (props.existingDoc === undefined || props.existingDoc === null) { if (props.existingDoc === undefined || props.existingDoc === null) {
return undefined; return undefined;
} }
if (props.existingDoc.status !== 'ready') { if (props.existingDoc.status !== "ready") {
return undefined; return undefined;
} }
@ -38,28 +43,36 @@ const dav_link_href = computed<string|undefined>(() => {
if (props.existingDoc === undefined || props.existingDoc === null) { if (props.existingDoc === undefined || props.existingDoc === null) {
return undefined; return undefined;
} }
if (props.existingDoc.status !== 'ready') { if (props.existingDoc.status !== "ready") {
return undefined; return undefined;
} }
return props.existingDoc._links?.dav_link?.href; return props.existingDoc._links?.dav_link?.href;
}) });
const onAddDocument = ({stored_object, stored_object_version}: {stored_object: StoredObject, stored_object_version: StoredObjectVersion}): void => { const onAddDocument = ({
emit('addDocument', {stored_object, stored_object_version}); stored_object,
} stored_object_version,
}: {
stored_object: StoredObject;
stored_object_version: StoredObjectVersion;
}): void => {
emit("addDocument", { stored_object, stored_object_version });
};
const onRemoveDocument = (e: Event): void => { const onRemoveDocument = (e: Event): void => {
e.stopPropagation(); e.stopPropagation();
e.preventDefault(); e.preventDefault();
emit('removeDocument'); emit("removeDocument");
} };
</script> </script>
<template> <template>
<div> <div>
<drop-file :existingDoc="props.existingDoc" @addDocument="onAddDocument"></drop-file> <drop-file
:existingDoc="props.existingDoc"
@addDocument="onAddDocument"
></drop-file>
<ul class="record_actions"> <ul class="record_actions">
<li v-if="has_existing_doc"> <li v-if="has_existing_doc">
@ -72,12 +85,14 @@ const onRemoveDocument = (e: Event): void => {
/> />
</li> </li>
<li> <li>
<button v-if="allowRemove" class="btn btn-delete" @click="onRemoveDocument($event)" ></button> <button
v-if="allowRemove"
class="btn btn-delete"
@click="onRemoveDocument($event)"
></button>
</li> </li>
</ul> </ul>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -4,22 +4,43 @@ interface FileIconConfig {
} }
const props = defineProps<FileIconConfig>(); const props = defineProps<FileIconConfig>();
</script> </script>
<template> <template>
<i class="fa fa-file-pdf-o" v-if="props.type === 'application/pdf'"></i> <i class="fa fa-file-pdf-o" v-if="props.type === 'application/pdf'"></i>
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/vnd.oasis.opendocument.text'"></i> <i
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/vnd.openxmlformats-officedocument.wordprocessingml.document'"></i> class="fa fa-file-word-o"
<i class="fa fa-file-word-o" v-else-if="props.type === 'application/msword'"></i> v-else-if="props.type === 'application/vnd.oasis.opendocument.text'"
<i class="fa fa-file-excel-o" v-else-if="props.type === 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'"></i> ></i>
<i class="fa fa-file-excel-o" v-else-if="props.type === 'application/vnd.ms-excel'"></i> <i
class="fa fa-file-word-o"
v-else-if="
props.type ===
'application/vnd.openxmlformats-officedocument.wordprocessingml.document'
"
></i>
<i
class="fa fa-file-word-o"
v-else-if="props.type === 'application/msword'"
></i>
<i
class="fa fa-file-excel-o"
v-else-if="
props.type ===
'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
"
></i>
<i
class="fa fa-file-excel-o"
v-else-if="props.type === 'application/vnd.ms-excel'"
></i>
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/jpeg'"></i> <i class="fa fa-file-image-o" v-else-if="props.type === 'image/jpeg'"></i>
<i class="fa fa-file-image-o" v-else-if="props.type === 'image/png'"></i> <i class="fa fa-file-image-o" v-else-if="props.type === 'image/png'"></i>
<i class="fa fa-file-archive-o" v-else-if="props.type === 'application/x-zip-compressed'"></i> <i
class="fa fa-file-archive-o"
v-else-if="props.type === 'application/x-zip-compressed'"
></i>
<i class="fa fa-file-code-o" v-else></i> <i class="fa fa-file-code-o" v-else></i>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -6,20 +6,23 @@
</template> </template>
<script lang="ts" setup> <script lang="ts" setup>
import {
import {build_convert_link, download_and_decrypt_doc, download_doc} from "./helpers"; build_convert_link,
download_and_decrypt_doc,
download_doc,
} from "./helpers";
import mime from "mime"; import mime from "mime";
import { reactive, ref } from "vue"; import { reactive, ref } from "vue";
import { StoredObject } from "../../types"; import { StoredObject } from "../../types";
interface ConvertButtonConfig { interface ConvertButtonConfig {
storedObject: StoredObject, storedObject: StoredObject;
classes: { [key: string]: boolean}, classes: Record<string, boolean>;
filename?: string, filename?: string;
}; }
interface DownloadButtonState { interface DownloadButtonState {
content: null|string content: null | string;
} }
const props = defineProps<ConvertButtonConfig>(); const props = defineProps<ConvertButtonConfig>();
@ -32,13 +35,15 @@ async function download_and_open(event: Event): Promise<void> {
if (null === state.content) { if (null === state.content) {
event.preventDefault(); event.preventDefault();
const raw = await download_doc(build_convert_link(props.storedObject.uuid)); const raw = await download_doc(
build_convert_link(props.storedObject.uuid),
);
state.content = window.URL.createObjectURL(raw); state.content = window.URL.createObjectURL(raw);
button.href = window.URL.createObjectURL(raw); button.href = window.URL.createObjectURL(raw);
button.type = 'application/pdf'; button.type = "application/pdf";
button.download = (props.filename + '.pdf') || 'document.pdf'; button.download = props.filename + ".pdf" || "document.pdf";
} }
button.click(); button.click();
@ -47,11 +52,10 @@ async function download_and_open(event: Event): Promise<void> {
function reset_state(): void { function reset_state(): void {
state.content = null; state.content = null;
btn.value?.removeAttribute('download'); btn.value?.removeAttribute("download");
btn.value?.removeAttribute('href'); btn.value?.removeAttribute("href");
btn.value?.removeAttribute('type'); btn.value?.removeAttribute("type");
} }
</script> </script>
<style scoped lang="scss"> <style scoped lang="scss">

View File

@ -1,9 +1,23 @@
<template> <template>
<a v-if="!state.is_ready" :class="props.classes" @click="download_and_open()" title="T&#233;l&#233;charger"> <a
v-if="!state.is_ready"
:class="props.classes"
@click="download_and_open()"
title="T&#233;l&#233;charger"
>
<i class="fa fa-download"></i> <i class="fa fa-download"></i>
<template v-if="displayActionStringInButton">Télécharger</template> <template v-if="displayActionStringInButton">Télécharger</template>
</a> </a>
<a v-else :class="props.classes" target="_blank" :type="props.atVersion.type" :download="buildDocumentName()" :href="state.href_url" ref="open_button" title="Ouvrir"> <a
v-else
:class="props.classes"
target="_blank"
:type="props.atVersion.type"
:download="buildDocumentName()"
:href="state.href_url"
ref="open_button"
title="Ouvrir"
>
<i class="fa fa-external-link"></i> <i class="fa fa-external-link"></i>
<template v-if="displayActionStringInButton">Ouvrir</template> <template v-if="displayActionStringInButton">Ouvrir</template>
</a> </a>
@ -16,43 +30,50 @@ import mime from "mime";
import { StoredObject, StoredObjectVersion } from "../../types"; import { StoredObject, StoredObjectVersion } from "../../types";
interface DownloadButtonConfig { interface DownloadButtonConfig {
storedObject: StoredObject, storedObject: StoredObject;
atVersion: StoredObjectVersion, atVersion: StoredObjectVersion;
classes: { [k: string]: boolean }, classes: Record<string, boolean>;
filename?: string, filename?: string;
/** /**
* if true, display the action string into the button. If false, displays only * if true, display the action string into the button. If false, displays only
* the icon * the icon
*/ */
displayActionStringInButton?: boolean, displayActionStringInButton?: boolean;
/** /**
* if true, will download directly the file on load * if true, will download directly the file on load
*/ */
directDownload?: boolean, directDownload?: boolean;
} }
interface DownloadButtonState { interface DownloadButtonState {
is_ready: boolean, is_ready: boolean;
is_running: boolean, is_running: boolean;
href_url: string, href_url: string;
} }
const props = withDefaults(defineProps<DownloadButtonConfig>(), {displayActionStringInButton: true, directDownload: false}); const props = withDefaults(defineProps<DownloadButtonConfig>(), {
const state: DownloadButtonState = reactive({is_ready: false, is_running: false, href_url: "#"}); displayActionStringInButton: true,
directDownload: false,
});
const state: DownloadButtonState = reactive({
is_ready: false,
is_running: false,
href_url: "#",
});
const open_button = ref<HTMLAnchorElement | null>(null); const open_button = ref<HTMLAnchorElement | null>(null);
function buildDocumentName(): string { function buildDocumentName(): string {
let document_name = props.filename ?? props.storedObject.title; let document_name = props.filename ?? props.storedObject.title;
if ('' === document_name) { if ("" === document_name) {
document_name = 'document'; document_name = "document";
} }
const ext = mime.getExtension(props.atVersion.type); const ext = mime.getExtension(props.atVersion.type);
if (null !== ext) { if (null !== ext) {
return document_name + '.' + ext; return document_name + "." + ext;
} }
return document_name; return document_name;
@ -60,21 +81,24 @@ function buildDocumentName(): string {
async function download_and_open(): Promise<void> { async function download_and_open(): Promise<void> {
if (state.is_running) { if (state.is_running) {
console.log('state is running, aborting'); console.log("state is running, aborting");
return; return;
} }
state.is_running = true; state.is_running = true;
if (state.is_ready) { if (state.is_ready) {
console.log('state is ready. This should not happens'); console.log("state is ready. This should not happens");
return; return;
} }
let raw; let raw;
try { try {
raw = await download_and_decrypt_doc(props.storedObject, props.atVersion); raw = await download_and_decrypt_doc(
props.storedObject,
props.atVersion,
);
} catch (e) { } catch (e) {
console.error("error while downloading and decrypting document"); console.error("error while downloading and decrypting document");
console.error(e); console.error(e);
@ -89,13 +113,13 @@ async function download_and_open(): Promise<void> {
await nextTick(); await nextTick();
open_button.value?.click(); open_button.value?.click();
console.log('open button should have been clicked'); console.log("open button should have been clicked");
setTimeout(reset_state, 45000); setTimeout(reset_state, 45000);
} }
} }
function reset_state(): void { function reset_state(): void {
state.href_url = '#'; state.href_url = "#";
state.is_ready = false; state.is_ready = false;
state.is_running = false; state.is_running = false;
} }

View File

@ -1,7 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import HistoryButtonModal from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonModal.vue"; import HistoryButtonModal from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonModal.vue";
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../types"; import {
StoredObject,
StoredObjectVersionWithPointInTime,
} from "./../../types";
import { computed, reactive, ref, useTemplateRef } from "vue"; import { computed, reactive, ref, useTemplateRef } from "vue";
import { get_versions } from "./HistoryButton/api"; import { get_versions } from "./HistoryButton/api";
@ -17,7 +19,7 @@ interface HistoryButtonState {
const props = defineProps<HistoryButtonConfig>(); const props = defineProps<HistoryButtonConfig>();
const state = reactive<HistoryButtonState>({ versions: [], loaded: false }); const state = reactive<HistoryButtonState>({ versions: [], loaded: false });
const modal = useTemplateRef<typeof HistoryButtonModal>('modal'); const modal = useTemplateRef<typeof HistoryButtonModal>("modal");
const download_version_and_open_modal = async function (): Promise<void> { const download_version_and_open_modal = async function (): Promise<void> {
if (null !== modal.value) { if (null !== modal.value) {
@ -34,17 +36,26 @@ const download_version_and_open_modal = async function (): Promise<void> {
} }
state.loaded = true; state.loaded = true;
} }
} };
const onRestoreVersion = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => { const onRestoreVersion = ({
newVersion,
}: {
newVersion: StoredObjectVersionWithPointInTime;
}) => {
state.versions.unshift(newVersion); state.versions.unshift(newVersion);
} };
</script> </script>
<template> <template>
<a @click="download_version_and_open_modal" class="dropdown-item"> <a @click="download_version_and_open_modal" class="dropdown-item">
<history-button-modal ref="modal" :versions="state.versions" :stored-object="storedObject" :can-edit="canEdit" @restore-version="onRestoreVersion"></history-button-modal> <history-button-modal
ref="modal"
:versions="state.versions"
:stored-object="storedObject"
:can-edit="canEdit"
@restore-version="onRestoreVersion"
></history-button-modal>
<i class="fa fa-history"></i> <i class="fa fa-history"></i>
Historique Historique
</a> </a>

View File

@ -1,5 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../../types"; import {
StoredObject,
StoredObjectVersionWithPointInTime,
} from "./../../../types";
import HistoryButtonListItem from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonListItem.vue"; import HistoryButtonListItem from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonListItem.vue";
import { computed, reactive } from "vue"; import { computed, reactive } from "vue";
@ -10,8 +13,8 @@ interface HistoryButtonListConfig {
} }
const emit = defineEmits<{ const emit = defineEmits<{
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime] restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
}>() }>();
interface HistoryButtonListState { interface HistoryButtonListState {
/** /**
@ -22,12 +25,14 @@ interface HistoryButtonListState {
const props = defineProps<HistoryButtonListConfig>(); const props = defineProps<HistoryButtonListConfig>();
const state = reactive<HistoryButtonListState>({restored: -1}) const state = reactive<HistoryButtonListState>({ restored: -1 });
const higher_version = computed<number>(() => props.versions.reduce( const higher_version = computed<number>(() =>
(accumulator: number, version: StoredObjectVersionWithPointInTime) => Math.max(accumulator, version.version), props.versions.reduce(
-1 (accumulator: number, version: StoredObjectVersionWithPointInTime) =>
) Math.max(accumulator, version.version),
-1,
),
); );
/** /**
@ -35,11 +40,14 @@ const higher_version = computed<number>(() => props.versions.reduce(
* *
* internally, keep track of the newly restored version * internally, keep track of the newly restored version
*/ */
const onRestored = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => { const onRestored = ({
newVersion,
}: {
newVersion: StoredObjectVersionWithPointInTime;
}) => {
state.restored = newVersion.version; state.restored = newVersion.version;
emit('restoreVersion', {newVersion}); emit("restoreVersion", { newVersion });
} };
</script> </script>
<template> <template>
@ -59,9 +67,6 @@ const onRestored = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTim
<template v-else> <template v-else>
<p>Chargement des versions</p> <p>Chargement des versions</p>
</template> </template>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,5 +1,9 @@
<script setup lang="ts"> <script setup lang="ts">
import {StoredObject, StoredObjectPointInTime, StoredObjectVersionWithPointInTime} from "./../../../types"; import {
StoredObject,
StoredObjectPointInTime,
StoredObjectVersionWithPointInTime,
} from "./../../../types";
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue"; import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
import { ISOToDatetime } from "./../../../../../../ChillMainBundle/Resources/public/chill/js/date"; import { ISOToDatetime } from "./../../../../../../ChillMainBundle/Resources/public/chill/js/date";
import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue"; import FileIcon from "ChillDocStoreAssets/vuejs/FileIcon.vue";
@ -15,47 +19,120 @@ interface HistoryButtonListItemConfig {
} }
const emit = defineEmits<{ const emit = defineEmits<{
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime] restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
}>() }>();
const props = defineProps<HistoryButtonListItemConfig>(); const props = defineProps<HistoryButtonListItemConfig>();
const onRestore = ({newVersion}: {newVersion: StoredObjectVersionWithPointInTime}) => { const onRestore = ({
emit('restoreVersion', {newVersion}); newVersion,
} }: {
newVersion: StoredObjectVersionWithPointInTime;
}) => {
emit("restoreVersion", { newVersion });
};
const isKeptBeforeConversion = computed<boolean>(() => props.version["point-in-times"].reduce( const isKeptBeforeConversion = computed<boolean>(() =>
(accumulator: boolean, pit: StoredObjectPointInTime) => accumulator || "keep-before-conversion" === pit.reason, props.version["point-in-times"].reduce(
false (accumulator: boolean, pit: StoredObjectPointInTime) =>
accumulator || "keep-before-conversion" === pit.reason,
false,
), ),
); );
const isRestored = computed<boolean>(() => props.version.version > 0 && null !== props.version["from-restored"]); const isRestored = computed<boolean>(
() => props.version.version > 0 && null !== props.version["from-restored"],
);
const isDuplicated = computed<boolean>(() => props.version.version === 0 && null !== props.version["from-restored"]); const isDuplicated = computed<boolean>(
() =>
const classes = computed<{row: true, 'row-hover': true, 'blinking-1': boolean, 'blinking-2': boolean}>(() => ({row: true, 'row-hover': true, 'blinking-1': props.isRestored && 0 === props.version.version % 2, 'blinking-2': props.isRestored && 1 === props.version.version % 2})); props.version.version === 0 && null !== props.version["from-restored"],
);
const classes = computed<{
row: true;
"row-hover": true;
"blinking-1": boolean;
"blinking-2": boolean;
}>(() => ({
row: true,
"row-hover": true,
"blinking-1": props.isRestored && 0 === props.version.version % 2,
"blinking-2": props.isRestored && 1 === props.version.version % 2,
}));
</script> </script>
<template> <template>
<div :class="classes"> <div :class="classes">
<div class="col-12 tags" v-if="isCurrent || isKeptBeforeConversion || isRestored || isDuplicated"> <div
<span class="badge bg-success" v-if="isCurrent">Version actuelle</span> class="col-12 tags"
<span class="badge bg-info" v-if="isKeptBeforeConversion">Conservée avant conversion dans un autre format</span> v-if="
<span class="badge bg-info" v-if="isRestored">Restaurée depuis la version {{ version["from-restored"]?.version + 1 }}</span> isCurrent ||
<span class="badge bg-info" v-if="isDuplicated">Dupliqué depuis un autre document</span> 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
>
<span class="badge bg-info" v-if="isRestored"
>Restaurée depuis la version
{{ version["from-restored"]?.version + 1 }}</span
>
<span class="badge bg-info" v-if="isDuplicated"
>Dupliqué depuis un autre document</span
>
</div> </div>
<div class="col-12"> <div class="col-12">
<file-icon :type="version.type"></file-icon> <span><strong>#{{ version.version + 1 }}</strong></span> <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></span> <strong>à</strong> {{ $d(ISOToDatetime(version.createdAt.datetime8601), 'long') }}</template><template v-if="version.createdBy === null && version.createdAt !== null"><strong v-if="version.version == 0">Créé le</strong><strong v-else>modifié le</strong> {{ $d(ISOToDatetime(version.createdAt.datetime8601), 'long') }}</template> <file-icon :type="version.type"></file-icon>
<span
><strong>#{{ version.version + 1 }}</strong></span
>
<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
></span>
<strong>à</strong>
{{
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
}}</template
><template
v-if="version.createdBy === null && version.createdAt !== null"
><strong v-if="version.version == 0">Créé le</strong
><strong v-else>modifié le</strong>
{{
$d(ISOToDatetime(version.createdAt.datetime8601), "long")
}}</template
>
</div> </div>
<div class="col-12"> <div class="col-12">
<ul class="record_actions small slim on-version-actions"> <ul class="record_actions small slim on-version-actions">
<li v-if="canEdit && !isCurrent"> <li v-if="canEdit && !isCurrent">
<restore-version-button :stored-object-version="props.version" @restore-version="onRestore"></restore-version-button> <restore-version-button
:stored-object-version="props.version"
@restore-version="onRestore"
></restore-version-button>
</li> </li>
<li> <li>
<download-button :stored-object="storedObject" :at-version="version" :classes="{btn: true, 'btn-outline-primary': true, 'btn-sm': true}" :display-action-string-in-button="false"></download-button> <download-button
:stored-object="storedObject"
:at-version="version"
:classes="{
btn: true,
'btn-outline-primary': true,
'btn-sm': true,
}"
:display-action-string-in-button="false"
></download-button>
</li> </li>
</ul> </ul>
</div> </div>

View File

@ -2,7 +2,10 @@
import Modal from "ChillMainAssets/vuejs/_components/Modal.vue"; import Modal from "ChillMainAssets/vuejs/_components/Modal.vue";
import { reactive } from "vue"; import { reactive } from "vue";
import HistoryButtonList from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue"; import HistoryButtonList from "ChillDocStoreAssets/vuejs/StoredObjectButton/HistoryButton/HistoryButtonList.vue";
import {StoredObject, StoredObjectVersionWithPointInTime} from "./../../../types"; import {
StoredObject,
StoredObjectVersionWithPointInTime,
} from "./../../../types";
interface HistoryButtonListConfig { interface HistoryButtonListConfig {
versions: StoredObjectVersionWithPointInTime[]; versions: StoredObjectVersionWithPointInTime[];
@ -11,8 +14,8 @@ interface HistoryButtonListConfig {
} }
const emit = defineEmits<{ const emit = defineEmits<{
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime] restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
}>() }>();
interface HistoryButtonModalState { interface HistoryButtonModalState {
opened: boolean; opened: boolean;
@ -23,10 +26,9 @@ const state = reactive<HistoryButtonModalState>({opened: false});
const open = () => { const open = () => {
state.opened = true; state.opened = true;
} };
defineExpose({ open }); defineExpose({ open });
</script> </script>
<template> <template>
<Teleport to="body"> <Teleport to="body">
@ -36,12 +38,17 @@ defineExpose({open});
</template> </template>
<template v-slot:body> <template v-slot:body>
<p>Les versions sont conservées pendant 90 jours.</p> <p>Les versions sont conservées pendant 90 jours.</p>
<history-button-list :versions="props.versions" :can-edit="canEdit" :stored-object="storedObject" @restore-version="(payload) => emit('restoreVersion', payload)"></history-button-list> <history-button-list
:versions="props.versions"
:can-edit="canEdit"
:stored-object="storedObject"
@restore-version="
(payload) => emit('restoreVersion', payload)
"
></history-button-list>
</template> </template>
</modal> </modal>
</Teleport> </Teleport>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,17 +1,20 @@
<script setup lang="ts"> <script setup lang="ts">
import {StoredObjectVersionPersisted, StoredObjectVersionWithPointInTime} from "../../../types"; import {
StoredObjectVersionPersisted,
StoredObjectVersionWithPointInTime,
} from "../../../types";
import { useToast } from "vue-toast-notification"; import { useToast } from "vue-toast-notification";
import { restore_version } from "./api"; import { restore_version } from "./api";
interface RestoreVersionButtonProps { interface RestoreVersionButtonProps {
storedObjectVersion: StoredObjectVersionPersisted, storedObjectVersion: StoredObjectVersionPersisted;
} }
const emit = defineEmits<{ const emit = defineEmits<{
restoreVersion: [newVersion: StoredObjectVersionWithPointInTime] restoreVersion: [newVersion: StoredObjectVersionWithPointInTime];
}>() }>();
const props = defineProps<RestoreVersionButtonProps>() const props = defineProps<RestoreVersionButtonProps>();
const $toast = useToast(); const $toast = useToast();
@ -19,14 +22,18 @@ const restore_version_fn = async () => {
const newVersion = await restore_version(props.storedObjectVersion); const newVersion = await restore_version(props.storedObjectVersion);
$toast.success("Version restaurée"); $toast.success("Version restaurée");
emit('restoreVersion', {newVersion}); emit("restoreVersion", { newVersion });
} };
</script> </script>
<template> <template>
<button class="btn btn-outline-action" @click="restore_version_fn" title="Restaurer"><i class="fa fa-rotate-left"></i> Restaurer</button> <button
class="btn btn-outline-action"
@click="restore_version_fn"
title="Restaurer"
>
<i class="fa fa-rotate-left"></i> Restaurer
</button>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,5 +1,11 @@
<template> <template>
<a :class="Object.assign(props.classes, {'btn': true})" @click="beforeLeave($event)" :href="build_wopi_editor_link(props.storedObject.uuid, props.returnPath)"> <a
:class="Object.assign(props.classes, { btn: true })"
@click="beforeLeave($event)"
:href="
build_wopi_editor_link(props.storedObject.uuid, props.returnPath)
"
>
<i class="fa fa-paragraph"></i> <i class="fa fa-paragraph"></i>
Editer en ligne Editer en ligne
</a> </a>
@ -8,13 +14,16 @@
<script lang="ts" setup> <script lang="ts" setup>
import WopiEditButton from "./WopiEditButton.vue"; import WopiEditButton from "./WopiEditButton.vue";
import { build_wopi_editor_link } from "./helpers"; import { build_wopi_editor_link } from "./helpers";
import {StoredObject, WopiEditButtonExecutableBeforeLeaveFunction} from "../../types"; import {
StoredObject,
WopiEditButtonExecutableBeforeLeaveFunction,
} from "../../types";
interface WopiEditButtonConfig { interface WopiEditButtonConfig {
storedObject: StoredObject, storedObject: StoredObject;
returnPath?: string, returnPath?: string;
classes: {[k: string] : boolean}, classes: Record<string, boolean>;
executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction, executeBeforeLeave?: WopiEditButtonExecutableBeforeLeaveFunction;
} }
const props = defineProps<WopiEditButtonConfig>(); const props = defineProps<WopiEditButtonConfig>();
@ -43,4 +52,3 @@ i.fa::before {
color: var(--bs-dropdown-link-hover-color); color: var(--bs-dropdown-link-hover-color);
} }
</style> </style>

View File

@ -1,7 +1,7 @@
import { createApp } from 'vue'; import { createApp } from "vue";
import PickEntity from 'ChillMainAssets/vuejs/PickEntity/PickEntity.vue'; import PickEntity from "ChillMainAssets/vuejs/PickEntity/PickEntity.vue";
import { _createI18n } from 'ChillMainAssets/vuejs/_js/i18n'; import { _createI18n } from "ChillMainAssets/vuejs/_js/i18n";
import { appMessages } from 'ChillMainAssets/vuejs/PickEntity/i18n'; import { appMessages } from "ChillMainAssets/vuejs/PickEntity/i18n";
const i18n = _createI18n(appMessages); const i18n = _createI18n(appMessages);
@ -9,34 +9,35 @@ let appsOnPage = new Map();
let appsPerInput = new Map(); let appsPerInput = new Map();
function loadDynamicPicker(element) { function loadDynamicPicker(element) {
let apps = element.querySelectorAll('[data-module="pick-dynamic"]'); let apps = element.querySelectorAll('[data-module="pick-dynamic"]');
apps.forEach(function (el) { apps.forEach(function (el) {
const isMultiple = parseInt(el.dataset.multiple) === 1,
const
isMultiple = parseInt(el.dataset.multiple) === 1,
uniqId = el.dataset.uniqid, uniqId = el.dataset.uniqid,
input = element.querySelector('[data-input-uniqid="'+ el.dataset.uniqid +'"]'), input = element.querySelector(
'[data-input-uniqid="' + el.dataset.uniqid + '"]',
),
// the "picked" will always be an array, even if multiple is false // the "picked" will always be an array, even if multiple is false
picked = isMultiple ? picked = isMultiple
JSON.parse(input.value) : ( ? JSON.parse(input.value)
(input.value === '[]' || input.value === '') ? : input.value === "[]" || input.value === ""
null : [ JSON.parse(input.value) ] ? null
) : [JSON.parse(input.value)];
suggested = JSON.parse(el.dataset.suggested), (suggested = JSON.parse(el.dataset.suggested)),
as_id = parseInt(el.dataset.asId) === 1, (as_id = parseInt(el.dataset.asId) === 1),
submit_on_adding_new_entity = parseInt(el.dataset.submitOnAddingNewEntity) === 1 (submit_on_adding_new_entity =
parseInt(el.dataset.submitOnAddingNewEntity) === 1);
label = el.dataset.label; label = el.dataset.label;
if (!isMultiple) { if (!isMultiple) {
if (input.value === '[]'){ if (input.value === "[]") {
input.value = null; input.value = null;
} }
} }
const app = createApp({ const app = createApp({
template: '<pick-entity ' + template:
"<pick-entity " +
':multiple="multiple" ' + ':multiple="multiple" ' +
':types="types" ' + ':types="types" ' +
':picked="picked" ' + ':picked="picked" ' +
@ -46,7 +47,7 @@ function loadDynamicPicker(element) {
'@addNewEntity="addNewEntity" ' + '@addNewEntity="addNewEntity" ' +
'@removeEntity="removeEntity" ' + '@removeEntity="removeEntity" ' +
'@addNewEntityProcessEnded="addNewEntityProcessEnded"' + '@addNewEntityProcessEnded="addNewEntityProcessEnded"' +
'></pick-entity>', "></pick-entity>",
components: { components: {
PickEntity, PickEntity,
}, },
@ -60,7 +61,7 @@ function loadDynamicPicker(element) {
as_id, as_id,
submit_on_adding_new_entity, submit_on_adding_new_entity,
label, label,
} };
}, },
computed: { computed: {
notPickedSuggested() { notPickedSuggested() {
@ -68,34 +69,40 @@ function loadDynamicPicker(element) {
for (const p of this.picked) { for (const p of this.picked) {
pickedIds.add(`${p.type}${p.id}`); pickedIds.add(`${p.type}${p.id}`);
} }
return this.suggested.filter(e => !pickedIds.has(`${e.type}${e.id}`)) return this.suggested.filter(
} (e) => !pickedIds.has(`${e.type}${e.id}`),
);
},
}, },
methods: { methods: {
addNewEntity({ entity }) { addNewEntity({ entity }) {
if (this.multiple) { if (this.multiple) {
if (!this.picked.some(el => { if (
!this.picked.some((el) => {
return el.type === entity.type && el.id === entity.id; return el.type === entity.type && el.id === entity.id;
})) { })
) {
this.picked.push(entity); this.picked.push(entity);
if (!as_id) { if (!as_id) {
input.value = JSON.stringify(this.picked); input.value = JSON.stringify(this.picked);
} else { } else {
const ids = this.picked.map(el => el.id); const ids = this.picked.map((el) => el.id);
input.value = ids.join(','); input.value = ids.join(",");
} }
console.log(entity) console.log(entity);
} }
} else { } else {
if (!this.picked.some(el => { if (
!this.picked.some((el) => {
return el.type === entity.type && el.id === entity.id; return el.type === entity.type && el.id === entity.id;
})) { })
) {
this.picked.splice(0, this.picked.length); this.picked.splice(0, this.picked.length);
this.picked.push(entity); this.picked.push(entity);
if (!as_id) { if (!as_id) {
input.value = JSON.stringify(this.picked[0]); input.value = JSON.stringify(this.picked[0]);
} else { } else {
input.value = this.picked.map(el => el.id); input.value = this.picked.map((el) => el.id);
} }
} }
} }
@ -106,17 +113,24 @@ function loadDynamicPicker(element) {
} }
}, },
removeEntity({ entity }) { removeEntity({ entity }) {
if (-1 === this.suggested.findIndex(e => e.type === entity.type && e.id === entity.id)) { if (
-1 ===
this.suggested.findIndex(
(e) => e.type === entity.type && e.id === entity.id,
)
) {
this.suggested.push(entity); this.suggested.push(entity);
} }
this.picked = this.picked.filter(e => !(e.type === entity.type && e.id === entity.id)); this.picked = this.picked.filter(
(e) => !(e.type === entity.type && e.id === entity.id),
);
if (this.multiple) { if (this.multiple) {
input.value = JSON.stringify(this.picked); input.value = JSON.stringify(this.picked);
} else { } else {
input.value = ""; input.value = "";
} }
}, },
} },
}) })
.use(i18n) .use(i18n)
.mount(el); .mount(el);
@ -126,41 +140,41 @@ function loadDynamicPicker(element) {
}); });
} }
document.addEventListener("show-hide-show", function (e) {
document.addEventListener('show-hide-show', function(e) { loadDynamicPicker(e.detail.container);
loadDynamicPicker(e.detail.container)
}); });
document.addEventListener('show-hide-hide', function(e) { document.addEventListener("show-hide-hide", function (e) {
console.log('hiding event caught') console.log("hiding event caught");
e.detail.container.querySelectorAll('[data-module="pick-dynamic"]').forEach((el) => { e.detail.container
.querySelectorAll('[data-module="pick-dynamic"]')
.forEach((el) => {
let uniqId = el.dataset.uniqid; let uniqId = el.dataset.uniqid;
if (appsOnPage.has(uniqId)) { if (appsOnPage.has(uniqId)) {
appsOnPage.get(uniqId).unmount(); appsOnPage.get(uniqId).unmount();
appsOnPage.delete(uniqId); appsOnPage.delete(uniqId);
} }
}) });
}); });
document.addEventListener('pick-entity-type-action', function (e) { document.addEventListener("pick-entity-type-action", function (e) {
console.log('pick entity event', e); console.log("pick entity event", e);
if (!appsPerInput.has(e.detail.name)) { if (!appsPerInput.has(e.detail.name)) {
console.error('no app with this name'); console.error("no app with this name");
return; return;
} }
const app = appsPerInput.get(e.detail.name); const app = appsPerInput.get(e.detail.name);
if (e.detail.action === 'add') { if (e.detail.action === "add") {
app.addNewEntity(e.detail.entity); app.addNewEntity(e.detail.entity);
} else if (e.detail.action === 'remove') { } else if (e.detail.action === "remove") {
app.removeEntity(e.detail.entity); app.removeEntity(e.detail.entity);
} else { } else {
console.error('action not supported: '+e.detail.action); console.error("action not supported: " + e.detail.action);
} }
}); });
document.addEventListener('DOMContentLoaded', function(e) { document.addEventListener("DOMContentLoaded", function (e) {
loadDynamicPicker(document) loadDynamicPicker(document);
}) });
window.loadDynamicPicker = loadDynamicPicker; window.loadDynamicPicker = loadDynamicPicker;

View File

@ -1,20 +1,21 @@
import {ShowHide} from 'ChillMainAssets/lib/show_hide/show_hide.js'; import { ShowHide } from "ChillMainAssets/lib/show_hide/show_hide.js";
window.addEventListener('DOMContentLoaded', function() {
const
divTransitions = document.querySelector('#transitions'),
futureDestUsersContainer = document.querySelector('#futureDests'),
personSignatureField = document.querySelector('#person-signature-field'),
userSignatureField = document.querySelector('#user-signature-field'),
signatureTypeChoices = document.querySelector('#signature-type-choice'),
personChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_0'),
userChoice = document.querySelector('#workflow_step_isPersonOrUserSignature_1'),
signatureZone = document.querySelector('#signature-zone'),
transitionFilterContainer = document.querySelector('#transitionFilter'),
transitionsContainer = document.querySelector('#transitions'),
sendExternalContainer = document.querySelector('#sendExternalContainer')
;
window.addEventListener("DOMContentLoaded", function () {
const divTransitions = document.querySelector("#transitions"),
futureDestUsersContainer = document.querySelector("#futureDests"),
personSignatureField = document.querySelector("#person-signature-field"),
userSignatureField = document.querySelector("#user-signature-field"),
signatureTypeChoices = document.querySelector("#signature-type-choice"),
personChoice = document.querySelector(
"#workflow_step_isPersonOrUserSignature_0",
),
userChoice = document.querySelector(
"#workflow_step_isPersonOrUserSignature_1",
),
signatureZone = document.querySelector("#signature-zone"),
transitionFilterContainer = document.querySelector("#transitionFilter"),
transitionsContainer = document.querySelector("#transitions"),
sendExternalContainer = document.querySelector("#sendExternalContainer");
// ShowHide instance for future dest users // ShowHide instance for future dest users
new ShowHide({ new ShowHide({
debug: false, debug: false,
@ -23,22 +24,24 @@ window.addEventListener('DOMContentLoaded', function() {
container: [futureDestUsersContainer], container: [futureDestUsersContainer],
test: function (froms, event) { test: function (froms, event) {
for (let transition of froms) { for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) { for (let input of transition.querySelectorAll("input")) {
if (input.checked) { if (input.checked) {
if ('1' === input.dataset.toFinal) { if ("1" === input.dataset.toFinal) {
return false; return false;
} }
if ('1' === input.dataset.isSentExternal) { if ("1" === input.dataset.isSentExternal) {
return false; return false;
} }
const inputData = JSON.parse(input.getAttribute('data-is-signature')) const inputData = JSON.parse(
if (inputData.includes('person') || inputData.includes('user')) { input.getAttribute("data-is-signature"),
);
if (inputData.includes("person") || inputData.includes("user")) {
return false; return false;
} else { } else {
personChoice.checked = false personChoice.checked = false;
userChoice.checked = false userChoice.checked = false;
return true; return true;
} }
@ -46,7 +49,7 @@ window.addEventListener('DOMContentLoaded', function() {
} }
} }
return false; return false;
} },
}); });
// ShowHide instance for send external // ShowHide instance for send external
@ -57,17 +60,17 @@ window.addEventListener('DOMContentLoaded', function() {
container: [sendExternalContainer], container: [sendExternalContainer],
test: function (froms, event) { test: function (froms, event) {
for (let transition of froms) { for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) { for (let input of transition.querySelectorAll("input")) {
if (input.checked) { if (input.checked) {
if ('1' === input.dataset.isSentExternal) { if ("1" === input.dataset.isSentExternal) {
return true; return true;
} }
} }
} }
} }
return false; return false;
} },
}) });
// ShowHide signature zone // ShowHide signature zone
new ShowHide({ new ShowHide({
@ -77,17 +80,19 @@ window.addEventListener('DOMContentLoaded', function() {
container: [signatureZone], container: [signatureZone],
test: function (froms, event) { test: function (froms, event) {
for (let transition of froms) { for (let transition of froms) {
for (let input of transition.querySelectorAll('input')) { for (let input of transition.querySelectorAll("input")) {
if (input.checked) { if (input.checked) {
const inputData = JSON.parse(input.getAttribute('data-is-signature')) const inputData = JSON.parse(
if (inputData.includes('person') || inputData.includes('user')) { input.getAttribute("data-is-signature"),
);
if (inputData.includes("person") || inputData.includes("user")) {
return true; return true;
} }
} }
} }
} }
return false; return false;
} },
}); });
// ShowHides for personSignatureField or userSignatureField within signature zone // ShowHides for personSignatureField or userSignatureField within signature zone
@ -122,7 +127,7 @@ window.addEventListener('DOMContentLoaded', function() {
container: [futureDestUsersContainer], container: [futureDestUsersContainer],
test: function (divs, arg2, arg3) { test: function (divs, arg2, arg3) {
for (let div of divs) { for (let div of divs) {
for (let input of div.querySelectorAll('input')) { for (let input of div.querySelectorAll("input")) {
if (input.checked) { if (input.checked) {
if (input.dataset.toFinal === "1") { if (input.dataset.toFinal === "1") {
return false; return false;
@ -139,9 +144,10 @@ window.addEventListener('DOMContentLoaded', function() {
} }
if (null !== transitionFilterContainer) { if (null !== transitionFilterContainer) {
transitionsContainer.querySelectorAll('.form-check').forEach(function(row) { transitionsContainer
.querySelectorAll(".form-check")
const isForward = row.querySelector('input').dataset.isForward; .forEach(function (row) {
const isForward = row.querySelector("input").dataset.isForward;
new ShowHide({ new ShowHide({
load_event: null, load_event: null,
@ -149,7 +155,7 @@ window.addEventListener('DOMContentLoaded', function() {
container: row, container: row,
test: function (containers) { test: function (containers) {
for (let container of containers) { for (let container of containers) {
for (let input of container.querySelectorAll('input')) { for (let input of container.querySelectorAll("input")) {
if (input.checked) { if (input.checked) {
return isForward === input.value; return isForward === input.value;
} }
@ -159,8 +165,8 @@ window.addEventListener('DOMContentLoaded', function() {
}, },
toggle_callback: function (c, dir) { toggle_callback: function (c, dir) {
for (let div of c) { for (let div of c) {
let input = div.querySelector('input'); let input = div.querySelector("input");
if ('hide' === dir) { if ("hide" === dir) {
input.checked = false; input.checked = false;
input.disabled = true; input.disabled = true;
} else { } else {

View File

@ -28,7 +28,11 @@
/> />
<span class="mx-2">{{ getStep(w) }}</span> <span class="mx-2">{{ getStep(w) }}</span>
</div> </div>
<span v-if="w.isOnHoldAtCurrentStep" class="badge bg-success rounded-pill">{{ $t('on_hold') }}</span> <span
v-if="w.isOnHoldAtCurrentStep"
class="badge bg-success rounded-pill"
>{{ $t("on_hold") }}</span
>
</div> </div>
</td> </td>
<td v-if="w.datas.persons !== null"> <td v-if="w.datas.persons !== null">

View File

@ -3,20 +3,25 @@ const appMessages = {
main_title: "Vue d'ensemble", main_title: "Vue d'ensemble",
my_works: { my_works: {
tab: "Mes actions", tab: "Mes actions",
description: "Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance.", description:
"Liste des actions d'accompagnement dont je suis référent et qui arrivent à échéance.",
}, },
my_evaluations: { my_evaluations: {
tab: "Mes évaluations", tab: "Mes évaluations",
description: "Liste des évaluations dont je suis référent et qui arrivent à échéance.", description:
"Liste des évaluations dont je suis référent et qui arrivent à échéance.",
}, },
my_tasks: { my_tasks: {
tab: "Mes tâches", tab: "Mes tâches",
description_alert: "Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée.", description_alert:
description_warning: "Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée.", "Liste des tâches auxquelles je suis assigné et dont la date de rappel est dépassée.",
description_warning:
"Liste des tâches auxquelles je suis assigné et dont la date d'échéance est dépassée.",
}, },
my_accompanying_courses: { my_accompanying_courses: {
tab: "Mes nouveaux parcours", tab: "Mes nouveaux parcours",
description: "Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours.", description:
"Liste des parcours d'accompagnement que l'on vient de m'attribuer depuis moins de 15 jours.",
}, },
my_notifications: { my_notifications: {
tab: "Mes nouvelles notifications", tab: "Mes nouvelles notifications",
@ -25,7 +30,7 @@ const appMessages = {
my_workflows: { my_workflows: {
tab: "Mes workflows", tab: "Mes workflows",
description: "Liste des workflows en attente d'une action.", description: "Liste des workflows en attente d'une action.",
description_cc: "Liste des workflows dont je suis en copie." description_cc: "Liste des workflows dont je suis en copie.",
}, },
opening_date: "Date d'ouverture", opening_date: "Date d'ouverture",
social_issues: "Problématiques sociales", social_issues: "Problématiques sociales",
@ -55,10 +60,13 @@ const appMessages = {
no_data: "Aucun résultats", no_data: "Aucun résultats",
no_dashboard: "Pas de tableaux de bord", no_dashboard: "Pas de tableaux de bord",
counter: { counter: {
unread_notifications: "{n} notification non lue | {n} notifications non lues", unread_notifications:
assignated_courses: "{n} parcours récent assigné | {n} parcours récents assignés", "{n} notification non lue | {n} notifications non lues",
assignated_courses:
"{n} parcours récent assigné | {n} parcours récents assignés",
assignated_actions: "{n} action assignée | {n} actions assignées", assignated_actions: "{n} action assignée | {n} actions assignées",
assignated_evaluations: "{n} évaluation assignée | {n} évaluations assignées", assignated_evaluations:
"{n} évaluation assignée | {n} évaluations assignées",
alert_tasks: "{n} tâche en rappel | {n} tâches en rappel", alert_tasks: "{n} tâche en rappel | {n} tâches en rappel",
warning_tasks: "{n} tâche à échéance | {n} tâches à échéance", warning_tasks: "{n} tâche à échéance | {n} tâches à échéance",
}, },
@ -70,14 +78,12 @@ const appMessages = {
title: "Actualités", title: "Actualités",
readMore: "Lire la suite", readMore: "Lire la suite",
date: "Date", date: "Date",
none: "Aucune actualité" none: "Aucune actualité",
} },
} },
} },
}; };
Object.assign(appMessages.fr); Object.assign(appMessages.fr);
export { export { appMessages };
appMessages
};

View File

@ -18,7 +18,9 @@
</li> </li>
</ul> </ul>
<ul class="list-suggest add-items inline"> <ul class="list-suggest add-items inline">
<li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)"><span>{{ s.text }}</span></li> <li v-for="s in suggested" :key="s.id" @click="addNewSuggested(s)">
<span>{{ s.text }}</span>
</li>
</ul> </ul>
</template> </template>
@ -55,20 +57,20 @@ export default {
}, },
suggested: { suggested: {
type: Array, type: Array,
default: [] default: [],
}, },
label: { label: {
type: String, type: String,
required: false, required: false,
}
}, },
emits: ['addNewEntity', 'removeEntity', 'addNewEntityProcessEnded'], },
emits: ["addNewEntity", "removeEntity", "addNewEntityProcessEnded"],
components: { components: {
AddPersons, AddPersons,
}, },
data() { data() {
return { return {
key: '' key: "",
}; };
}, },
computed: { computed: {
@ -78,57 +80,63 @@ export default {
type: this.types, type: this.types,
priority: null, priority: null,
button: { button: {
size: 'btn-sm', size: "btn-sm",
class: 'btn-submit', class: "btn-submit",
}, },
}; };
}, },
translatedListOfTypes() { translatedListOfTypes() {
if (this.label !== '') { if (this.label !== "") {
return this.label; return this.label;
} }
let trans = []; let trans = [];
this.types.forEach(t => { this.types.forEach((t) => {
if (this.$props.multiple) { if (this.$props.multiple) {
trans.push(appMessages.fr.pick_entity[t].toLowerCase()); trans.push(appMessages.fr.pick_entity[t].toLowerCase());
} else { } else {
trans.push(appMessages.fr.pick_entity[t + '_one'].toLowerCase()); trans.push(
appMessages.fr.pick_entity[t + "_one"].toLowerCase(),
);
} }
}) });
if (this.$props.multiple) { if (this.$props.multiple) {
return appMessages.fr.pick_entity.modal_title + trans.join(', '); return (
appMessages.fr.pick_entity.modal_title + trans.join(", ")
);
} else { } else {
return appMessages.fr.pick_entity.modal_title_one + trans.join(', '); return (
appMessages.fr.pick_entity.modal_title_one +
trans.join(", ")
);
} }
}, },
listClasses() { listClasses() {
return { return {
'list-suggest': true, "list-suggest": true,
'remove-items': this.$props.removableIfSet, "remove-items": this.$props.removableIfSet,
}; };
}, },
}, },
methods: { methods: {
addNewSuggested(entity) { addNewSuggested(entity) {
this.$emit('addNewEntity', {entity: entity}); this.$emit("addNewEntity", { entity: entity });
}, },
addNewEntity({ selected, modal }) { addNewEntity({ selected, modal }) {
selected.forEach((item) => { selected.forEach((item) => {
this.$emit('addNewEntity', { entity: item.result}); this.$emit("addNewEntity", { entity: item.result });
}, this }, this);
);
this.$refs.addPersons.resetSearch(); // to cast child method this.$refs.addPersons.resetSearch(); // to cast child method
modal.showModal = false; modal.showModal = false;
this.$emit('addNewEntityProcessEnded'); this.$emit("addNewEntityProcessEnded");
}, },
removeEntity(entity) { removeEntity(entity) {
if (!this.$props.removableIfSet) { if (!this.$props.removableIfSet) {
return; return;
} }
this.$emit('removeEntity',{ entity: entity }); this.$emit("removeEntity", { entity: entity });
}
}, },
} },
};
</script> </script>

View File

@ -8,19 +8,18 @@ interface UserGroupRenderBoxProps {
const props = defineProps<UserGroupRenderBoxProps>(); const props = defineProps<UserGroupRenderBoxProps>();
const styles = computed<{color: string, "background-color": string}>(() => { const styles = computed<{ color: string; "background-color": string }>(() => {
return { return {
color: props.userGroup.foregroundColor, color: props.userGroup.foregroundColor,
"background-color": props.userGroup.backgroundColor, "background-color": props.userGroup.backgroundColor,
} };
}); });
</script> </script>
<template> <template>
<span class="badge-user-group" :style="styles">{{ userGroup.label.fr }}</span> <span class="badge-user-group" :style="styles">{{
userGroup.label.fr
}}</span>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,8 +1,10 @@
<template> <template>
<div class="flex-table workflow" id="workflow-list"> <div class="flex-table workflow" id="workflow-list">
<div v-for="(w, i) in workflows" :key="`workflow-${i}`" <div
class="item-bloc"> v-for="(w, i) in workflows"
:key="`workflow-${i}`"
class="item-bloc"
>
<div> <div>
<div class="item-row col"> <div class="item-row col">
<h2>{{ w.title }}</h2> <h2>{{ w.title }}</h2>
@ -16,20 +18,25 @@
<div class="breadcrumb"> <div class="breadcrumb">
<template v-for="(step, j) in w.steps" :key="`step-${j}`"> <template v-for="(step, j) in w.steps" :key="`step-${j}`">
<span class="mx-2" <span
class="mx-2"
tabindex="0" tabindex="0"
data-bs-trigger="focus hover" data-bs-trigger="focus hover"
data-bs-toggle="popover" data-bs-toggle="popover"
data-bs-placement="bottom" data-bs-placement="bottom"
data-bs-custom-class="workflow-transition" data-bs-custom-class="workflow-transition"
:title="getPopTitle(step)" :title="getPopTitle(step)"
:data-bs-content="getPopContent(step)"> :data-bs-content="getPopContent(step)"
>
<i v-if="step.currentStep.name === 'initial'" <i
class="fa fa-circle me-1 text-chill-yellow"> v-if="step.currentStep.name === 'initial'"
class="fa fa-circle me-1 text-chill-yellow"
>
</i> </i>
<i v-if="step.isFreezed" <i
class="fa fa-snowflake-o fa-sm me-1"> v-if="step.isFreezed"
class="fa fa-snowflake-o fa-sm me-1"
>
</i> </i>
{{ step.currentStep.text }} {{ step.currentStep.text }}
</span> </span>
@ -38,47 +45,56 @@
</span> </span>
</template> </template>
</div> </div>
<span v-if="w.isOnHoldAtCurrentStep" class="badge bg-success rounded-pill">{{ $t('on_hold') }}</span> <span
v-if="w.isOnHoldAtCurrentStep"
class="badge bg-success rounded-pill"
>{{ $t("on_hold") }}</span
>
</div> </div>
<div class="item-row"> <div class="item-row">
<div class="item-col flex-grow-1"> <div class="item-col flex-grow-1">
<p v-if="isUserSubscribedToStep(w)"> <p v-if="isUserSubscribedToStep(w)">
<i class="fa fa-check fa-fw"></i> <i class="fa fa-check fa-fw"></i>
{{ $t('you_subscribed_to_all_steps') }} {{ $t("you_subscribed_to_all_steps") }}
</p> </p>
<p v-if="isUserSubscribedToFinal(w)"> <p v-if="isUserSubscribedToFinal(w)">
<i class="fa fa-check fa-fw"></i> <i class="fa fa-check fa-fw"></i>
{{ $t('you_subscribed_to_final_step') }} {{ $t("you_subscribed_to_final_step") }}
</p> </p>
</div> </div>
<div class="item-col"> <div class="item-col">
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<a :href="goToUrl(w)" class="btn btn-sm btn-show" :title="$t('action.show')"></a> <a
:href="goToUrl(w)"
class="btn btn-sm btn-show"
:title="$t('action.show')"
></a>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import Popover from 'bootstrap/js/src/popover'; import Popover from "bootstrap/js/src/popover";
const i18n = { const i18n = {
messages: { messages: {
fr: { fr: {
you_subscribed_to_all_steps: "Vous recevrez une notification à chaque étape", you_subscribed_to_all_steps:
you_subscribed_to_final_step: "Vous recevrez une notification à l'étape finale", "Vous recevrez une notification à chaque étape",
you_subscribed_to_final_step:
"Vous recevrez une notification à l'étape finale",
by: "Par", by: "Par",
at: "Le", at: "Le",
on_hold: "En attente" on_hold: "En attente",
} },
} },
} };
export default { export default {
name: "ListWorkflow", name: "ListWorkflow",
@ -87,7 +103,7 @@ export default {
workflows: { workflows: {
type: Array, type: Array,
required: true, required: true,
} },
}, },
methods: { methods: {
goToUrl(w) { goToUrl(w) {
@ -96,7 +112,9 @@ export default {
getPopTitle(step) { getPopTitle(step) {
if (step.transitionPrevious != null) { if (step.transitionPrevious != null) {
//console.log(step.transitionPrevious.text); //console.log(step.transitionPrevious.text);
let freezed = step.isFreezed ? `<i class="fa fa-snowflake-o fa-sm me-1"></i>` : ``; let freezed = step.isFreezed
? `<i class="fa fa-snowflake-o fa-sm me-1"></i>`
: ``;
return `${freezed}${step.transitionPrevious.text}`; return `${freezed}${step.transitionPrevious.text}`;
} }
}, },
@ -106,17 +124,20 @@ export default {
return `<ul class="small_in_title"> return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li> <li><span class="item-key">${i18n.messages.fr.by} : </span><b>${step.transitionPreviousBy.text}</b></li>
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li> <li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>` </ul>`;
;
} else { } else {
return `<ul class="small_in_title"> return `<ul class="small_in_title">
<li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li> <li><span class="item-key">${i18n.messages.fr.at} : </span><b>${this.formatDate(step.transitionPreviousAt.datetime)}</b></li>
</ul>` </ul>`;
} }
} }
}, },
formatDate(datetime) { formatDate(datetime) {
return datetime.split('T')[0] +' '+ datetime.split('T')[1].substring(0,5) return (
datetime.split("T")[0] +
" " +
datetime.split("T")[1].substring(0, 5)
);
}, },
isUserSubscribedToStep(w) { isUserSubscribedToStep(w) {
// todo // todo
@ -128,13 +149,15 @@ export default {
}, },
}, },
mounted() { mounted() {
const triggerList = [].slice.call(document.querySelectorAll('[data-bs-toggle="popover"]')); const triggerList = [].slice.call(
document.querySelectorAll('[data-bs-toggle="popover"]'),
);
const popoverList = triggerList.map(function (el) { const popoverList = triggerList.map(function (el) {
//console.log('popover', el) //console.log('popover', el)
return new Popover(el, { return new Popover(el, {
html: true, html: true,
}); });
}); });
} },
} };
</script> </script>

View File

@ -11,50 +11,53 @@
></pick-workflow> ></pick-workflow>
<teleport to="body"> <teleport to="body">
<modal v-if="modal.showModal" <modal
v-if="modal.showModal"
:modalDialogClass="modal.modalDialogClass" :modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false"> @close="modal.showModal = false"
>
<template v-slot:header> <template v-slot:header>
<h2 class="modal-title">{{ $t('workflow_list') }}</h2> <h2 class="modal-title">{{ $t("workflow_list") }}</h2>
</template> </template>
<template v-slot:body> <template v-slot:body>
<list-workflow-vue <list-workflow-vue :workflows="workflows"></list-workflow-vue>
:workflows="workflows"
></list-workflow-vue>
</template> </template>
<template v-slot:footer> <template v-slot:footer>
<pick-workflow v-if="allowCreate" <pick-workflow
v-if="allowCreate"
:relatedEntityClass="this.relatedEntityClass" :relatedEntityClass="this.relatedEntityClass"
:relatedEntityId="this.relatedEntityId" :relatedEntityId="this.relatedEntityId"
:workflowsAvailables="workflowsAvailables" :workflowsAvailables="workflowsAvailables"
:preventDefaultMoveToGenerate="this.$props.preventDefaultMoveToGenerate" :preventDefaultMoveToGenerate="
:goToGenerateWorkflowPayload="this.goToGenerateWorkflowPayload" this.$props.preventDefaultMoveToGenerate
"
:goToGenerateWorkflowPayload="
this.goToGenerateWorkflowPayload
"
:countExistingWorkflows="countWorkflows" :countExistingWorkflows="countWorkflows"
:embedded-within-list-modal="true" :embedded-within-list-modal="true"
@go-to-generate-workflow="this.goToGenerateWorkflow" @go-to-generate-workflow="this.goToGenerateWorkflow"
></pick-workflow> ></pick-workflow>
</template> </template>
</modal> </modal>
</teleport> </teleport>
</template> </template>
<script> <script>
import Modal from 'ChillMainAssets/vuejs/_components/Modal'; import Modal from "ChillMainAssets/vuejs/_components/Modal";
import PickWorkflow from 'ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue'; import PickWorkflow from "ChillMainAssets/vuejs/_components/EntityWorkflow/PickWorkflow.vue";
import ListWorkflowVue from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflow.vue'; import ListWorkflowVue from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflow.vue";
export default { export default {
name: "ListWorkflowModal", name: "ListWorkflowModal",
components: { components: {
Modal, Modal,
PickWorkflow, PickWorkflow,
ListWorkflowVue ListWorkflowVue,
}, },
emits: ['goToGenerateWorkflow'], emits: ["goToGenerateWorkflow"],
props: { props: {
workflows: { workflows: {
type: Array, type: Array,
@ -83,16 +86,16 @@ export default {
}, },
goToGenerateWorkflowPayload: { goToGenerateWorkflowPayload: {
required: false, required: false,
default: {} default: {},
}, },
}, },
data() { data() {
return { return {
modal: { modal: {
showModal: false, showModal: false,
modalDialogClass: "modal-dialog-scrollable modal-xl" modalDialogClass: "modal-dialog-scrollable modal-xl",
}, },
} };
}, },
computed: { computed: {
countWorkflows() { countWorkflows() {
@ -100,16 +103,16 @@ export default {
}, },
hasWorkflow() { hasWorkflow() {
return this.countWorkflows > 0; return this.countWorkflows > 0;
} },
}, },
methods: { methods: {
openModal() { openModal() {
this.modal.showModal = true; this.modal.showModal = true;
}, },
goToGenerateWorkflow(data) { goToGenerateWorkflow(data) {
console.log('go to generate workflow intercepted', data); console.log("go to generate workflow intercepted", data);
this.$emit('goToGenerateWorkflow', data); this.$emit("goToGenerateWorkflow", data);
} },
}, },
i18n: { i18n: {
messages: { messages: {
@ -117,10 +120,10 @@ export default {
workflow_list: "Liste des workflows associés", workflow_list: "Liste des workflows associés",
workflow: " workflow associé", workflow: " workflow associé",
workflows: " workflows associés", workflows: " workflows associés",
} },
} },
} },
} };
</script> </script>
<style scoped></style> <style scoped></style>

View File

@ -1,12 +1,27 @@
<template> <template>
<template v-if="props.workflowsAvailables.length >= 1"> <template v-if="props.workflowsAvailables.length >= 1">
<div v-if="countExistingWorkflows == 0 || embeddedWithinListModal" class="dropdown d-grid gap-2"> <div
<button class="btn btn-primary dropdown-toggle" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false"> v-if="countExistingWorkflows == 0 || embeddedWithinListModal"
class="dropdown d-grid gap-2"
>
<button
class="btn btn-primary dropdown-toggle"
type="button"
id="createWorkflowButton"
data-bs-toggle="dropdown"
aria-expanded="false"
>
Créer un workflow Créer un workflow
</button> </button>
<ul class="dropdown-menu" aria-labelledby="createWorkflowButton"> <ul class="dropdown-menu" aria-labelledby="createWorkflowButton">
<li v-for="w in props.workflowsAvailables" :key="w.name"> <li v-for="w in props.workflowsAvailables" :key="w.name">
<button class="dropdown-item" type="button" @click.prevent="goToGenerateWorkflow($event, w.name)">{{ w.text }}</button> <button
class="dropdown-item"
type="button"
@click.prevent="goToGenerateWorkflow($event, w.name)"
>
{{ w.text }}
</button>
</li> </li>
</ul> </ul>
</div> </div>
@ -20,12 +35,31 @@
{{ countExistingWorkflows }} workflows associés {{ countExistingWorkflows }} workflows associés
</template> </template>
</button> </button>
<button class="btn btn-primary dropdown-toggle dropdown-toggle-split" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false"> <button
<span class="visually-hidden">Liste des workflows disponibles</span> class="btn btn-primary dropdown-toggle dropdown-toggle-split"
type="button"
id="createWorkflowButton"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<span class="visually-hidden"
>Liste des workflows disponibles</span
>
</button> </button>
<ul class="dropdown-menu" aria-labelledby="createWorkflowButton"> <ul
class="dropdown-menu"
aria-labelledby="createWorkflowButton"
>
<li v-for="w in props.workflowsAvailables" :key="w.name"> <li v-for="w in props.workflowsAvailables" :key="w.name">
<button class="dropdown-item" type="button" @click.prevent="goToGenerateWorkflow($event, w.name)">{{ w.text }}</button> <button
class="dropdown-item"
type="button"
@click.prevent="
goToGenerateWorkflow($event, w.name)
"
>
{{ w.text }}
</button>
</li> </li>
</ul> </ul>
</div> </div>
@ -33,7 +67,14 @@
</template> </template>
<template v-else> <template v-else>
<div v-if="countExistingWorkflows > 0" class="dropdown d-grid gap-2"> <div v-if="countExistingWorkflows > 0" class="dropdown d-grid gap-2">
<button @click="emit('clickOpenList')" class="btn btn-primary" type="button" id="createWorkflowButton" data-bs-toggle="dropdown" aria-expanded="false"> <button
@click="emit('clickOpenList')"
class="btn btn-primary"
type="button"
id="createWorkflowButton"
data-bs-toggle="dropdown"
aria-expanded="false"
>
<template v-if="countExistingWorkflows === 1"> <template v-if="countExistingWorkflows === 1">
1 workflow associé 1 workflow associé
</template> </template>
@ -46,8 +87,7 @@
</template> </template>
<script setup lang="ts"> <script setup lang="ts">
import { buildLinkCreate } from "../../../lib/entity-workflow/api";
import {buildLinkCreate} from '../../../lib/entity-workflow/api';
import { WorkflowAvailable } from "../../../types"; import { WorkflowAvailable } from "../../../types";
interface PickWorkflowConfig { interface PickWorkflowConfig {
@ -69,39 +109,68 @@ interface PickWorkflowConfig {
embeddedWithinListModal: boolean; embeddedWithinListModal: boolean;
} }
const props = withDefaults(defineProps<PickWorkflowConfig>(), {preventDefaultMoveToGenerate: false, goToGenerateWorkflowPayload: {}, allowCreateWorkflow: false}); const props = withDefaults(defineProps<PickWorkflowConfig>(), {
preventDefaultMoveToGenerate: false,
goToGenerateWorkflowPayload: {},
allowCreateWorkflow: false,
});
const emit = defineEmits<{ const emit = defineEmits<{
(e: 'goToGenerateWorkflow', {event: MouseEvent, workflowName: string, isLinkValid: boolean, link: string, payload: object}): void; (
(e: 'clickOpenList'): void; e: "goToGenerateWorkflow",
{
event: MouseEvent,
workflowName: string,
isLinkValid: boolean,
link: string,
payload: object,
},
): void;
(e: "clickOpenList"): void;
}>(); }>();
const makeLink = (workflowName: string): string => buildLinkCreate(workflowName, props.relatedEntityClass, props.relatedEntityId); const makeLink = (workflowName: string): string =>
buildLinkCreate(
workflowName,
props.relatedEntityClass,
props.relatedEntityId,
);
const goToGenerateWorkflow = (event: MouseEvent, workflowName: string): void => { const goToGenerateWorkflow = (
console.log('goToGenerateWorkflow', event, workflowName); event: MouseEvent,
let link = ''; workflowName: string,
): void => {
console.log("goToGenerateWorkflow", event, workflowName);
let link = "";
let isLinkValid = false; let isLinkValid = false;
try { try {
link = makeLink(workflowName); link = makeLink(workflowName);
isLinkValid = true; isLinkValid = true;
} catch (e) { } catch (e) {
console.info("could not generate link to create workflow, maybe the relatedEntityId is not yet known", e); console.info(
"could not generate link to create workflow, maybe the relatedEntityId is not yet known",
e,
);
} }
if (!props.preventDefaultMoveToGenerate) { if (!props.preventDefaultMoveToGenerate) {
window.location.assign(link); window.location.assign(link);
} }
emit('goToGenerateWorkflow', {event, workflowName, link, isLinkValid, payload: props.goToGenerateWorkflowPayload}); emit("goToGenerateWorkflow", {
} event,
workflowName,
link,
isLinkValid,
payload: props.goToGenerateWorkflowPayload,
});
};
const goToDuplicateRelatedEntity = (event: MouseEvent, workflowName: string): void => { const goToDuplicateRelatedEntity = (
event: MouseEvent,
} workflowName: string,
): void => {};
</script> </script>
<style scoped> <style scoped></style>
</style>

View File

@ -4,7 +4,9 @@
<div> <div>
<p class="wl-item social-issues"> <p class="wl-item social-issues">
<span class="chill-entity entity-social-issue"> <span class="chill-entity entity-social-issue">
<span class="badge bg-chill-l-gray text-dark">{{ work.socialAction.issue.text }}</span> <span class="badge bg-chill-l-gray text-dark">{{
work.socialAction.issue.text
}}</span>
</span> </span>
</p> </p>
</div> </div>
@ -15,17 +17,23 @@
</div> </div>
<div id="startDate" class="action-row"> <div id="startDate" class="action-row">
<label class="col-form-label">{{ $t('startDate') }}</label> <label class="col-form-label">{{ $t("startDate") }}</label>
<input v-model="startDate" type="date" required="true" class="form-control" v-once/> <input
v-model="startDate"
type="date"
required="true"
class="form-control"
v-once
/>
</div> </div>
<div id="endDate" class="action-row"> <div id="endDate" class="action-row">
<label class="col-form-label">{{ $t('endDate') }}</label> <label class="col-form-label">{{ $t("endDate") }}</label>
<input v-model="endDate" type="date" class="form-control" /> <input v-model="endDate" type="date" class="form-control" />
</div> </div>
<div id="privateComment" class="action-row"> <div id="privateComment" class="action-row">
<label class="col-form-label">{{ $t('private_comment') }}</label> <label class="col-form-label">{{ $t("private_comment") }}</label>
<ckeditor <ckeditor
v-model="privateComment" v-model="privateComment"
:editor="editor" :editor="editor"
@ -34,28 +42,30 @@
</div> </div>
<div id="comment" class="action-row"> <div id="comment" class="action-row">
<label class="col-form-label">{{ $t('comments') }}</label> <label class="col-form-label">{{ $t("comments") }}</label>
<ckeditor <ckeditor v-model="note" :editor="editor" tag-name="textarea"></ckeditor>
v-model="note"
:editor="editor"
tag-name="textarea"
></ckeditor>
</div> </div>
<div id="objectives" class="action-row"> <div id="objectives" class="action-row">
<div aria="hidden" class="title"> <div aria="hidden" class="title">
<div><h3>{{ $t('goals_title') }}</h3></div> <div>
<div><h3>{{ $t('results_title') }}</h3></div> <h3>{{ $t("goals_title") }}</h3>
</div>
<div>
<h3>{{ $t("results_title") }}</h3>
</div>
</div> </div>
<!-- results which are not attached to an objective --> <!-- results which are not attached to an objective -->
<div v-if="hasResultsForAction"> <div v-if="hasResultsForAction">
<div class="results_without_objective"> <div class="results_without_objective">
{{ $t('results_without_objective') }} {{ $t("results_without_objective") }}
</div> </div>
<div> <div>
<add-result :availableResults="resultsForAction" destination="action"></add-result> <add-result
:availableResults="resultsForAction"
destination="action"
></add-result>
</div> </div>
</div> </div>
@ -71,51 +81,65 @@
<div class="accordion" id="expandedSuggestions"> <div class="accordion" id="expandedSuggestions">
<div v-if="availableForCheckGoal.length > 0" class="accordion-item"> <div v-if="availableForCheckGoal.length > 0" class="accordion-item">
<h2 class="accordion-header" id="heading_expanded_suggestions"> <h2 class="accordion-header" id="heading_expanded_suggestions">
<button
<button v-if="isExpanded" v-if="isExpanded"
class="accordion-button" class="accordion-button"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
aria-expanded="true" aria-expanded="true"
@click="toggleSelect"> @click="toggleSelect"
>
Masquer Masquer
</button> </button>
<button v-else <button
v-else
class="accordion-button collapsed" class="accordion-button collapsed"
type="button" type="button"
data-bs-toggle="collapse" data-bs-toggle="collapse"
aria-expanded="false" aria-expanded="false"
@click="toggleSelect"> @click="toggleSelect"
>
Motifs, objectifs et dispositfs disponibles Motifs, objectifs et dispositfs disponibles
</button> </button>
</h2> </h2>
<div class="accordion-collapse" id="collapse_expanded_suggestions" <div
aria-labelledby="heading_expanded_suggestions" data-bs-parent="#expandedSuggestions"> class="accordion-collapse"
id="collapse_expanded_suggestions"
aria-labelledby="heading_expanded_suggestions"
data-bs-parent="#expandedSuggestions"
>
<template v-if="isExpanded"> <template v-if="isExpanded">
<ul class="list-suggest add-items"> <ul class="list-suggest add-items">
<li v-for="g in availableForCheckGoal" @click="addGoal(g)" :key="g.id"> <li
v-for="g in availableForCheckGoal"
@click="addGoal(g)"
:key="g.id"
>
<span>{{ g.title.fr }}</span> <span>{{ g.title.fr }}</span>
</li> </li>
</ul> </ul>
</template> </template>
</div> </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é Aucun objectif associé
</p> </p>
</div> </div>
<div v-else> <div v-else>
<span class="chill-no-data-statement">{{ $t('no_goals_available') }}</span> <span class="chill-no-data-statement">{{
$t("no_goals_available")
}}</span>
</div> </div>
</div> </div>
</div> </div>
<div id="evaluations" class="action-row"> <div id="evaluations" class="action-row">
<div aria="hidden" class="title"> <div aria="hidden" class="title">
<div><h3>{{ $t('Evaluations') }} - {{ $t('Forms') }} - {{ $t('Post') }}</h3></div> <div>
<h3>
{{ $t("Evaluations") }} - {{ $t("Forms") }} - {{ $t("Post") }}
</h3>
</div>
</div> </div>
<!-- list evaluations --> <!-- list evaluations -->
@ -123,37 +147,56 @@
v-for="e in pickedEvaluations" v-for="e in pickedEvaluations"
v-bind:key="e.key" v-bind:key="e.key"
v-bind:evaluation="e" v-bind:evaluation="e"
v-bind:docAnchorId="this.docAnchorId"> v-bind:docAnchorId="this.docAnchorId"
>
</add-evaluation> </add-evaluation>
<!-- box to add new evaluation --> <!-- box to add new evaluation -->
<div class="add_evaluation"> <div class="add_evaluation">
<div v-if="showAddEvaluation"> <div v-if="showAddEvaluation">
<p>{{ $t('available_evaluations_text') }}</p> <p>{{ $t("available_evaluations_text") }}</p>
<ul class="list-suggest add-items"> <ul class="list-suggest add-items">
<li v-for="e in evaluationsForAction" @click="addEvaluation(e)" :key="e.id"> <li
v-for="e in evaluationsForAction"
@click="addEvaluation(e)"
:key="e.id"
>
<span>{{ e.title.fr }}</span> <span>{{ e.title.fr }}</span>
</li> </li>
</ul> </ul>
</div> </div>
<ul class="record_actions" v-if="evaluationsForAction.length > 0"> <ul class="record_actions" v-if="evaluationsForAction.length > 0">
<li> <li>
<button :title="$t('add_an_evaluation')" class="btn btn-create" @click="toggleAddEvaluation">{{ $t('add_an_evaluation') }}</button> <button
:title="$t('add_an_evaluation')"
class="btn btn-create"
@click="toggleAddEvaluation"
>
{{ $t("add_an_evaluation") }}
</button>
</li> </li>
</ul> </ul>
<div v-else> <div v-else>
<span class="chill-no-data-statement">{{ $t('no_evaluations_available') }}</span> <span class="chill-no-data-statement">{{
$t("no_evaluations_available")
}}</span>
</div> </div>
</div> </div>
</div> </div>
<div id="persons" class="action-row"> <div id="persons" class="action-row">
<h3 class="mb-3">{{ $t('persons_involved') }}</h3> <h3 class="mb-3">{{ $t("persons_involved") }}</h3>
<ul class="list-unstyled"> <ul class="list-unstyled">
<li v-for="p in personsReachables" :key="p.id"> <li v-for="p in personsReachables" :key="p.id">
<div class="form-check"> <div class="form-check">
<input v-model="personsPicked" :value="p.id" type="checkbox" class="me-2 form-check-input" :id="'person_check'+p.id"> <input
v-model="personsPicked"
:value="p.id"
type="checkbox"
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> <person-text :person="p"></person-text>
</label> </label>
@ -163,15 +206,20 @@
</div> </div>
<div id="referrers" class="action-row"> <div id="referrers" class="action-row">
<h3>{{ $t('referrers') }}</h3> <h3>{{ $t("referrers") }}</h3>
<div v-if="!hasReferrers"> <div v-if="!hasReferrers">
<p class="chill-no-data-statement">{{ $t('no_referrers') }}</p> <p class="chill-no-data-statement">{{ $t("no_referrers") }}</p>
</div> </div>
<div v-else> <div v-else>
<ul class="list-suggest remove-items inline"> <ul class="list-suggest remove-items inline">
<li v-for="u in referrers" :key="u.id" :title="$t('remove_referrer')" @click="removeReferrer(u)"> <li
v-for="u in referrers"
:key="u.id"
:title="$t('remove_referrer')"
@click="removeReferrer(u)"
>
<span> <span>
{{ u.text }} {{ u.text }}
</span> </span>
@ -187,18 +235,19 @@
:buttonTitle="$t('add_referrers')" :buttonTitle="$t('add_referrers')"
:modalTitle="$t('choose_referrers')" :modalTitle="$t('choose_referrers')"
:options="referrerPicker.options" :options="referrerPicker.options"
@addNewPersons="addReferrers"> @addNewPersons="addReferrers"
>
</add-persons> </add-persons>
</li> </li>
</ul> </ul>
</div> </div>
<div id="handlingThirdParty" class="action-row"> <div id="handlingThirdParty" class="action-row">
<h3>{{ $t('handling_thirdparty') }}</h3> <h3>{{ $t("handling_thirdparty") }}</h3>
<div v-if="!hasHandlingThirdParty"> <div v-if="!hasHandlingThirdParty">
<p class="chill-no-data-statement"> <p class="chill-no-data-statement">
{{ $t('no_handling_thirdparty') }} {{ $t("no_handling_thirdparty") }}
</p> </p>
<ul class="record_actions"> <ul class="record_actions">
@ -209,7 +258,9 @@
v-bind:buttonTitle="$t('precise_handling_thirdparty')" v-bind:buttonTitle="$t('precise_handling_thirdparty')"
v-bind:modalTitle="$t('choose_a_thirdparty')" v-bind:modalTitle="$t('choose_a_thirdparty')"
v-bind:options="handlingThirdPartyPicker.options" v-bind:options="handlingThirdPartyPicker.options"
@addNewPersons="setHandlingThirdParty"> <!-- to cast child method --> @addNewPersons="setHandlingThirdParty"
>
<!-- to cast child method -->
</add-persons> </add-persons>
</li> </li>
</ul> </ul>
@ -224,22 +275,28 @@
addInfo: false, addInfo: false,
hLevel: 3, hLevel: 3,
isMultiline: true, isMultiline: true,
isConfidential: false isConfidential: false,
}"></third-party-render-box> }"
></third-party-render-box>
<ul class="record_actions"> <ul class="record_actions">
<li> <li>
<button :title="$t('remove_handling_thirdparty')" class="btn btn-remove" @click="removeHandlingThirdParty"/> <button
:title="$t('remove_handling_thirdparty')"
class="btn btn-remove"
@click="removeHandlingThirdParty"
/>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
<div id="thirdParties" class="action-row"> <div id="thirdParties" class="action-row">
<h3>{{ $t('thirdparty_intervener') }}</h3> <h3>{{ $t("thirdparty_intervener") }}</h3>
<div v-if="!hasThirdParties"> <div v-if="!hasThirdParties">
<p class="chill-no-data-statement">{{ $t('no_thirdparty_intervener') }}</p> <p class="chill-no-data-statement">
{{ $t("no_thirdparty_intervener") }}
</p>
</div> </div>
<div v-else> <div v-else>
@ -248,14 +305,38 @@
v-for="thirdparty in thirdParties" v-for="thirdparty in thirdParties"
:key="thirdparty.id" :key="thirdparty.id"
:thirdparty="thirdparty" :thirdparty="thirdparty"
:options="{ addLink : false, addId : false, addEntity: true, addInfo: false, hLevel: 3 }" :options="{
addLink: false,
addId: false,
addEntity: true,
addInfo: false,
hLevel: 3,
}"
> >
<template v-slot:record-actions> <template v-slot:record-actions>
<ul class="record_actions"> <ul class="record_actions">
<li><on-the-fly :type="thirdparty.type" :id="thirdparty.id" action="show"></on-the-fly></li>
<li><on-the-fly :type="thirdparty.type" :id="thirdparty.id" action="edit" @saveFormOnTheFly="saveFormOnTheFly" ref="onTheFly"></on-the-fly></li>
<li> <li>
<button :title="$t('remove_thirdparty')" class="btn btn-sm btn-remove" @click="removeThirdParty(thirdparty)" /> <on-the-fly
:type="thirdparty.type"
:id="thirdparty.id"
action="show"
></on-the-fly>
</li>
<li>
<on-the-fly
:type="thirdparty.type"
:id="thirdparty.id"
action="edit"
@saveFormOnTheFly="saveFormOnTheFly"
ref="onTheFly"
></on-the-fly>
</li>
<li>
<button
:title="$t('remove_thirdparty')"
class="btn btn-sm btn-remove"
@click="removeThirdParty(thirdparty)"
/>
</li> </li>
</ul> </ul>
</template> </template>
@ -271,19 +352,24 @@
v-bind:buttonTitle="$t('add_thirdparties')" v-bind:buttonTitle="$t('add_thirdparties')"
v-bind:modalTitle="$t('choose_thirdparties')" v-bind:modalTitle="$t('choose_thirdparties')"
v-bind:options="thirdPartyPicker.options" v-bind:options="thirdPartyPicker.options"
@addNewPersons="addThirdParties"> <!-- to cast child method --> @addNewPersons="addThirdParties"
>
<!-- to cast child method -->
</add-persons> </add-persons>
</li> </li>
</ul> </ul>
</div> </div>
<div v-if="errors.length > 0" id="errors" class="alert alert-danger flashbag"> <div
<p>{{ $t('fix_these_errors') }}</p> v-if="errors.length > 0"
id="errors"
class="alert alert-danger flashbag"
>
<p>{{ $t("fix_these_errors") }}</p>
<ul> <ul>
<li v-for="e in errors" :key="e.id">{{ e }}</li> <li v-for="e in errors" :key="e.id">{{ e }}</li>
</ul> </ul>
</div> </div>
</div> </div>
<ul class="record_actions sticky-form-buttons"> <ul class="record_actions sticky-form-buttons">
<li> <li>
@ -299,64 +385,87 @@
</li> </li>
<li> <li>
<button v-if="AmIRefferer" <button
v-if="AmIRefferer"
class="btn btn-notify" class="btn btn-notify"
@click="goToGenerateNotification(false)" @click="goToGenerateNotification(false)"
></button> ></button>
<template v-else> <template v-else>
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" :title="$t('notification_send')" data-bs-toggle="dropdown" aria-expanded="false">&nbsp;</button> <button
id="btnGroupNotifyButtons"
type="button"
class="btn btn-notify dropdown-toggle"
:title="$t('notification_send')"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</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></li> <li>
<li><a class="dropdown-item" @click="goToGenerateNotification(false)">{{ $t('notification_notify_any') }}</a></li> <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>
</li>
</ul> </ul>
</template> </template>
</li> </li>
<li v-if="!isPosting"> <li v-if="!isPosting">
<button class="btn btn-save" @click="submit"> <button class="btn btn-save" @click="submit">
{{ $t('action.save') }} {{ $t("action.save") }}
</button> </button>
</li> </li>
<li v-if="isPosting"> <li v-if="isPosting">
<button class="btn btn-save" disabled> <button class="btn btn-save" disabled>
{{ $t('action.save') }} {{ $t("action.save") }}
</button> </button>
</li> </li>
</ul> </ul>
</template> </template>
<script> <script>
import {mapState, mapGetters,} from 'vuex'; import { mapState, mapGetters } from "vuex";
import {dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date'; import {
import CKEditor from '@ckeditor/ckeditor5-vue'; dateToISO,
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/editor_config'; ISOToDate,
import AddResult from './components/AddResult.vue'; ISOToDatetime,
import AddEvaluation from './components/AddEvaluation.vue'; } from "ChillMainAssets/chill/js/date";
import AddPersons from 'ChillPersonAssets/vuejs/_components/AddPersons.vue'; import CKEditor from "@ckeditor/ckeditor5-vue";
import AddressRenderBox from 'ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue'; import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import ThirdPartyRenderBox from 'ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue'; import AddResult from "./components/AddResult.vue";
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue'; import AddEvaluation from "./components/AddEvaluation.vue";
import OnTheFly from 'ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue'; import AddPersons from "ChillPersonAssets/vuejs/_components/AddPersons.vue";
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue'; import AddressRenderBox from "ChillMainAssets/vuejs/_components/Entity/AddressRenderBox.vue";
import PersonText from 'ChillPersonAssets/vuejs/_components/Entity/PersonText.vue'; import ThirdPartyRenderBox from "ChillThirdPartyAssets/vuejs/_components/Entity/ThirdPartyRenderBox.vue";
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api'; import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
import { makeFetch } from 'ChillMainAssets/lib/api/apiMethods'; import OnTheFly from "ChillMainAssets/vuejs/OnTheFly/components/OnTheFly.vue";
import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue";
import PersonText from "ChillPersonAssets/vuejs/_components/Entity/PersonText.vue";
import { buildLinkCreate } from "ChillMainAssets/lib/entity-workflow/api";
import { makeFetch } from "ChillMainAssets/lib/api/apiMethods";
const i18n = { const i18n = {
messages: { messages: {
fr: { fr: {
action: { action: {
save: "Enregistrer" save: "Enregistrer",
}, },
conflict_on_save: "Désolé, cette action d'accompagnement a été modifiée dans une autre fenêtre ou par un autre utilisateur. Rechargez la page pour voir ses changements.", conflict_on_save:
"Désolé, cette action d'accompagnement a été modifiée dans une autre fenêtre ou par un autre utilisateur. Rechargez la page pour voir ses changements.",
action_title: "Action d'accompagnement", action_title: "Action d'accompagnement",
comments: "Commentaire", comments: "Commentaire",
startDate: "Date de début", startDate: "Date de début",
endDate: "Date de fin", endDate: "Date de fin",
goals_title: "Motifs - objectifs - dispositifs", goals_title: "Motifs - objectifs - dispositifs",
available_goals_text: "Motifs, objectifs et dispositifs disponibles pour ajout :", available_goals_text:
"Motifs, objectifs et dispositifs disponibles pour ajout :",
results_title: "Orientations - résultats", 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_objectif: "Ajouter un motif - objectif - dispositif",
@ -389,12 +498,12 @@ const i18n = {
notification_notify_referrer: "Notifier le référent", notification_notify_referrer: "Notifier le référent",
notification_notify_any: "Notifier d'autres utilisateurs", notification_notify_any: "Notifier d'autres utilisateurs",
notification_send: "Envoyer une notification", notification_send: "Envoyer une notification",
} },
} },
}; };
export default { export default {
name: 'App', name: "App",
components: { components: {
ckeditor: CKEditor.component, ckeditor: CKEditor.component,
AddResult, AddResult,
@ -416,163 +525,174 @@ export default {
showAddObjective: false, showAddObjective: false,
showAddEvaluation: false, showAddEvaluation: false,
handlingThirdPartyPicker: { handlingThirdPartyPicker: {
key: 'handling-third-party', key: "handling-third-party",
options: { options: {
type: ['thirdparty'], type: ["thirdparty"],
priority: null, priority: null,
uniq: true, uniq: true,
button: { button: {
display: false display: false,
} },
}, },
}, },
thirdPartyPicker: { thirdPartyPicker: {
key: 'third-party', key: "third-party",
options: { options: {
type: ['thirdparty'], type: ["thirdparty"],
priority: null, priority: null,
uniq: false, uniq: false,
button: { button: {
display: false display: false,
} },
}, },
}, },
referrerPicker: { referrerPicker: {
key: 'referrer', key: "referrer",
options: { options: {
type: ['user'], type: ["user"],
priority: null, priority: null,
uniq: false, uniq: false,
button: { button: {
display: false display: false,
} },
}, },
}, },
}; };
}, },
beforeMount() { beforeMount() {
const urlParams = new URLSearchParams(window.location.search); const urlParams = new URLSearchParams(window.location.search);
this.docAnchorId = urlParams.get('doc_id'); this.docAnchorId = urlParams.get("doc_id");
}, },
mounted() { mounted() {
this.scrollToElement(this.docAnchorId); this.scrollToElement(this.docAnchorId);
}, },
computed: { computed: {
...mapState([ ...mapState([
'work', "work",
'resultsForAction', "resultsForAction",
'evaluationsForAction', "evaluationsForAction",
'goalsPicked', "goalsPicked",
'personsReachables', "personsReachables",
'handlingThirdParty', "handlingThirdParty",
'thirdParties', "thirdParties",
'referrers', "referrers",
'isPosting', "isPosting",
'errors', "errors",
'templatesAvailablesForAction', "templatesAvailablesForAction",
'me', "me",
'version' "version",
]), ]),
...mapGetters([ ...mapGetters([
'hasResultsForAction', "hasResultsForAction",
'hasHandlingThirdParty', "hasHandlingThirdParty",
'hasThirdParties', "hasThirdParties",
'hasReferrers' "hasReferrers",
]), ]),
startDate: { startDate: {
get() { get() {
return this.$store.state.startDate; return this.$store.state.startDate;
}, },
set(v) { set(v) {
this.$store.commit('setStartDate', v); this.$store.commit("setStartDate", v);
} },
}, },
endDate: { endDate: {
get() { get() {
return this.$store.state.endDate; return this.$store.state.endDate;
}, },
set(v) { set(v) {
this.$store.commit('setEndDate', v); this.$store.commit("setEndDate", v);
} },
}, },
note: { note: {
get() { get() {
return this.$store.state.note; return this.$store.state.note;
}, },
set(v) { set(v) {
this.$store.commit('setNote', v); this.$store.commit("setNote", v);
} },
}, },
privateComment: { privateComment: {
get() { get() {
return this.$store.state.privateComment; return this.$store.state.privateComment;
}, },
set(v) { set(v) {
this.$store.commit('setPrivateComment', v); this.$store.commit("setPrivateComment", v);
} },
}, },
availableForCheckGoal() { availableForCheckGoal() {
let pickedIds = this.$store.state.goalsPicked.map(g => g.goal.id); let pickedIds = this.$store.state.goalsPicked.map((g) => g.goal.id);
return this.$store.state.goalsForAction.filter(g => !pickedIds.includes(g.id)); return this.$store.state.goalsForAction.filter(
(g) => !pickedIds.includes(g.id),
);
}, },
pickedEvaluations() { pickedEvaluations() {
return this.$store.state.evaluationsPicked; return this.$store.state.evaluationsPicked;
}, },
personsPicked: { personsPicked: {
get() { get() {
let s = this.$store.state.personsPicked.map(p => p.id); let s = this.$store.state.personsPicked.map((p) => p.id);
return s; return s;
}, },
set(v) { set(v) {
this.$store.commit('setPersonsPickedIds', v); this.$store.commit("setPersonsPickedIds", v);
} },
}, },
AmIRefferer() { AmIRefferer() {
return (!(this.work.accompanyingPeriod.user && this.me return !(
&& (this.work.accompanyingPeriod.user.id !== this.me.id))); this.work.accompanyingPeriod.user &&
} this.me &&
this.work.accompanyingPeriod.user.id !== this.me.id
);
},
}, },
methods: { methods: {
toggleSelect() { toggleSelect() {
this.isExpanded = !this.isExpanded; this.isExpanded = !this.isExpanded;
}, },
addGoal(g) { addGoal(g) {
this.$store.commit('addGoal', g); this.$store.commit("addGoal", g);
}, },
removeGoal(g) { removeGoal(g) {
this.$store.commit('removeGoal', g); this.$store.commit("removeGoal", g);
}, },
addEvaluation(e) { addEvaluation(e) {
this.$store.dispatch('addEvaluation', e); this.$store.dispatch("addEvaluation", e);
}, },
toggleAddEvaluation() { toggleAddEvaluation() {
this.showAddEvaluation = !this.showAddEvaluation; this.showAddEvaluation = !this.showAddEvaluation;
}, },
setHandlingThirdParty({ selected, modal }) { setHandlingThirdParty({ selected, modal }) {
this.$store.commit('setHandlingThirdParty', selected.shift().result); this.$store.commit("setHandlingThirdParty", selected.shift().result);
this.$refs.handlingThirdPartyPicker.resetSearch(); this.$refs.handlingThirdPartyPicker.resetSearch();
modal.showModal = false; modal.showModal = false;
}, },
removeHandlingThirdParty() { removeHandlingThirdParty() {
this.$store.commit('setHandlingThirdParty', null); this.$store.commit("setHandlingThirdParty", null);
}, },
addThirdParties({ selected, modal }) { addThirdParties({ selected, modal }) {
this.$store.commit('addThirdParties', selected.map(r => r.result)); this.$store.commit(
"addThirdParties",
selected.map((r) => r.result),
);
this.$refs.thirdPartyPicker.resetSearch(); this.$refs.thirdPartyPicker.resetSearch();
modal.showModal = false; modal.showModal = false;
}, },
removeThirdParty(t) { removeThirdParty(t) {
this.$store.commit('removeThirdParty', t); this.$store.commit("removeThirdParty", t);
}, },
addReferrers({ selected, modal }) { addReferrers({ selected, modal }) {
this.$store.commit('addReferrers', selected.map(r => r.result)); this.$store.commit(
"addReferrers",
selected.map((r) => r.result),
);
this.$refs.referrerPicker.resetSearch(); this.$refs.referrerPicker.resetSearch();
modal.showModal = false; modal.showModal = false;
}, },
removeReferrer(u) { removeReferrer(u) {
this.$store.commit('removeReferrer', u); this.$store.commit("removeReferrer", u);
}, },
goToGenerateWorkflow({ link }) { goToGenerateWorkflow({ link }) {
// console.log('save before leave to generate workflow') // console.log('save before leave to generate workflow')
@ -580,30 +700,43 @@ export default {
window.location.assign(link); window.location.assign(link);
}; };
return this.$store.dispatch('submit', callback) return this.$store.dispatch("submit", callback).catch((e) => {
.catch(e => { console.log(e); throw e; }); console.log(e);
throw e;
});
}, },
goToGenerateNotification(tos) { goToGenerateNotification(tos) {
console.log('save before leave to notification'); console.log("save before leave to notification");
const callback = (data) => { const callback = (data) => {
if (tos === true) { if (tos === true) {
window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&tos[0]=${this.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`); window.location.assign(
`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&tos[0]=${this.work.accompanyingPeriod.user.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`,
);
} else { } else {
window.location.assign(`/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`); window.location.assign(
} `/fr/notification/create?entityClass=Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork&entityId=${this.work.id}&returnPath=/fr/person/accompanying-period/${this.work.accompanyingPeriod.id}/work`,
);
} }
};
return this.$store.dispatch('submit', callback) return this.$store.dispatch("submit", callback).catch((e) => {
.catch(e => {console.log(e); throw e}); console.log(e);
throw e;
});
}, },
submit() { submit() {
this.$store.dispatch('submit').catch((error) => { this.$store.dispatch("submit").catch((error) => {
if (error.name === 'ValidationException' || error.name === 'AccessException') { if (
error.violations.forEach((violation) => this.$toast.open({message: violation})); error.name === "ValidationException" ||
} else if (error.name === 'ConflictHttpException') { error.name === "AccessException"
this.$toast.open({message: this.$t('conflict_on_save')}); ) {
error.violations.forEach((violation) =>
this.$toast.open({ message: violation }),
);
} else if (error.name === "ConflictHttpException") {
this.$toast.open({ message: this.$t("conflict_on_save") });
} else { } else {
this.$toast.open({message: 'An error occurred'}); this.$toast.open({ message: "An error occurred" });
throw error; throw error;
} }
}); });
@ -617,37 +750,40 @@ export default {
body.telephone = payload.data.phonenumber; body.telephone = payload.data.phonenumber;
body.address = { id: payload.data.address.address_id }; body.address = { id: payload.data.address.address_id };
makeFetch('PATCH', `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`, body) makeFetch(
.then(response => { "PATCH",
this.$store.dispatch('updateThirdParty', response) `/api/1.0/thirdparty/thirdparty/${payload.data.id}.json`,
body,
)
.then((response) => {
this.$store.dispatch("updateThirdParty", response);
this.$refs.onTheFly.closeModal(); this.$refs.onTheFly.closeModal();
}) })
.catch((error) => { .catch((error) => {
if (error.name === 'ValidationException') { if (error.name === "ValidationException") {
for (let v of error.violations) { for (let v of error.violations) {
this.$toast.open({ message: v }); this.$toast.open({ message: v });
} }
} else if (error.name === 'ConflictHttpException') { } else if (error.name === "ConflictHttpException") {
this.$toast.open({message: this.$t('conflict_on_save')}); this.$toast.open({ message: this.$t("conflict_on_save") });
} else { } else {
this.$toast.open({message: 'An error occurred'}); this.$toast.open({ message: "An error occurred" });
} }
}) });
}, },
scrollToElement(docAnchorId) { scrollToElement(docAnchorId) {
const documentEl = document.getElementById(`document_${docAnchorId}`); const documentEl = document.getElementById(`document_${docAnchorId}`);
if (documentEl) { if (documentEl) {
documentEl.scrollIntoView({behavior: 'smooth'}); documentEl.scrollIntoView({ behavior: "smooth" });
}
}
} }
},
},
}; };
</script> </script>
<style lang="scss"> <style lang="scss">
@import '~ChillMainAssets/module/bootstrap/shared'; @import "~ChillMainAssets/module/bootstrap/shared";
@import '~ChillMainAssets/chill/scss/mixins'; @import "~ChillMainAssets/chill/scss/mixins";
div#workEditor { div#workEditor {
display: grid; display: grid;
@ -667,29 +803,41 @@ div#workEditor {
"errors errors"; "errors errors";
#title { #title {
grid-area: title; } grid-area: title;
}
#startDate { #startDate {
grid-area: startDate; } grid-area: startDate;
}
#endDate { #endDate {
grid-area: endDate; } grid-area: endDate;
}
#comment { #comment {
grid-area: comment; } grid-area: comment;
}
#privateComment { #privateComment {
grid-area: privateComment; } grid-area: privateComment;
}
#objectives { #objectives {
grid-area: objectives; } grid-area: objectives;
}
#evaluations { #evaluations {
grid-area: evaluations; } grid-area: evaluations;
}
#persons { #persons {
grid-area: persons; } grid-area: persons;
}
#handlingThirdParty { #handlingThirdParty {
grid-area: handling; } grid-area: handling;
}
#thirdParties { #thirdParties {
grid-area: tparties; } grid-area: tparties;
}
#referrers { #referrers {
grid-area: referrers; } grid-area: referrers;
}
#errors { #errors {
grid-area: errors; } grid-area: errors;
}
div.action-row { div.action-row {
@include border-collapse; @include border-collapse;
@ -718,10 +866,12 @@ div#workEditor {
padding: 1em; padding: 1em;
&:nth-child(1) { &:nth-child(1) {
grid-area: obj; } grid-area: obj;
}
&:nth-child(2) { &:nth-child(2) {
grid-area: res; } grid-area: res;
}
} }
& > div.results_without_objective { & > div.results_without_objective {
@ -771,7 +921,9 @@ div#workEditor {
padding: 0.25rem; padding: 0.25rem;
color: $white; color: $white;
&.fa-times { color: $red; } &.fa-times {
color: $red;
}
} }
} }
@ -791,15 +943,15 @@ div#workEditor {
} }
} }
.accordion-item:first-of-type, .accordion-item:last-of-type { .accordion-item:first-of-type,
.accordion-item:last-of-type {
border-radius: 0rem; border-radius: 0rem;
border: 0px; border: 0px;
.accordion-button { .accordion-button {
padding: .25rem; padding: 0.25rem;
border: 1px solid rgba(17, 17, 17, 0.125); border: 1px solid rgba(17, 17, 17, 0.125);
margin-top: 20px; margin-top: 20px;
margin-bottom: 20px; margin-bottom: 20px;
} }
} }
</style> </style>

View File

@ -7,15 +7,21 @@
<div class="item-url mt-3 mb-4" v-if="evaluation.evaluation.url"> <div class="item-url mt-3 mb-4" v-if="evaluation.evaluation.url">
<i class="fa fa-link fa-lg"></i> <i class="fa fa-link fa-lg"></i>
<a :href="evaluation.evaluation.url" target="_blank">{{ evaluation.evaluation.url }}</a> <a :href="evaluation.evaluation.url" target="_blank">{{
evaluation.evaluation.url
}}</a>
</div> </div>
<div> <div>
<form-evaluation ref="FormEvaluation" :key="evaluation.key" :evaluation="evaluation" :docAnchorId="docAnchorId"></form-evaluation> <form-evaluation
ref="FormEvaluation"
:key="evaluation.key"
:evaluation="evaluation"
:docAnchorId="docAnchorId"
></form-evaluation>
<ul class="record_actions"> <ul class="record_actions">
<li v-if="evaluation.workflows_availables.length > 0"> <li v-if="evaluation.workflows_availables.length > 0">
<list-workflow-modal <list-workflow-modal
:workflows="evaluation.workflows" :workflows="evaluation.workflows"
:allowCreate="true" :allowCreate="true"
@ -24,25 +30,33 @@
:workflowsAvailables="evaluation.workflows_availables" :workflowsAvailables="evaluation.workflows_availables"
@go-to-generate-workflow="goToGenerateWorkflow" @go-to-generate-workflow="goToGenerateWorkflow"
></list-workflow-modal> ></list-workflow-modal>
</li> </li>
<li v-if="canDelete"> <li v-if="canDelete">
<a class="btn btn-delete" @click="modal.showModal = true" :title="$t('action.delete')">{{ $t('delete_evaluation')}}</a> <a
class="btn btn-delete"
@click="modal.showModal = true"
:title="$t('action.delete')"
>{{ $t("delete_evaluation") }}</a
>
</li> </li>
</ul> </ul>
</div> </div>
<teleport to="body"> <teleport to="body">
<modal v-if="modal.showModal" :modalDialogClass="modal.modalDialogClass" @close="modal.showModal = false"> <modal
v-if="modal.showModal"
:modalDialogClass="modal.modalDialogClass"
@close="modal.showModal = false"
>
<template v-slot:header> <template v-slot:header>
<h2 class="modal-title">{{ $t('delete.sure') }}</h2> <h2 class="modal-title">{{ $t("delete.sure") }}</h2>
</template> </template>
<template v-slot:body> <template v-slot:body>
<p>{{ $t('delete.sure_description') }}</p> <p>{{ $t("delete.sure_description") }}</p>
</template> </template>
<template v-slot:footer> <template v-slot:footer>
<button class="btn btn-danger" @click="removeEvaluation(evaluation)"> <button class="btn btn-danger" @click="removeEvaluation(evaluation)">
{{ $t('delete.ok') }} {{ $t("delete.ok") }}
</button> </button>
</template> </template>
</modal> </modal>
@ -51,10 +65,10 @@
</template> </template>
<script> <script>
import FormEvaluation from './FormEvaluation.vue'; import FormEvaluation from "./FormEvaluation.vue";
import Modal from 'ChillMainAssets/vuejs/_components/Modal'; import Modal from "ChillMainAssets/vuejs/_components/Modal";
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue'; import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue";
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api'; import { buildLinkCreate } from "ChillMainAssets/lib/entity-workflow/api";
const i18n = { const i18n = {
messages: { messages: {
@ -70,12 +84,13 @@ const i18n = {
documents: "Documents", documents: "Documents",
delete: { delete: {
sure: "Êtes-vous sûr?", sure: "Êtes-vous sûr?",
sure_description: "Cette évaluation sera supprimée de cette action d'accompagnement", sure_description:
ok: "Supprimer" "Cette évaluation sera supprimée de cette action d'accompagnement",
ok: "Supprimer",
}, },
delete_evaluation: "Supprimer l'évaluation", delete_evaluation: "Supprimer l'évaluation",
} },
} },
}; };
export default { export default {
@ -85,14 +100,14 @@ export default {
Modal, Modal,
ListWorkflowModal, ListWorkflowModal,
}, },
props: ['evaluation', 'docAnchorId'], props: ["evaluation", "docAnchorId"],
i18n, i18n,
data() { data() {
return { return {
modal: { modal: {
showModal: false, showModal: false,
modalDialogClass: "modal-dialog-centered modal-md" modalDialogClass: "modal-dialog-centered modal-md",
} },
}; };
}, },
computed: { computed: {
@ -115,27 +130,36 @@ export default {
}, },
methods: { methods: {
removeEvaluation(e) { removeEvaluation(e) {
this.$store.commit('removeEvaluation', e); this.$store.commit("removeEvaluation", e);
return; return;
}, },
toggleEditEvaluation(e) { toggleEditEvaluation(e) {
this.$store.commit('toggleEvaluationEdit', { key: this.evaluation.key }); this.$store.commit("toggleEvaluationEdit", { key: this.evaluation.key });
}, },
submitForm() { submitForm() {
this.toggleEditEvaluation(); this.toggleEditEvaluation();
}, },
goToGenerateWorkflow({ event, link, workflowName }) { goToGenerateWorkflow({ event, link, workflowName }) {
const callback = (data) => { const callback = (data) => {
let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id; let evaluationId = data.accompanyingPeriodWorkEvaluations.find(
window.location.assign(buildLinkCreate(workflowName, (e) => e.key === this.evaluation.key,
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation', evaluationId)); ).id;
window.location.assign(
buildLinkCreate(
workflowName,
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation",
evaluationId,
),
);
}; };
return this.$store.dispatch('submit', callback) return this.$store.dispatch("submit", callback).catch((e) => {
.catch(e => { console.log(e); throw e; }); console.log(e);
} throw e;
} });
} },
},
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -19,43 +19,63 @@
<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">
{{ $t('evaluation_startdate') }} {{ $t("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 class="form-control form-control-sm" type="date" v-model="startDate"/> <input
class="form-control form-control-sm"
type="date"
v-model="startDate"
/>
</div> </div>
<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">
{{ $t('evaluation_enddate') }} {{ $t("evaluation_enddate") }}
</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 class="form-control form-control-sm" type="date" v-model="endDate"/> <input
class="form-control form-control-sm"
type="date"
v-model="endDate"
/>
</div> </div>
</div> </div>
<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">
{{ $t('evaluation_maxdate') }} {{ $t("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 class="form-control form-control-sm" type="date" v-model="maxDate"/> <input
class="form-control form-control-sm"
type="date"
v-model="maxDate"
/>
</div> </div>
<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">
{{ $t('evaluation_warning_interval') }} {{ $t("evaluation_warning_interval") }}
</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 class="form-control form-control-sm" type="number" v-model.number="warningInterval"/> <input
class="form-control form-control-sm"
type="number"
v-model.number="warningInterval"
/>
</div> </div>
</div> </div>
<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">
{{ $t('evaluation_time_spent') }} {{ $t("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 class="form-control form-control-sm" type="time" v-model="timeSpent"> <select
<option disabled value="">{{ $t('select_time_spent') }}</option> class="form-control form-control-sm"
type="time"
v-model="timeSpent"
>
<option disabled value="">{{ $t("select_time_spent") }}</option>
<option v-for="time in timeSpentChoices" :value="time.value"> <option v-for="time in timeSpentChoices" :value="time.value">
{{ time.text }} {{ time.text }}
</option> </option>
@ -64,7 +84,9 @@
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<label class="col-sm-4 col-form-label visually-hidden">{{ $t('evaluation_public_comment') }}</label> <label class="col-sm-4 col-form-label visually-hidden">{{
$t("evaluation_public_comment")
}}</label>
<div class="col-sm-12"> <div class="col-sm-12">
<ckeditor <ckeditor
:editor="editor" :editor="editor"
@ -76,13 +98,22 @@
</div> </div>
<div v-if="evaluation.documents.length > 0" class="row mb-3"> <div v-if="evaluation.documents.length > 0" class="row mb-3">
<h5>{{ $t('Documents') }} :</h5> <h5>{{ $t("Documents") }} :</h5>
<div class="flex-table"> <div class="flex-table">
<div class="item-bloc" v-for="(d, i) in evaluation.documents" :key="d.id" :class="[parseInt(this.docAnchorId) === d.id ? 'bg-blink' : 'nothing']"> <div
class="item-bloc"
v-for="(d, i) in evaluation.documents"
:key="d.id"
:class="[
parseInt(this.docAnchorId) === d.id ? 'bg-blink' : 'nothing',
]"
>
<div :id="`document_${d.id}`" class="item-row"> <div :id="`document_${d.id}`" class="item-row">
<div class="input-group input-group-lg mb-3 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"> <div class="col-sm-9">
<input <input
class="form-control document-title" class="form-control document-title"
@ -90,20 +121,28 @@
:value="d.title" :value="d.title"
:id="d.id" :id="d.id"
:data-key="i" :data-key="i"
@input="onInputDocumentTitle"/> @input="onInputDocumentTitle"
/>
</div> </div>
</div> </div>
</div> </div>
<div class="item-row"> <div class="item-row">
<div class="item-col item-meta"> <div class="item-col item-meta">
<p v-if="d.createdBy" class="createdBy">Créé par {{ d.createdBy.text }}<br/> <p v-if="d.createdBy" class="createdBy">
Le {{ $d(ISOToDatetime(d.createdAt.datetime), 'long') }}</p> Créé par {{ d.createdBy.text }}<br />
Le {{ $d(ISOToDatetime(d.createdAt.datetime), "long") }}
</p>
</div> </div>
</div> </div>
<div class="item-row"> <div class="item-row">
<div class="item-col"> <div class="item-col">
<ul class="record_actions"> <ul class="record_actions">
<li v-if="d.workflows_availables.length > 0 || d.workflows.length > 0"> <li
v-if="
d.workflows_availables.length > 0 ||
d.workflows.length > 0
"
>
<list-workflow-modal <list-workflow-modal
:workflows="d.workflows" :workflows="d.workflows"
:allowCreate="true" :allowCreate="true"
@ -112,20 +151,46 @@
:workflowsAvailables="d.workflows_availables" :workflowsAvailables="d.workflows_availables"
:preventDefaultMoveToGenerate="true" :preventDefaultMoveToGenerate="true"
:goToGenerateWorkflowPayload="{ doc: d }" :goToGenerateWorkflowPayload="{ doc: d }"
@go-to-generate-workflow="goToGenerateWorkflowEvaluationDocument" @go-to-generate-workflow="
goToGenerateWorkflowEvaluationDocument
"
></list-workflow-modal> ></list-workflow-modal>
</li> </li>
<li> <li>
<button <button
v-if="AmIRefferer" v-if="AmIRefferer"
class="btn btn-notify" class="btn btn-notify"
@click="goToGenerateDocumentNotification(d, false)"> @click="goToGenerateDocumentNotification(d, false)"
</button> ></button>
<template v-else> <template v-else>
<button id="btnGroupNotifyButtons" type="button" class="btn btn-notify dropdown-toggle" :title="$t('notification_send')" data-bs-toggle="dropdown" aria-expanded="false">&nbsp;</button> <button
<ul class="dropdown-menu" aria-labelledby="btnGroupNotifyButtons"> id="btnGroupNotifyButtons"
<li><a class="dropdown-item" @click="goToGenerateDocumentNotification(d, true)">{{ $t('notification_notify_referrer') }}</a></li> type="button"
<li><a class="dropdown-item" @click="goToGenerateDocumentNotification(d, false)">{{ $t('notification_notify_any') }}</a></li> class="btn btn-notify dropdown-toggle"
:title="$t('notification_send')"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</button>
<ul
class="dropdown-menu"
aria-labelledby="btnGroupNotifyButtons"
>
<li>
<a
class="dropdown-item"
@click="goToGenerateDocumentNotification(d, true)"
>{{ $t("notification_notify_referrer") }}</a
>
</li>
<li>
<a
class="dropdown-item"
@click="goToGenerateDocumentNotification(d, false)"
>{{ $t("notification_notify_any") }}</a
>
</li>
</ul> </ul>
</template> </template>
</li> </li>
@ -136,19 +201,36 @@
:can-edit="true" :can-edit="true"
:execute-before-leave="submitBeforeLeaveToEditor" :execute-before-leave="submitBeforeLeaveToEditor"
:davLink="d.storedObject._links?.dav_link.href" :davLink="d.storedObject._links?.dav_link.href"
:davLinkExpiration="d.storedObject._links?.dav_link.expiration" :davLinkExpiration="
d.storedObject._links?.dav_link.expiration
"
@on-stored-object-status-change="onStatusDocumentChanged" @on-stored-object-status-change="onStatusDocumentChanged"
></document-action-buttons-group> ></document-action-buttons-group>
</li> </li>
<li v-if="d.storedObject._permissions.canEdit"> <li v-if="d.storedObject._permissions.canEdit">
<drop-file-modal :existing-doc="d.storedObject" :allow-remove="false" @add-document="(arg) => replaceDocument(d, arg.stored_object, arg.stored_object_version)"></drop-file-modal> <drop-file-modal
:existing-doc="d.storedObject"
:allow-remove="false"
@add-document="
(arg) =>
replaceDocument(
d,
arg.stored_object,
arg.stored_object_version,
)
"
></drop-file-modal>
</li> </li>
<li v-if="d.workflows.length === 0"> <li v-if="d.workflows.length === 0">
<a class="btn btn-delete" @click="removeDocument(d)"> <a class="btn btn-delete" @click="removeDocument(d)"> </a>
</a>
</li> </li>
<li v-if="Number.isInteger(d.id)"> <li v-if="Number.isInteger(d.id)">
<button type="button" @click="duplicateDocument(d)" class="btn btn-duplicate" title="Dupliquer"></button> <button
type="button"
@click="duplicateDocument(d)"
class="btn btn-duplicate"
title="Dupliquer"
></button>
</li> </li>
</ul> </ul>
</div> </div>
@ -158,7 +240,7 @@
</div> </div>
<div class="row mb-3"> <div class="row mb-3">
<h6>{{ $t('document_add') }} :</h6> <h6>{{ $t("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"
@ -167,33 +249,41 @@
@go-to-generate-document="submitBeforeGenerate" @go-to-generate-document="submitBeforeGenerate"
> >
<template v-slot:title> <template v-slot:title>
<label class="col-form-label">{{ $t('evaluation_generate_a_document') }}</label> <label class="col-form-label">{{
$t("evaluation_generate_a_document")
}}</label>
</template> </template>
</pick-template> </pick-template>
<div> <div>
<label class="col-form-label">{{ $t('document_upload') }}</label> <label class="col-form-label">{{ $t("document_upload") }}</label>
<ul class="record_actions document-upload"> <ul class="record_actions document-upload">
<li> <li>
<drop-file-modal :allow-remove="false" @add-document="addDocument"></drop-file-modal> <drop-file-modal
:allow-remove="false"
@add-document="addDocument"
></drop-file-modal>
</li> </li>
</ul> </ul>
</div> </div>
</div> </div>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import {dateToISO, ISOToDate, ISOToDatetime} from 'ChillMainAssets/chill/js/date'; import {
import CKEditor from '@ckeditor/ckeditor5-vue'; dateToISO,
import ClassicEditor from 'ChillMainAssets/module/ckeditor5/editor_config'; ISOToDate,
import { mapGetters, mapState } from 'vuex'; ISOToDatetime,
import PickTemplate from 'ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue'; } from "ChillMainAssets/chill/js/date";
import {buildLink} from 'ChillDocGeneratorAssets/lib/document-generator'; import CKEditor from "@ckeditor/ckeditor5-vue";
import ListWorkflowModal from 'ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue'; import ClassicEditor from "ChillMainAssets/module/ckeditor5/editor_config";
import {buildLinkCreate} from 'ChillMainAssets/lib/entity-workflow/api'; import { mapGetters, mapState } from "vuex";
import {buildLinkCreate as buildLinkCreateNotification} from 'ChillMainAssets/lib/entity-notification/api'; import PickTemplate from "ChillDocGeneratorAssets/vuejs/_components/PickTemplate.vue";
import { buildLink } from "ChillDocGeneratorAssets/lib/document-generator";
import ListWorkflowModal from "ChillMainAssets/vuejs/_components/EntityWorkflow/ListWorkflowModal.vue";
import { buildLinkCreate } from "ChillMainAssets/lib/entity-workflow/api";
import { buildLinkCreate as buildLinkCreateNotification } from "ChillMainAssets/lib/entity-notification/api";
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";
@ -226,13 +316,13 @@ const i18n = {
notification_notify_referrer: "Notifier le référent", notification_notify_referrer: "Notifier le référent",
notification_notify_any: "Notifier d'autres utilisateurs", notification_notify_any: "Notifier d'autres utilisateurs",
notification_send: "Envoyer une notification", notification_send: "Envoyer une notification",
} },
} },
}; };
export default { export default {
name: "FormEvaluation", name: "FormEvaluation",
props: ['evaluation', 'docAnchorId'], props: ["evaluation", "docAnchorId"],
components: { components: {
DropFileModal, DropFileModal,
ckeditor: CKEditor.component, ckeditor: CKEditor.component,
@ -251,132 +341,212 @@ export default {
required: false, required: false,
}, },
timeSpentChoices: [ timeSpentChoices: [
{ text: '1 minute', value: 60 }, { text: '2 minutes', value: 120 }, { text: "1 minute", value: 60 },
{ text: '3 minutes', value: 180 }, { text: '4 minutes', value: 240 }, { text: "2 minutes", value: 120 },
{ text: '5 minutes', value: 300 }, { text: '10 minutes', value: 600 }, { text: "3 minutes", value: 180 },
{ text: '15 minutes', value: 900 },{ text: '20 minutes', value: 1200 }, { text: "4 minutes", value: 240 },
{ text: '25 minutes', value: 1500 }, { text: '30 minutes', value: 1800 }, { text: "5 minutes", value: 300 },
{ text: '45 minutes', value: 2700 },{ text: '1 hour', value: 3600 }, { text: "10 minutes", value: 600 },
{ text: '1 hour 15 minutes', value: 4500 }, { text: '1 hour 30 minutes', value: 5400 }, { text: "15 minutes", value: 900 },
{ text: '1 hour 45 minutes', value: 6300 }, { text: '2 hours', value: 7200 }, { text: "20 minutes", value: 1200 },
{ text: '2 hours 30 minutes', value: 9000 }, { text: '3 hours', value: 10800 }, { text: "25 minutes", value: 1500 },
{ text: '3 hours 30 minutes', value: 12600 },{ text: '4 hours', value: 14400 }, { text: "30 minutes", value: 1800 },
{ text: '4 hours 30 minutes', value: 16200 },{ text: '5 hours', value: 18000 }, { text: "45 minutes", value: 2700 },
{ text: '5 hours 30 minutes', value: 19800 },{ text: '6 hours', value: 21600 }, { text: "1 hour", value: 3600 },
{ text: '6 hours 30 minutes', value: 23400 },{ text: '7 hours', value: 25200 }, { text: "1 hour 15 minutes", value: 4500 },
{ text: '7 hours 30 minutes', value: 27000 },{ text: '8 hours', value: 28800 }, { text: "1 hour 30 minutes", value: 5400 },
] { text: "1 hour 45 minutes", value: 6300 },
} { text: "2 hours", value: 7200 },
{ text: "2 hours 30 minutes", value: 9000 },
{ text: "3 hours", value: 10800 },
{ text: "3 hours 30 minutes", value: 12600 },
{ text: "4 hours", value: 14400 },
{ text: "4 hours 30 minutes", value: 16200 },
{ text: "5 hours", value: 18000 },
{ text: "5 hours 30 minutes", value: 19800 },
{ text: "6 hours", value: 21600 },
{ text: "6 hours 30 minutes", value: 23400 },
{ text: "7 hours", value: 25200 },
{ text: "7 hours 30 minutes", value: 27000 },
{ text: "8 hours", value: 28800 },
],
};
}, },
computed: { computed: {
...mapState([ ...mapState(["isPosting", "work", "me"]),
'isPosting',
'work',
'me',
]),
AmIRefferer() { AmIRefferer() {
return (!(this.$store.state.work.accompanyingPeriod.user && this.$store.state.me return !(
&& (this.$store.state.work.accompanyingPeriod.user.id !== this.$store.state.me.id))); this.$store.state.work.accompanyingPeriod.user &&
this.$store.state.me &&
this.$store.state.work.accompanyingPeriod.user.id !==
this.$store.state.me.id
);
}, },
getTemplatesAvailables() { getTemplatesAvailables() {
return this.$store.getters.getTemplatesAvailablesForEvaluation(this.evaluation.evaluation); return this.$store.getters.getTemplatesAvailablesForEvaluation(
this.evaluation.evaluation,
);
}, },
canGenerate() { canGenerate() {
return !this.$store.state.isPosting && this.template !== null; return !this.$store.state.isPosting && this.template !== null;
}, },
startDate: { startDate: {
get() { get() {
console.log('evaluation', this.evaluation); console.log("evaluation", this.evaluation);
return this.evaluation.startDate; return this.evaluation.startDate;
}, },
set(v) { set(v) {
this.$store.commit('setEvaluationStartDate', { key: this.evaluation.key, date: v }); this.$store.commit("setEvaluationStartDate", {
} key: this.evaluation.key,
date: v,
});
},
}, },
endDate: { endDate: {
get() { get() {
return this.evaluation.endDate; return this.evaluation.endDate;
}, },
set(v) { set(v) {
this.$store.commit('setEvaluationEndDate', { key: this.evaluation.key, date: v }); this.$store.commit("setEvaluationEndDate", {
} key: this.evaluation.key,
date: v,
});
},
}, },
maxDate: { maxDate: {
get() { get() {
return this.evaluation.maxDate; return this.evaluation.maxDate;
}, },
set(v) { set(v) {
this.$store.commit('setEvaluationMaxDate', { key: this.evaluation.key, date: v }); this.$store.commit("setEvaluationMaxDate", {
} key: this.evaluation.key,
date: v,
});
},
}, },
warningInterval: { warningInterval: {
get() { return this.evaluation.warningInterval; }, get() {
set(v) { this.$store.commit('setEvaluationWarningInterval', { key: this.evaluation.key, days: v }); } return this.evaluation.warningInterval;
},
set(v) {
this.$store.commit("setEvaluationWarningInterval", {
key: this.evaluation.key,
days: v,
});
},
}, },
timeSpent: { timeSpent: {
get() { return this.evaluation.timeSpent }, get() {
set(v) { this.$store.commit('setEvaluationTimeSpent', { key: this.evaluation.key, time: v}) } return this.evaluation.timeSpent;
},
set(v) {
this.$store.commit("setEvaluationTimeSpent", {
key: this.evaluation.key,
time: v,
});
},
}, },
comment: { comment: {
get() { return this.evaluation.comment; }, get() {
set(v) { this.$store.commit('setEvaluationComment', { key: this.evaluation.key, comment: v }); } return this.evaluation.comment;
},
set(v) {
this.$store.commit("setEvaluationComment", {
key: this.evaluation.key,
comment: v,
});
},
}, },
}, },
methods: { methods: {
ISOToDatetime, ISOToDatetime,
listAllStatus() { listAllStatus() {
console.log('load all status'); console.log("load all status");
let url = `/api/`; let url = `/api/`;
fetch(url) fetch(url).then((response) => {
.then(response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'yeeah', s: response.status, b: response.body }; throw { m: "yeeah", s: response.status, b: response.body };
}) });
;
}, },
buildEditLink(document) { buildEditLink(document) {
return `/chill/wopi/edit/${document.storedObject.uuid}?returnPath=` + encodeURIComponent( return (
window.location.pathname + window.location.search + window.location.hash); `/chill/wopi/edit/${document.storedObject.uuid}?returnPath=` +
encodeURIComponent(
window.location.pathname +
window.location.search +
window.location.hash,
)
);
}, },
submitBeforeLeaveToEditor() { submitBeforeLeaveToEditor() {
console.log('submit beore edit 2'); console.log("submit beore edit 2");
// empty callback // empty callback
const callback = () => null; const callback = () => null;
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; }); return this.$store.dispatch("submit", callback).catch((e) => {
console.log(e);
throw e;
});
}, },
submitBeforeEdit(storedObject) { submitBeforeEdit(storedObject) {
const callback = (data) => { const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); let evaluation = data.accompanyingPeriodWorkEvaluations.find(
let document = evaluation.documents.find(d => d.storedObject.id === storedObject.id); (e) => e.key === this.evaluation.key,
);
let document = evaluation.documents.find(
(d) => d.storedObject.id === storedObject.id,
);
//console.log('=> document', document); //console.log('=> document', document);
window.location.assign(this.buildEditLink(document)); window.location.assign(this.buildEditLink(document));
}; };
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; }); return this.$store.dispatch("submit", callback).catch((e) => {
console.log(e);
throw e;
});
}, },
submitBeforeGenerate({ template }) { submitBeforeGenerate({ template }) {
const callback = (data) => { const callback = (data) => {
let evaluationId = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key).id; let evaluationId = data.accompanyingPeriodWorkEvaluations.find(
(e) => e.key === this.evaluation.key,
).id;
window.location.assign(buildLink(template, evaluationId, 'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation')); window.location.assign(
buildLink(
template,
evaluationId,
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation",
),
);
}; };
return this.$store.dispatch('submit', callback).catch(e => { console.log(e); throw e; }); return this.$store.dispatch("submit", callback).catch((e) => {
console.log(e);
throw e;
});
}, },
onInputDocumentTitle(event) { 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;
this.$store.commit('updateDocumentTitle', {id: id, key: key, evaluationKey: this.evaluation.key, title: title}); this.$store.commit("updateDocumentTitle", {
id: id,
key: key,
evaluationKey: this.evaluation.key,
title: title,
});
}, },
addDocument({ stored_object, stored_object_version }) { 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",
}; };
this.$store.commit('addDocument', {key: this.evaluation.key, document, stored_object_version}); this.$store.commit("addDocument", {
key: this.evaluation.key,
document,
stored_object_version,
});
}, },
/** /**
* Replaces a document in the store with a new document. * Replaces a document in the store with a new document.
@ -388,51 +558,99 @@ export default {
*/ */
replaceDocument(oldDocument, storedObject, storedObjectVersion) { replaceDocument(oldDocument, storedObject, storedObjectVersion) {
let document = { let document = {
type: 'accompanying_period_work_evaluation_document', type: "accompanying_period_work_evaluation_document",
storedObject: storedObject, storedObject: storedObject,
title: oldDocument.title title: oldDocument.title,
}; };
this.$store.commit('replaceDocument', {key: this.evaluation.key, document, oldDocument: oldDocument, stored_object_version: storedObjectVersion}); this.$store.commit("replaceDocument", {
key: this.evaluation.key,
document,
oldDocument: oldDocument,
stored_object_version: storedObjectVersion,
});
}, },
removeDocument(document) { removeDocument(document) {
if (window.confirm("Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre \"" + document.title +"\" ?")) { if (
this.$store.commit('removeDocument', {key: this.evaluation.key, document: document}); window.confirm(
'Êtes-vous sûr·e de vouloir supprimer le document qui a pour titre "' +
document.title +
'" ?',
)
) {
this.$store.commit("removeDocument", {
key: this.evaluation.key,
document: document,
});
} }
}, },
duplicateDocument(document) { duplicateDocument(document) {
this.$store.dispatch('duplicateDocument', {evaluation_key: this.evaluation.key, document: document}); this.$store.dispatch("duplicateDocument", {
evaluation_key: this.evaluation.key,
document: document,
});
}, },
onStatusDocumentChanged(newStatus) { onStatusDocumentChanged(newStatus) {
console.log('onStatusDocumentChanged', newStatus); console.log("onStatusDocumentChanged", newStatus);
this.$store.commit('statusDocumentChanged', {key: this.evaluation.key, newStatus: newStatus}); this.$store.commit("statusDocumentChanged", {
key: this.evaluation.key,
newStatus: newStatus,
});
}, },
goToGenerateWorkflowEvaluationDocument({event, link, workflowName, payload}) { goToGenerateWorkflowEvaluationDocument({
event,
link,
workflowName,
payload,
}) {
const callback = (data) => { const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); let evaluation = data.accompanyingPeriodWorkEvaluations.find(
let updatedDocument = evaluation.documents.find(d => d.key === payload.doc.key); (e) => e.key === this.evaluation.key,
window.location.assign(buildLinkCreate(workflowName, );
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', updatedDocument.id)); let updatedDocument = evaluation.documents.find(
(d) => d.key === payload.doc.key,
);
window.location.assign(
buildLinkCreate(
workflowName,
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
updatedDocument.id,
),
);
}; };
return this.$store.dispatch('submit', callback) return this.$store.dispatch("submit", callback).catch((e) => {
.catch(e => { console.log(e); throw e; }); console.log(e);
throw e;
});
}, },
goToGenerateDocumentNotification(document, tos) { goToGenerateDocumentNotification(document, tos) {
const callback = (data) => { const callback = (data) => {
let evaluation = data.accompanyingPeriodWorkEvaluations.find(e => e.key === this.evaluation.key); let evaluation = data.accompanyingPeriodWorkEvaluations.find(
let updatedDocument = evaluation.documents.find(d => d.key === document.key); (e) => e.key === this.evaluation.key,
window.location.assign(buildLinkCreateNotification( );
'Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument', let updatedDocument = evaluation.documents.find(
(d) => d.key === document.key,
);
window.location.assign(
buildLinkCreateNotification(
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluationDocument",
updatedDocument.id, updatedDocument.id,
tos === true ? this.$store.state.work.accompanyingPeriod.user.id : null, tos === true
window.location.pathname + window.location.search + window.location.hash ? this.$store.state.work.accompanyingPeriod.user.id
)); : null,
window.location.pathname +
window.location.search +
window.location.hash,
),
);
}; };
return this.$store.dispatch('submit', callback) return this.$store.dispatch("submit", callback).catch((e) => {
.catch(e => {console.log(e); throw e}); console.log(e);
} throw e;
});
}, },
} },
};
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>
@ -454,8 +672,14 @@ export default {
} }
@keyframes blinkingBackground { @keyframes blinkingBackground {
0% { background-color: #ed776d;} 0% {
50% { background-color: #ffffff;} background-color: #ed776d;
100% { background-color: #ed776d;} }
50% {
background-color: #ffffff;
}
100% {
background-color: #ed776d;
}
} }
</style> </style>

View File

@ -1,22 +1,35 @@
import { createStore } from 'vuex'; import { createStore } from "vuex";
import { dateToISO, ISOToDate, datetimeToISO, ISOToDatetime, intervalDaysToISO, intervalISOToDays } from 'ChillMainAssets/chill/js/date'; import {
import { findSocialActionsBySocialIssue } from 'ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js'; dateToISO,
import { create } from 'ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js'; ISOToDate,
import { fetchResults, makeFetch } from 'ChillMainAssets/lib/api/apiMethods.ts'; datetimeToISO,
import { fetchTemplates } from 'ChillDocGeneratorAssets/api/pickTemplate.js'; ISOToDatetime,
import { duplicate } from '../_api/accompanyingCourseWorkEvaluationDocument'; intervalDaysToISO,
intervalISOToDays,
} from "ChillMainAssets/chill/js/date";
import { findSocialActionsBySocialIssue } from "ChillPersonAssets/vuejs/_api/SocialWorkSocialAction.js";
import { create } from "ChillPersonAssets/vuejs/_api/AccompanyingCourseWork.js";
import { fetchResults, makeFetch } from "ChillMainAssets/lib/api/apiMethods.ts";
import { fetchTemplates } from "ChillDocGeneratorAssets/api/pickTemplate.js";
import { duplicate } from "../_api/accompanyingCourseWorkEvaluationDocument";
const debug = process.env.NODE_ENV !== 'production'; const debug = process.env.NODE_ENV !== "production";
const evalFQDN = encodeURIComponent("Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation"); const evalFQDN = encodeURIComponent(
"Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWorkEvaluation",
);
const store = createStore({ const store = createStore({
strict: debug, strict: debug,
state: { state: {
work: window.accompanyingCourseWork, work: window.accompanyingCourseWork,
startDate: window.accompanyingCourseWork.startDate !== null ? startDate:
dateToISO(new Date(window.accompanyingCourseWork.startDate.datetime)) : null, window.accompanyingCourseWork.startDate !== null
endDate: window.accompanyingCourseWork.endDate !== null ? ? dateToISO(new Date(window.accompanyingCourseWork.startDate.datetime))
dateToISO(new Date(window.accompanyingCourseWork.endDate.datetime)) : null, : null,
endDate:
window.accompanyingCourseWork.endDate !== null
? dateToISO(new Date(window.accompanyingCourseWork.endDate.datetime))
: null,
note: window.accompanyingCourseWork.note, note: window.accompanyingCourseWork.note,
privateComment: window.accompanyingCourseWork.privateComment, privateComment: window.accompanyingCourseWork.privateComment,
goalsPicked: window.accompanyingCourseWork.goals, goalsPicked: window.accompanyingCourseWork.goals,
@ -29,15 +42,17 @@ const store = createStore({
templatesAvailablesForAction: [], templatesAvailablesForAction: [],
templatesAvailablesForEvaluation: new Map([]), templatesAvailablesForEvaluation: new Map([]),
personsPicked: window.accompanyingCourseWork.persons, personsPicked: window.accompanyingCourseWork.persons,
personsReachables: window.accompanyingCourseWork.accompanyingPeriod.participations.filter(p => p.endDate == null) personsReachables:
.map(p => p.person), window.accompanyingCourseWork.accompanyingPeriod.participations
.filter((p) => p.endDate == null)
.map((p) => p.person),
handlingThirdParty: window.accompanyingCourseWork.handlingThierParty, handlingThirdParty: window.accompanyingCourseWork.handlingThierParty,
thirdParties: window.accompanyingCourseWork.thirdParties, thirdParties: window.accompanyingCourseWork.thirdParties,
referrers: window.accompanyingCourseWork.referrers, referrers: window.accompanyingCourseWork.referrers,
isPosting: false, isPosting: false,
errors: [], errors: [],
me: null, me: null,
version: window.accompanyingCourseWork.version version: window.accompanyingCourseWork.version,
}, },
getters: { getters: {
socialAction(state) { socialAction(state) {
@ -47,12 +62,12 @@ const store = createStore({
return state.resultsForAction.length > 0; return state.resultsForAction.length > 0;
}, },
resultsForGoal: (state) => (goal) => { resultsForGoal: (state) => (goal) => {
let founds = state.resultsForGoal.filter(r => r.goalId === goal.id); let founds = state.resultsForGoal.filter((r) => r.goalId === goal.id);
return founds === undefined ? [] : founds; return founds === undefined ? [] : founds;
}, },
resultsPickedForGoal: (state) => (goal) => { resultsPickedForGoal: (state) => (goal) => {
let found = state.goalsPicked.find(g => g.goal.id === goal.id); let found = state.goalsPicked.find((g) => g.goal.id === goal.id);
return found === undefined ? [] : found.results; return found === undefined ? [] : found.results;
}, },
@ -74,26 +89,38 @@ const store = createStore({
}, },
buildPayload(state) { buildPayload(state) {
return { return {
type: 'accompanying_period_work', type: "accompanying_period_work",
id: state.work.id, id: state.work.id,
version: state.version, version: state.version,
startDate: state.startDate === null || state.startDate === '' ? null : { startDate:
datetime: datetimeToISO(ISOToDate(state.startDate)) state.startDate === null || state.startDate === ""
? null
: {
datetime: datetimeToISO(ISOToDate(state.startDate)),
}, },
endDate: state.endDate === null || state.endDate === '' ? null : { endDate:
datetime: datetimeToISO(ISOToDate(state.endDate)) state.endDate === null || state.endDate === ""
? null
: {
datetime: datetimeToISO(ISOToDate(state.endDate)),
}, },
note: state.note, note: state.note,
privateComment: state.privateComment, privateComment: state.privateComment,
persons: state.personsPicked.map(p => ({id: p.id, type: p.type})), persons: state.personsPicked.map((p) => ({ id: p.id, type: p.type })),
handlingThierParty: state.handlingThirdParty === null ? null : { handlingThierParty:
state.handlingThirdParty === null
? null
: {
id: state.handlingThirdParty.id, id: state.handlingThirdParty.id,
type: state.handlingThirdParty.type type: state.handlingThirdParty.type,
}, },
results: state.resultsPicked.map(r => ({id: r.id, type: r.type})), results: state.resultsPicked.map((r) => ({ id: r.id, type: r.type })),
thirdParties: state.thirdParties.map(t => ({id: t.id, type: t.type})), thirdParties: state.thirdParties.map((t) => ({
referrers: state.referrers.map(t => ({id: t.id, type: t.type})), id: t.id,
goals: state.goalsPicked.map(g => { type: t.type,
})),
referrers: state.referrers.map((t) => ({ id: t.id, type: t.type })),
goals: state.goalsPicked.map((g) => {
let o = { let o = {
type: g.type, type: g.type,
note: g.note, note: g.note,
@ -101,37 +128,46 @@ const store = createStore({
type: g.goal.type, type: g.goal.type,
id: g.goal.id, id: g.goal.id,
}, },
results: g.results.map(r => ({id: r.id, type: r.type})), results: g.results.map((r) => ({ id: r.id, type: r.type })),
}; };
if (g.id !== undefined) { if (g.id !== undefined) {
o.id = g.id; o.id = g.id;
} }
return o; return o;
}), }),
accompanyingPeriodWorkEvaluations: state.evaluationsPicked.map(e => { accompanyingPeriodWorkEvaluations: state.evaluationsPicked.map((e) => {
let o = { let o = {
type: e.type, type: e.type,
key: e.key, key: e.key,
evaluation: { evaluation: {
id: e.evaluation.id, id: e.evaluation.id,
type: e.evaluation.type type: e.evaluation.type,
}, },
startDate: e.startDate === null || e.startDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.startDate)) }, startDate:
endDate: e.endDate === null || e.endDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.endDate)) }, e.startDate === null || e.startDate === ""
maxDate: e.maxDate === null || e.maxDate === '' ? null : { datetime: datetimeToISO(ISOToDate(e.maxDate)) }, ? null
: { datetime: datetimeToISO(ISOToDate(e.startDate)) },
endDate:
e.endDate === null || e.endDate === ""
? null
: { datetime: datetimeToISO(ISOToDate(e.endDate)) },
maxDate:
e.maxDate === null || e.maxDate === ""
? null
: { datetime: datetimeToISO(ISOToDate(e.maxDate)) },
warningInterval: intervalDaysToISO(e.warningInterval), warningInterval: intervalDaysToISO(e.warningInterval),
timeSpent: e.timeSpent, timeSpent: e.timeSpent,
comment: e.comment, comment: e.comment,
documents: e.documents documents: e.documents,
}; };
if (e.id !== undefined) { if (e.id !== undefined) {
o.id = e.id; o.id = e.id;
} }
return o; return o;
}) }),
}; };
} },
}, },
mutations: { mutations: {
setWhoAmiI(state, me) { setWhoAmiI(state, me) {
@ -142,14 +178,22 @@ const store = createStore({
var k = Object.assign(e, { var k = Object.assign(e, {
key: index, key: index,
editEvaluation: false, editEvaluation: false,
startDate: e.startDate !== null ? dateToISO(new Date(e.startDate.datetime)) : null, startDate:
endDate: e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null, e.startDate !== null
maxDate: e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null, ? dateToISO(new Date(e.startDate.datetime))
warningInterval: e.warningInterval !== null ? intervalISOToDays(e.warningInterval) : null, : null,
endDate:
e.endDate !== null ? dateToISO(new Date(e.endDate.datetime)) : null,
maxDate:
e.maxDate !== null ? dateToISO(new Date(e.maxDate.datetime)) : null,
warningInterval:
e.warningInterval !== null
? intervalISOToDays(e.warningInterval)
: null,
timeSpent: e.timeSpent !== null ? e.timeSpent : null, timeSpent: e.timeSpent !== null ? e.timeSpent : null,
documents: e.documents.map((d, docIndex) => { documents: e.documents.map((d, docIndex) => {
return Object.assign(d, { return Object.assign(d, {
key: docIndex key: docIndex,
}); });
}), }),
}); });
@ -181,28 +225,30 @@ const store = createStore({
state.resultsPicked.push(result); state.resultsPicked.push(result);
}, },
removeResultPicked(state, result) { removeResultPicked(state, result) {
state.resultsPicked = state.resultsPicked.filter(r => r.id !== result.id); state.resultsPicked = state.resultsPicked.filter(
(r) => r.id !== result.id,
);
}, },
addGoal(state, goal) { addGoal(state, goal) {
let g = { let g = {
type: "accompanying_period_work_goal", type: "accompanying_period_work_goal",
goal: goal, goal: goal,
note: '', note: "",
results: [] results: [],
}
const tmpIndex = () => {
let ar = state.goalsPicked.map(g => g.id),
s = Math.min(...ar);
return (s < 0) ? s : 0
}; };
g.id = tmpIndex() -1 const tmpIndex = () => {
let ar = state.goalsPicked.map((g) => g.id),
s = Math.min(...ar);
return s < 0 ? s : 0;
};
g.id = tmpIndex() - 1;
state.goalsPicked.push(g); state.goalsPicked.push(g);
}, },
removeGoal(state, goal) { removeGoal(state, goal) {
state.goalsPicked = state.goalsPicked.filter(g => g.id !== goal.id); state.goalsPicked = state.goalsPicked.filter((g) => g.id !== goal.id);
}, },
addResultForGoalPicked(state, { goal, result }) { addResultForGoalPicked(state, { goal, result }) {
let found = state.goalsPicked.find(g => g.goal.id === goal.id); let found = state.goalsPicked.find((g) => g.goal.id === goal.id);
if (found === undefined) { if (found === undefined) {
return; return;
@ -211,39 +257,48 @@ const store = createStore({
found.results.push(result); found.results.push(result);
}, },
removeResultForGoalPicked(state, { goal, result }) { removeResultForGoalPicked(state, { goal, result }) {
let found = state.goalsPicked.find(g => g.goal.id === goal.id); let found = state.goalsPicked.find((g) => g.goal.id === goal.id);
if (found === undefined) { if (found === undefined) {
return; return;
} }
found.results = found.results.filter(r => r.id !== result.id); found.results = found.results.filter((r) => r.id !== result.id);
}, },
addDocument(state, payload) { addDocument(state, payload) {
// associate version to stored object // associate version to stored object
payload.document.storedObject.currentVersion = payload.stored_object_version; payload.document.storedObject.currentVersion =
payload.stored_object_version;
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key); let evaluation = state.evaluationsPicked.find(
(e) => e.key === payload.key,
);
evaluation.documents.push(Object.assign( evaluation.documents.push(
payload.document, { Object.assign(payload.document, {
key: evaluation.documents.length + 1, key: evaluation.documents.length + 1,
workflows_availables: state.work.workflows_availables_evaluation_documents, workflows_availables:
state.work.workflows_availables_evaluation_documents,
workflows: [], workflows: [],
})); }),
);
}, },
removeDocument(state, { key, document }) { removeDocument(state, { key, document }) {
let evaluation = state.evaluationsPicked.find(e => e.key === key); let evaluation = state.evaluationsPicked.find((e) => e.key === key);
if (evaluation === undefined) { if (evaluation === undefined) {
return; return;
} }
evaluation.documents = evaluation.documents.filter(d => d.key !== document.key); evaluation.documents = evaluation.documents.filter(
(d) => d.key !== document.key,
);
}, },
addDuplicatedDocument(state, { document, evaluation_key }) { addDuplicatedDocument(state, { document, evaluation_key }) {
console.log('add duplicated document', document); console.log("add duplicated document", document);
console.log('add duplicated dcuemnt - evaluation key', evaluation_key); console.log("add duplicated dcuemnt - evaluation key", evaluation_key);
let evaluation = state.evaluationsPicked.find(e => e.key === evaluation_key); let evaluation = state.evaluationsPicked.find(
(e) => e.key === evaluation_key,
);
document.key = evaluation.documents.length + 1; document.key = evaluation.documents.length + 1;
evaluation.documents.splice(0, 0, document); evaluation.documents.splice(0, 0, document);
}, },
@ -255,28 +310,33 @@ const store = createStore({
* @return {void} - returns nothing. * @return {void} - returns nothing.
*/ */
replaceDocument(state, payload) { replaceDocument(state, payload) {
let evaluation = state.evaluationsPicked.find(e => e.key === payload.key); let evaluation = state.evaluationsPicked.find(
(e) => e.key === payload.key,
);
if (evaluation === undefined) { if (evaluation === undefined) {
return; return;
} }
let doc = evaluation.documents.find(d => d.key === payload.oldDocument.key); let doc = evaluation.documents.find(
(d) => d.key === payload.oldDocument.key,
);
if (typeof doc === 'undefined') { if (typeof doc === "undefined") {
console.error('doc not found'); console.error("doc not found");
return; return;
} }
doc.storedObject.currentVersion = payload.stored_object_version; doc.storedObject.currentVersion = payload.stored_object_version;
return; return;
let newDocument = Object.assign( let newDocument = Object.assign(payload.document, {
payload.document, {
key: evaluation.documents.length + 1, key: evaluation.documents.length + 1,
workflows_availables: state.work.workflows_availables_evaluation_documents, workflows_availables:
state.work.workflows_availables_evaluation_documents,
workflows: [], workflows: [],
} });
evaluation.documents = evaluation.documents.map((d) =>
d.id === payload.oldDocument.id ? newDocument : d,
); );
evaluation.documents = evaluation.documents.map(d => d.id === payload.oldDocument.id ? newDocument : d);
}, },
addEvaluation(state, evaluation) { addEvaluation(state, evaluation) {
let e = { let e = {
@ -297,35 +357,31 @@ const store = createStore({
state.evaluationsPicked.push(e); state.evaluationsPicked.push(e);
}, },
removeEvaluation(state, evaluation) { removeEvaluation(state, evaluation) {
state.evaluationsPicked = state.evaluationsPicked.filter(e => e.key !== evaluation.key); state.evaluationsPicked = state.evaluationsPicked.filter(
(e) => e.key !== evaluation.key,
);
}, },
setEvaluationStartDate(state, { key, date }) { setEvaluationStartDate(state, { key, date }) {
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).startDate = date;
.startDate = date;
}, },
setEvaluationEndDate(state, { key, date }) { setEvaluationEndDate(state, { key, date }) {
console.log('commit date', date) console.log("commit date", date);
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).endDate = date;
.endDate = date;
}, },
setEvaluationMaxDate(state, { key, date }) { setEvaluationMaxDate(state, { key, date }) {
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).maxDate = date;
.maxDate = date;
}, },
setEvaluationWarningInterval(state, { key, days }) { setEvaluationWarningInterval(state, { key, days }) {
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).warningInterval = days;
.warningInterval = days;
}, },
setEvaluationTimeSpent(state, { key, time }) { setEvaluationTimeSpent(state, { key, time }) {
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).timeSpent = time;
.timeSpent = time;
}, },
setEvaluationComment(state, { key, comment }) { setEvaluationComment(state, { key, comment }) {
state.evaluationsPicked.find(e => e.key === key) state.evaluationsPicked.find((e) => e.key === key).comment = comment;
.comment = comment;
}, },
toggleEvaluationEdit(state, { key }) { toggleEvaluationEdit(state, { key }) {
let evaluation = state.evaluationsPicked.find(e => e.key === key); let evaluation = state.evaluationsPicked.find((e) => e.key === key);
evaluation.editEvaluation = !evaluation.editEvaluation; evaluation.editEvaluation = !evaluation.editEvaluation;
}, },
setTemplatesForEvaluation(state, { templates, evaluation }) { setTemplatesForEvaluation(state, { templates, evaluation }) {
@ -335,8 +391,9 @@ const store = createStore({
state.templatesAvailablesForAction = templates; state.templatesAvailablesForAction = templates;
}, },
setPersonsPickedIds(state, ids) { setPersonsPickedIds(state, ids) {
state.personsPicked = state.personsReachables state.personsPicked = state.personsReachables.filter((p) =>
.filter(p => ids.includes(p.id)) ids.includes(p.id),
);
}, },
setNote(state, note) { setNote(state, note) {
state.note = note; state.note = note;
@ -349,8 +406,8 @@ const store = createStore({
}, },
addThirdParties(state, thirdParties) { addThirdParties(state, thirdParties) {
// filter to remove existing thirdparties // filter to remove existing thirdparties
let ids = state.thirdParties.map(t => t.id); let ids = state.thirdParties.map((t) => t.id);
let unexistings = thirdParties.filter(t => !ids.includes(t.id)); let unexistings = thirdParties.filter((t) => !ids.includes(t.id));
for (let i in unexistings) { for (let i in unexistings) {
state.thirdParties.push(unexistings[i]); state.thirdParties.push(unexistings[i]);
@ -359,26 +416,28 @@ const store = createStore({
updateThirdParty(state, thirdParty) { updateThirdParty(state, thirdParty) {
for (let t of state.thirdParties) { for (let t of state.thirdParties) {
if (t.id === thirdParty.id) { if (t.id === thirdParty.id) {
state.thirdParties = state.thirdParties.filter(t => t.id !== thirdParty.id); state.thirdParties = state.thirdParties.filter(
(t) => t.id !== thirdParty.id,
);
state.thirdParties.push(thirdParty); state.thirdParties.push(thirdParty);
} }
} }
}, },
removeThirdParty(state, thirdParty) { removeThirdParty(state, thirdParty) {
state.thirdParties = state.thirdParties state.thirdParties = state.thirdParties.filter(
.filter(t => t.id !== thirdParty.id); (t) => t.id !== thirdParty.id,
);
}, },
addReferrers(state, referrers) { addReferrers(state, referrers) {
let ids = state.referrers.map(t => t.id); let ids = state.referrers.map((t) => t.id);
let unexistings = referrers.filter(t => !ids.includes(t.id)); let unexistings = referrers.filter((t) => !ids.includes(t.id));
for (let i in unexistings) { for (let i in unexistings) {
state.referrers.push(unexistings[i]); state.referrers.push(unexistings[i]);
} }
}, },
removeReferrer(state, user) { removeReferrer(state, user) {
state.referrers = state.referrers state.referrers = state.referrers.filter((u) => u.id !== user.id);
.filter(u => u.id !== user.id);
}, },
setErrors(state, errors) { setErrors(state, errors) {
state.errors = errors; state.errors = errors;
@ -388,22 +447,24 @@ const store = createStore({
}, },
updateDocumentTitle(state, payload) { updateDocumentTitle(state, payload) {
if (payload.id === 0) { if (payload.id === 0) {
state.evaluationsPicked.find(e => e.key === payload.evaluationKey) state.evaluationsPicked
.documents.find(d => d.key === payload.key).title = payload.title; .find((e) => e.key === payload.evaluationKey)
.documents.find((d) => d.key === payload.key).title = payload.title;
} else { } else {
state.evaluationsPicked.find(e => e.key === payload.evaluationKey) state.evaluationsPicked
.documents.find(d => d.id === payload.id).title = payload.title; .find((e) => e.key === payload.evaluationKey)
.documents.find((d) => d.id === payload.id).title = payload.title;
} }
}, },
statusDocumentChanged(state, { newStatus, key }) { statusDocumentChanged(state, { newStatus, key }) {
const e = state.evaluationsPicked.find(e => e.key === key); const e = state.evaluationsPicked.find((e) => e.key === key);
if (typeof e === 'undefined') { if (typeof e === "undefined") {
console.error('evaluation not found for given key', {key}); console.error("evaluation not found for given key", { key });
} }
const doc = e.documents.find(d => d.storedObject?.id === newStatus.id); const doc = e.documents.find((d) => d.storedObject?.id === newStatus.id);
if (typeof doc === 'undefined') { if (typeof doc === "undefined") {
console.error('document not found', {newStatus}); console.error("document not found", { newStatus });
} }
doc.storedObject.status = newStatus.status; doc.storedObject.status = newStatus.status;
@ -414,164 +475,188 @@ const store = createStore({
actions: { actions: {
getWhoAmI({ commit }) { getWhoAmI({ commit }) {
let url = `/api/1.0/main/whoami.json`; let url = `/api/1.0/main/whoami.json`;
window.fetch(url) window
.then(response => { .fetch(url)
.then((response) => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'Error while retriving results for goal', s: response.status, b: response.body }; throw {
m: "Error while retriving results for goal",
s: response.status,
b: response.body,
};
}) })
.then(data => { .then((data) => {
commit('setWhoAmiI', data); commit("setWhoAmiI", data);
}); });
}, },
updateThirdParty({ commit }, payload) { updateThirdParty({ commit }, payload) {
commit('updateThirdParty', payload); commit("updateThirdParty", payload);
}, },
getReachablesGoalsForAction({ getters, commit, dispatch }) { getReachablesGoalsForAction({ getters, commit, dispatch }) {
let let socialActionId = getters.socialAction.id,
socialActionId = getters.socialAction.id, url = `/api/1.0/person/social-work/goal/by-social-action/${socialActionId}.json`;
url = `/api/1.0/person/social-work/goal/by-social-action/${socialActionId}.json`
;
window window
.fetch( .fetch(url)
url .then((response) => {
).then( response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'Error while retriving goal for social action', s: response.status, b: response.body }; throw {
}).then( data => { m: "Error while retriving goal for social action",
s: response.status,
b: response.body,
};
})
.then((data) => {
for (let i in data.results) { for (let i in data.results) {
dispatch('getReachablesResultsForGoal', data.results[i]); dispatch("getReachablesResultsForGoal", data.results[i]);
} }
}).catch( errors => { })
commit('addErrors', errors); .catch((errors) => {
commit("addErrors", errors);
}); });
}, },
getReachablesResultsForGoal({ commit }, goal) { getReachablesResultsForGoal({ commit }, goal) {
let let url = `/api/1.0/person/social-work/result/by-goal/${goal.id}.json`;
url = `/api/1.0/person/social-work/result/by-goal/${goal.id}.json` window
; .fetch(url)
window.fetch(url) .then((response) => {
.then(response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'Error while retriving results for goal', s: response.status, b: response.body }; throw {
m: "Error while retriving results for goal",
s: response.status,
b: response.body,
};
}) })
.then(data => { .then((data) => {
commit('setResultsForGoal', { goal, results: data.results }); commit("setResultsForGoal", { goal, results: data.results });
}); });
}, },
getReachablesResultsForAction({ getters, commit }) { getReachablesResultsForAction({ getters, commit }) {
let let socialActionId = getters.socialAction.id,
socialActionId = getters.socialAction.id, url = `/api/1.0/person/social-work/result/by-social-action/${socialActionId}.json`;
url = `/api/1.0/person/social-work/result/by-social-action/${socialActionId}.json` window
; .fetch(url)
window.fetch(url) .then((response) => {
.then(response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'Error while retriving results for social action', s: response.status, b: response.body }; throw {
m: "Error while retriving results for social action",
s: response.status,
b: response.body,
};
}) })
.then(data => { .then((data) => {
commit('setResultsForAction', data.results); commit("setResultsForAction", data.results);
}); });
}, },
getReachablesEvaluationsForAction({ getters, commit }) { getReachablesEvaluationsForAction({ getters, commit }) {
let let socialActionId = getters.socialAction.id,
socialActionId = getters.socialAction.id, url = `/api/1.0/person/social-work/evaluation/by-social-action/${socialActionId}.json`;
url = `/api/1.0/person/social-work/evaluation/by-social-action/${socialActionId}.json` window
; .fetch(url)
window.fetch(url) .then((response) => {
.then(response => {
if (response.ok) { if (response.ok) {
return response.json(); return response.json();
} }
throw { m: 'Error while retriving evaluations for social action', s: response.status, b: response.body }; throw {
m: "Error while retriving evaluations for social action",
s: response.status,
b: response.body,
};
}) })
.then(data => { .then((data) => {
commit('setEvaluationsForAction', data.results); commit("setEvaluationsForAction", data.results);
}); });
}, },
addEvaluation({ commit, dispatch }, evaluation) { addEvaluation({ commit, dispatch }, evaluation) {
commit('addEvaluation', evaluation); commit("addEvaluation", evaluation);
dispatch('fetchTemplatesAvailablesForEvaluation', evaluation); dispatch("fetchTemplatesAvailablesForEvaluation", evaluation);
}, },
fetchTemplatesAvailablesForEvaluation({ commit, state }, evaluation) { fetchTemplatesAvailablesForEvaluation({ commit, state }, evaluation) {
if (!state.templatesAvailablesForEvaluation.has(evaluation.id)) { if (!state.templatesAvailablesForEvaluation.has(evaluation.id)) {
// commit an empty array to avoid parallel fetching for same evaluation id // commit an empty array to avoid parallel fetching for same evaluation id
commit('setTemplatesForEvaluation', {templates: [], evaluation}); commit("setTemplatesForEvaluation", { templates: [], evaluation });
fetchResults(`/api/1.0/person/docgen/template/by-evaluation/${evaluation.id}.json`) fetchResults(
.then(templates => { `/api/1.0/person/docgen/template/by-evaluation/${evaluation.id}.json`,
commit('setTemplatesForEvaluation', {templates, evaluation}); ).then((templates) => {
commit("setTemplatesForEvaluation", { templates, evaluation });
}); });
} }
}, },
addDocument({ commit }, payload) { addDocument({ commit }, payload) {
commit('addDocument', payload); commit("addDocument", payload);
}, },
async duplicateDocument({ commit }, { document, evaluation_key }) { async duplicateDocument({ commit }, { document, evaluation_key }) {
const newDoc = await duplicate(document.id); const newDoc = await duplicate(document.id);
commit('addDuplicatedDocument', {document: newDoc, evaluation_key}); commit("addDuplicatedDocument", { document: newDoc, evaluation_key });
}, },
removeDocument({ commit }, payload) { removeDocument({ commit }, payload) {
commit('removeDocument', payload); commit("removeDocument", payload);
}, },
replaceDocument({ commit }, payload) { replaceDocument({ commit }, payload) {
commit('replaceDocument', payload); commit("replaceDocument", payload);
}, },
submit({ getters, state, commit }, callback) { submit({ getters, state, commit }, callback) {
let let payload = getters.buildPayload,
payload = getters.buildPayload, params = new URLSearchParams({ entity_version: state.version }),
params = new URLSearchParams({'entity_version': state.version}),
url = `/api/1.0/person/accompanying-course/work/${state.work.id}.json?${params}`, url = `/api/1.0/person/accompanying-course/work/${state.work.id}.json?${params}`,
errors = [] errors = [];
; commit("setIsPosting", true);
commit('setIsPosting', true);
// console.log('the social action', payload); // console.log('the social action', payload);
return makeFetch('PUT', url, payload) return makeFetch("PUT", url, payload)
.then(data => { .then((data) => {
if (typeof(callback) !== 'undefined') { if (typeof callback !== "undefined") {
return callback(data); return callback(data);
} else { } else {
// console.log('payload', payload.privateComment) // console.log('payload', payload.privateComment)
// console.info('nothing to do here, bye bye'); // console.info('nothing to do here, bye bye');
window.location.assign(`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`); window.location.assign(
`/fr/person/accompanying-period/${state.work.accompanyingPeriod.id}/work`,
);
} }
}).catch(error => { })
console.log('error', error) .catch((error) => {
commit('setIsPosting', false); console.log("error", error);
commit("setIsPosting", false);
throw error; throw error;
}); });
}, },
updateDocumentTitle({ commit }, payload) { updateDocumentTitle({ commit }, payload) {
commit('updateDocumentTitle', payload) commit("updateDocumentTitle", payload);
} },
} },
}); });
store.commit('setEvaluationsPicked', window.accompanyingCourseWork.accompanyingPeriodWorkEvaluations); store.commit(
store.dispatch('getReachablesResultsForAction'); "setEvaluationsPicked",
store.dispatch('getReachablesGoalsForAction'); window.accompanyingCourseWork.accompanyingPeriodWorkEvaluations,
store.dispatch('getReachablesEvaluationsForAction'); );
store.dispatch('getWhoAmI'); store.dispatch("getReachablesResultsForAction");
store.dispatch("getReachablesGoalsForAction");
store.dispatch("getReachablesEvaluationsForAction");
store.dispatch("getWhoAmI");
store.state.evaluationsPicked.forEach(evaluation => { store.state.evaluationsPicked.forEach((evaluation) => {
store.dispatch('fetchTemplatesAvailablesForEvaluation', evaluation.evaluation) store.dispatch(
"fetchTemplatesAvailablesForEvaluation",
evaluation.evaluation,
);
}); });
fetchTemplates('Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork') fetchTemplates(
.then(templates => { "Chill\\PersonBundle\\Entity\\AccompanyingPeriod\\AccompanyingPeriodWork",
store.commit('setTemplatesAvailablesForAction', templates); ).then((templates) => {
} store.commit("setTemplatesAvailablesForAction", templates);
) });
export { store }; export { store };

View File

@ -1,6 +1,5 @@
<template> <template>
<div class="list-item" :class="{ checked: isChecked }"> <div class="list-item" :class="{ checked: isChecked }">
<label> <label>
<div> <div>
<input <input
@ -8,48 +7,51 @@
v-model="selected" v-model="selected"
name="item" name="item"
v-bind:id="item" v-bind:id="item"
v-bind:value="setValueByType(item, type)" /> v-bind:value="setValueByType(item, type)"
/>
</div> </div>
<suggestion-person <suggestion-person
v-if="item.result.type === 'person'" v-if="item.result.type === 'person'"
v-bind:item="item"> v-bind:item="item"
>
</suggestion-person> </suggestion-person>
<suggestion-third-party <suggestion-third-party
v-if="item.result.type === 'thirdparty'" v-if="item.result.type === 'thirdparty'"
@newPriorSuggestion="newPriorSuggestion" @newPriorSuggestion="newPriorSuggestion"
v-bind:item="item"> v-bind:item="item"
>
</suggestion-third-party> </suggestion-third-party>
<suggestion-user <suggestion-user v-if="item.result.type === 'user'" v-bind:item="item">
v-if="item.result.type === 'user'"
v-bind:item="item">
</suggestion-user> </suggestion-user>
<suggestion-user-group <suggestion-user-group
v-if="item.result.type === 'user_group'" v-if="item.result.type === 'user_group'"
v-bind:item="item"> v-bind:item="item"
></suggestion-user-group> >
></suggestion-user-group
>
<suggestion-household <suggestion-household
v-if="item.result.type === 'household'" v-if="item.result.type === 'household'"
v-bind:item="item"> v-bind:item="item"
>
</suggestion-household> </suggestion-household>
</label> </label>
</div> </div>
</template> </template>
<script> <script>
import SuggestionPerson from './TypePerson'; import SuggestionPerson from "./TypePerson";
import SuggestionThirdParty from './TypeThirdParty'; import SuggestionThirdParty from "./TypeThirdParty";
import SuggestionUser from './TypeUser'; import SuggestionUser from "./TypeUser";
import SuggestionHousehold from './TypeHousehold'; import SuggestionHousehold from "./TypeHousehold";
import SuggestionUserGroup from './TypeUserGroup'; import SuggestionUserGroup from "./TypeUserGroup";
export default { export default {
name: 'PersonSuggestion', name: "PersonSuggestion",
components: { components: {
SuggestionPerson, SuggestionPerson,
SuggestionThirdParty, SuggestionThirdParty,
@ -57,34 +59,30 @@ export default {
SuggestionHousehold, SuggestionHousehold,
SuggestionUserGroup, SuggestionUserGroup,
}, },
props: [ props: ["item", "search", "type"],
'item', emits: ["updateSelected", "newPriorSuggestion"],
'search',
'type'
],
emits: ['updateSelected', 'newPriorSuggestion'],
computed: { computed: {
selected: { selected: {
set(value) { set(value) {
//console.log('value', value); //console.log('value', value);
this.$emit('updateSelected', value); this.$emit("updateSelected", value);
}, },
get() { get() {
return this.search.selected; return this.search.selected;
} },
}, },
isChecked() { isChecked() {
return (this.search.selected.indexOf(this.item) === -1) ? false : true; return this.search.selected.indexOf(this.item) === -1 ? false : true;
}, },
}, },
methods: { methods: {
setValueByType(value, type) { setValueByType(value, type) {
return (type === 'radio')? [value] : value; return type === "radio" ? [value] : value;
}, },
newPriorSuggestion(response) { newPriorSuggestion(response) {
this.$emit('newPriorSuggestion', response) this.$emit("newPriorSuggestion", response);
} },
} },
}; };
</script> </script>

View File

@ -1,6 +1,8 @@
<script setup lang="ts"> <script setup lang="ts">
import {
import {ResultItem, UserGroup} from "../../../../../../ChillMainBundle/Resources/public/types"; ResultItem,
UserGroup,
} from "../../../../../../ChillMainBundle/Resources/public/types";
import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue"; import BadgeEntity from "ChillMainAssets/vuejs/_components/BadgeEntity.vue";
import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue"; import UserRenderBoxBadge from "ChillMainAssets/vuejs/_components/Entity/UserRenderBoxBadge.vue";
import UserGroupRenderBox from "ChillMainAssets/vuejs/_components/Entity/UserGroupRenderBox.vue"; import UserGroupRenderBox from "ChillMainAssets/vuejs/_components/Entity/UserGroupRenderBox.vue";
@ -15,16 +17,14 @@ const props = defineProps<TypeUserGroupProps>();
<template> <template>
<div class="container user-group-container"> <div class="container user-group-container">
<div class="user-group-identification"> <div class="user-group-identification">
<user-group-render-box :user-group="props.item.result"></user-group-render-box> <user-group-render-box
:user-group="props.item.result"
></user-group-render-box>
</div> </div>
</div> </div>
<div class="right_actions"> <div class="right_actions">
<span class="badge rounded-pill bg-user-group"> <span class="badge rounded-pill bg-user-group"> Groupe d'utilisateur </span>
Groupe d'utilisateur
</span>
</div> </div>
</template> </template>
<style scoped lang="scss"> <style scoped lang="scss"></style>
</style>

View File

@ -1,7 +1,8 @@
<template> <template>
<div v-if="action === 'show'"> <div v-if="action === 'show'">
<div class="flex-table"> <div class="flex-table">
<person-render-box render="bloc" <person-render-box
render="bloc"
:person="person" :person="person"
:options="{ :options="{
addInfo: true, addInfo: true,
@ -13,7 +14,7 @@
hLevel: 3, hLevel: 3,
addCenter: true, addCenter: true,
addNoData: true, addNoData: true,
isMultiline: true isMultiline: true,
}" }"
:show-residential-addresses="true" :show-residential-addresses="true"
></person-render-box> ></person-render-box>
@ -21,7 +22,6 @@
</div> </div>
<div v-else-if="action === 'edit' || action === 'create'"> <div v-else-if="action === 'edit' || action === 'create'">
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
@ -30,12 +30,16 @@
:placeholder="$t('person.lastname')" :placeholder="$t('person.lastname')"
@change="checkErrors" @change="checkErrors"
/> />
<label for="lastname">{{ $t('person.lastname') }}</label> <label for="lastname">{{ $t("person.lastname") }}</label>
</div> </div>
<div v-if="queryItems"> <div v-if="queryItems">
<ul class="list-suggest add-items inline"> <ul class="list-suggest add-items inline">
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('lastName', qi)"> <li
v-for="(qi, i) in queryItems"
:key="i"
@click="addQueryItem('lastName', qi)"
>
<span class="person-text">{{ qi }}</span> <span class="person-text">{{ qi }}</span>
</li> </li>
</ul> </ul>
@ -49,18 +53,26 @@
:placeholder="$t('person.firstname')" :placeholder="$t('person.firstname')"
@change="checkErrors" @change="checkErrors"
/> />
<label for="firstname">{{ $t('person.firstname') }}</label> <label for="firstname">{{ $t("person.firstname") }}</label>
</div> </div>
<div v-if="queryItems"> <div v-if="queryItems">
<ul class="list-suggest add-items inline"> <ul class="list-suggest add-items inline">
<li v-for="(qi, i) in queryItems" :key="i" @click="addQueryItem('firstName', qi)"> <li
v-for="(qi, i) in queryItems"
:key="i"
@click="addQueryItem('firstName', qi)"
>
<span class="person-text">{{ qi }}</span> <span class="person-text">{{ qi }}</span>
</li> </li>
</ul> </ul>
</div> </div>
<div v-for="(a, i) in config.altNames" :key="a.key" class="form-floating mb-3"> <div
v-for="(a, i) in config.altNames"
:key="a.key"
class="form-floating mb-3"
>
<input <input
class="form-control form-control-lg" class="form-control form-control-lg"
:id="a.key" :id="a.key"
@ -73,29 +85,26 @@
<!-- TODO fix placeholder if undefined <!-- TODO fix placeholder if undefined
--> -->
<div class="form-floating mb-3"> <div class="form-floating mb-3">
<select <select class="form-select form-select-lg" id="gender" v-model="gender">
class="form-select form-select-lg" <option selected disabled>{{ $t("person.gender.placeholder") }}</option>
id="gender"
v-model="gender"
>
<option selected disabled >{{ $t('person.gender.placeholder') }}</option>
<option v-for="g in config.genders" :value="g.id" :key="g.id"> <option v-for="g in config.genders" :value="g.id" :key="g.id">
{{ g.label }} {{ g.label }}
</option> </option>
</select> </select>
<label>{{ $t('person.gender.title') }}</label> <label>{{ $t("person.gender.title") }}</label>
</div> </div>
<div class="form-floating mb-3" v-if="showCenters && config.centers.length > 1"> <div
<select class="form-floating mb-3"
class="form-select form-select-lg" v-if="showCenters && config.centers.length > 1"
id="center"
v-model="center"
> >
<option selected disabled>{{ $t('person.center.placeholder') }}</option> <select class="form-select form-select-lg" id="center" v-model="center">
<option v-for="c in config.centers" :value="c" :key="c.id" >{{ c.name }}</option> <option selected disabled>{{ $t("person.center.placeholder") }}</option>
<option v-for="c in config.centers" :value="c" :key="c.id">
{{ c.name }}
</option>
</select> </select>
<label>{{ $t('person.center.title') }}</label> <label>{{ $t("person.center.title") }}</label>
</div> </div>
<div class="form-floating mb-3"> <div class="form-floating mb-3">
@ -104,97 +113,127 @@
id="civility" id="civility"
v-model="civility" v-model="civility"
> >
<option selected disabled >{{ $t('person.civility.placeholder') }}</option> <option selected disabled>
{{ $t("person.civility.placeholder") }}
</option>
<option v-for="c in config.civilities" :value="c.id" :key="c.id"> <option v-for="c in config.civilities" :value="c.id" :key="c.id">
{{ c.name.fr }} {{ c.name.fr }}
</option> </option>
</select> </select>
<label>{{ $t('person.civility.title') }}</label> <label>{{ $t("person.civility.title") }}</label>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-text" id="birthdate"><i class="fa fa-fw fa-birthday-cake"></i></span> <span class="input-group-text" id="birthdate"
<input type="date" ><i class="fa fa-fw fa-birthday-cake"></i
></span>
<input
type="date"
class="form-control form-control-lg" class="form-control form-control-lg"
id="chill_personbundle_person_birthdate" id="chill_personbundle_person_birthdate"
name="chill_personbundle_person[birthdate]" name="chill_personbundle_person[birthdate]"
v-model="birthDate" v-model="birthDate"
aria-describedby="birthdate" /> aria-describedby="birthdate"
/>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-text" id="phonenumber"><i class="fa fa-fw fa-phone"></i></span> <span class="input-group-text" id="phonenumber"
<input class="form-control form-control-lg" ><i class="fa fa-fw fa-phone"></i
></span>
<input
class="form-control form-control-lg"
v-model="phonenumber" v-model="phonenumber"
:placeholder="$t('person.phonenumber')" :placeholder="$t('person.phonenumber')"
:aria-label="$t('person.phonenumber')" :aria-label="$t('person.phonenumber')"
aria-describedby="phonenumber" /> aria-describedby="phonenumber"
/>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-text" id="mobilenumber"><i class="fa fa-fw fa-mobile"></i></span> <span class="input-group-text" id="mobilenumber"
<input class="form-control form-control-lg" ><i class="fa fa-fw fa-mobile"></i
></span>
<input
class="form-control form-control-lg"
v-model="mobilenumber" v-model="mobilenumber"
:placeholder="$t('person.mobilenumber')" :placeholder="$t('person.mobilenumber')"
:aria-label="$t('person.mobilenumber')" :aria-label="$t('person.mobilenumber')"
aria-describedby="mobilenumber" /> aria-describedby="mobilenumber"
/>
</div> </div>
<div class="input-group mb-3"> <div class="input-group mb-3">
<span class="input-group-text" id="email"><i class="fa fa-fw fa-at"></i></span> <span class="input-group-text" id="email"
<input class="form-control form-control-lg" ><i class="fa fa-fw fa-at"></i
></span>
<input
class="form-control form-control-lg"
v-model="email" v-model="email"
:placeholder="$t('person.email')" :placeholder="$t('person.email')"
:aria-label="$t('person.email')" :aria-label="$t('person.email')"
aria-describedby="email" /> aria-describedby="email"
/>
</div> </div>
<div v-if="action === 'create'" class="input-group mb-3 form-check"> <div v-if="action === 'create'" class="input-group mb-3 form-check">
<input class="form-check-input" <input
type='checkbox' class="form-check-input"
type="checkbox"
v-model="showAddressForm" v-model="showAddressForm"
name='showAddressForm'/> name="showAddressForm"
<label class="form-check-label">{{ $t('person.address.show_address_form') }}</label> />
<label class="form-check-label">{{
$t("person.address.show_address_form")
}}</label>
</div> </div>
<div v-if="action === 'create' && showAddressFormValue" class="form-floating mb-3"> <div
<p>{{ $t('person.address.warning') }}</p> v-if="action === 'create' && showAddressFormValue"
class="form-floating mb-3"
>
<p>{{ $t("person.address.warning") }}</p>
<add-address <add-address
:context="addAddress.context" :context="addAddress.context"
:options="addAddress.options" :options="addAddress.options"
:addressChangedCallback="submitNewAddress" :addressChangedCallback="submitNewAddress"
ref="addAddress"> ref="addAddress"
>
</add-address> </add-address>
</div> </div>
<div class="alert alert-warning" v-if="errors.length"> <div class="alert alert-warning" v-if="errors.length">
<ul> <ul>
<li v-for="(e, i) in errors" :key="i">{{ e }}</li> <li v-for="(e, i) in errors" :key="i">{{ e }}</li>
</ul> </ul>
</div> </div>
</div> </div>
</template> </template>
<script> <script>
import { getCentersForPersonCreation, getCivilities, getGenders, getPerson, getPersonAltNames } from '../../_api/OnTheFly'; import {
import PersonRenderBox from '../Entity/PersonRenderBox.vue'; getCentersForPersonCreation,
getCivilities,
getGenders,
getPerson,
getPersonAltNames,
} from "../../_api/OnTheFly";
import PersonRenderBox from "../Entity/PersonRenderBox.vue";
import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue"; import AddAddress from "ChillMainAssets/vuejs/Address/components/AddAddress.vue";
export default { export default {
name: "OnTheFlyPerson", name: "OnTheFlyPerson",
props: ['id', 'type', 'action', 'query'], props: ["id", "type", "action", "query"],
//emits: ['createAction'], //emits: ['createAction'],
components: { components: {
PersonRenderBox, PersonRenderBox,
AddAddress AddAddress,
}, },
data() { data() {
return { return {
person: { person: {
type: 'person', type: "person",
lastName: '', lastName: "",
firstName: '', firstName: "",
altNames: [], altNames: [],
addressId: null, addressId: null,
center: null, center: null,
@ -203,46 +242,60 @@ export default {
altNames: [], altNames: [],
civilities: [], civilities: [],
centers: [], centers: [],
genders: [] genders: [],
}, },
showCenters: false, // NOTE: must remains false if the form is not in create mode showCenters: false, // NOTE: must remains false if the form is not in create mode
showAddressFormValue: false, showAddressFormValue: false,
addAddress: { addAddress: {
options: { options: {
button: { button: {
text: { create: 'person.address.create_address' }, text: { create: "person.address.create_address" },
size: 'btn-sm' size: "btn-sm",
}, },
title: { create: 'person.address.create_address' }, title: { create: "person.address.create_address" },
}, },
context: { context: {
target: {}, // boilerplate for getting the address id target: {}, // boilerplate for getting the address id
edit: false, edit: false,
addressId: null, addressId: null,
defaults: window.addaddress defaults: window.addaddress,
}
}, },
errors: [] },
} errors: [],
};
}, },
computed: { computed: {
firstName: { firstName: {
set(value) { set(value) {
this.person.firstName = value; this.person.firstName = value;
}, },
get() { return this.person.firstName; } get() {
return this.person.firstName;
},
}, },
lastName: { lastName: {
set(value) { this.person.lastName = value; }, set(value) {
get() { return this.person.lastName; } this.person.lastName = value;
},
get() {
return this.person.lastName;
},
}, },
gender: { gender: {
set(value) { this.person.gender = {id: value, type: 'chill_main_gender'}; }, set(value) {
get() { return this.person.gender ? this.person.gender.id : null; } this.person.gender = { id: value, type: "chill_main_gender" };
},
get() {
return this.person.gender ? this.person.gender.id : null;
},
}, },
civility: { civility: {
set(value) { this.person.civility = {id: value, type: 'chill_main_civility'}; }, set(value) {
get() { return this.person.civility ? this.person.civility.id : null; } this.person.civility = { id: value, type: "chill_main_civility" };
},
get() {
return this.person.civility ? this.person.civility.id : null;
},
}, },
birthDate: { birthDate: {
set(value) { set(value) {
@ -253,101 +306,117 @@ export default {
} }
}, },
get() { get() {
return (this.person.birthdate) ? this.person.birthdate.datetime.split('T')[0] : ''; return this.person.birthdate
} ? this.person.birthdate.datetime.split("T")[0]
: "";
},
}, },
phonenumber: { phonenumber: {
set(value) { this.person.phonenumber = value; }, set(value) {
get() { return this.person.phonenumber; } this.person.phonenumber = value;
},
get() {
return this.person.phonenumber;
},
}, },
mobilenumber: { mobilenumber: {
set(value) { this.person.mobilenumber = value; }, set(value) {
get() { return this.person.mobilenumber; } this.person.mobilenumber = value;
},
get() {
return this.person.mobilenumber;
},
}, },
email: { email: {
set(value) { this.person.email = value; }, set(value) {
get() { return this.person.email; } this.person.email = value;
},
get() {
return this.person.email;
},
}, },
showAddressForm: { showAddressForm: {
set(value) { this.showAddressFormValue = value; }, set(value) {
get() { return this.showAddressFormValue; } this.showAddressFormValue = value;
},
get() {
return this.showAddressFormValue;
},
}, },
center: { center: {
set(value) { set(value) {
console.log('will set center', value); console.log("will set center", value);
this.person.center = { id: value.id, type: value.type }; this.person.center = { id: value.id, type: value.type };
}, },
get() { get() {
const center = this.config.centers.find(c => this.person.center !== null && this.person.center.id === c.id); const center = this.config.centers.find(
(c) => this.person.center !== null && this.person.center.id === c.id,
);
console.log('center get', center); console.log("center get", center);
return typeof center === 'undefined' ? null : center; return typeof center === "undefined" ? null : center;
}, },
}, },
genderClass() { genderClass() {
switch (this.person.gender) { switch (this.person.gender) {
case 'woman': case "woman":
return 'fa-venus'; return "fa-venus";
case 'man': case "man":
return 'fa-mars'; return "fa-mars";
case 'both': case "both":
return 'fa-neuter'; return "fa-neuter";
case 'unknown': case "unknown":
return 'fa-genderless'; return "fa-genderless";
default: default:
return 'fa-genderless'; return "fa-genderless";
} }
}, },
genderTranslation() { genderTranslation() {
switch (this.person.gender.genderTranslation) { switch (this.person.gender.genderTranslation) {
case 'woman': case "woman":
return 'person.gender.woman'; return "person.gender.woman";
case 'man': case "man":
return 'person.gender.man'; return "person.gender.man";
case 'neutral': case "neutral":
return 'person.gender.neutral'; return "person.gender.neutral";
case 'unknown': case "unknown":
return 'person.gender.unknown'; return "person.gender.unknown";
default: default:
return 'person.gender.unknown'; return "person.gender.unknown";
} }
}, },
feminized() { feminized() {
return (this.person.gender === 'woman')? 'e' : ''; return this.person.gender === "woman" ? "e" : "";
}, },
personAltNamesLabels() { personAltNamesLabels() {
return this.person.altNames.map(a => a ? a.label : ''); return this.person.altNames.map((a) => (a ? a.label : ""));
}, },
queryItems() { queryItems() {
return this.query ? this.query.split(' ') : null; return this.query ? this.query.split(" ") : null;
} },
}, },
mounted() { mounted() {
getPersonAltNames() getPersonAltNames().then((altNames) => {
.then(altNames => {
this.config.altNames = altNames; this.config.altNames = altNames;
}); });
getCivilities() getCivilities().then((civilities) => {
.then(civilities => { if ("results" in civilities) {
if ('results' in civilities) {
this.config.civilities = civilities.results; this.config.civilities = civilities.results;
} }
}); });
getGenders() getGenders().then((genders) => {
.then(genders => { if ("results" in genders) {
if ('results' in genders) { console.log("genders", genders.results);
console.log('genders', genders.results)
this.config.genders = genders.results; this.config.genders = genders.results;
} }
}); });
if (this.action !== 'create') { if (this.action !== "create") {
this.loadData(); this.loadData();
} else { } else {
// console.log('show centers', this.showCenters); // console.log('show centers', this.showCenters);
getCentersForPersonCreation() getCentersForPersonCreation().then((params) => {
.then(params => { this.config.centers = params.centers.filter((c) => c.isActive);
this.config.centers = params.centers.filter(c => c.isActive);
this.showCenters = params.showCenters; this.showCenters = params.showCenters;
// console.log('centers', this.config.centers) // console.log('centers', this.config.centers)
// console.log('show centers inside', this.showCenters); // console.log('show centers inside', this.showCenters);
@ -374,37 +443,41 @@ export default {
} }
}, },
loadData() { loadData() {
getPerson(this.id) getPerson(this.id).then(
.then(person => new Promise((resolve, reject) => { (person) =>
new Promise((resolve, reject) => {
this.person = person; this.person = person;
//console.log('get person', this.person); //console.log('get person', this.person);
resolve(); resolve();
})); }),
);
}, },
onAltNameInput(event) { onAltNameInput(event) {
const key = event.target.id; const key = event.target.id;
const label = event.target.value; const label = event.target.value;
let updateAltNames = this.person.altNames.filter((a) => a.key !== key); let updateAltNames = this.person.altNames.filter((a) => a.key !== key);
updateAltNames.push( updateAltNames.push({ key: key, label: label });
{'key': key, 'label': label}
)
this.person.altNames = updateAltNames; this.person.altNames = updateAltNames;
}, },
addQueryItem(field, queryItem) { addQueryItem(field, queryItem) {
switch (field) { switch (field) {
case 'lastName': case "lastName":
this.person.lastName = this.person.lastName ? this.person.lastName += ` ${queryItem}` : queryItem; this.person.lastName = this.person.lastName
? (this.person.lastName += ` ${queryItem}`)
: queryItem;
break; break;
case 'firstName': case "firstName":
this.person.firstName = this.person.firstName ? this.person.firstName += ` ${queryItem}` : queryItem; this.person.firstName = this.person.firstName
? (this.person.firstName += ` ${queryItem}`)
: queryItem;
break; break;
} }
}, },
submitNewAddress(payload) { submitNewAddress(payload) {
this.person.addressId = payload.addressId; this.person.addressId = payload.addressId;
} },
} },
} };
</script> </script>
<style lang="scss" scoped> <style lang="scss" scoped>

View File

@ -1,6 +1,6 @@
const Encore = require('@symfony/webpack-encore'); const Encore = require("@symfony/webpack-encore");
const { resolve, parse } = require('path'); const { resolve, parse } = require("path");
const { readdir } = require('fs').promises; const { readdir } = require("fs").promises;
/** /**
* get the file names inside given directory recursively, limiting to * get the file names inside given directory recursively, limiting to
@ -23,7 +23,7 @@ async function* getFiles(dir, depth, ignored) {
yield res; yield res;
} }
} }
}; }
/** /**
* populate the config of encore in directories inside `'./src'` and * populate the config of encore in directories inside `'./src'` and
@ -41,13 +41,12 @@ async function populateConfig(Encore, chillEntries) {
// chill-main contains some bootstrap that must be loaded first. // chill-main contains some bootstrap that must be loaded first.
// we register them first and, then, store this chill.webpack.config.js file // we register them first and, then, store this chill.webpack.config.js file
// into `toIgnore`, ignoring it when we loop on other folders. // into `toIgnore`, ignoring it when we loop on other folders.
let let toIgnore = [];
toIgnore = [];
// loop into chill main // loop into chill main
for await (const f of getFiles('./src/Bundle/ChillMainBundle/', 1, [])) { for await (const f of getFiles("./src/Bundle/ChillMainBundle/", 1, [])) {
let filename = parse(f).base; let filename = parse(f).base;
if (filename === 'chill.webpack.config.js') { if (filename === "chill.webpack.config.js") {
configure = require(f); configure = require(f);
configure(Encore, chillEntries); configure(Encore, chillEntries);
toIgnore.push(f); toIgnore.push(f);
@ -55,30 +54,28 @@ async function populateConfig(Encore, chillEntries) {
} }
// loop into other chill bundles // loop into other chill bundles
for await (const f of getFiles('./src/Bundle', 2, toIgnore)) { for await (const f of getFiles("./src/Bundle", 2, toIgnore)) {
let filename = parse(f).base; let filename = parse(f).base;
if (filename === 'chill.webpack.config.js') { if (filename === "chill.webpack.config.js") {
configure = require(f); configure = require(f);
configure(Encore, chillEntries); configure(Encore, chillEntries);
} }
} }
}; }
// export the final configuration // export the final configuration
module.exports = (async () => { module.exports = (async () => {
// Manually configure the runtime environment if not already configured yet by the "encore" command. // Manually configure the runtime environment if not already configured yet by the "encore" command.
// It's useful when you use tools that rely on webpack.config.js file. // It's useful when you use tools that rely on webpack.config.js file.
if (!Encore.isRuntimeEnvironmentConfigured()) { if (!Encore.isRuntimeEnvironmentConfigured()) {
Encore.configureRuntimeEnvironment(process.env.NODE_ENV || 'dev'); Encore.configureRuntimeEnvironment(process.env.NODE_ENV || "dev");
} }
// basic encore configuration // basic encore configuration
Encore Encore.setOutputPath("public/build/")
.setOutputPath('public/build/') .setPublicPath("/build")
.setPublicPath('/build')
.enableSassLoader() .enableSassLoader()
.enableVueLoader(() => {}, { .enableVueLoader(() => {}, {
version: 3 version: 3,
}) })
.enableTypeScriptLoader(function (tsConfig) { .enableTypeScriptLoader(function (tsConfig) {
tsConfig.appendTsSuffixTo = [/\.vue$/]; tsConfig.appendTsSuffixTo = [/\.vue$/];
@ -94,7 +91,7 @@ module.exports = (async () => {
//.enableBuildNotifications() //.enableBuildNotifications()
.enableVersioning() .enableVersioning()
.enableSingleRuntimeChunk() .enableSingleRuntimeChunk()
.splitEntryChunks() .splitEntryChunks();
// added when upgrading to symfony 5.4 // added when upgrading to symfony 5.4
// enables and configure @babel/preset-env polyfills // enables and configure @babel/preset-env polyfills
//.configureBabelPresetEnv((config) => { //.configureBabelPresetEnv((config) => {
@ -102,7 +99,6 @@ module.exports = (async () => {
// config.corejs = '3.23'; // config.corejs = '3.23';
//}) //})
//.addLoader({ test: /\.pdf$/, loader: 'file-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'pdf/' } }) //.addLoader({ test: /\.pdf$/, loader: 'file-loader', options: { name: '[name]_[hash].[ext]', outputPath: 'pdf/' } })
;
// populate config with chill entries // populate config with chill entries
let chillEntries = []; let chillEntries = [];
@ -118,7 +114,7 @@ module.exports = (async () => {
if (!Encore.isProduction()) { if (!Encore.isProduction()) {
console.log(config); console.log(config);
config.devtool = 'eval-source-map'; config.devtool = "eval-source-map";
} }
return config; return config;