Skip to content

Commit 872e537

Browse files
committed
Merge branch 'develop'
2 parents 6f72b76 + 63a5c1e commit 872e537

File tree

808 files changed

+49513
-6637
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

808 files changed

+49513
-6637
lines changed

.gitignore

+5
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,7 @@
11
.DS_Store
2+
# common location for local config file containing connection credentials
3+
server/report_builder/config.yaml
24
.vscode/*
5+
6+
# Temp export files
7+
server/data

README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# Open mSupply
22

33
This is the home of an open source version of the popular [mSupply](https://msupply.org.nz/) - providing pharmaceutical supply chain management and dispensing, all the way from national warehouses to remote clinics, on servers, laptops and mobile.
4-
Used in over 30 countries and for over 20 years and now becoming open source.
4+
Used in over 30 countries and for over 20 years and now becoming open source software.
55

66
The code is separated into two main areas, the client and server:
77

build/windows/omsupply-build.bat

+17-7
Original file line numberDiff line numberDiff line change
@@ -13,10 +13,20 @@ xcopy "build\windows\*.*" "omSupply" /c
1313
xcopy "build\windows\demo" "omSupply\demo" /c /y /i
1414
copy "version.txt" "omSupply\version.txt"
1515

16-
@cd "build\windows"
17-
start /b /wait omsupply-prepare.bat
18-
start /b /wait omsupply-sqlite-build.bat
19-
start /b /wait omsupply-postgres-build.bat
20-
start /b /wait omsupply-desktop-build.bat
21-
cd "..\..\server"
22-
start /wait cargo build --release && copy "target\release\remote_server.exe" "..\omSupply\Server\omSupply-server-sqlite.exe"
16+
start /wait /b build\windows\omsupply-prepare.bat
17+
@if %errorlevel% neq 0 exit /b %errorlevel%
18+
19+
@ECHO ##### Building omsupply for the sqlite #####
20+
cd "server" && cargo build --release --bin omsupply_service && copy "target\release\omsupply_service.exe" "..\omSupply\Server\omSupply-sqlite.exe"
21+
@if %errorlevel% neq 0 exit /b %errorlevel%
22+
23+
@ECHO ##### Building omsupply for the postgres #####
24+
cd "server" && cargo build --release --bin omsupply_service --features postgres && copy "target\release\omsupply_service.exe" "..\omSupply\Server\omSupply-postgres.exe"
25+
@if %errorlevel% neq 0 exit /b %errorlevel%
26+
27+
@ECHO ##### Building omSupply for the desktop #####
28+
cd "client" && yarn electron:build && xcopy "packages\electron\out\open mSupply-win32-x64\**" "..\omSupply\Desktop\" /e /h /c /i
29+
@if %errorlevel% neq 0 exit /b %errorlevel%
30+
31+
cd "server" && cargo build --release && copy "target\release\remote_server.exe" "..\omSupply\Server\omSupply-server-sqlite.exe"
32+
@if %errorlevel% neq 0 exit /b %errorlevel%

build/windows/omsupply-desktop-build.bat

-2
This file was deleted.

build/windows/omsupply-postgres-build.bat

-2
This file was deleted.

build/windows/omsupply-prepare.bat

+3-2
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
1-
@ECHO ##### Prepare omsupply build #####
2-
cd "..\..\client" && yarn install --force --frozen-lockfile && yarn build
1+
ECHO ##### Prepare omsupply build #####
2+
cd "client" && yarn install --force --frozen-lockfile && yarn build
3+
if %errorlevel% neq 0 exit /b %errorlevel%

build/windows/omsupply-sqlite-build.bat

-2
This file was deleted.

client/.eslintrc.js

+9-2
Original file line numberDiff line numberDiff line change
@@ -30,10 +30,17 @@ module.exports = {
3030
plugins: ['react', , '@typescript-eslint'],
3131
rules: {
3232
camelcase: ['error', { allow: ['_ONLY_FOR_TESTING'] }],
33-
'require-jsdoc': 0,
33+
'require-jsdoc': 'off',
34+
'valid-jsdoc': 'off',
3435
'react/display-name': 'off',
3536
'no-unused-vars': 'off',
36-
'@typescript-eslint/no-unused-vars': 'error',
37+
'@typescript-eslint/no-unused-vars': [
38+
'error',
39+
{
40+
argsIgnorePattern: '^_',
41+
caughtErrorsIgnorePattern: '^_',
42+
},
43+
],
3744
'react/prop-types': 'off',
3845
'@typescript-eslint/no-empty-function': 'off',
3946
'spaced-comment': [

client/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -72,6 +72,7 @@ client
7272
│ ├─ host
7373
│ ├─ inventory
7474
│ ├─ invoices
75+
│ ├─ programs
7576
│ ├─ requisitions
7677
│ └─ system
7778
```
@@ -174,7 +175,6 @@ and you will see the keys being referenced in other hooks, like so:
174175
useQuery(api.keys.paramList(queryParams), ...
175176
```
176177

177-
178178
where the file `hooks/index.ts` has something like this in it:
179179

180180
```

client/lerna.json

+4-1
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,8 @@
11
{
22
"version": "0.0.0",
33
"npmClient": "yarn",
4-
"useWorkspaces": true
4+
"useWorkspaces": true,
5+
"packages": [
6+
"packages/*"
7+
]
58
}

client/package.json

+1-1
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,12 @@
1313
"serve": "lerna run --scope @openmsupply-client/* --parallel serve",
1414
"clean": "lerna run --scope @openmsupply-client/* --parallel clean",
1515
"compile": "lerna run --scope @openmsupply-client/* --parallel tsc --since HEAD -- --noEmit",
16+
"compile-full": "lerna run --scope @openmsupply-client/* --parallel tsc",
1617
"prepare": "cd .. && husky install client/.husky",
1718
"pre-commit-lint": "yarn compile && yarn lint-staged",
1819
"test": "jest --config ./jest.config.js --maxWorkers=50% --env=jsdom",
1920
"storybook": "storybook dev -p 6006",
2021
"build-storybook": "storybook build",
21-
"//": "The sed command here is a temporary workaround to fix an issue in graphql-codegen",
2222
"generate": "cd ../server && cargo run --bin remote_server_cli -- export-graphql-schema && cd ../client && graphql-codegen --config codegen.yml",
2323
"android:run": "npx cap run android",
2424
"android:build:server": "yarn build && lerna run --scope @openmsupply-client/android build:server --stream",

client/packages/android/README.MD

+24-18
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
11
# Mobile App with Discovery
22

33
The Android app can run as standalone site with a local server, as a client connecting to another server or as a server for other clients.
4-
On android, the server always starts and this allows for one mobile app for both client and client/server.
5-
The mobile app will broadcast via dns sd and will be reachable by both Mobile and Electron clients on the local network.
6-
We are using Capacitor to make use of existing optimisations and large library of native plugins.
4+
On android, the server always starts and this allows for one mobile app for both client and client/server.
5+
The mobile app will broadcast via dns sd and will be reachable by both Mobile and Electron clients on the local network.
6+
We are using Capacitor to make use of existing optimisations and large library of native plugins.
77
UI is not bundled within Capacitor, it is served by the server the client connect to, and discovery UI is always served by local bundled server.
88

99
## Getting started
@@ -18,7 +18,7 @@ Next step is to open this directory in Android Studio, this will engage gradle s
1818

1919
It's recommended to use Android Studio for debugging and running Android App, there is a lot of functionality that cannot be replicated in Visual Studio Code (although there are some extensions for Visual Studio Code they are quite limited).
2020

21-
Debugging native code is straight forward, breakpoint in Android Studio and press debug.
21+
Debugging native code is straight forward, breakpoint in Android Studio and press debug.
2222

2323
Debugging web app code is done by opening `chrome://inspect`, you should see Web View when app is running in emulator. When bundled is served from remote server (default setup), js bundle is minimised and this makes debugging very hard, however we can run the bundle from webpack server by commenting out plugins section in `capacitor.config.ts` and entering your local ip in the debugUrl field and running `yarn apply-config`. Please make sure that you start front end server with `yarn start-local` from 'client' directory for this to work.
2424

@@ -28,7 +28,7 @@ When running the Android app in an emulator the service discovery will not work
2828

2929
## Scripts
3030

31-
The following scripts are available
31+
The following scripts are available
3232

3333
```bash
3434
# Builds remote server binaries for android and copies them to android package
@@ -41,7 +41,7 @@ yarn build:release
4141
yarn apply-config
4242
```
4343

44-
As per earlier comment, please make sure to build front end with `yarn build` from client directory prior to runner the above or run `yarn android:{command here}` from client directory to do both with one command.
44+
As per earlier comment, please make sure to build front end with `yarn build` from client directory prior to runner the above or run `yarn android:{command here}` from client directory to do both with one command.
4545

4646
### Know script issues
4747

@@ -81,10 +81,10 @@ A few configuration/modifications were made to make sure we can serve Android bu
8181

8282
1. capacitor.config.ts (see comment in that file)
8383
2. Capacitor `proxies` inject some pre-requisite <scripts> into the target webpage.
84-
Since the mSupply servers uses self signed certs, fetching the target webpage fails and the pre-requisite scripts are not inserted.
85-
For this reason `ExtendedWebViewClient` was created to manually inject the required <script> tags.
86-
[Discussion](https://github.com/ionic-team/capacitor/discussions/6166) was made on capacitor github to see if there is another way to overcome this.
87-
3. Base url is loaded manually in `handleOnStart()` method in `NativeApi.java`
84+
Since the mSupply servers uses self signed certs, fetching the target webpage fails and the pre-requisite scripts are not inserted.
85+
For this reason `ExtendedWebViewClient` was created to manually inject the required <script> tags.
86+
[Discussion](https://github.com/ionic-team/capacitor/discussions/6166) was made on capacitor github to see if there is another way to overcome this.
87+
3. Base url is loaded manually in `handleOnStart()` method in `NativeApi.java`
8888

8989
## Extra
9090

@@ -96,11 +96,11 @@ The cert plugin (`app/src/main/java/org/openmsupply/client/certplugin/CertPlugin
9696

9797
Capacitor comes with cli, we mainly use `npx cap copy` (or `yarn apply-config`), this moves bundled assets to app/src/main/assets/public. Usually capacitor would bundle web app within the APK, since we are serving front end bundle with server we don't need to move them (you will not that in capacitor.config.ts `webDir` is pointed to a non-existant directory). Capacitor also moves pre requisites to cordova plugins to that folder, which is automatically injected into served `html`. Another task of `npx cap copy` is to copy configuration files `capacitor.config.ts` is translated to JSON file and moved to app/src/main/assets
9898

99-
`app/src/main/assets/public` directory is typically not committed, but since it's only going to have cordova artifacts, it is in our case (to reduce setup).
99+
`app/src/main/assets/public` directory is typically not committed, but since it's only going to have cordova artifacts, it is in our case (to reduce setup).
100100

101101
`npx cap copy` or `yarn apply-config` should only be run when cordova plugins are added or updated or when updating capacitor.config.ts
102102

103-
When adding plugins - add them to the android package; if they are not here, then `npx cap sync` does not detect them. You should see
103+
When adding plugins - add them to the android package; if they are not here, then `npx cap sync` does not detect them. You should see
104104

105105
```
106106
✔ Updating Android plugins in 2.09ms
@@ -111,24 +111,30 @@ When adding plugins - add them to the android package; if they are not here, the
111111
[info] Found 1 Cordova plugin for android:
112112
113113
```
114-
114+
115115
with the new plugin showing up under the Cordova or Capacitor plugins sections.
116+
Also, add the plugin to `onPageStarted` in `ExtendedWebViewClient` - see the other plugins for details.
116117
If you require the plugin to be used in other packages, then you can also install in the root, or in individual packages, to make it available for use elsewhere.
117118

118119
You can check the plugins using `npx cap ls` or the configuration generally with `npx cap doctor`
119120

120-
If you are having gradle issues, open the project (packages/android folder) in Android Studio and then click on the "Sync Project with Gradle Files" button in the top right of Android Studio (the icon looks like an elephant).
121+
If you are having gradle issues, open the project (packages/android folder) in Android Studio and then click on the "Sync Project with Gradle Files" button in the top right of Android Studio (the icon looks like an elephant).
121122

122123
## Self signed cert SSL security
123124

124125
To avoid an error being thrown by the native web view when the server certificate is self-signed, we override the web view certificate error listener and allow connection when:
125-
* In debug mode
126-
* The connection is local after verifying the certificate against the local `cert.pem` file : this is for discovery or when connecting to a local server
127-
*The stored SSL fingerprint matches the server fingerprint
128126

129-
For the above to work we store the SSL fingerprint when we first connect to the server and then check that fingerprint on consecutive connections.
127+
- In debug mode
128+
- The connection is local after verifying the certificate against the local `cert.pem` file : this is for discovery or when connecting to a local server
129+
\*The stored SSL fingerprint matches the server fingerprint
130+
131+
For the above to work we store the SSL fingerprint when we first connect to the server and then check that fingerprint on consecutive connections.
130132
The SSL fingerprint is stored in app data and is associated with the `hardwareId` and `port` of the server.
131133
This works very similar to ssh client, but we associate fingerprint with hardwareId and port instead of domain or ip since local ip can change for the server.
132134

133135
App data would need to be cleared if the local certificate was changed.
134136

137+
## Log files on Android
138+
139+
Go to `browse files` in device manager, then navigate to `data/org.openmsupply.client/files/(log_name).log` to view log, logs that have exceeded the max file size is compressed and saved as a `.gz` zip.
140+
Alternatively when using an emulator, navigate to `data/user/0/org.openmsupply.client/files/(log_name).log`.

client/packages/android/app/capacitor.build.gradle

+1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ apply from: "../capacitor-cordova-android-plugins/cordova.variables.gradle"
1111
dependencies {
1212
implementation project(':capacitor-community-barcode-scanner')
1313
implementation project(':capacitor-community-keep-awake')
14+
implementation project(':capacitor-app')
1415
implementation project(':capacitor-keyboard')
1516
implementation project(':capacitor-preferences')
1617
implementation "com.android.support:support-v4:28.+"

client/packages/android/app/src/main/assets/capacitor.plugins.json

+4
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,10 @@
77
"pkg": "@capacitor-community/keep-awake",
88
"classpath": "com.getcapacitor.community.keepawake.KeepAwakePlugin"
99
},
10+
{
11+
"pkg": "@capacitor/app",
12+
"classpath": "com.capacitorjs.plugins.app.AppPlugin"
13+
},
1014
{
1115
"pkg": "@capacitor/keyboard",
1216
"classpath": "com.capacitorjs.plugins.keyboard.KeyboardPlugin"

client/packages/android/app/src/main/java/org/openmsupply/client/ExtendedWebViewClient.java

+2-1
Original file line numberDiff line numberDiff line change
@@ -39,7 +39,8 @@ public void onPageStarted(WebView webView,
3939
bridge.getPlugin("WebView"),
4040
bridge.getPlugin("BarcodeScanner"),
4141
bridge.getPlugin("Preferences"),
42-
bridge.getPlugin("KeepAwake")
42+
bridge.getPlugin("KeepAwake"),
43+
bridge.getPlugin("App")
4344
);
4445

4546
try {

client/packages/android/app/src/main/java/org/openmsupply/client/NativeApi.java

+4-3
Original file line numberDiff line numberDiff line change
@@ -282,7 +282,7 @@ public void connectToServer(PluginCall call) throws MalformedURLException {
282282
response.put("success", true);
283283
} else {
284284
response.put("success", false);
285-
response.put("error", "Connecting to server: response code="+ status);
285+
response.put("error", "Connecting to server: response code=" + status);
286286
}
287287
} catch (SSLHandshakeException e) {
288288
// server is running and responding with an SSL error
@@ -383,6 +383,7 @@ private void addLocalServerToDiscovery() {
383383
}
384384
}
385385

386+
386387
private String parseAttribute(NsdServiceInfo serviceInfo, String name) {
387388
byte[] attributeBytes = serviceInfo.getAttributes().get(name);
388389
if (attributeBytes == null) {
@@ -469,7 +470,7 @@ public void saveFile(@NonNull PluginCall call) {
469470
/** Helper class to get access to the JS FrontEndHost data */
470471
public class FrontEndHost {
471472
JSObject data;
472-
473+
473474
public FrontEndHost(JSObject data) {
474475
this.data = data;
475476
}
@@ -491,7 +492,7 @@ public String getConnectionUrl() {
491492
if (data.getString("path") != null) {
492493
path = "/" + data.getString("path");
493494
}
494-
return getUrl() + path;
495+
return getUrl() + path;
495496
}
496497

497498
public boolean isLocal() {

client/packages/android/capacitor.settings.gradle

+3
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@ project(':capacitor-community-barcode-scanner').projectDir = new File('../../nod
88
include ':capacitor-community-keep-awake'
99
project(':capacitor-community-keep-awake').projectDir = new File('../../node_modules/@capacitor-community/keep-awake/android')
1010

11+
include ':capacitor-app'
12+
project(':capacitor-app').projectDir = new File('../../node_modules/@capacitor/app/android')
13+
1114
include ':capacitor-keyboard'
1215
project(':capacitor-keyboard').projectDir = new File('../../node_modules/@capacitor/keyboard/android')
1316

client/packages/android/package.json

+2
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44
"private": true,
55
"devDependencies": {
66
"@capacitor-community/barcode-scanner": "^3.0.3",
7+
"@capacitor-community/keep-awake": "^3.0.0",
8+
"@capacitor/app": "^4.1.1",
79
"@capacitor/cli": "^4.7.1",
810
"@capacitor/keyboard": "^4.1.1",
911
"@capacitor/preferences": "^4.0.2",

client/packages/common/package.json

+4
Original file line numberDiff line numberDiff line change
@@ -13,11 +13,14 @@
1313
"dependencies": {
1414
"@bugsnag/js": "^7.14.1",
1515
"@capacitor-community/barcode-scanner": "^3.0.3",
16+
"@capacitor/app": "^4.1.1",
17+
"@capacitor/core": "^4.7.0",
1618
"@emotion/react": "^11.7.1",
1719
"@emotion/styled": "^11.6.0",
1820
"@mui/lab": "^5.0.0-alpha.59",
1921
"@mui/material": "^5.11.13",
2022
"@openmsupply-client/config": "^0.0.0",
23+
"autosuggest-highlight": "^3.3.4",
2124
"currency.js": "^2.0.4",
2225
"date-fns": "^2.27.0",
2326
"dompurify": "^3.0.1",
@@ -48,6 +51,7 @@
4851
"zustand": "^4.3.6"
4952
},
5053
"devDependencies": {
54+
"@types/autosuggest-highlight": "^3.2.0",
5155
"@types/css-mediaquery": "^0.1.1",
5256
"@types/dompurify": "^3.0.0",
5357
"@types/js-cookie": "^3.0.1",

client/packages/common/src/authentication/api/hooks/useLogin.ts

+5-5
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import { IntlUtils } from '@common/intl';
1+
import { useIntlUtils } from '@common/intl';
22
import { AuthCookie, AuthError, setAuthCookie } from '../../AuthContext';
33
import { useGetAuthToken } from './useGetAuthToken';
44
import {
@@ -10,7 +10,7 @@ import {
1010
useLocalStorage,
1111
useQueryClient,
1212
} from '@openmsupply-client/common';
13-
import { UserNode } from '@common/types';
13+
import { LanguageType, UserNode } from '@common/types';
1414

1515
import { DefinitionNode, DocumentNode, OperationDefinitionNode } from 'graphql';
1616

@@ -43,7 +43,7 @@ export const useLogin = (
4343
setCookie: React.Dispatch<React.SetStateAction<AuthCookie | undefined>>
4444
) => {
4545
const { mutateAsync, isLoading: isLoggingIn } = useGetAuthToken();
46-
const changeLanguage = IntlUtils.useChangeLanguage();
46+
const { changeLanguage, getLocaleCode, getUserLocale } = useIntlUtils();
4747
const { setHeader, setSkipRequest } = useGql();
4848
const { mutateAsync: getUserDetails } = useGetUserDetails();
4949
const queryClient = useQueryClient();
@@ -119,9 +119,9 @@ export const useLogin = (
119119
},
120120
};
121121

122-
const userLocale = IntlUtils.getUserLocale(username);
122+
const userLocale = getUserLocale(username);
123123
if (userLocale === undefined) {
124-
changeLanguage(userDetails?.language);
124+
changeLanguage(getLocaleCode(userDetails?.language as LanguageType));
125125
}
126126
setMRUCredentials({ username, store });
127127
setAuthCookie(authCookie);

0 commit comments

Comments
 (0)