Skip to content

Commit

Permalink
(feat) - O3-3197 - initial ward app (#1139)
Browse files Browse the repository at this point in the history
* (feat) - O3-3197 - initial ward app

* address PR comments

* add tests and config

* add webpack config

* Update packages/esm-ward-app/package.json

Co-authored-by: Dennis Kigen <[email protected]>

---------

Co-authored-by: Dennis Kigen <[email protected]>
  • Loading branch information
chibongho and denniskigen authored May 21, 2024
1 parent 3a5cb6b commit 2cccab3
Show file tree
Hide file tree
Showing 13 changed files with 222 additions and 0 deletions.
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ This repository contains frontend modules for the OpenMRS SPA. These modules rel
- [Patient search](packages/esm-patient-search-app)
- [Patient registration](packages/esm-patient-registration-app)
- [Patient list management](packages/esm-patient-list-management-app)
- [Ward](packages/esm-ward-app)

## Setup

Expand Down
3 changes: 3 additions & 0 deletions packages/esm-ward-app/jest.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
const rootConfig = require('../../jest.config.js');

module.exports = rootConfig;
53 changes: 53 additions & 0 deletions packages/esm-ward-app/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
{
"name": "@openmrs/esm-ward-app",
"version": "7.0.0",
"description": "Ward and bed management module for O3",
"browser": "dist/openmrs-esm-ward-app.js",
"main": "src/index.ts",
"source": true,
"license": "MPL-2.0",
"homepage": "https://github.com/openmrs/openmrs-esm-patient-management#readme",
"scripts": {
"start": "openmrs develop",
"serve": "webpack serve --mode=development",
"debug": "npm run serve",
"build": "webpack --mode production",
"analyze": "webpack --mode=production --env.analyze=true",
"lint": "cross-env eslint src --ext ts,tsx",
"test": "cross-env TZ=UTC jest --config jest.config.js --verbose false --passWithNoTests --color",
"test:watch": "cross-env TZ=UTC jest --watch --config jest.config.js --color",
"coverage": "yarn test --coverage",
"typescript": "tsc",
"extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.resource.ts' --config ../../tools/i18next-parser.config.js"
},
"browserslist": [
"extends browserslist-config-openmrs"
],
"keywords": [
"openmrs"
],
"publishConfig": {
"access": "public"
},
"repository": {
"type": "git",
"url": "git+https://github.com/openmrs/openmrs-esm-patient-management.git"
},
"bugs": {
"url": "https://github.com/openmrs/openmrs-esm-patient-management/issues"
},
"dependencies": {
"@carbon/react": "~1.37.0",
"lodash-es": "^4.17.15"
},
"peerDependencies": {
"@openmrs/esm-framework": "5.x",
"react": "^18.1.0",
"react-i18next": "11.x",
"react-router-dom": "6.x",
"swr": "2.x"
},
"devDependencies": {
"webpack": "^5.74.0"
}
}
5 changes: 5 additions & 0 deletions packages/esm-ward-app/src/config-schema.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { type ConfigSchema } from '@openmrs/esm-framework';

export const configSchema: ConfigSchema = {};

export interface ConfigObject {}
20 changes: 20 additions & 0 deletions packages/esm-ward-app/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { defineConfigSchema, getSyncLifecycle, registerBreadcrumbs } from '@openmrs/esm-framework';
import rootComponent from './root.component';
import { configSchema } from './config-schema';

export const importTranslation = require.context('../translations', false, /.json$/, 'lazy');

const moduleName = '@openmrs/esm-ward-app';

const options = {
featureName: 'ward',
moduleName,
};

export const root = getSyncLifecycle(rootComponent, options);

export function startupApp() {
registerBreadcrumbs([]);

defineConfigSchema(moduleName, configSchema);
}
20 changes: 20 additions & 0 deletions packages/esm-ward-app/src/root.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import React from 'react';
import { BrowserRouter, Route, Routes } from 'react-router-dom';
import WardView from './ward-view/ward-view.component';

const Root: React.FC = () => {
const wardViewBasename = window.getOpenmrsSpaBase() + 'ward';

return (
<main>
<BrowserRouter basename={wardViewBasename}>
<Routes>
<Route path="/" element={<WardView />} />
<Route path="/:locationUuid" element={<WardView />} />
</Routes>
</BrowserRouter>
</main>
);
};

export default Root;
14 changes: 14 additions & 0 deletions packages/esm-ward-app/src/routes.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
{
"$schema": "https://json.openmrs.org/routes.schema.json",
"backendDependencies": {
"webservices.rest": "^2.2.0"
},
"extensions": [
],
"pages": [
{
"component": "root",
"route": "ward"
}
]
}
32 changes: 32 additions & 0 deletions packages/esm-ward-app/src/ward-view/ward-view.component.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
import React from 'react';
import { showToast, useLocations, useSession } from '@openmrs/esm-framework';
import { useParams } from 'react-router-dom';
import { useTranslation } from 'react-i18next';

const WardView = () => {
const { locationUuid: locationUuidFromUrl } = useParams();
const { sessionLocation } = useSession();
const allLocations = useLocations();
const { t } = useTranslation();
const locationFromUrl = allLocations.find((l) => l.uuid === locationUuidFromUrl);

if (locationUuidFromUrl && !locationFromUrl) {
showToast({
title: t('invalidLocationSpecified', 'Invalid location specified'),
kind: 'warning',
description: t('unknownLocationUuid', 'Unknown location uuid: {{locationUuidFromUrl}}', { locationUuidFromUrl }),
});

return <></>;
}

const location = locationFromUrl ?? sessionLocation;

return (
<div>
<h1 id="ward-location">{location?.display}</h1>
</div>
);
};

export default WardView;
48 changes: 48 additions & 0 deletions packages/esm-ward-app/src/ward-view/ward-view.test.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
import React from 'react';
import { getDefaultsFromConfigSchema, useConfig, useSession } from '@openmrs/esm-framework';
import { screen } from '@testing-library/react';
import { useParams } from 'react-router-dom';
import { mockLocations } from '../../../../__mocks__/locations.mock';
import { renderWithSwr } from '../../../../tools/test-utils';
import { configSchema } from '../config-schema';
import WardView from './ward-view.component';

jest.mocked(useConfig).mockReturnValue({
...getDefaultsFromConfigSchema(configSchema),
});

const mockedSessionLocation = { uuid: 'abcd', display: 'mock location', links: [] };
jest.mocked(useSession).mockReturnValue({
sessionLocation: mockedSessionLocation,
authenticated: true,
sessionId: 'sessionId',
});

jest.mock('@openmrs/esm-framework', () => {
return {
...jest.requireActual('@openmrs/esm-framework'),
useLocations: jest.fn().mockImplementation(() => mockLocations.data.results),
};
});

jest.mock('react-router-dom', () => ({
...jest.requireActual('react-router-dom'),
useParams: jest.fn().mockReturnValue({}),
}));
const mockedUseParams = useParams as jest.Mock;

describe('WardView:', () => {
it('renders the session location when no location provided in URL', () => {
renderWithSwr(<WardView />);
const header = screen.getByRole('heading', { name: mockedSessionLocation.display });
expect(header).toBeInTheDocument();
});

it('renders the location provided in URL', () => {
const locationToUse = mockLocations.data.results[0];
mockedUseParams.mockReturnValueOnce({ locationUuid: locationToUse.uuid });
renderWithSwr(<WardView />);
const header = screen.getByRole('heading', { name: locationToUse.display });
expect(header).toBeInTheDocument();
});
});
4 changes: 4 additions & 0 deletions packages/esm-ward-app/translations/en.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"invalidLocationSpecified": "Invalid location specified",
"unknownLocationUuid": "Unknown location uuid: {{locationUuidFromUrl}}"
}
5 changes: 5 additions & 0 deletions packages/esm-ward-app/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
{
"extends": "../../tsconfig.json",
"include": ["src/**/*"],
"exclude": ["src/**/*.test.tsx"]
}
1 change: 1 addition & 0 deletions packages/esm-ward-app/webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
module.exports = require('openmrs/default-webpack-config');
16 changes: 16 additions & 0 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -3583,6 +3583,22 @@ __metadata:
languageName: node
linkType: hard

"@openmrs/esm-ward-app@workspace:packages/esm-ward-app":
version: 0.0.0-use.local
resolution: "@openmrs/esm-ward-app@workspace:packages/esm-ward-app"
dependencies:
"@carbon/react": "npm:~1.37.0"
lodash-es: "npm:^4.17.15"
webpack: "npm:^5.74.0"
peerDependencies:
"@openmrs/esm-framework": 5.x
react: ^18.1.0
react-i18next: 11.x
react-router-dom: 6.x
swr: 2.x
languageName: unknown
linkType: soft

"@openmrs/webpack-config@npm:5.5.1-pre.1756":
version: 5.5.1-pre.1756
resolution: "@openmrs/webpack-config@npm:5.5.1-pre.1756"
Expand Down

0 comments on commit 2cccab3

Please sign in to comment.