diff --git a/app/src/recoil/actions.js b/app/src/recoil/actions.js index d9381d19d..c8bd50f14 100644 --- a/app/src/recoil/actions.js +++ b/app/src/recoil/actions.js @@ -44,6 +44,19 @@ const encryptedFields = [ 'history', ]; +export const allowedActionFieldsInHistory = [ + { name: 'categories', label: 'Catégorie(s)' }, + { name: 'person', label: 'Personne suivie' }, + { name: 'group', label: 'Action familiale' }, + { name: 'name', label: "Nom de l'action" }, + { name: 'description', label: 'Description' }, + { name: 'teams', label: 'Équipe(s) en charge' }, + { name: 'urgent', label: 'Action urgente' }, + { name: 'completedAt', label: 'Faite le' }, + { name: 'dueAt', label: 'À faire le' }, + { name: 'status', label: 'Status' }, +]; + export const prepareActionForEncryption = (action) => { try { if (!looseUuidRegex.test(action.person)) { diff --git a/app/src/scenes/Actions/Action.js b/app/src/scenes/Actions/Action.js index 9df21c7f1..551c197d9 100644 --- a/app/src/scenes/Actions/Action.js +++ b/app/src/scenes/Actions/Action.js @@ -21,7 +21,7 @@ import ActionCategoriesModalSelect from '../../components/ActionCategoriesModalS import Label from '../../components/Label'; import Tags from '../../components/Tags'; import { MyText } from '../../components/MyText'; -import { actionsState, DONE, CANCEL, TODO, prepareActionForEncryption, mappedIdsToLabels } from '../../recoil/actions'; +import { actionsState, DONE, CANCEL, TODO, prepareActionForEncryption, mappedIdsToLabels, allowedActionFieldsInHistory } from '../../recoil/actions'; import { useRecoilState, useRecoilValue } from 'recoil'; import { commentsState, prepareCommentForEncryption } from '../../recoil/comments'; import API from '../../services/api'; @@ -205,6 +205,18 @@ const Action = ({ navigation, route }) => { } } delete action.team; + + const historyEntry = { + date: new Date(), + user: user._id, + data: {}, + }; + for (const key in action) { + if (!allowedActionFieldsInHistory.map((field) => field.name).includes(key)) continue; + if (action[key] !== oldAction[key]) historyEntry.data[key] = { oldValue: oldAction[key], newValue: action[key] }; + } + if (!!Object.keys(historyEntry.data).length) action.history = [...(action.history || []), historyEntry]; + const response = await API.put({ path: `/action/${oldAction._id}`, body: prepareActionForEncryption(action), @@ -218,17 +230,6 @@ const Action = ({ navigation, route }) => { }) ); if (!!newAction.completedAt) await createReportAtDateIfNotExist(newAction.completedAt); - if (!statusChanged) return response; - const comment = { - comment: `${user.name} a changé le status de l'action: ${mappedIdsToLabels.find((status) => status._id === newAction.status)?.name}`, - action: actionDB?._id, - team: currentTeam._id, - user: user._id, - organisation: organisation._id, - date: new Date().toISOString(), - }; - const commentResponse = await API.post({ path: '/comment', body: prepareCommentForEncryption(comment) }); - if (commentResponse.ok) setComments((comments) => [commentResponse.decryptedData, ...comments]); return response; } catch (error) { capture(error, { extra: { message: 'error in updating action', action } }); diff --git a/dashboard/src/components/ActionModal.js b/dashboard/src/components/ActionModal.js index c0831d0a2..d3b8fc876 100644 --- a/dashboard/src/components/ActionModal.js +++ b/dashboard/src/components/ActionModal.js @@ -2,7 +2,7 @@ import React, { useEffect, useMemo, useState, useRef } from 'react'; import { toast } from 'react-toastify'; import { useRecoilValue, useSetRecoilState } from 'recoil'; import { useHistory, useLocation } from 'react-router-dom'; -import { actionsState, allowedActionFieldsInHistory, CANCEL, DONE, mappedIdsToLabels, prepareActionForEncryption, TODO } from '../recoil/actions'; +import { actionsState, allowedActionFieldsInHistory, CANCEL, DONE, prepareActionForEncryption, TODO } from '../recoil/actions'; import { currentTeamState, organisationState, teamsState, userState } from '../recoil/auth'; import { dayjsInstance, now, outOfBoundariesDate } from '../services/date'; import API from '../services/api'; @@ -289,7 +289,7 @@ function ActionContent({ onClose, action, personId = null, personIds = null, isM data: {}, }; for (const key in body) { - if (!allowedActionFieldsInHistory.includes(key)) continue; + if (!allowedActionFieldsInHistory.map((field) => field.name).includes(key)) continue; if (body[key] !== action[key]) historyEntry.data[key] = { oldValue: action[key], newValue: body[key] }; } if (!!Object.keys(historyEntry.data).length) body.history = [...(action.history || []), historyEntry]; @@ -312,17 +312,6 @@ function ActionContent({ onClose, action, personId = null, personIds = null, isM await createReportAtDateIfNotExist(newAction.completedAt); } } - if (statusChanged) { - const comment = { - comment: `${user.name} a changé le status de l'action: ${mappedIdsToLabels.find((status) => status._id === newAction.status)?.name}`, - action: action._id, - team: currentTeam._id, - user: user._id, - organisation: organisation._id, - }; - const commentResponse = await API.post({ path: '/comment', body: prepareCommentForEncryption(comment) }); - if (commentResponse.ok) setComments((comments) => [commentResponse.decryptedData, ...comments]); - } toast.success('Mise à jour !'); if (location.pathname !== '/stats') refresh(); // if we refresh when we're on stats page, it will remove the view we're on const actionCancelled = action.status !== CANCEL && body.status === CANCEL; @@ -658,6 +647,12 @@ function ActionContent({ onClose, action, personId = null, personIds = null, isM /> )} +
Date | -Utilisateur | -Donnée | -||||||
---|---|---|---|---|---|---|---|---|
{dayjsInstance(h.date).format('DD/MM/YYYY HH:mm')} | -
- |
-
- {Object.entries(h.data).map(([key, value]) => {
- const personField = personFieldsIncludingCustomFields.find((f) => f.name === key);
- if (key === 'teams') {
+ {!history?.length ? (
+
+
+ ) : (
+ Cette action n'a pas encore d'historique. +
+ Lorsqu'une action est modifiée, les changements sont enregistrés dans un historique,
+
|
+
Date | -Utilisateur | -Donnée | -||||||
---|---|---|---|---|---|---|---|---|
{dayjsInstance(h.date).format('DD/MM/YYYY HH:mm')} | -
- |
-
- {Object.entries(h.data).map(([key, value]) => {
- const personField = personFieldsIncludingCustomFields.find((f) => f.name === key);
- if (key === 'merge') {
- return (
-
-
- Fusion avec :
- {personField?.label} :
-
- {personField?.label}:
- - {value.newValue === true ? 'Sortie de file active' : 'Réintégration dans la file active'} - - ); - } - if (key === 'outOfActiveListDate') { - if (!value.newValue) return null; +
+
+ {!history?.length ? (
+ Historique+
+
+ ) : (
+ Cette personne n'a pas encore d'historique. +
+ Lorsqu'une personne est modifiée, les changements sont enregistrés dans un historique,
+
|
+