Rebrand to Open Health and add Dashboard metrics view#1
Conversation
❌ Deploy Preview for storied-kelpie-ec8419 failed. Why did it fail? →
|
Reviewer's GuideRebrands the frontend from HospitalRun to Open Health and implements a metrics-driven Dashboard that aggregates counts from core repositories and displays them with localized labels across all supported locales. Sequence diagram for loading dashboard metrics with react-querysequenceDiagram
actor User
participant Dashboard
participant ReactQuery_useQuery
participant PatientRepository
participant AppointmentRepository
participant LabRepository
participant MedicationRepository
participant ImagingRepository
participant IncidentRepository
User->>Dashboard: Navigate to dashboard route
Dashboard->>Dashboard: useEffect updateTitle(t(dashboard.label))
Dashboard->>ReactQuery_useQuery: useQuery(dashboard-metrics, fetchPlatformMetrics)
ReactQuery_useQuery-->>Dashboard: isLoading true, data undefined
Dashboard->>User: Render Spinner loading state
par Fetch_all_metrics_in_parallel
ReactQuery_useQuery->>PatientRepository: count()
ReactQuery_useQuery->>AppointmentRepository: count()
ReactQuery_useQuery->>LabRepository: count()
ReactQuery_useQuery->>MedicationRepository: count()
ReactQuery_useQuery->>ImagingRepository: count()
ReactQuery_useQuery->>IncidentRepository: count()
and All_repositories_respond
PatientRepository-->>ReactQuery_useQuery: patientsCount
AppointmentRepository-->>ReactQuery_useQuery: appointmentsCount
LabRepository-->>ReactQuery_useQuery: labsCount
MedicationRepository-->>ReactQuery_useQuery: medicationsCount
ImagingRepository-->>ReactQuery_useQuery: imagingsCount
IncidentRepository-->>ReactQuery_useQuery: incidentsCount
end
alt Successful_metrics_fetch
ReactQuery_useQuery-->>Dashboard: data DataMetric_array, isLoading false
Dashboard->>Dashboard: totalRecords = sum(metrics.value)
Dashboard->>User: Render central hub title and description
Dashboard->>User: Render totalRecords card
Dashboard->>User: Render per-domain metric cards
else Metrics_fetch_error
ReactQuery_useQuery-->>Dashboard: error, isError true, isLoading false
Dashboard->>User: Render Alert with metricsLoadError
end
Updated class diagram for the dashboard metrics aggregationclassDiagram
class Dashboard {
+render() JSXElement
-useUpdateTitle() void
-useTranslator() void
}
class DataMetric {
+DataDomain domain
+number value
}
class DataDomain {
}
class fetchPlatformMetrics {
+call() Promise_DataMetric_array
}
class PatientRepository {
+count() Promise_number
}
class AppointmentRepository {
+count() Promise_number
}
class LabRepository {
+count() Promise_number
}
class MedicationRepository {
+count() Promise_number
}
class ImagingRepository {
+count() Promise_number
}
class IncidentRepository {
+count() Promise_number
}
Dashboard --> DataMetric : uses
Dashboard ..> DataDomain : uses
Dashboard ..> fetchPlatformMetrics : passes_to_useQuery
fetchPlatformMetrics --> PatientRepository : calls_count
fetchPlatformMetrics --> AppointmentRepository : calls_count
fetchPlatformMetrics --> LabRepository : calls_count
fetchPlatformMetrics --> MedicationRepository : calls_count
fetchPlatformMetrics --> ImagingRepository : calls_count
fetchPlatformMetrics --> IncidentRepository : calls_count
File-Level Changes
Tips and commandsInteracting with Sourcery
Customizing Your ExperienceAccess your dashboard to:
Getting Help
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: d6b0854428
ℹ️ About Codex in GitHub
Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".
| const [patients, appointments, labs, medications, imagings, incidents] = await Promise.all([ | ||
| PatientRepository.count(), | ||
| AppointmentRepository.count(), | ||
| LabRepository.count(), | ||
| MedicationRepository.count(), |
There was a problem hiding this comment.
Gate dashboard metrics by user permissions
fetchPlatformMetrics always queries counts for patients, appointments, labs, medications, imaging, and incidents before rendering, but this component does not check state.user.permissions first. Users who are denied module access are redirected to / by PrivateRoute, so they can still see record counts for domains they are not authorized to read, which leaks restricted operational data. Filter metric queries/rendering by the corresponding read permissions (or skip unauthorized repositories entirely) before requesting these counts.
Useful? React with 👍 / 👎.
There was a problem hiding this comment.
Hey - I've found 2 issues, and left some high level feedback:
- All of the non-enUs locale entries for the new dashboard strings are currently English; if this isn’t intentional, consider providing localized text (or explicit TODO markers) so it’s clear these still need translation.
Prompt for AI Agents
Please address the comments from this code review:
## Overall Comments
- All of the non-enUs locale entries for the new dashboard strings are currently English; if this isn’t intentional, consider providing localized text (or explicit TODO markers) so it’s clear these still need translation.
## Individual Comments
### Comment 1
<location path="src/dashboard/Dashboard.tsx" line_range="61" />
<code_context>
+ </Col>
+ </Row>
+ {isError && <Alert variant="danger">{t('dashboard.metricsLoadError')}</Alert>}
+ {isLoading && <Spinner animation="border" role="status" />}
+ {!isLoading && !isError && (
+ <>
</code_context>
<issue_to_address>
**suggestion:** The loading spinner could be made more accessible and visually integrated with the layout.
Consider wrapping the spinner in a `Row/Col` or flex container and centering it, and include accessible text per Bootstrap’s pattern, e.g.:
```tsx
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>
```
This will make the loading state clearer and more accessible.
Suggested implementation:
```typescript
{isError && <Alert variant="danger">{t('dashboard.metricsLoadError')}</Alert>}
{isLoading && (
<Row className="justify-content-center my-4">
<Col xs="auto" className="text-center">
<Spinner animation="border" role="status">
<span className="visually-hidden">{t('dashboard.loading')}</span>
</Spinner>
</Col>
</Row>
)}
{!isLoading && !isError && (
```
1. Ensure that a `dashboard.loading` key exists in your i18n translation files (e.g., `"dashboard.loading": "Loading..."`), or change the key in the code to match an existing translation such as `t('common.loading')` if that already exists in your project.
</issue_to_address>
### Comment 2
<location path="src/shared/locales/ar/translations/dashboard/index.ts" line_range="4-13" />
<code_context>
export default {
dashboard: {
label: 'لوحة القيادة',
+ centralHubTitle: 'Digital Health Command Center',
+ centralHubDescription: 'Centralize your care data across patients, appointments, labs, medications, imaging, and incidents.',
+ totalRecordsLabel: 'Total clinical records',
+ metricsLoadError: 'Unable to load centralized healthcare metrics. Please try again.',
+ metrics: {
+ patients: 'Patients',
+ appointments: 'Appointments',
+ labs: 'Lab requests',
+ medications: 'Medication requests',
+ imagings: 'Imaging requests',
+ incidents: 'Incidents',
+ },
},
</code_context>
<issue_to_address>
**issue:** New dashboard strings are left in English across non-English locale files.
These new keys (`centralHubTitle`, `centralHubDescription`, `totalRecordsLabel`, `metricsLoadError`, and `metrics.*`) are still in English in this non-en locale. If this bundle is user-facing, please either add translations now or mark them clearly as pending (e.g., with a TODO) to avoid a mixed-language UI.
</issue_to_address>Help me be more useful! Please click 👍 or 👎 on each comment and I'll use the feedback to improve your reviews.
| </Col> | ||
| </Row> | ||
| {isError && <Alert variant="danger">{t('dashboard.metricsLoadError')}</Alert>} | ||
| {isLoading && <Spinner animation="border" role="status" />} |
There was a problem hiding this comment.
suggestion: The loading spinner could be made more accessible and visually integrated with the layout.
Consider wrapping the spinner in a Row/Col or flex container and centering it, and include accessible text per Bootstrap’s pattern, e.g.:
<Spinner animation="border" role="status">
<span className="visually-hidden">Loading...</span>
</Spinner>This will make the loading state clearer and more accessible.
Suggested implementation:
{isError && <Alert variant="danger">{t('dashboard.metricsLoadError')}</Alert>}
{isLoading && (
<Row className="justify-content-center my-4">
<Col xs="auto" className="text-center">
<Spinner animation="border" role="status">
<span className="visually-hidden">{t('dashboard.loading')}</span>
</Spinner>
</Col>
</Row>
)}
{!isLoading && !isError && (- Ensure that a
dashboard.loadingkey exists in your i18n translation files (e.g.,"dashboard.loading": "Loading..."), or change the key in the code to match an existing translation such ast('common.loading')if that already exists in your project.
| centralHubTitle: 'Digital Health Command Center', | ||
| centralHubDescription: 'Centralize your care data across patients, appointments, labs, medications, imaging, and incidents.', | ||
| totalRecordsLabel: 'Total clinical records', | ||
| metricsLoadError: 'Unable to load centralized healthcare metrics. Please try again.', | ||
| metrics: { | ||
| patients: 'Patients', | ||
| appointments: 'Appointments', | ||
| labs: 'Lab requests', | ||
| medications: 'Medication requests', | ||
| imagings: 'Imaging requests', |
There was a problem hiding this comment.
issue: New dashboard strings are left in English across non-English locale files.
These new keys (centralHubTitle, centralHubDescription, totalRecordsLabel, metricsLoadError, and metrics.*) are still in English in this non-en locale. If this bundle is user-facing, please either add translations now or mark them clearly as pending (e.g., with a TODO) to avoid a mixed-language UI.
Motivation
Description
README.md,public/index.htmltitle/description, and navbar header label toOpen Healthand adjust default test user insrc/user/user-slice.tsto match the new name.src/__tests__/shared/components/navbar/Navbar.test.tsxto expectOpen Health.Dashboardimplementation insrc/dashboard/Dashboard.tsxthat usesreact-queryand repository count methods (PatientRepository,AppointmentRepository,LabRepository,MedicationRepository,ImagingRepository,IncidentRepository) to fetch metrics, and renders loading, error, total-records and per-domain cards usingreact-bootstrapcomponents.src/shared/locales/*/translations/dashboard/index.ts.Testing
yarn testand updatedNavbartests; all tests passed.Codex Task
Summary by Sourcery
Introduce a centralized dashboard that surfaces key platform metrics and rebrand visible frontend text from HospitalRun to Open Health.
New Features:
Enhancements:
Tests: