From f3ae49063481c214c4d346b63ac6731a45a96abb Mon Sep 17 00:00:00 2001 From: Marcelo Arocha Date: Mon, 18 May 2026 21:28:19 -0300 Subject: [PATCH 01/18] feat: last clinical notes selection --- src/components/Forms/ClinicalNotes/Base.jsx | 107 ++++++++++++++---- .../serverActions/ServerActionsSlice.js | 13 +++ src/services/api.js | 6 + 3 files changed, 106 insertions(+), 20 deletions(-) diff --git a/src/components/Forms/ClinicalNotes/Base.jsx b/src/components/Forms/ClinicalNotes/Base.jsx index e75f4b2f..2294dba0 100644 --- a/src/components/Forms/ClinicalNotes/Base.jsx +++ b/src/components/Forms/ClinicalNotes/Base.jsx @@ -9,6 +9,8 @@ import { SettingOutlined, DownloadOutlined, CopyOutlined, + LeftOutlined, + RightOutlined, } from "@ant-design/icons"; import { formatDate } from "utils/date"; @@ -24,9 +26,10 @@ import { import notification from "components/notification"; import { getErrorMessage } from "utils/errorHandler"; +import Modal from "components/Modal"; import MemoryText from "containers/MemoryText"; import MemoryDraft from "features/memory/MemoryDraft/MemoryDraft"; -import { getUserLastClinicalNotes } from "features/serverActions/ServerActionsSlice"; +import { getUserLastClinicalNotesList } from "features/serverActions/ServerActionsSlice"; import getInterventionTemplate from "./util/getInterventionTemplate"; import { EditorBox } from "../Form.style"; @@ -37,6 +40,9 @@ export default function Base({ prescription, account, signature, action }) { const { t } = useTranslation(); const { values, setFieldValue, errors, touched } = useFormikContext(); const [loadingCopy, setLoadingCopy] = useState(false); + const [lastNotesList, setLastNotesList] = useState([]); + const [lastNotesModalOpen, setLastNotesModalOpen] = useState(false); + const [currentNoteIndex, setCurrentNoteIndex] = useState(0); const { notes, concilia, date, notesType } = values; const clinicalNotesTypeOptions = ( @@ -49,7 +55,7 @@ export default function Base({ prescription, account, signature, action }) { const loadDefaultText = () => { setFieldValue( "notes", - getInterventionTemplate(prescription, account, signature, concilia) + getInterventionTemplate(prescription, account, signature, concilia), ); }; @@ -68,36 +74,37 @@ export default function Base({ prescription, account, signature, action }) { prescription, clinicalNote, { signature, account }, - t - ) + t, + ), ); }; + const applyLastNote = (item) => { + setFieldValue( + "notes", + `---Cópia do dia: ${formatDate(item.date)}\n\n${item.text}`, + ); + setLastNotesModalOpen(false); + notification.success({ message: "Evolução copiada com sucesso" }); + }; + const loadLastNote = () => { setLoadingCopy(true); dispatch( - getUserLastClinicalNotes({ + getUserLastClinicalNotesList({ admissionNumber: values.admissionNumber, - }) + }), ).then((response) => { setLoadingCopy(false); if (response.error) { - notification.error({ - message: getErrorMessage(response, t), - }); + notification.error({ message: getErrorMessage(response, t) }); } else { - if (response.payload.data) { - setFieldValue( - "notes", - `---Cópia do dia: ${formatDate(response.payload.data?.date)}\n\n${ - response.payload.data?.text - }` - ); - - notification.success({ - message: "Última evolução copiada com sucesso", - }); + const list = response.payload?.data; + if (list && list.length > 0) { + setLastNotesList(list); + setCurrentNoteIndex(0); + setLastNotesModalOpen(true); } else { notification.error({ message: "Não encontramos evolução para este atendimento", @@ -275,6 +282,66 @@ export default function Base({ prescription, account, signature, action }) { + setLastNotesModalOpen(false)} + footer={ +
+ + + +
+ } + width={660} + > +

+ Navegue pelas evoluções anteriores e selecione a que deseja copiar + para o campo de evolução. +

+ {lastNotesList[currentNoteIndex] && ( + <> + {formatDate(lastNotesList[currentNoteIndex].date)} +
+ {lastNotesList[currentNoteIndex].text} +
+ + )} +
); } diff --git a/src/features/serverActions/ServerActionsSlice.js b/src/features/serverActions/ServerActionsSlice.js index 3b8bbed6..a4014fe1 100644 --- a/src/features/serverActions/ServerActionsSlice.js +++ b/src/features/serverActions/ServerActionsSlice.js @@ -82,6 +82,19 @@ export const getUserLastClinicalNotes = createAsyncThunk( } ); +export const getUserLastClinicalNotesList = createAsyncThunk( + "serverActions/get-last-clinical-notes-list", + async (params, thunkAPI) => { + try { + const response = await api.clinicalNotes.getUserLastList(params); + + return response.data; + } catch (err) { + return thunkAPI.rejectWithValue(err.response.data); + } + } +); + export const getSubstanceHandling = createAsyncThunk( "serverActions/get-substance-handling", async (params, thunkAPI) => { diff --git a/src/services/api.js b/src/services/api.js index 9f04e55b..a92d4b07 100644 --- a/src/services/api.js +++ b/src/services/api.js @@ -814,6 +814,12 @@ api.clinicalNotes.getUserLast = (params) => ...setHeaders(), }); +api.clinicalNotes.getUserLastList = (params) => + instance.get(`/notes/get-user-last-list`, { + params, + ...setHeaders(), + }); + api.clinicalNotes.createClinicalNote = (params = {}) => instance.post(`${endpoints.clinicalNotes}`, params, setHeaders()); From 34ccb404d42f86220afeeb6cb9019aec0c95f14e Mon Sep 17 00:00:00 2001 From: Marcelo Arocha Date: Mon, 18 May 2026 21:38:05 -0300 Subject: [PATCH 02/18] feat: stacked charts --- src/components/ChartCreator/ChartCreator.tsx | 10 ++++++++++ .../ChartCreator/ChartFormFields.tsx | 20 ++++++++++++++++++- src/components/ChartCreator/types.ts | 1 + src/components/ChartCreator/utils.ts | 5 ++++- 4 files changed, 34 insertions(+), 2 deletions(-) diff --git a/src/components/ChartCreator/ChartCreator.tsx b/src/components/ChartCreator/ChartCreator.tsx index 2b00b765..e92a7eb9 100644 --- a/src/components/ChartCreator/ChartCreator.tsx +++ b/src/components/ChartCreator/ChartCreator.tsx @@ -29,6 +29,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: const [newReferenceLine, setNewReferenceLine] = useState(undefined); const [newShowTitle, setNewShowTitle] = useState(true); const [newColorPalette, setNewColorPalette] = useState("default"); + const [newStacked, setNewStacked] = useState(false); // State for EDITING chart form (Modal) const [editTitle, setEditTitle] = useState(""); @@ -47,6 +48,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: const [editReferenceLine, setEditReferenceLine] = useState(undefined); const [editShowTitle, setEditShowTitle] = useState(true); const [editColorPalette, setEditColorPalette] = useState("default"); + const [editStacked, setEditStacked] = useState(false); const [editingChartId, setEditingChartId] = useState(null); const keys = useMemo(() => { @@ -86,6 +88,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: referenceLine: newReferenceLine, showTitle: newShowTitle, colorPalette: newColorPalette, + stacked: newStacked, }, ]); setNewTitle(""); @@ -104,6 +107,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: setNewReferenceLine(undefined); setNewShowTitle(true); setNewColorPalette("default"); + setNewStacked(false); } }; @@ -125,6 +129,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: setEditReferenceLine(chart.referenceLine); setEditShowTitle(chart.showTitle ?? true); setEditColorPalette(chart.colorPalette ?? "default"); + setEditStacked(chart.stacked ?? false); }, []); const saveEdit = () => { @@ -150,6 +155,7 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: referenceLine: editReferenceLine, showTitle: editShowTitle, colorPalette: editColorPalette, + stacked: editStacked, } : c, ), @@ -228,6 +234,8 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: setShowTitle={setNewShowTitle} colorPalette={newColorPalette} setColorPalette={setNewColorPalette} + stacked={newStacked} + setStacked={setNewStacked} keys={keys} /> @@ -286,6 +294,8 @@ export function ChartCreator({ data, initialCharts, onChartsChange, readOnly }: setShowTitle={setEditShowTitle} colorPalette={editColorPalette} setColorPalette={setEditColorPalette} + stacked={editStacked} + setStacked={setEditStacked} keys={keys} /> diff --git a/src/components/ChartCreator/ChartFormFields.tsx b/src/components/ChartCreator/ChartFormFields.tsx index 7e746700..881214d4 100644 --- a/src/components/ChartCreator/ChartFormFields.tsx +++ b/src/components/ChartCreator/ChartFormFields.tsx @@ -40,6 +40,8 @@ interface ChartFormFieldsProps { setShowTitle: (val: boolean) => void; colorPalette: ColorPalette; setColorPalette: (val: ColorPalette) => void; + stacked: boolean; + setStacked: (val: boolean) => void; keys: string[]; } @@ -121,6 +123,8 @@ export const ChartFormFields = ({ setShowTitle, colorPalette, setColorPalette, + stacked, + setStacked, keys, }: ChartFormFieldsProps) => { const allYOptions = keys.map((k) => ({ label: k, value: k })); @@ -359,7 +363,7 @@ export const ChartFormFields = ({ - {/* Show labels + X label rotation */} + {/* Show labels + Stacked */} + {(type === "bar" || type === "hbar") && ( + + + + + )} {/* Reference line */} diff --git a/src/components/ChartCreator/types.ts b/src/components/ChartCreator/types.ts index e4a7d1d6..fcf4a831 100644 --- a/src/components/ChartCreator/types.ts +++ b/src/components/ChartCreator/types.ts @@ -39,6 +39,7 @@ export interface ChartConfig { referenceLine?: ReferenceLine; showTitle?: boolean; colorPalette?: ColorPalette; + stacked?: boolean; } export interface ChartCreatorProps { diff --git a/src/components/ChartCreator/utils.ts b/src/components/ChartCreator/utils.ts index 1701c9b3..a4be60ed 100644 --- a/src/components/ChartCreator/utils.ts +++ b/src/components/ChartCreator/utils.ts @@ -236,9 +236,10 @@ export const getChartOption = (data: any[], config: ChartConfig) => { } const isHBar = config.type === "hbar"; + const isStacked = !!config.stacked && (config.type === "bar" || config.type === "hbar"); const label = { show: showLabels, - position: isHBar ? "right" as const : "top" as const, + position: isStacked ? "inside" as const : (isHBar ? "right" as const : "top" as const), formatter: isCountPct ? (params: any) => `${params.data.rawCount} (${params.value}%)` : "{c}", @@ -276,6 +277,7 @@ export const getChartOption = (data: any[], config: ChartConfig) => { type: echartsType, label, markLine, + ...(isStacked ? { stack: "total" } : {}), }, ] : config.yKeys @@ -287,6 +289,7 @@ export const getChartOption = (data: any[], config: ChartConfig) => { label, // Only attach markLine to the first series to avoid duplication ...(idx === 0 && markLine ? { markLine } : {}), + ...(isStacked ? { stack: "total" } : {}), })); const legendData = isCount From b43651a536b4b5eadde29065ef4aa7ae970626b3 Mon Sep 17 00:00:00 2001 From: Marcelo Arocha Date: Mon, 18 May 2026 22:08:25 -0300 Subject: [PATCH 03/18] feat: responsible physician filter --- .../Filter/components/FilterFields.jsx | 31 +++++++++++++++++++ .../Prioritization/Filter/index.jsx | 3 ++ src/models/Feature.js | 8 +++++ 3 files changed, 42 insertions(+) diff --git a/src/components/Prioritization/Filter/components/FilterFields.jsx b/src/components/Prioritization/Filter/components/FilterFields.jsx index 20e97687..08a3cb31 100644 --- a/src/components/Prioritization/Filter/components/FilterFields.jsx +++ b/src/components/Prioritization/Filter/components/FilterFields.jsx @@ -394,6 +394,37 @@ export default function FilterFields({ )} + {FeatureService.has( + Feature.PRIORITIZATION_FIELD_RESPONSIBLE_PHYSICIAN, + ) && ( +
+
+
+ +
+
+