From cbeb1621fe800d912fb0497e884fc7be98edbbc7 Mon Sep 17 00:00:00 2001 From: Felix Evers Date: Fri, 30 Jan 2026 17:59:13 +0100 Subject: [PATCH 1/3] fix expandables --- web/components/layout/Page.tsx | 6 +++--- web/components/patients/PatientTasksView.tsx | 4 ++-- web/hooks/useStateWithLocalStorage.ts | 8 ++------ 3 files changed, 7 insertions(+), 11 deletions(-) diff --git a/web/components/layout/Page.tsx b/web/components/layout/Page.tsx index b76aa457..c82fe5e7 100644 --- a/web/components/layout/Page.tsx +++ b/web/components/layout/Page.tsx @@ -498,7 +498,7 @@ export const Sidebar = ({ isOpen, onClose, ...props }: SidebarProps) => { {translation('teams')} - + {context.teams.map(team => ( {team.title} @@ -526,7 +526,7 @@ export const Sidebar = ({ isOpen, onClose, ...props }: SidebarProps) => { {translation('wards')} - + {context.wards.map(ward => ( {ward.title} @@ -554,7 +554,7 @@ export const Sidebar = ({ isOpen, onClose, ...props }: SidebarProps) => { {translation('clinics')} - + {context.clinics.map(clinic => ( {clinic.title} diff --git a/web/components/patients/PatientTasksView.tsx b/web/components/patients/PatientTasksView.tsx index e980e081..8da93821 100644 --- a/web/components/patients/PatientTasksView.tsx +++ b/web/components/patients/PatientTasksView.tsx @@ -113,7 +113,7 @@ export const PatientTasksView = ({ {translation('openTasks')} ({openTasks.length}) - + {openTasks.length === 0 &&
{translation('noOpenTasks')}
} {openTasks.map(task => ( @@ -139,7 +139,7 @@ export const PatientTasksView = ({ {translation('closedTasks')} ({closedTasks.length}) - + {closedTasks.length === 0 &&
{translation('noClosedTasks')}
} {closedTasks.map(task => ( diff --git a/web/hooks/useStateWithLocalStorage.ts b/web/hooks/useStateWithLocalStorage.ts index 8c6b7eb1..9ee630e7 100644 --- a/web/hooks/useStateWithLocalStorage.ts +++ b/web/hooks/useStateWithLocalStorage.ts @@ -26,12 +26,8 @@ export const useStateWithLocalStorage = ({ }: useStateWithLocalStorageProps): [T, Dispatch>] => { const [value, setValue] = useState(() => loadFromLocalStorage(key, defaultValue)) - if('task-list-column-filters' === key) { - console.log('loading from localStorage', key, value) - } - useEffect(() => { saveToLocalStorage(key, value) - }, [key,value]) + }, [key, value]) return [value, setValue] -} \ No newline at end of file +} From e68dc0c36f0807b2f2e8a0f843c3610c54228448 Mon Sep 17 00:00:00 2001 From: Felix Evers Date: Fri, 30 Jan 2026 18:00:04 +0100 Subject: [PATCH 2/3] enable wards to use org-ids --- backend/scaffold.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/backend/scaffold.py b/backend/scaffold.py index 2df53ea0..468c0d79 100644 --- a/backend/scaffold.py +++ b/backend/scaffold.py @@ -326,10 +326,10 @@ async def _create_location_tree( organization_ids = data.get("organization_ids", []) if organization_ids: - allowed_types_for_orgs = {"HOSPITAL", "CLINIC", "PRACTICE", "TEAM"} + allowed_types_for_orgs = {"HOSPITAL", "CLINIC", "PRACTICE", "TEAM", "WARD"} if location_type.value not in allowed_types_for_orgs: logger.warning( - f"Organization IDs can only be assigned to HOSPITAL, CLINIC, PRACTICE, or TEAM. " + f"Organization IDs can only be assigned to HOSPITAL, CLINIC, PRACTICE, TEAM, or WARD. " f"Skipping organization assignment for location '{name}' (type: {location_type.value})" ) else: From 8a540cadaa5aff07cdd5877291338e010c46a1a8 Mon Sep 17 00:00:00 2001 From: Felix Evers Date: Fri, 30 Jan 2026 18:22:59 +0100 Subject: [PATCH 3/3] update location picker for positioning --- web/components/layout/Page.tsx | 2 +- .../locations/LocationSelectionDialog.tsx | 16 +++--- web/hooks/useTasksContext.tsx | 49 ++++++++++++++----- web/pages/wards/index.tsx | 4 +- 4 files changed, 47 insertions(+), 24 deletions(-) diff --git a/web/components/layout/Page.tsx b/web/components/layout/Page.tsx index c82fe5e7..e8579c14 100644 --- a/web/components/layout/Page.tsx +++ b/web/components/layout/Page.tsx @@ -159,7 +159,7 @@ export const SurveyModal = () => { } } - setupSurvey().catch(() => {}) + setupSurvey().catch(() => { }) }, [config.onboardingSurveyUrl, config.weeklySurveyUrl, user?.id, onboardingSurveyCompleted, weeklySurveyLastCompleted, surveyLastDismissed, isSurveyOpen]) const handleDismiss = () => { diff --git a/web/components/locations/LocationSelectionDialog.tsx b/web/components/locations/LocationSelectionDialog.tsx index f8e91c35..eb1ab980 100644 --- a/web/components/locations/LocationSelectionDialog.tsx +++ b/web/components/locations/LocationSelectionDialog.tsx @@ -138,15 +138,15 @@ const LocationTreeItem = ({ if (!hasChildren) { return ( -
- +
+ {labelContent}
) } return ( -
+
{ onExpandToggle(node.id, isOpen) }} - className="!shadow-none !bg-transparent !rounded-none" + className="!shadow-none !bg-transparent !rounded-none w-full" headerClassName="px-2 hover:bg-surface-hover rounded-lg transition-colors !text-text-primary hover:!text-text-primary flex-row-reverse justify-end cursor-pointer" - contentExpandedClassName="!max-h-none !overflow-visible border-l-2 border-divider ml-5 pl-2 pr-0 mt-1" + contentExpandedClassName="!max-h-none !h-auto !min-h-0 !overflow-visible !flex !flex-col px-1 data-[expanded]:py-2 border-l-2 border-divider ml-5 pl-2 pr-0 mt-1" >
{node.children.map(child => ( @@ -269,7 +269,7 @@ export const LocationSelectionDialog = ({ return (node: LocationNodeType) => { const kindStr = node.kind.toString().toUpperCase() return allowedKinds.has(node.kind as LocationType) || - allowedKinds.has(kindStr) + allowedKinds.has(kindStr) } } else if (useCase === 'clinic') { return (node: LocationNodeType) => { @@ -292,7 +292,7 @@ export const LocationSelectionDialog = ({ return (node: LocationNodeType) => { const kindStr = node.kind.toString().toUpperCase() return allowedKinds.has(node.kind as LocationType) || - allowedKinds.has(kindStr) + allowedKinds.has(kindStr) } } else if (useCase === 'teams') { const allowedKinds = new Set([ @@ -306,7 +306,7 @@ export const LocationSelectionDialog = ({ return (node: LocationNodeType) => { const kindStr = node.kind.toString().toUpperCase() return allowedKinds.has(node.kind as LocationType) || - allowedKinds.has(kindStr) + allowedKinds.has(kindStr) } } diff --git a/web/hooks/useTasksContext.tsx b/web/hooks/useTasksContext.tsx index 46522ca9..503b493f 100644 --- a/web/hooks/useTasksContext.tsx +++ b/web/hooks/useTasksContext.tsx @@ -49,6 +49,13 @@ function filterLocationsByRootSubtree( .map(loc => ({ id: loc.id, title: loc.title })) } +const ROOT_LOCATION_KINDS = new Set(['HOSPITAL', 'PRACTICE', 'CLINIC', 'TEAM', 'WARD']) + +function isAllowedRootKind(kind: string | undefined): boolean { + if (!kind) return false + return ROOT_LOCATION_KINDS.has(kind.toString().toUpperCase()) +} + type User = { id: string, name: string, @@ -154,10 +161,10 @@ export const TasksContextProvider = ({ children }: PropsWithChildren) => { const queryKey = query.queryKey as unknown[] const queryKeyStr = JSON.stringify(queryKey) return queryKeyStr.includes('GetPatients') || - queryKeyStr.includes('GetTasks') || - queryKeyStr.includes('GetLocations') || - queryKeyStr.includes('GetGlobalData') || - queryKeyStr.includes('GetOverviewData') + queryKeyStr.includes('GetTasks') || + queryKeyStr.includes('GetLocations') || + queryKeyStr.includes('GetGlobalData') || + queryKeyStr.includes('GetOverviewData') } }) } @@ -177,31 +184,46 @@ export const TasksContextProvider = ({ children }: PropsWithChildren) => { useEffect(() => { const totalPatientsCount = data?.patients?.length ?? 0 const waitingPatientsCount = data?.waitingPatients?.length ?? 0 - const rootLocations = data?.me?.rootLocations?.map(loc => ({ id: loc.id, title: loc.title, kind: loc.kind })) ?? [] + const backendRootLocations = data?.me?.rootLocations?.map(loc => ({ id: loc.id, title: loc.title, kind: loc.kind })) ?? [] + const backendRootIds = new Set(backendRootLocations.map(loc => loc.id)) + + const allNodes = allLocationsData?.locationNodes ?? [] + const allowedRootLocationIds = new Set(backendRootIds) + allNodes.forEach((node: { id: string, kind?: string }) => { + if (isAllowedRootKind(node.kind)) { + allowedRootLocationIds.add(node.id) + } + }) setState(prevState => { let selectedRootLocationIds = prevState.selectedRootLocationIds || [] - if (rootLocations.length > 0) { - const rootLocationIds = new Set(rootLocations.map(loc => loc.id)) - + if (allowedRootLocationIds.size > 0) { const isInitialSet = storedSelectedRootLocationIds.length === 0 - const validSelectedIds = selectedRootLocationIds.filter(id => rootLocationIds.has(id)) + const validSelectedIds = selectedRootLocationIds.filter(id => allowedRootLocationIds.has(id)) if (validSelectedIds.length !== selectedRootLocationIds.length) { selectedRootLocationIds = validSelectedIds } - const validStoredIds = storedSelectedRootLocationIds.filter(id => rootLocationIds.has(id)) + const validStoredIds = storedSelectedRootLocationIds.filter(id => allowedRootLocationIds.has(id)) if (validStoredIds.length !== storedSelectedRootLocationIds.length) { setStoredSelectedRootLocationIds(validStoredIds) } if (isInitialSet && selectedRootLocationIds.length === 0) { - selectedRootLocationIds = rootLocations.map(loc => loc.id) + selectedRootLocationIds = backendRootLocations.map(loc => loc.id) } } + const selectedIdsSet = new Set(selectedRootLocationIds) + const rootLocations: Array<{ id: string, title: string, kind?: string }> = [...backendRootLocations] + allNodes.forEach((node: { id: string, title: string, kind?: string }) => { + if (selectedIdsSet.has(node.id) && isAllowedRootKind(node.kind) && !backendRootIds.has(node.id)) { + rootLocations.push({ id: node.id, title: node.title, kind: node.kind }) + } + }) + return { ...prevState, user: data?.me ? { @@ -258,7 +280,8 @@ export const TasksContextProvider = ({ children }: PropsWithChildren) => { setState(prevState => { const newState = typeof updater === 'function' ? updater(prevState) : updater if (newState.selectedRootLocationIds !== prevState.selectedRootLocationIds) { - setStoredSelectedRootLocationIds(newState.selectedRootLocationIds || []) + const idsToStore = newState.selectedRootLocationIds || [] + setStoredSelectedRootLocationIds(idsToStore) } return newState }) @@ -275,4 +298,4 @@ export const TasksContextProvider = ({ children }: PropsWithChildren) => { {children} ) -} \ No newline at end of file +} diff --git a/web/pages/wards/index.tsx b/web/pages/wards/index.tsx index b173c69d..217eca14 100644 --- a/web/pages/wards/index.tsx +++ b/web/pages/wards/index.tsx @@ -242,7 +242,7 @@ const WardsOverviewPage: NextPage = () => {
)} headerClassName="typography-label-md font-bold !px-4 !py-4 rounded-xl" - contentExpandedClassName="pb-4" + contentExpandedClassName="!max-h-none !h-auto !overflow-visible pb-4" className="rounded-xl" isExpanded={true} > @@ -259,7 +259,7 @@ const WardsOverviewPage: NextPage = () => { key={index} label={wardGroup.name} headerClassName="typography-label-md font-bold !px-4 !py-4 rounded-xl" - contentExpandedClassName="pb-4" + contentExpandedClassName="!max-h-none !h-auto !overflow-visible pb-4" className="rounded-xl" isExpanded={false} >