diff --git a/backend/scaffold.py b/backend/scaffold.py index 2df53ea..468c0d7 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: diff --git a/web/components/layout/Page.tsx b/web/components/layout/Page.tsx index b76aa45..e8579c1 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 = () => { @@ -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/locations/LocationSelectionDialog.tsx b/web/components/locations/LocationSelectionDialog.tsx index f8e91c3..eb1ab98 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/components/patients/PatientTasksView.tsx b/web/components/patients/PatientTasksView.tsx index e980e08..8da9382 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 8c6b7eb..9ee630e 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 +} diff --git a/web/hooks/useTasksContext.tsx b/web/hooks/useTasksContext.tsx index 46522ca..503b493 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 b173c69..217eca1 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} >