From cdc72ef2979a04d5719c286ec1a032bdc57fa2bd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9becca=20Tinchon?= Date: Mon, 14 Oct 2024 10:02:22 +0200 Subject: [PATCH 1/4] presence management --- .../Controller/EventPresenceController.php | 36 ++++++++------ src/plugin/cursus/Entity/EventPresence.php | 36 ++++++++++++++ .../Migrations/Version20241014084016.php | 47 +++++++++++++++++++ .../cursus/Manager/EventPresenceManager.php | 2 +- .../actions/presence/confirm-presence.js | 25 ---------- .../modules/event/components/list.jsx | 13 +++++ .../modules/event/components/page.jsx | 15 +++++- src/plugin/cursus/Resources/modules/plugin.js | 1 - .../modules/presence/components/list.jsx | 13 +++++ .../Resources/translations/presence.en.json | 6 ++- .../Resources/translations/presence.fr.json | 6 ++- .../Serializer/EventPresenceSerializer.php | 11 +++++ 12 files changed, 165 insertions(+), 46 deletions(-) create mode 100644 src/plugin/cursus/Installation/Migrations/Version20241014084016.php delete mode 100644 src/plugin/cursus/Resources/modules/actions/presence/confirm-presence.js diff --git a/src/plugin/cursus/Controller/EventPresenceController.php b/src/plugin/cursus/Controller/EventPresenceController.php index be9408172bd..8aac1dfc2e1 100644 --- a/src/plugin/cursus/Controller/EventPresenceController.php +++ b/src/plugin/cursus/Controller/EventPresenceController.php @@ -91,34 +91,39 @@ public function signStatusAction(Request $request): JsonResponse return new JsonResponse(['success' => false]); } - $presenceData = $this->serializer->serialize($presence); - $presenceData['status'] = EventPresence::PRESENT; - $presenceData['signature'] = $signature; + $presence->setStatus(EventPresence::PRESENT); + $presence->setSignature($signature); + $presence->setPresenceUpdatedBy($this->tokenStorage->getToken()->getUser()); + $presence->setPresenceUpdatedAt(new \DateTime()); - $this->crud->update($presence, $presenceData); + $this->om->persist($presence); + $this->om->flush(); return new JsonResponse(['success' => true]); } /** - * Confirm the status of a EventPresence for current user. + * Confirm the status of a EventPresence for current event. + * + * @Route("/confirm/{id}", name="apiv2_cursus_event_presence_confirm", methods={"PUT"}) * - * @Route("/confirm", name="apiv2_cursus_event_presence_confirm", methods={"PUT"}) + * @EXT\ParamConverter("event", class="Claroline\CursusBundle\Entity\Event", options={"mapping": {"id": "uuid"}}) */ - public function confirmStatusAction(Request $request): JsonResponse + public function confirmStatusAction(Event $event): JsonResponse { - $data = $this->decodeRequest($request); - if (empty($data)) { - throw new InvalidDataException('Invalid data'); - } + $this->checkPermission('ADMINISTRATE', $event, [], true); + + $presences = $this->om->getRepository(EventPresence::class)->findBy(['event' => $event]); + $presencesToValidate = array_filter($presences, function (EventPresence $presence) { + return EventPresence::UNKNOWN !== $presence->getStatus(); + }); - $presences = $this->om->getRepository(EventPresence::class)->findBy(['uuid' => $data]); $this->om->startFlushSuite(); - foreach ($presences as $presence) { - $this->checkPermission('ADMINISTRATE', $presence, [], true); + foreach ($presencesToValidate as $presence) { $this->manager->setValidationDate([$presence], new \DateTime()); } + $this->om->endFlushSuite(); return new JsonResponse(); @@ -211,6 +216,9 @@ public function updateStatusAction(string $status, Request $request): JsonRespon $this->checkPermission('EDIT', $presence, [], true); $this->manager->setStatus([$presence], $status); + + $presence->setPresenceUpdatedBy($this->tokenStorage->getToken()->getUser()); + $presence->setPresenceUpdatedAt(new \DateTime()); } $this->om->endFlushSuite(); diff --git a/src/plugin/cursus/Entity/EventPresence.php b/src/plugin/cursus/Entity/EventPresence.php index dd25bb865d0..e44ab0078a5 100644 --- a/src/plugin/cursus/Entity/EventPresence.php +++ b/src/plugin/cursus/Entity/EventPresence.php @@ -62,6 +62,18 @@ class EventPresence */ private ?array $evidences = null; + /** + * @ORM\ManyToOne(targetEntity="Claroline\CoreBundle\Entity\User") + * + * @ORM\JoinColumn(name="presence_updated_by", referencedColumnName="id", nullable=true) + */ + private ?User $presenceUpdatedBy = null; + + /** + * @ORM\Column(name="presence_updated_at", type="datetime", nullable=true) + */ + private ?\DateTimeInterface $presenceUpdatedAt = null; + public function __construct() { $this->refreshUuid(); @@ -126,4 +138,28 @@ public function setEvidences(?array $evidences): void { $this->evidences = $evidences; } + + public function getPresenceUpdatedBy(): ?User + { + return $this->presenceUpdatedBy; + } + + public function setPresenceUpdatedBy(?User $user): self + { + $this->presenceUpdatedBy = $user; + + return $this; + } + + public function getPresenceUpdatedAt(): ?\DateTimeInterface + { + return $this->presenceUpdatedAt; + } + + public function setPresenceUpdatedAt(?\DateTimeInterface $date): self + { + $this->presenceUpdatedAt = $date; + + return $this; + } } diff --git a/src/plugin/cursus/Installation/Migrations/Version20241014084016.php b/src/plugin/cursus/Installation/Migrations/Version20241014084016.php new file mode 100644 index 00000000000..0a33576739f --- /dev/null +++ b/src/plugin/cursus/Installation/Migrations/Version20241014084016.php @@ -0,0 +1,47 @@ +addSql(' + ALTER TABLE claro_cursusbundle_presence_status + ADD presence_updated_by INT DEFAULT NULL, + ADD presence_updated_at DATETIME DEFAULT NULL + '); + $this->addSql(' + ALTER TABLE claro_cursusbundle_presence_status + ADD CONSTRAINT FK_DFE5E1FE349A94C7 FOREIGN KEY (presence_updated_by) + REFERENCES claro_user (id) + '); + $this->addSql(' + CREATE INDEX IDX_DFE5E1FE349A94C7 ON claro_cursusbundle_presence_status (presence_updated_by) + '); + } + + public function down(Schema $schema): void + { + $this->addSql(' + ALTER TABLE claro_cursusbundle_presence_status + DROP FOREIGN KEY FK_DFE5E1FE349A94C7 + '); + $this->addSql(' + DROP INDEX IDX_DFE5E1FE349A94C7 ON claro_cursusbundle_presence_status + '); + $this->addSql(' + ALTER TABLE claro_cursusbundle_presence_status + DROP presence_updated_by, + DROP presence_updated_at + '); + } +} diff --git a/src/plugin/cursus/Manager/EventPresenceManager.php b/src/plugin/cursus/Manager/EventPresenceManager.php index 5727a810e42..cec148e0e58 100644 --- a/src/plugin/cursus/Manager/EventPresenceManager.php +++ b/src/plugin/cursus/Manager/EventPresenceManager.php @@ -92,7 +92,7 @@ public function setStatus(array $presences, string $status): array return $presences; } - public function setValidationDate(array $presences, \DateTimeInterface $date): array + public function setValidationDate(array $presences, ?\DateTimeInterface $date): array { foreach ($presences as $presence) { $presence->setValidationDate($date); diff --git a/src/plugin/cursus/Resources/modules/actions/presence/confirm-presence.js b/src/plugin/cursus/Resources/modules/actions/presence/confirm-presence.js deleted file mode 100644 index 9375029e76e..00000000000 --- a/src/plugin/cursus/Resources/modules/actions/presence/confirm-presence.js +++ /dev/null @@ -1,25 +0,0 @@ -import {ASYNC_BUTTON} from '#/main/app/buttons' -import {trans} from '#/main/app/intl' -import {hasPermission} from '#/main/app/security' - -export default (presences, refresher) => { - const processable = presences.filter(presence => hasPermission('administrate', presence)) - - return { - name: 'confirm-presence', - type: ASYNC_BUTTON, - icon: 'fa fa-fw fa-clipboard-check', - label: trans('presence_validation', {}, 'presence'), - request: { - url: ['apiv2_cursus_event_presence_confirm'], - request: { - method: 'PUT', - body: JSON.stringify(processable.map(presence => presence.id)) - }, - success: refresher.update - }, - displayed: 0 !== processable.length, - group: trans('validation', {}, 'presence'), - scope: ['collection', 'object'] - } -} diff --git a/src/plugin/cursus/Resources/modules/event/components/list.jsx b/src/plugin/cursus/Resources/modules/event/components/list.jsx index 1317a120df9..f387722ae0c 100644 --- a/src/plugin/cursus/Resources/modules/event/components/list.jsx +++ b/src/plugin/cursus/Resources/modules/event/components/list.jsx @@ -103,6 +103,19 @@ const Events = (props) => displayed: hasPermission('edit', rows[0]), group: trans('presences', {}, 'cursus'), target: ['apiv2_cursus_event_presence_download', {id: rows[0].id, filled: 1}] + }, { + name: 'confirm-status', + type: ASYNC_BUTTON, + icon: 'fa fa-fw fa-clipboard-check', + label: trans('presence_validation', {}, 'presence'), + displayed: hasPermission('edit', rows[0]), + group: trans('validation', {}, 'presence'), + request: { + url: ['apiv2_cursus_event_presence_confirm', {id: rows[0].id}], + request: { + method: 'PUT' + } + } } ].concat(props.customActions(rows))} delete={{ diff --git a/src/plugin/cursus/Resources/modules/event/components/page.jsx b/src/plugin/cursus/Resources/modules/event/components/page.jsx index c5905174013..33f28a07eaa 100644 --- a/src/plugin/cursus/Resources/modules/event/components/page.jsx +++ b/src/plugin/cursus/Resources/modules/event/components/page.jsx @@ -5,7 +5,7 @@ import isEmpty from 'lodash/isEmpty' import {trans} from '#/main/app/intl/translation' import {hasPermission} from '#/main/app/security' -import {MODAL_BUTTON, URL_BUTTON} from '#/main/app/buttons' +import {MODAL_BUTTON, URL_BUTTON, ASYNC_BUTTON} from '#/main/app/buttons' import {ContentLoader} from '#/main/app/content/components/loader' import {ToolPage} from '#/main/core/tool' @@ -82,6 +82,19 @@ const EventPage = (props) => { displayed: hasPermission('edit', props.event), group: trans('presences', {}, 'cursus'), target: ['apiv2_cursus_event_presence_download', {id: props.event.id, filled: 1}] + }, { + name: 'confirm-status', + type: ASYNC_BUTTON, + icon: 'fa fa-fw fa-clipboard-check', + label: trans('presence_validation', {}, 'presence'), + displayed: hasPermission('edit', props.event), + group: trans('validation', {}, 'presence'), + request: { + url: ['apiv2_cursus_event_presence_confirm', {id: props.event.id}], + request: { + method: 'PUT' + } + } } ]} diff --git a/src/plugin/cursus/Resources/modules/plugin.js b/src/plugin/cursus/Resources/modules/plugin.js index 48b74fe4c98..a8012452ea1 100644 --- a/src/plugin/cursus/Resources/modules/plugin.js +++ b/src/plugin/cursus/Resources/modules/plugin.js @@ -53,7 +53,6 @@ registry.add('ClarolineCursusBundle', { 'mark-absent-unjustified': () => { return import(/* webpackChunkName: "training-action-presence-absent-unjustified" */ '#/plugin/cursus/actions/presence/mark-absent-unjustified') }, 'mark-absent-present' : () => { return import(/* webpackChunkName: "training-action-presence-present" */ '#/plugin/cursus/actions/presence/mark-present') }, 'mark-unknown' : () => { return import(/* webpackChunkName: "training-action-presence-unknown" */ '#/plugin/cursus/actions/presence/mark-unknown') }, - 'confirm-presence' : () => { return import(/* webpackChunkName: "training-action-presence-confirm" */ '#/plugin/cursus/actions/presence/confirm-presence') }, 'add-evidence' : () => { return import(/* webpackChunkName: "training-action-presence-add-evidence" */ '#/plugin/cursus/actions/presence/add-evidence') } } }, diff --git a/src/plugin/cursus/Resources/modules/presence/components/list.jsx b/src/plugin/cursus/Resources/modules/presence/components/list.jsx index 9e4817ca54b..a7c172c92a4 100644 --- a/src/plugin/cursus/Resources/modules/presence/components/list.jsx +++ b/src/plugin/cursus/Resources/modules/presence/components/list.jsx @@ -46,6 +46,19 @@ const Presences = props => { ), displayed: true }, { + name: 'presence_updated_by', + type: 'user', + label: trans('presence_updated_by', {}, 'presence'), + displayed: true + }, { + name: 'presence_updated_at', + type: 'date', + label: trans('presence_updated_at', {}, 'presence'), + displayed: true, + options: { + time: true + } + },{ name: 'validation_date', type: 'date', label: trans('presence_confirmation_date', {}, 'presence'), diff --git a/src/plugin/cursus/Resources/translations/presence.en.json b/src/plugin/cursus/Resources/translations/presence.en.json index a5a65b4fd00..7d20e641fd9 100644 --- a/src/plugin/cursus/Resources/translations/presence.en.json +++ b/src/plugin/cursus/Resources/translations/presence.en.json @@ -16,10 +16,12 @@ "presence_confirm_title": "Presence confirmation", "presence_confirm_desc": "Your %event_title% event signature has been successfully recorded.", "presence_confirm_other": "Confirm another presence", - "presence_confirmation_date": "Confirmation date", + "presence_confirmation_date": "Validation date", "presence_validation_date": "Validation date by tutor", "presence_info": "Me, %user%, was present at the event %event_title% from %event_date_start% to %event_date_end%.", - "presence_validation": "Validate presence", + "presence_validation": "Validate status", + "presence_updated_by": "Status updated by", + "presence_updated_at": "Update date", "validate": "Validate", "validation": "Validation" diff --git a/src/plugin/cursus/Resources/translations/presence.fr.json b/src/plugin/cursus/Resources/translations/presence.fr.json index c9589c0afd3..3aafec7970e 100644 --- a/src/plugin/cursus/Resources/translations/presence.fr.json +++ b/src/plugin/cursus/Resources/translations/presence.fr.json @@ -16,10 +16,12 @@ "presence_confirm_title": "Confirmation de présence", "presence_confirm_desc": "Votre présence à la séance %event_title% a bien été enregistrée.", "presence_confirm_other": "Confirmer une autre présence", - "presence_confirmation_date": "Date de confirmation", + "presence_confirmation_date": "Date de validation", "presence_validation_date": "Date de validation par le formateur", "presence_info": "Moi, %user%, étais présent à la séance %event_title% du %event_datetime_start% au %event_datetime_end%.", - "presence_validation": "Confirmer la présence", + "presence_validation": "Valider les statuts", + "presence_updated_by": "Statut mis à jour par", + "presence_updated_at": "Date de mise à jour", "validate": "Valider", "validation": "Validation" diff --git a/src/plugin/cursus/Serializer/EventPresenceSerializer.php b/src/plugin/cursus/Serializer/EventPresenceSerializer.php index 7f30fa8f2d7..f4c966444ee 100644 --- a/src/plugin/cursus/Serializer/EventPresenceSerializer.php +++ b/src/plugin/cursus/Serializer/EventPresenceSerializer.php @@ -54,6 +54,8 @@ public function serialize(EventPresence $eventPresence, array $options = []): ar 'signature' => $eventPresence->getSignature(), 'validation_date' => DateNormalizer::normalize($eventPresence->getValidationDate()), 'evidences' => $eventPresence->getEvidences(), + 'presence_updated_by' => $eventPresence->getPresenceUpdatedBy() ? $this->userSerializer->serialize($eventPresence->getPresenceUpdatedBy(), [SerializerInterface::SERIALIZE_MINIMAL]) : null, + 'presence_updated_at' => DateNormalizer::normalize($eventPresence->getPresenceUpdatedAt()), ]; if (!in_array(SerializerInterface::SERIALIZE_TRANSFER, $options)) { @@ -88,6 +90,15 @@ public function deserialize(array $data, EventPresence $eventPresence): EventPre $eventPresence->setEvidences($data['evidences'] ?? null); } + if (isset($data['presence_updated_by'])) { + $updatedBy = $this->om->getRepository(User::class)->findOneBy(['uuid' => $data['presence_updated_by']['id']]); + $eventPresence->setPresenceUpdatedBy($updatedBy); + } + + if (isset($data['presence_updated_at'])) { + $eventPresence->setPresenceUpdatedAt(DateNormalizer::denormalize($data['presence_updated_at'])); + } + return $eventPresence; } } From deedd2fb21a3a67b113de6615861bcade64bb7bf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?R=C3=A9becca=20Tinchon?= Date: Fri, 18 Oct 2024 11:01:11 +0200 Subject: [PATCH 2/4] Delete evidence --- .../Controller/EventPresenceController.php | 19 ++++++++- .../modules/actions/presence/add-evidence.js | 6 ++- .../actions/presence/delete-evidence.js | 33 +++++++++++++++ .../presence/evidences/components/modal.jsx | 26 ++++++------ .../modals/presence/evidences/store.js | 6 +-- src/plugin/cursus/Resources/modules/plugin.js | 3 +- .../modules/presence/components/list.jsx | 41 ++++++------------- .../Resources/translations/presence.en.json | 13 ++++-- .../Resources/translations/presence.fr.json | 13 ++++-- 9 files changed, 106 insertions(+), 54 deletions(-) create mode 100644 src/plugin/cursus/Resources/modules/actions/presence/delete-evidence.js diff --git a/src/plugin/cursus/Controller/EventPresenceController.php b/src/plugin/cursus/Controller/EventPresenceController.php index 8aac1dfc2e1..46adff587d1 100644 --- a/src/plugin/cursus/Controller/EventPresenceController.php +++ b/src/plugin/cursus/Controller/EventPresenceController.php @@ -267,7 +267,7 @@ public function downloadUserPdfAction(EventPresence $eventPresence, Request $req } /** - * @Route("/{id}/evidences", name="apiv2_cursus_presence_evidences_upload", methods={"POST"}) + * @Route("/{id}/evidences", name="apiv2_cursus_presence_evidence_upload", methods={"POST"}) * * @EXT\ParamConverter("eventPresence", class="Claroline\CursusBundle\Entity\EventPresence", options={"mapping": {"id": "uuid"}}) */ @@ -298,6 +298,23 @@ public function uploadEvidences(EventPresence $eventPresence, Request $request): return new JsonResponse($this->serializer->serialize($eventPresence)); } + /** + * @Route("/{id}/evidences", name="apiv2_cursus_presence_evidence_delete", methods={"DELETE"}) + * + * @EXT\ParamConverter("eventPresence", class="Claroline\CursusBundle\Entity\EventPresence", options={"mapping": {"id": "uuid"}}) + */ + public function deleteEvidenceAction(EventPresence $eventPresence): JsonResponse + { + $this->checkPermission('EDIT', $eventPresence, [], true); + + $eventPresence->setEvidences(null); + + $this->om->persist($eventPresence); + $this->om->flush(); + + return new JsonResponse(['success' => true]); + } + /** * @Route("/{id}/evidences", name="apiv2_cursus_presence_evidence_download", methods={"GET"}) * diff --git a/src/plugin/cursus/Resources/modules/actions/presence/add-evidence.js b/src/plugin/cursus/Resources/modules/actions/presence/add-evidence.js index 7acf1aca7d5..9a97e3ca03b 100644 --- a/src/plugin/cursus/Resources/modules/actions/presence/add-evidence.js +++ b/src/plugin/cursus/Resources/modules/actions/presence/add-evidence.js @@ -11,13 +11,15 @@ export default (presences, refresher) => { name: 'add-evidence', type: MODAL_BUTTON, icon: 'fa fa-fw fa-file-upload', - label: trans('add_evidences', {}, 'presence'), + label: trans('add_evidence', {}, 'presence'), modal: [MODAL_EVIDENCE, { parent: processable[0], onSuccess: refresher.update, editable: true }], - displayed: 0 !== processable.length && [constants.PRESENCE_STATUS_ABSENT_UNJUSTIFIED, constants.PRESENCE_STATUS_ABSENT_JUSTIFIED].includes(processable[0].status), + displayed: 0 !== processable.length + && [constants.PRESENCE_STATUS_ABSENT_UNJUSTIFIED, constants.PRESENCE_STATUS_ABSENT_JUSTIFIED].includes(processable[0].status) + && (!processable[0].evidences || processable[0].evidences.length === 0), group: trans('validation', {}, 'presence'), scope: ['object'] } diff --git a/src/plugin/cursus/Resources/modules/actions/presence/delete-evidence.js b/src/plugin/cursus/Resources/modules/actions/presence/delete-evidence.js new file mode 100644 index 00000000000..8be070f1b23 --- /dev/null +++ b/src/plugin/cursus/Resources/modules/actions/presence/delete-evidence.js @@ -0,0 +1,33 @@ +import {hasPermission} from '#/main/app/security' +import {url} from '#/main/app/api' +import {ASYNC_BUTTON} from '#/main/app/buttons' +import {trans} from '#/main/app/intl/translation' + +/** + * Delete evidence action. + */ +export default (presences, refresher) => { + const processable = presences.filter(presence => hasPermission('edit', presence)) + + return { + name: 'delete-evidence', + type: ASYNC_BUTTON, + icon: 'fa fa-fw fa-trash', + label: trans('delete_evidence', {}, 'presence'), + displayed: 0 !== processable.length && (processable[0].evidences && processable[0].evidences.length > 0), + dangerous: true, + confirm: { + title: trans('delete_evidence', {}, 'presence'), + message: trans('delete_evidence_message', {}, 'presence') + }, + request: { + url: url(['apiv2_cursus_presence_evidence_delete', {id: processable[0].id}]), + request: { + method: 'DELETE' + }, + success: () => refresher.delete(processable) + }, + group: trans('management'), + scope: ['object'] + } +} diff --git a/src/plugin/cursus/Resources/modules/modals/presence/evidences/components/modal.jsx b/src/plugin/cursus/Resources/modules/modals/presence/evidences/components/modal.jsx index 7f402cdf38b..45eac224756 100644 --- a/src/plugin/cursus/Resources/modules/modals/presence/evidences/components/modal.jsx +++ b/src/plugin/cursus/Resources/modules/modals/presence/evidences/components/modal.jsx @@ -4,7 +4,7 @@ import {PropTypes as T} from 'prop-types' import omit from 'lodash/omit' import classes from 'classnames' -import isEmpty from 'lodash/isEmpty' +import isNull from 'lodash/isNull' import {trans} from '#/main/app/intl/translation' import {CALLBACK_BUTTON} from '#/main/app/buttons' @@ -15,28 +15,28 @@ import {actions} from '#/plugin/cursus/modals/presence/evidences/store' import {FileThumbnail} from '#/main/app/data/types/file/components/thumbnail' const EvidenceModalComponent = (props) => { - const [files, setFiles] = useState([]) + const [file, setFile] = useState(null) return (
{props.editable && @@ -59,8 +59,8 @@ const EvidenceModalComponent = (props) => { type={CALLBACK_BUTTON} primary={true} label={trans('add', {}, 'actions')} - disabled={isEmpty(files)} - callback={() => props.createFiles(props.parent, files, () => { + disabled={isNull(file)} + callback={() => props.createFile(props.parent, file, () => { props.onSuccess() props.fadeModal() })} @@ -74,15 +74,15 @@ EvidenceModalComponent.propTypes = { parent: T.object.isRequired, editable: T.bool.isRequired, onSuccess: T.func.isRequired, - createFiles: T.func.isRequired, + createFile: T.func.isRequired, fadeModal: T.func.isRequired } const EvidenceModal = connect( null, (dispatch) => ({ - createFiles(parent, files, callback) { - dispatch(actions.createFiles(parent, files, callback)) + createFile(parent, file, callback) { + dispatch(actions.createFile(parent, file, callback)) } }) )(EvidenceModalComponent) diff --git a/src/plugin/cursus/Resources/modules/modals/presence/evidences/store.js b/src/plugin/cursus/Resources/modules/modals/presence/evidences/store.js index 7f0cdaf5497..9cf798a6187 100644 --- a/src/plugin/cursus/Resources/modules/modals/presence/evidences/store.js +++ b/src/plugin/cursus/Resources/modules/modals/presence/evidences/store.js @@ -1,13 +1,13 @@ import {API_REQUEST} from '#/main/app/api' export const actions = {} -actions.createFiles = (presence, files, onSuccess) => { +actions.createFile = (presence, file, onSuccess) => { const formData = new FormData() - files.forEach((file, index) => formData.append(index, file)) + formData.append(0, file) return ({ [API_REQUEST]: { - url: ['apiv2_cursus_presence_evidences_upload', {id: presence.id}], + url: ['apiv2_cursus_presence_evidence_upload', {id: presence.id}], type: 'upload', request: { method: 'POST', diff --git a/src/plugin/cursus/Resources/modules/plugin.js b/src/plugin/cursus/Resources/modules/plugin.js index a8012452ea1..9ee6c1f2ebe 100644 --- a/src/plugin/cursus/Resources/modules/plugin.js +++ b/src/plugin/cursus/Resources/modules/plugin.js @@ -53,7 +53,8 @@ registry.add('ClarolineCursusBundle', { 'mark-absent-unjustified': () => { return import(/* webpackChunkName: "training-action-presence-absent-unjustified" */ '#/plugin/cursus/actions/presence/mark-absent-unjustified') }, 'mark-absent-present' : () => { return import(/* webpackChunkName: "training-action-presence-present" */ '#/plugin/cursus/actions/presence/mark-present') }, 'mark-unknown' : () => { return import(/* webpackChunkName: "training-action-presence-unknown" */ '#/plugin/cursus/actions/presence/mark-unknown') }, - 'add-evidence' : () => { return import(/* webpackChunkName: "training-action-presence-add-evidence" */ '#/plugin/cursus/actions/presence/add-evidence') } + 'add-evidence' : () => { return import(/* webpackChunkName: "training-action-presence-add-evidence" */ '#/plugin/cursus/actions/presence/add-evidence') }, + 'delete-evidence' : () => { return import(/* webpackChunkName: "training-action-presence-delete-evidence" */ '#/plugin/cursus/actions/presence/delete-evidence') } } }, diff --git a/src/plugin/cursus/Resources/modules/presence/components/list.jsx b/src/plugin/cursus/Resources/modules/presence/components/list.jsx index a7c172c92a4..a6970017f22 100644 --- a/src/plugin/cursus/Resources/modules/presence/components/list.jsx +++ b/src/plugin/cursus/Resources/modules/presence/components/list.jsx @@ -5,13 +5,12 @@ import omit from 'lodash/omit' import merge from 'lodash/merge' import classes from 'classnames' -import {trans, transChoice} from '#/main/app/intl/translation' +import {trans} from '#/main/app/intl/translation' import {Button} from '#/main/app/action' import {constants} from '#/plugin/cursus/constants' -import {MODAL_BUTTON, DOWNLOAD_BUTTON} from '#/main/app/buttons' +import {DOWNLOAD_BUTTON} from '#/main/app/buttons' import {ListData} from '#/main/app/content/list/containers/data' import {actions as listActions} from '#/main/app/content/list/store' -import {MODAL_EVIDENCE} from '#/plugin/cursus/modals/presence/evidences' import {selectors as securitySelectors} from '#/main/app/security/store' import {getActions, getDefaultAction} from '#/plugin/cursus/presence/utils' @@ -69,34 +68,20 @@ const Presences = props => { }, { name: 'evidences', type: 'number', - label: trans('evidences', {}, 'presence'), + label: trans('evidence', {}, 'presence'), displayed: true, render: (row) => { - if (row.evidences && row.evidences.length > 0) { - if( row.evidences.length === 1) { - return ( -