@digihmis/esm-login-app 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (186) hide show
  1. package/README.md +35 -0
  2. package/__mocks__/config.mock.ts +34 -0
  3. package/__mocks__/locations.mock.ts +540 -0
  4. package/__mocks__/react-i18next.js +49 -0
  5. package/dist/1091.js +1 -0
  6. package/dist/1091.js.map +1 -0
  7. package/dist/119.js +1 -0
  8. package/dist/119.js.map +1 -0
  9. package/dist/1339.js +1 -0
  10. package/dist/1339.js.map +1 -0
  11. package/dist/1465.js +1 -0
  12. package/dist/1576.js +1 -0
  13. package/dist/1799.js +1 -0
  14. package/dist/1827.js +1 -0
  15. package/dist/204.js +1 -0
  16. package/dist/204.js.map +1 -0
  17. package/dist/2197.js +1 -0
  18. package/dist/2254.js +1 -0
  19. package/dist/2273.js +1 -0
  20. package/dist/2573.js +1 -0
  21. package/dist/2573.js.map +1 -0
  22. package/dist/2603.js +1 -0
  23. package/dist/2802.js +1 -0
  24. package/dist/3040.js +1 -0
  25. package/dist/3074.js +1 -0
  26. package/dist/3116.js +1 -0
  27. package/dist/3408.js +1 -0
  28. package/dist/3472.js +1 -0
  29. package/dist/3472.js.map +1 -0
  30. package/dist/3549.js +1 -0
  31. package/dist/3566.js +1 -0
  32. package/dist/3631.js +1 -0
  33. package/dist/3663.js +15 -0
  34. package/dist/3663.js.map +1 -0
  35. package/dist/3667.js +1 -0
  36. package/dist/3667.js.map +1 -0
  37. package/dist/3720.js +1 -0
  38. package/dist/3720.js.map +1 -0
  39. package/dist/3809.js +1 -0
  40. package/dist/3890.js +1 -0
  41. package/dist/3890.js.map +1 -0
  42. package/dist/4316.js +1 -0
  43. package/dist/4523.js +1 -0
  44. package/dist/4523.js.map +1 -0
  45. package/dist/4571.js +1 -0
  46. package/dist/4618.js +1 -0
  47. package/dist/4641.js +1 -0
  48. package/dist/466.js +1 -0
  49. package/dist/466.js.map +1 -0
  50. package/dist/4904.js +1 -0
  51. package/dist/5138.js +1 -0
  52. package/dist/5170.js +1 -0
  53. package/dist/5170.js.map +1 -0
  54. package/dist/5177.js +1 -0
  55. package/dist/5882.js +1 -0
  56. package/dist/6339.js +1 -0
  57. package/dist/6666.js +1 -0
  58. package/dist/689.js +1 -0
  59. package/dist/689.js.map +1 -0
  60. package/dist/6989.js +1 -0
  61. package/dist/6989.js.map +1 -0
  62. package/dist/7085.js +1 -0
  63. package/dist/7085.js.map +1 -0
  64. package/dist/7127.js +1 -0
  65. package/dist/720.js +1 -0
  66. package/dist/7240.js +1 -0
  67. package/dist/7240.js.map +1 -0
  68. package/dist/7329.js +1 -0
  69. package/dist/7329.js.map +1 -0
  70. package/dist/760.js +1 -0
  71. package/dist/760.js.map +1 -0
  72. package/dist/7751.js +1 -0
  73. package/dist/7874.js +1 -0
  74. package/dist/7874.js.map +1 -0
  75. package/dist/7925.js +43 -0
  76. package/dist/7925.js.map +1 -0
  77. package/dist/8037.js +1 -0
  78. package/dist/8381.js +1 -0
  79. package/dist/8474.js +1 -0
  80. package/dist/8674.js +1 -0
  81. package/dist/868.js +1 -0
  82. package/dist/8925.js +1 -0
  83. package/dist/8958.js +1 -0
  84. package/dist/8958.js.map +1 -0
  85. package/dist/900.js +1 -0
  86. package/dist/9001.js +1 -0
  87. package/dist/9001.js.map +1 -0
  88. package/dist/916.js +1 -0
  89. package/dist/918.js +1 -0
  90. package/dist/954.js +1 -0
  91. package/dist/970.js +1 -0
  92. package/dist/9754.js +1 -0
  93. package/dist/998.js +1 -0
  94. package/dist/998.js.map +1 -0
  95. package/dist/digihmis-esm-login-app.js +6 -0
  96. package/dist/digihmis-esm-login-app.js.buildmanifest.json +1704 -0
  97. package/dist/digihmis-esm-login-app.js.map +1 -0
  98. package/dist/main.js +6 -0
  99. package/dist/main.js.map +1 -0
  100. package/dist/routes.json +1 -0
  101. package/jest.config.js +20 -0
  102. package/package.json +73 -0
  103. package/rspack.config.js +1 -0
  104. package/src/background-wrapper/background-wrapper.component.tsx +58 -0
  105. package/src/background-wrapper/background-wrapper.scss +45 -0
  106. package/src/change-location-link/change-location-link.extension.tsx +32 -0
  107. package/src/change-location-link/change-location-link.scss +17 -0
  108. package/src/change-location-link/change-location-link.test.tsx +36 -0
  109. package/src/change-password/change-password-link.extension.tsx +30 -0
  110. package/src/change-password/change-password-link.test.tsx +27 -0
  111. package/src/change-password/change-password-modal.scss +11 -0
  112. package/src/change-password/change-password.component.tsx +159 -0
  113. package/src/change-password/change-password.modal.tsx +175 -0
  114. package/src/change-password/change-password.resource.ts +12 -0
  115. package/src/change-password/change-password.scss +51 -0
  116. package/src/change-password/change-password.test.tsx +53 -0
  117. package/src/config-schema.ts +166 -0
  118. package/src/declarations.d.ts +1 -0
  119. package/src/flag/flag.component.tsx +19 -0
  120. package/src/footer.component.tsx +41 -0
  121. package/src/footer.scss +105 -0
  122. package/src/index.ts +25 -0
  123. package/src/loading/loading.component.tsx +11 -0
  124. package/src/loading/loading.scss +7 -0
  125. package/src/location-picker/location-picker-view.component.tsx +174 -0
  126. package/src/location-picker/location-picker.resource.ts +111 -0
  127. package/src/location-picker/location-picker.scss +94 -0
  128. package/src/location-picker/location-picker.test.tsx +341 -0
  129. package/src/login/login.component.tsx +256 -0
  130. package/src/login/login.scss +174 -0
  131. package/src/login/login.test.tsx +289 -0
  132. package/src/login.resource.ts +147 -0
  133. package/src/logo.component.tsx +24 -0
  134. package/src/logout/logout.extension.tsx +23 -0
  135. package/src/logout/logout.scss +12 -0
  136. package/src/redirect-logout/logout.resource.ts +21 -0
  137. package/src/redirect-logout/redirect-logout.component.tsx +34 -0
  138. package/src/redirect-logout/redirect-logout.test.tsx +117 -0
  139. package/src/root.component.tsx +22 -0
  140. package/src/routes.json +63 -0
  141. package/src/setupTests.ts +15 -0
  142. package/src/test-helpers/render-with-router.tsx +17 -0
  143. package/src/types.ts +34 -0
  144. package/translations/am.json +39 -0
  145. package/translations/ar.json +41 -0
  146. package/translations/ar_SY.json +41 -0
  147. package/translations/bn.json +41 -0
  148. package/translations/cs.json +41 -0
  149. package/translations/de.json +41 -0
  150. package/translations/en.json +39 -0
  151. package/translations/en_US.json +41 -0
  152. package/translations/es.json +41 -0
  153. package/translations/es_MX.json +41 -0
  154. package/translations/fr.json +41 -0
  155. package/translations/he.json +41 -0
  156. package/translations/hi.json +41 -0
  157. package/translations/hi_IN.json +41 -0
  158. package/translations/id.json +41 -0
  159. package/translations/it.json +41 -0
  160. package/translations/ka.json +41 -0
  161. package/translations/km.json +41 -0
  162. package/translations/ku.json +41 -0
  163. package/translations/ky.json +41 -0
  164. package/translations/lg.json +41 -0
  165. package/translations/ne.json +41 -0
  166. package/translations/pl.json +41 -0
  167. package/translations/pt.json +41 -0
  168. package/translations/pt_BR.json +41 -0
  169. package/translations/qu.json +41 -0
  170. package/translations/ro_RO.json +41 -0
  171. package/translations/ru_RU.json +41 -0
  172. package/translations/si.json +41 -0
  173. package/translations/sq.json +41 -0
  174. package/translations/sw.json +39 -0
  175. package/translations/sw_KE.json +41 -0
  176. package/translations/tr.json +41 -0
  177. package/translations/tr_TR.json +41 -0
  178. package/translations/uk.json +41 -0
  179. package/translations/uz.json +41 -0
  180. package/translations/uz@Latn.json +41 -0
  181. package/translations/uz_UZ.json +41 -0
  182. package/translations/vi.json +41 -0
  183. package/translations/zh.json +41 -0
  184. package/translations/zh_CN.json +41 -0
  185. package/translations/zh_TW.json +41 -0
  186. package/tsconfig.json +25 -0
@@ -0,0 +1,34 @@
1
+ import { useEffect } from 'react';
2
+ import { navigate, setUserLanguage, useConfig, useConnectivity, useSession } from '@openmrs/esm-framework';
3
+ import { clearHistory } from '@openmrs/esm-framework/src/internal';
4
+ import { type ConfigSchema } from '../config-schema';
5
+ import { performLogout } from './logout.resource';
6
+
7
+ const RedirectLogout: React.FC = () => {
8
+ const config = useConfig<ConfigSchema>();
9
+ const isLoginEnabled = useConnectivity();
10
+ const session = useSession();
11
+
12
+ useEffect(() => {
13
+ clearHistory();
14
+ if (!session.authenticated || !isLoginEnabled) {
15
+ if (config.provider.type !== 'oauth2') {
16
+ navigate({ to: '${openmrsSpaBase}/login' });
17
+ }
18
+ } else {
19
+ performLogout()
20
+ .then(() => {
21
+ if (config.provider.type !== 'oauth2') {
22
+ navigate({ to: '${openmrsSpaBase}/login' });
23
+ }
24
+ })
25
+ .catch((error) => {
26
+ console.error('Logout failed:', error);
27
+ });
28
+ }
29
+ }, [config, isLoginEnabled, session]);
30
+
31
+ return null;
32
+ };
33
+
34
+ export default RedirectLogout;
@@ -0,0 +1,117 @@
1
+ import React from 'react';
2
+ import { mutate } from 'swr';
3
+ import { render, waitFor } from '@testing-library/react';
4
+ import {
5
+ type FetchResponse,
6
+ type Session,
7
+ clearCurrentUser,
8
+ navigate,
9
+ openmrsFetch,
10
+ refetchCurrentUser,
11
+ restBaseUrl,
12
+ setUserLanguage,
13
+ useConfig,
14
+ useConnectivity,
15
+ useSession,
16
+ } from '@openmrs/esm-framework';
17
+ import RedirectLogout from './redirect-logout.component';
18
+
19
+ jest.mock('swr', () => ({
20
+ mutate: jest.fn(),
21
+ }));
22
+
23
+ const mockClearCurrentUser = jest.mocked(clearCurrentUser);
24
+ const mockNavigate = jest.mocked(navigate);
25
+ const mockOpenmrsFetch = jest.mocked(openmrsFetch);
26
+ const mockRefetchCurrentUser = jest.mocked(refetchCurrentUser);
27
+ const mockSetUserLanguage = jest.mocked(setUserLanguage);
28
+ const mockUseConfig = jest.mocked(useConfig);
29
+ const mockUseConnectivity = jest.mocked(useConnectivity);
30
+ const mockUseSession = jest.mocked(useSession);
31
+
32
+ describe('RedirectLogout', () => {
33
+ beforeEach(() => {
34
+ mockUseConnectivity.mockReturnValue(true);
35
+ mockOpenmrsFetch.mockResolvedValue({} as FetchResponse<unknown>);
36
+
37
+ mockUseSession.mockReturnValue({
38
+ authenticated: true,
39
+ sessionId: 'xyz',
40
+ } as Session);
41
+
42
+ mockUseConfig.mockReturnValue({
43
+ provider: {
44
+ type: '',
45
+ },
46
+ });
47
+
48
+ Object.defineProperty(document, 'documentElement', {
49
+ configurable: true,
50
+ value: {
51
+ getAttribute: jest.fn().mockReturnValue('km'),
52
+ },
53
+ });
54
+ });
55
+
56
+ it('should redirect to login if the session is already unauthenticated', async () => {
57
+ mockUseSession.mockReturnValue({
58
+ authenticated: false,
59
+ } as Session);
60
+
61
+ render(<RedirectLogout />);
62
+
63
+ expect(mockNavigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' });
64
+ });
65
+
66
+ it('should redirect to login if the application is offline', async () => {
67
+ mockUseConnectivity.mockReturnValue(false);
68
+
69
+ render(<RedirectLogout />);
70
+
71
+ expect(mockNavigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' });
72
+ });
73
+
74
+ it('should handle logout failure gracefully', async () => {
75
+ const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {});
76
+ mockOpenmrsFetch.mockRejectedValue(new Error('Logout failed'));
77
+
78
+ render(<RedirectLogout />);
79
+
80
+ await waitFor(() => {
81
+ expect(consoleError).toHaveBeenCalledWith('Logout failed:', new Error('Logout failed'));
82
+ });
83
+
84
+ consoleError.mockRestore();
85
+ });
86
+
87
+ it('should handle config changes appropriately', async () => {
88
+ const { rerender } = render(<RedirectLogout />);
89
+
90
+ mockUseConfig.mockReturnValue({
91
+ provider: {
92
+ type: 'testProvider',
93
+ },
94
+ });
95
+
96
+ rerender(<RedirectLogout />);
97
+
98
+ await waitFor(() => {
99
+ expect(mockNavigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' });
100
+ });
101
+ });
102
+
103
+ it('should not redirect to login if user is not authenticated and the provider is oauth2', async () => {
104
+ mockUseSession.mockReturnValue({
105
+ authenticated: false,
106
+ } as Session);
107
+ mockUseConfig.mockReturnValue({
108
+ provider: {
109
+ type: 'oauth2',
110
+ },
111
+ });
112
+
113
+ render(<RedirectLogout />);
114
+
115
+ expect(mockNavigate).toHaveBeenCalledTimes(0);
116
+ });
117
+ });
@@ -0,0 +1,22 @@
1
+ import React from 'react';
2
+ import { BrowserRouter, Route, Routes } from 'react-router-dom';
3
+ import ChangePassword from './change-password/change-password.component';
4
+ import LocationPickerView from './location-picker/location-picker-view.component';
5
+ import Login from './login/login.component';
6
+ import RedirectLogout from './redirect-logout/redirect-logout.component';
7
+
8
+ const Root: React.FC = () => {
9
+ return (
10
+ <BrowserRouter basename={window.getOpenmrsSpaBase()}>
11
+ <Routes>
12
+ <Route path="login" element={<Login />} />
13
+ <Route path="login/confirm" element={<Login />} />
14
+ <Route path="login/location" element={<LocationPickerView />} />
15
+ <Route path="logout" element={<RedirectLogout />} />
16
+ <Route path="change-password" element={<ChangePassword />} />
17
+ </Routes>
18
+ </BrowserRouter>
19
+ );
20
+ };
21
+
22
+ export default Root;
@@ -0,0 +1,63 @@
1
+ {
2
+ "$schema": "https://json.openmrs.org/routes.schema.json",
3
+ "backendDependencies": {
4
+ "webservices.rest": ">=2.2.0"
5
+ },
6
+ "pages": [
7
+ {
8
+ "component": "root",
9
+ "route": "login",
10
+ "online": true,
11
+ "offline": true
12
+ },
13
+ {
14
+ "component": "root",
15
+ "route": "logout",
16
+ "online": true,
17
+ "offline": true
18
+ },
19
+ {
20
+ "component": "root",
21
+ "route": "change-password",
22
+ "online": true,
23
+ "offline": true
24
+ }
25
+ ],
26
+ "extensions": [
27
+ {
28
+ "name": "location-picker",
29
+ "slot": "location-picker",
30
+ "component": "locationPicker",
31
+ "online": true,
32
+ "offline": true
33
+ },
34
+ {
35
+ "name": "logout-button",
36
+ "slot": "user-panel-bottom-slot",
37
+ "component": "logoutButton",
38
+ "online": true,
39
+ "offline": true
40
+ },
41
+ {
42
+ "name": "password-changer",
43
+ "slot": "user-panel-slot",
44
+ "component": "changePasswordLink",
45
+ "online": true,
46
+ "offline": true
47
+ },
48
+ {
49
+ "name": "location-changer",
50
+ "slot": "top-nav-info-slot",
51
+ "component": "changeLocationLink",
52
+ "online": true,
53
+ "offline": true,
54
+ "order": 1
55
+ }
56
+ ],
57
+ "modals": [
58
+ {
59
+ "name": "change-password-modal",
60
+ "component": "changePasswordModal"
61
+ }
62
+ ]
63
+ }
@@ -0,0 +1,15 @@
1
+ import '@testing-library/jest-dom';
2
+
3
+ declare global {
4
+ interface Window {
5
+ openmrsBase: string;
6
+ spaBase: string;
7
+ }
8
+ }
9
+
10
+ const { getComputedStyle } = window;
11
+ window.getComputedStyle = (element) => getComputedStyle(element);
12
+ window.openmrsBase = '/openmrs';
13
+ window.spaBase = '/spa';
14
+ window.getOpenmrsSpaBase = () => '/openmrs/spa/';
15
+ window.HTMLElement.prototype.scrollIntoView = jest.fn();
@@ -0,0 +1,17 @@
1
+ import React from 'react';
2
+ import { MemoryRouter } from 'react-router-dom';
3
+ import { render } from '@testing-library/react';
4
+
5
+ export default function renderWithRouter<T = unknown>(
6
+ Component: React.JSXElementConstructor<T>,
7
+ props: T = {} as unknown as T,
8
+ { route = '/', routes = [route], routeParams = {} } = {},
9
+ ) {
10
+ return {
11
+ ...render(
12
+ <MemoryRouter initialEntries={routes} initialIndex={(route && routes?.indexOf(route)) || undefined}>
13
+ <Component {...props} />
14
+ </MemoryRouter>,
15
+ ),
16
+ };
17
+ }
package/src/types.ts ADDED
@@ -0,0 +1,34 @@
1
+ import { type FHIRLocationResource } from '@openmrs/esm-framework';
2
+
3
+ export interface LocationResponse {
4
+ type: string;
5
+ total: number;
6
+ resourceType: string;
7
+ meta: {
8
+ lastUpdated: string;
9
+ };
10
+ link: Array<{
11
+ relation: string;
12
+ url: string;
13
+ }>;
14
+ id: string;
15
+ entry: Array<FHIRLocationResource>;
16
+ }
17
+
18
+ export interface LocationEntry {
19
+ resource: Resource;
20
+ }
21
+
22
+ export interface Resource {
23
+ id: string;
24
+ name: string;
25
+ resourceType: string;
26
+ status: 'active' | 'inactive';
27
+ meta?: {
28
+ tag?: Array<{
29
+ code: string;
30
+ display: string;
31
+ system: string;
32
+ }>;
33
+ };
34
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "cancel": "Cancel",
3
+ "change": "Change",
4
+ "changeLocation": "Change location",
5
+ "changePassword": "Change password",
6
+ "changingPassword": "Changing password",
7
+ "confirm": "Confirm",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "locationPreferenceRemoved": "Login location preference removed",
14
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
15
+ "locationSaved": "Location saved",
16
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
17
+ "locationUpdated": "Location updated",
18
+ "locationUpdateMessage": "Your preferred login location has been updated",
19
+ "loggingIn": "Logging in",
20
+ "login": "Log in",
21
+ "loginButtonIconDescription": "Log in button",
22
+ "Logout": "Logout",
23
+ "newPassword": "New password",
24
+ "newPasswordRequired": "New password is required",
25
+ "oldPassword": "Old password",
26
+ "oldPasswordRequired": "Old password is required",
27
+ "openmrsLogo": "OpenMRS logo",
28
+ "password": "Password",
29
+ "passwordChangedSuccessfully": "Password changed successfully",
30
+ "passwordConfirmationRequired": "Password confirmation is required",
31
+ "passwordsDoNotMatch": "Passwords do not match",
32
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
33
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
34
+ "showPassword": "Show password",
35
+ "submitting": "Submitting",
36
+ "username": "Username",
37
+ "validValueRequired": "A valid value is required",
38
+ "welcome": "Welcome"
39
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "يلغي",
4
+ "change": "تغيير",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "تغيير كلمة المرور",
7
+ "changingPassword": "تغيير كلمة المرور",
8
+ "confirmPassword": "تأكيد كلمة المرور الجديدة",
9
+ "continue": "استمرار",
10
+ "errorChangingPassword": "خطأ في تغيير كلمة المرور",
11
+ "footerlogo": "شعار التذييل",
12
+ "invalidCredentials": "بيانات الدخول غير صحيحة",
13
+ "learnMore": "Learn more",
14
+ "locationPreferenceRemoved": "تمت إزالة تفضيلات موقع تسجيل الدخول",
15
+ "locationPreferenceRemovedMessage": "سوف تحتاج إلى تحديد موقع عند كل تسجيل دخول",
16
+ "locationSaved": "تم حفظ الموقع",
17
+ "locationSaveMessage": "تم حفظ موقعك المفضل لتسجيلات الدخول المستقبلية",
18
+ "locationUpdated": "تم تحديث الموقع",
19
+ "locationUpdateMessage": "تم تحديث موقع تسجيل الدخول المفضل لديك",
20
+ "loggingIn": "جار الدخول",
21
+ "login": "تسجيل الدخول",
22
+ "loginButtonIconDescription": "Log in button",
23
+ "Logout": "تسجيل الخروج",
24
+ "newPassword": "New password",
25
+ "newPasswordRequired": "New password is required",
26
+ "oldPassword": "Old password",
27
+ "oldPasswordRequired": "Old password is required",
28
+ "openmrsLogo": "OpenMRS logo",
29
+ "password": "كلمة المرور",
30
+ "passwordChangedSuccessfully": "Password changed successfully",
31
+ "passwordConfirmationRequired": "مطلوب تأكيد كلمة المرور",
32
+ "passwordsDoNotMatch": "Passwords do not match",
33
+ "poweredBySubtext": "An open-source medical record system and global community",
34
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
35
+ "selectYourLocation": "اختر موقعك من القائمة أدناه. استخدم شريط البحث للعثور على موقعك.",
36
+ "showPassword": "Show password",
37
+ "submitting": "جار الإرسال",
38
+ "username": "اسم المستخدم",
39
+ "validValueRequired": "قيمة صالحة مطلوبة",
40
+ "welcome": "مرحبا"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "Cancel",
4
+ "change": "Change",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "Change password",
7
+ "changingPassword": "Changing password",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "learnMore": "Learn more",
14
+ "locationPreferenceRemoved": "Login location preference removed",
15
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
16
+ "locationSaved": "Location saved",
17
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
18
+ "locationUpdated": "Location updated",
19
+ "locationUpdateMessage": "Your preferred login location has been updated",
20
+ "loggingIn": "Logging in",
21
+ "login": "Log in",
22
+ "loginButtonIconDescription": "Log in button",
23
+ "Logout": "Logout",
24
+ "newPassword": "New password",
25
+ "newPasswordRequired": "New password is required",
26
+ "oldPassword": "Old password",
27
+ "oldPasswordRequired": "Old password is required",
28
+ "openmrsLogo": "OpenMRS logo",
29
+ "password": "Password",
30
+ "passwordChangedSuccessfully": "Password changed successfully",
31
+ "passwordConfirmationRequired": "Password confirmation is required",
32
+ "passwordsDoNotMatch": "Passwords do not match",
33
+ "poweredBySubtext": "An open-source medical record system and global community",
34
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
35
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
36
+ "showPassword": "Show password",
37
+ "submitting": "Submitting",
38
+ "username": "Username",
39
+ "validValueRequired": "A valid value is required",
40
+ "welcome": "Welcome"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "বাতিল",
4
+ "change": "পরিবর্তন",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "পাসওয়ার্ড পরিবর্তন",
7
+ "changingPassword": "পাসওয়ার্ড পরিবর্তন হচ্ছে",
8
+ "confirmPassword": "নতুন পাসওয়ার্ড নিশ্চিত করুন",
9
+ "continue": "এগিয়ে যান",
10
+ "errorChangingPassword": "পাসওয়ার্ড পরিবর্তনে ত্রুটি দেখা দিয়েছে",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "ইউজারনেম অথবা পাসওয়ার্ড সঠিক নয়",
13
+ "learnMore": "আরো জানুন",
14
+ "locationPreferenceRemoved": "Login location preference removed",
15
+ "locationPreferenceRemovedMessage": "প্রতিবার লগইন এর সময় ঠিকানা বাছাই করতে হবে",
16
+ "locationSaved": "ঠিকানা জমা হয়েছে",
17
+ "locationSaveMessage": "আপনার পছন্দনীয় ঠিকানা ভবিষ্যৎ লগইনের জন্য সংরক্ষন করা হয়েছে",
18
+ "locationUpdated": "ঠিকানা হালনাগাদ হয়েছে",
19
+ "locationUpdateMessage": "Your preferred login location has been updated",
20
+ "loggingIn": "লগ ইন হচ্ছে",
21
+ "login": "লগ ইন",
22
+ "loginButtonIconDescription": "লগ ইন বাটন",
23
+ "Logout": "লগ আউট",
24
+ "newPassword": "নতুন পাসওয়ার্ড",
25
+ "newPasswordRequired": "নতুন পাসওয়ার্ড প্রয়োজনীয়",
26
+ "oldPassword": "পুরাতন পাসওয়ার্ড",
27
+ "oldPasswordRequired": "পুরাতন পাসওয়ার্ড প্রয়োজনীয়",
28
+ "openmrsLogo": "ওপেনএমআরএস এর প্রতীক",
29
+ "password": "পাসওয়ার্ড",
30
+ "passwordChangedSuccessfully": "পাসওয়ার্ড পরিবর্তন সফল",
31
+ "passwordConfirmationRequired": "পাসওয়ার্ড নিশ্চিতকরণ প্রয়োজন",
32
+ "passwordsDoNotMatch": "পাসওয়ার্ডসমূহ মিলছে না",
33
+ "poweredBySubtext": "একটি ওপেন-সোর্স মেডিক্যাল রেকর্ড সিস্টেম এবং বিশ্বব্যাপী সম্প্রদায়",
34
+ "rememberLocationForFutureLogins": "ভবিষ্যৎ লগইনের জন্য ঠিকানা সংরক্ষন করুন",
35
+ "selectYourLocation": "নিমোক্ত তালিকা থেকে ঠিকানা বাছাই করুন। ঠিকানা খুজতে হলে সার্চবার ব্যবহার করুন।",
36
+ "showPassword": "পাসওয়ার্ড প্রদর্শন করুন",
37
+ "submitting": "সাবমিট করা হচ্ছে",
38
+ "username": "ইউজারনেম",
39
+ "validValueRequired": "বৈধ মান প্রয়োজন",
40
+ "welcome": "স্বাগতম"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "Cancel",
4
+ "change": "Change",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "Change password",
7
+ "changingPassword": "Changing password",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "learnMore": "Learn more",
14
+ "locationPreferenceRemoved": "Login location preference removed",
15
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
16
+ "locationSaved": "Location saved",
17
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
18
+ "locationUpdated": "Location updated",
19
+ "locationUpdateMessage": "Your preferred login location has been updated",
20
+ "loggingIn": "Logging in",
21
+ "login": "Log in",
22
+ "loginButtonIconDescription": "Log in button",
23
+ "Logout": "Logout",
24
+ "newPassword": "New password",
25
+ "newPasswordRequired": "New password is required",
26
+ "oldPassword": "Old password",
27
+ "oldPasswordRequired": "Old password is required",
28
+ "openmrsLogo": "OpenMRS logo",
29
+ "password": "Password",
30
+ "passwordChangedSuccessfully": "Password changed successfully",
31
+ "passwordConfirmationRequired": "Password confirmation is required",
32
+ "passwordsDoNotMatch": "Passwords do not match",
33
+ "poweredBySubtext": "An open-source medical record system and global community",
34
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
35
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
36
+ "showPassword": "Show password",
37
+ "submitting": "Submitting",
38
+ "username": "Username",
39
+ "validValueRequired": "A valid value is required",
40
+ "welcome": "Welcome"
41
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "Cancel",
4
+ "change": "Change",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "Change password",
7
+ "changingPassword": "Changing password",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "learnMore": "Learn more",
14
+ "locationPreferenceRemoved": "Login location preference removed",
15
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
16
+ "locationSaved": "Location saved",
17
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
18
+ "locationUpdated": "Location updated",
19
+ "locationUpdateMessage": "Your preferred login location has been updated",
20
+ "loggingIn": "Logging in",
21
+ "login": "Login",
22
+ "loginButtonIconDescription": "Log in button",
23
+ "Logout": "Logout",
24
+ "newPassword": "New password",
25
+ "newPasswordRequired": "New password is required",
26
+ "oldPassword": "Old password",
27
+ "oldPasswordRequired": "Old password is required",
28
+ "openmrsLogo": "OpenMRS logo",
29
+ "password": "Passwort",
30
+ "passwordChangedSuccessfully": "Password changed successfully",
31
+ "passwordConfirmationRequired": "Password confirmation is required",
32
+ "passwordsDoNotMatch": "Passwords do not match",
33
+ "poweredBySubtext": "An open-source medical record system and global community",
34
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
35
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
36
+ "showPassword": "Show password",
37
+ "submitting": "Submitting",
38
+ "username": "Benutzername",
39
+ "validValueRequired": "A valid value is required",
40
+ "welcome": "Willkommen"
41
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "cancel": "Cancel",
3
+ "change": "Change",
4
+ "changeLocation": "Change location",
5
+ "changePassword": "Change password",
6
+ "changingPassword": "Changing password",
7
+ "confirm": "Confirm",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "locationPreferenceRemoved": "Login location preference removed",
14
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
15
+ "locationSaved": "Location saved",
16
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
17
+ "locationUpdated": "Location updated",
18
+ "locationUpdateMessage": "Your preferred login location has been updated",
19
+ "loggingIn": "Logging in",
20
+ "login": "Log in",
21
+ "loginButtonIconDescription": "Log in button",
22
+ "Logout": "Logout",
23
+ "newPassword": "New password",
24
+ "newPasswordRequired": "New password is required",
25
+ "oldPassword": "Old password",
26
+ "oldPasswordRequired": "Old password is required",
27
+ "openmrsLogo": "OpenMRS logo",
28
+ "password": "Password",
29
+ "passwordChangedSuccessfully": "Password changed successfully",
30
+ "passwordConfirmationRequired": "Password confirmation is required",
31
+ "passwordsDoNotMatch": "Passwords do not match",
32
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
33
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
34
+ "showPassword": "Show password",
35
+ "submitting": "Submitting",
36
+ "username": "Username",
37
+ "validValueRequired": "A valid value is required",
38
+ "welcome": "Welcome"
39
+ }
@@ -0,0 +1,41 @@
1
+ {
2
+ "builtWith": "Built with",
3
+ "cancel": "Cancel",
4
+ "change": "Change",
5
+ "changeLocation": "Change location",
6
+ "changePassword": "Change password",
7
+ "changingPassword": "Changing password",
8
+ "confirmPassword": "Confirm new password",
9
+ "continue": "Continue",
10
+ "errorChangingPassword": "Error changing password",
11
+ "footerlogo": "Footer Logo",
12
+ "invalidCredentials": "Invalid username or password",
13
+ "learnMore": "Learn more",
14
+ "locationPreferenceRemoved": "Login location preference removed",
15
+ "locationPreferenceRemovedMessage": "You will need to select a location on each login",
16
+ "locationSaved": "Location saved",
17
+ "locationSaveMessage": "Your preferred location has been saved for future logins",
18
+ "locationUpdated": "Location updated",
19
+ "locationUpdateMessage": "Your preferred login location has been updated",
20
+ "loggingIn": "Logging in",
21
+ "login": "Log in",
22
+ "loginButtonIconDescription": "Log in button",
23
+ "Logout": "Logout",
24
+ "newPassword": "New password",
25
+ "newPasswordRequired": "New password is required",
26
+ "oldPassword": "Old password",
27
+ "oldPasswordRequired": "Old password is required",
28
+ "openmrsLogo": "OpenMRS logo",
29
+ "password": "Password",
30
+ "passwordChangedSuccessfully": "Password changed successfully",
31
+ "passwordConfirmationRequired": "Password confirmation is required",
32
+ "passwordsDoNotMatch": "Passwords do not match",
33
+ "poweredBySubtext": "An open-source medical record system and global community",
34
+ "rememberLocationForFutureLogins": "Remember my location for future logins",
35
+ "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.",
36
+ "showPassword": "Show password",
37
+ "submitting": "Submitting",
38
+ "username": "Username",
39
+ "validValueRequired": "A valid value is required",
40
+ "welcome": "Welcome"
41
+ }