enable moving documents between evaluations

- Add Vuex action and mutation for moving documents between evaluations
- Implement `moveDocumentToEvaluation` API method
- Update `DocumentsList.vue` and `FormEvaluation.vue` to handle move actions
This commit is contained in:
2025-08-13 16:36:13 +02:00
parent 14dba22181
commit d508fde8d2
4 changed files with 221 additions and 236 deletions

View File

@@ -1,230 +1,174 @@
<template>
<div class="row mb-3">
<h5>{{ trans(EVALUATION_DOCUMENTS) }} :</h5>
<div class="flex-table">
<div
class="item-bloc"
v-for="(d, i) in documents"
:key="d.id"
:class="[
parseInt(docAnchorId) === d.id ? 'bg-blink' : 'nothing',
]"
>
<div :id="'document_' + d.id" class="item-row">
<div class="input-group input-group-lg mb-3 row">
<label class="col-sm-3 col-form-label"
>Titre du document:</label
>
<div class="col-sm-9">
<input
class="form-control document-title"
type="text"
:value="d.title"
:id="d.id"
:data-key="i"
@input="$emit('inputDocumentTitle', $event)"
/>
</div>
</div>
</div>
<div class="item-row">
<div class="item-col item-meta">
<p v-if="d.createdBy" class="createdBy">
Créé par {{ d.createdBy.text }}<br />
Le
{{
$d(ISOToDatetime(d.createdAt.datetime), "long")
}}
</p>
</div>
</div>
<div class="item-row">
<div class="item-col">
<ul class="record_actions">
<li
v-if="
d.workflows_availables.length > 0 ||
d.workflows.length > 0
"
>
<list-workflow-modal
:workflows="d.workflows"
:allowCreate="true"
relatedEntityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument"
:relatedEntityId="d.id"
:workflowsAvailables="
d.workflows_availables
"
:preventDefaultMoveToGenerate="true"
:goToGenerateWorkflowPayload="{ doc: d }"
@go-to-generate-workflow="
$emit('goToGenerateWorkflow', $event)
"
></list-workflow-modal>
</li>
<li>
<button
v-if="AmIRefferer"
class="btn btn-notify"
@click="
$emit(
'goToGenerateNotification',
d,
false,
)
"
></button>
<template v-else>
<button
id="btnGroupNotifyButtons"
type="button"
class="btn btn-notify dropdown-toggle"
:title="
trans(EVALUATION_NOTIFICATION_SEND)
"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</button>
<ul
class="dropdown-menu"
aria-labelledby="btnGroupNotifyButtons"
>
<li>
<a
class="dropdown-item"
@click="
$emit(
'goToGenerateNotification',
d,
true,
)
"
>
{{
trans(
EVALUATION_NOTIFICATION_NOTIFY_REFERRER,
)
}}
</a>
</li>
<li>
<a
class="dropdown-item"
@click="
$emit(
'goToGenerateNotification',
d,
false,
)
"
>
{{
trans(
EVALUATION_NOTIFICATION_NOTIFY_ANY,
)
}}
</a>
</li>
</ul>
</template>
</li>
<li>
<document-action-buttons-group
:stored-object="d.storedObject"
:filename="d.title"
:can-edit="true"
:execute-before-leave="
submitBeforeLeaveToEditor
"
:davLink="
d.storedObject._links?.dav_link.href
"
:davLinkExpiration="
d.storedObject._links?.dav_link
.expiration
"
@on-stored-object-status-change="
$emit('statusDocumentChanged', $event)
"
></document-action-buttons-group>
</li>
<li v-if="Number.isInteger(d.id)">
<div class="duplicate-dropdown">
<button
class="btn btn-duplicate dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{
trans(EVALUATION_DOCUMENT_DUPLICATE)
}}
</button>
<ul class="dropdown-menu">
<li>
<a
class="dropdown-item"
@click="
$emit(
'duplicateDocument',
d,
)
"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_HERE,
)
}}</a
>
</li>
<li>
<a
class="dropdown-item"
@click="
prepareDocumentDuplicationToWork(
d,
)
"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
)
}}</a
>
</li>
</ul>
</div>
</li>
<li v-if="d.storedObject._permissions.canEdit">
<drop-file-modal
:existing-doc="d.storedObject"
:allow-remove="false"
@add-document="
(arg) =>
$emit(
'replaceDocument',
d,
arg.stored_object,
arg.stored_object_version,
)
"
></drop-file-modal>
</li>
<li v-if="d.workflows.length === 0">
<a
class="btn btn-delete"
@click="$emit('removeDocument', d)"
>
</a>
</li>
</ul>
</div>
</div>
<div class="row mb-3">
<h5>{{ trans(EVALUATION_DOCUMENTS) }} :</h5>
<div class="flex-table">
<div
class="item-bloc"
v-for="(d, i) in documents"
:key="d.id"
:class="[parseInt(docAnchorId) === d.id ? 'bg-blink' : 'nothing']"
>
<div :id="'document_' + d.id" class="item-row">
<div class="input-group input-group-lg mb-3 row">
<label class="col-sm-3 col-form-label">Titre du document:</label>
<div class="col-sm-9">
<input
class="form-control document-title"
type="text"
:value="d.title"
:id="d.id"
:data-key="i"
@input="$emit('inputDocumentTitle', $event)"
/>
</div>
</div>
</div>
<div class="item-row">
<div class="item-col item-meta">
<p v-if="d.createdBy" class="createdBy">
Créé par {{ d.createdBy.text }}<br />
Le {{ $d(ISOToDatetime(d.createdAt.datetime), "long") }}
</p>
</div>
</div>
<div class="item-row">
<div class="item-col">
<ul class="record_actions">
<li
v-if="
d.workflows_availables.length > 0 || d.workflows.length > 0
"
>
<list-workflow-modal
:workflows="d.workflows"
:allowCreate="true"
relatedEntityClass="Chill\PersonBundle\Entity\AccompanyingPeriod\AccompanyingPeriodWorkEvaluationDocument"
:relatedEntityId="d.id"
:workflowsAvailables="d.workflows_availables"
:preventDefaultMoveToGenerate="true"
:goToGenerateWorkflowPayload="{ doc: d }"
@go-to-generate-workflow="
$emit('goToGenerateWorkflow', $event)
"
></list-workflow-modal>
</li>
<li>
<button
v-if="AmIRefferer"
class="btn btn-notify"
@click="$emit('goToGenerateNotification', d, false)"
></button>
<template v-else>
<button
id="btnGroupNotifyButtons"
type="button"
class="btn btn-notify dropdown-toggle"
:title="trans(EVALUATION_NOTIFICATION_SEND)"
data-bs-toggle="dropdown"
aria-expanded="false"
>
&nbsp;
</button>
<ul
class="dropdown-menu"
aria-labelledby="btnGroupNotifyButtons"
>
<li>
<a
class="dropdown-item"
@click="$emit('goToGenerateNotification', d, true)"
>
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_REFERRER) }}
</a>
</li>
<li>
<a
class="dropdown-item"
@click="$emit('goToGenerateNotification', d, false)"
>
{{ trans(EVALUATION_NOTIFICATION_NOTIFY_ANY) }}
</a>
</li>
</ul>
</template>
</li>
<li>
<document-action-buttons-group
:stored-object="d.storedObject"
:filename="d.title"
:can-edit="true"
:execute-before-leave="submitBeforeLeaveToEditor"
:davLink="d.storedObject._links?.dav_link.href"
:davLinkExpiration="
d.storedObject._links?.dav_link.expiration
"
@on-stored-object-status-change="
$emit('statusDocumentChanged', $event)
"
></document-action-buttons-group>
</li>
<li v-if="Number.isInteger(d.id)">
<div class="duplicate-dropdown">
<button
class="btn btn-duplicate dropdown-toggle"
type="button"
data-bs-toggle="dropdown"
aria-expanded="false"
>
{{ trans(EVALUATION_DOCUMENT_DUPLICATE) }}
</button>
<ul class="dropdown-menu">
<li>
<a
class="dropdown-item"
@click="$emit('duplicateDocument', d)"
>{{ trans(EVALUATION_DOCUMENT_DUPLICATE_HERE) }}</a
>
</li>
<li>
<a
class="dropdown-item"
@click="prepareDocumentDuplicationToWork(d)"
>{{
trans(
EVALUATION_DOCUMENT_DUPLICATE_TO_OTHER_EVALUATION,
)
}}</a
>
</li>
</ul>
</div>
</li>
<li v-if="d.storedObject._permissions.canEdit">
<a class="btn btn-choose" @click="prepareDocumentMoveToWork(d)"
>EVALUATION_DOCUMENT_MOVE</a
>
</li>
<li v-if="d.storedObject._permissions.canEdit">
<drop-file-modal
:existing-doc="d.storedObject"
:allow-remove="false"
@add-document="
(arg) =>
$emit(
'replaceDocument',
d,
arg.stored_object,
arg.stored_object_version,
)
"
></drop-file-modal>
</li>
<li v-if="d.workflows.length === 0">
<a class="btn btn-delete" @click="$emit('removeDocument', d)">
</a>
</li>
</ul>
</div>
</div>
</div>
</div>
</div>
<AccompanyingPeriodWorkSelectorModal
v-if="showAccompanyingPeriodSelector"
@@ -294,7 +238,7 @@ watch(selectedEvaluation, (val) => {
});
} else {
emit("moveDocumentToEvaluation", {
evaluation: val,
evaluationDest: val,
document: selectedDocumentToMove.value,
});
}

View File

@@ -258,18 +258,13 @@ function duplicateDocumentToEvaluation({ evaluation, document }) {
});
}
function moveDocumentToEvaluation({ evaluation, document }) {
const url = `/api/1.0/person/accompanying-course-work-evaluation-document/${document.id}/evaluation/${evaluation.id}/move`;
// console.log('document id', document.id, 'evaluation id', evaluation.id)
makeFetch("POST", url)
.then((response) => {
console.log("document", response);
toast.open({ message: trans(DOCUMENT_DUPLICATE_TO_EVALUATION_SUCCESS) });
})
.catch((error) => {
console.log(error);
});
function moveDocumentToEvaluation({ evaluationDest, document }) {
console.log("dest eval in formEvaluation", evaluationDest);
store.dispatch("moveDocumentToEvaluation", {
evaluationInitial: props.evaluation,
evaluationDest: evaluationDest,
document: document,
});
}
function onStatusDocumentChanged(newStatus) {

View File

@@ -14,6 +14,7 @@ import { fetchTemplates } from "ChillDocGeneratorAssets/api/pickTemplate.js";
import {
duplicate,
duplicateDocumentToEvaluation,
moveDocumentToEvaluation,
} from "../_api/accompanyingCourseWorkEvaluationDocument";
const debug = process.env.NODE_ENV !== "production";
@@ -314,6 +315,29 @@ const store = createStore({
evaluationDest.documents.splice(0, 0, document);
}
},
moveDocumentToEvaluation(
state,
{ evaluationInitial, evaluationDest, document },
) {
let evaluationA = state.evaluationsPicked.find(
(e) => e.id === evaluationInitial.id,
);
let evaluationB = state.evaluationsPicked.find(
(e) => e.id === evaluationDest.id,
);
// add document to chosen evaluation
document.key = evaluationB.documents.length + 1;
evaluationB.documents.splice(0, 0, document);
// remove document from original evaluation
const indexToRemove = evaluationA.documents.findIndex(
(doc) => doc.id === document.id,
);
if (indexToRemove !== -1) {
evaluationA.documents.splice(indexToRemove, 1);
}
},
/**
* Replaces a document in the state with a new document.
*
@@ -627,6 +651,18 @@ const store = createStore({
throw error;
}
},
async moveDocumentToEvaluation(
{ commit },
{ evaluationInitial, evaluationDest, document },
) {
commit("moveDocumentToEvaluation", {
evaluationInitial,
evaluationDest,
document,
});
await moveDocumentToEvaluation(document.id, evaluationDest.id);
},
removeDocument({ commit }, payload) {
commit("removeDocument", payload);
},

View File

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