@openmrs/esm-dispensing-app 1.5.1-pre.367 → 1.6.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 (106) hide show
  1. package/.tx/config +1 -2
  2. package/dist/204.js +1 -1
  3. package/dist/204.js.map +1 -1
  4. package/dist/236.js +1 -0
  5. package/dist/240.js +1 -0
  6. package/dist/261.js +1 -0
  7. package/dist/271.js +1 -1
  8. package/dist/272.js +1 -0
  9. package/dist/319.js +1 -0
  10. package/dist/336.js +1 -0
  11. package/dist/378.js +1 -0
  12. package/dist/460.js +1 -0
  13. package/dist/524.js +2 -0
  14. package/dist/524.js.map +1 -0
  15. package/dist/539.js +1 -0
  16. package/dist/574.js +1 -1
  17. package/dist/626.js +1 -0
  18. package/dist/626.js.map +1 -0
  19. package/dist/637.js +1 -0
  20. package/dist/637.js.map +1 -0
  21. package/dist/644.js +1 -0
  22. package/dist/652.js +1 -0
  23. package/dist/673.js +1 -0
  24. package/dist/705.js +1 -0
  25. package/dist/711.js +1 -0
  26. package/dist/727.js +1 -0
  27. package/dist/737.js +1 -0
  28. package/dist/744.js +1 -0
  29. package/dist/757.js +1 -1
  30. package/dist/77.js +1 -0
  31. package/dist/77.js.map +1 -0
  32. package/dist/788.js +1 -0
  33. package/dist/807.js +1 -0
  34. package/dist/833.js +1 -0
  35. package/dist/890.js +1 -0
  36. package/dist/890.js.map +1 -0
  37. package/dist/899.js +1 -0
  38. package/dist/905.js +1 -0
  39. package/dist/905.js.map +1 -0
  40. package/dist/main.js +1 -1
  41. package/dist/main.js.map +1 -1
  42. package/dist/openmrs-esm-dispensing-app.js +1 -1
  43. package/dist/openmrs-esm-dispensing-app.js.buildmanifest.json +596 -37
  44. package/dist/routes.json +1 -1
  45. package/i18next-parser.config.js +89 -0
  46. package/package.json +7 -4
  47. package/src/components/prescription-actions/close-action-button.component.tsx +14 -21
  48. package/src/components/prescription-actions/dispense-action-button.component.tsx +16 -23
  49. package/src/components/prescription-actions/pause-action-button.component.tsx +13 -21
  50. package/src/config-schema.ts +3 -23
  51. package/src/dashboard/dispensing-dashboard.component.tsx +2 -3
  52. package/src/dispensing-tiles/dispensing-tiles.component.tsx +1 -1
  53. package/src/dispensing-tiles/dispensing-tiles.resource.tsx +1 -1
  54. package/src/dispensing.test.tsx +0 -22
  55. package/src/forms/{close-dispense-form.component.tsx → close-dispense-form.workspace.tsx} +25 -25
  56. package/src/forms/{dispense-form.component.tsx → dispense-form.workspace.tsx} +40 -31
  57. package/src/forms/forms.scss +23 -19
  58. package/src/forms/{pause-dispense-form.component.tsx → pause-dispense-form.workspace.tsx} +27 -25
  59. package/src/forms/stock-dispense/stock-dispense.component.tsx +8 -0
  60. package/src/history/history-and-comments.component.tsx +49 -45
  61. package/src/index.ts +25 -14
  62. package/src/location/location.resource.tsx +1 -1
  63. package/src/medication-dispense/medication-dispense.resource.tsx +2 -2
  64. package/src/medication-request/medication-request.resource.tsx +2 -2
  65. package/src/prescriptions/prescription-actions.component.tsx +24 -0
  66. package/src/prescriptions/prescription-actions.scss +15 -0
  67. package/src/prescriptions/prescription-details.component.tsx +4 -7
  68. package/src/print-prescription/prescription-print-action.component.tsx +30 -0
  69. package/src/print-prescription/prescription-print-preview.modal.tsx +92 -0
  70. package/src/print-prescription/prescription-printout.component.tsx +128 -0
  71. package/src/print-prescription/print-prescription.scss +48 -0
  72. package/src/print-prescription/printable-prescriptions.component.tsx +57 -0
  73. package/src/routes.json +28 -0
  74. package/src/types.ts +1 -0
  75. package/translations/am.json +85 -0
  76. package/translations/ar.json +85 -0
  77. package/translations/de.json +85 -0
  78. package/translations/en.json +26 -43
  79. package/translations/es.json +85 -0
  80. package/translations/fr.json +81 -96
  81. package/translations/he.json +85 -0
  82. package/translations/hi.json +85 -0
  83. package/translations/hi_IN.json +85 -0
  84. package/translations/id.json +85 -0
  85. package/translations/it.json +85 -0
  86. package/translations/km.json +85 -0
  87. package/translations/ne.json +85 -0
  88. package/translations/pt.json +85 -0
  89. package/translations/qu.json +85 -0
  90. package/translations/si.json +85 -0
  91. package/translations/sw.json +85 -0
  92. package/translations/sw_KE.json +85 -0
  93. package/translations/tr.json +85 -0
  94. package/translations/tr_TR.json +85 -0
  95. package/translations/uk.json +85 -0
  96. package/translations/vi.json +85 -0
  97. package/translations/zh.json +83 -10
  98. package/translations/zh_CN.json +85 -0
  99. package/dist/191.js +0 -2
  100. package/dist/191.js.map +0 -1
  101. package/dist/829.js +0 -1
  102. package/dist/829.js.map +0 -1
  103. package/src/forms/overlay/overlay.component.tsx +0 -47
  104. package/src/forms/overlay/overlay.scss +0 -93
  105. package/src/hooks/useOverlay.tsx +0 -46
  106. /package/dist/{191.js.LICENSE.txt → 524.js.LICENSE.txt} +0 -0
package/dist/routes.json CHANGED
@@ -1 +1 @@
1
- {"backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.2.0"},"pages":[{"component":"dispensing","route":"dispensing","online":true,"offline":true}],"extensions":[{"name":"dispensing-link","slot":"app-menu-slot","component":"dispensingLink","online":true,"offline":true},{"name":"dispensing-dashboard","slot":"dispensing-dashboard-slot","component":"dispensingDashboard","online":true,"offline":true},{"name":"dispensing-dashboard-link","component":"dispensingDashboardLink","meta":{"name":"dispensing","slot":"dispensing-dashboard-slot","title":"Dispensing"}},{"name":"dispense-action-button","slot":"prescription-action-button-slot","component":"dispenseActionButton"},{"name":"pause-action-button","slot":"prescription-action-button-slot","component":"pauseActionButton"},{"name":"close-action-button","slot":"prescription-action-button-slot","component":"closeActionButton"}],"version":"1.5.1-pre.367"}
1
+ {"$schema":"https://json.openmrs.org/routes.schema.json","backendDependencies":{"fhir2":">=1.2","webservices.rest":"^2.2.0"},"pages":[{"component":"dispensing","route":"dispensing","online":true,"offline":true}],"extensions":[{"name":"dispensing-link","slot":"app-menu-slot","component":"dispensingLink","online":true,"offline":true},{"name":"dispensing-dashboard","slot":"dispensing-dashboard-slot","component":"dispensingDashboard","online":true,"offline":true},{"name":"dispensing-dashboard-link","component":"dispensingDashboardLink","meta":{"name":"dispensing","slot":"dispensing-dashboard-slot","title":"Dispensing"}},{"name":"dispense-action-button","slot":"prescription-action-button-slot","component":"dispenseActionButton"},{"name":"pause-action-button","slot":"prescription-action-button-slot","component":"pauseActionButton"},{"name":"close-action-button","slot":"prescription-action-button-slot","component":"closeActionButton"}],"workspaces":[{"name":"close-dispense-workspace","component":"closeDispenseWorkspace","type":"dispense","title":"Close prescription"},{"name":"pause-dispense-workspace","component":"pauseDispenseWorkspace","type":"dispense","title":"Pause prescription"},{"name":"dispense-workspace","component":"dispenseWorkspace","type":"dispense","title":"Dispense prescription","width":"wider"}],"modals":[{"name":"prescription-print-preview-modal","component":"printPrescriptionPreviewModal"}],"version":"1.6.0"}
@@ -0,0 +1,89 @@
1
+ module.exports = {
2
+ contextSeparator: '_',
3
+ // Key separator used in your translation keys
4
+
5
+ createOldCatalogs: false,
6
+ // Save the \_old files
7
+
8
+ defaultNamespace: 'translations',
9
+ // Default namespace used in your i18next config
10
+
11
+ defaultValue: '',
12
+ // Default value to give to empty keys
13
+ // You may also specify a function accepting the locale, namespace, and key as arguments
14
+
15
+ indentation: 2,
16
+ // Indentation of the catalog files
17
+
18
+ keepRemoved: false,
19
+ // Keep keys from the catalog that are no longer in code
20
+
21
+ keySeparator: '.',
22
+ // Key separator used in your translation keys
23
+ // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
24
+
25
+ // see below for more details
26
+ lexers: {
27
+ hbs: ['HandlebarsLexer'],
28
+ handlebars: ['HandlebarsLexer'],
29
+
30
+ htm: ['HTMLLexer'],
31
+ html: ['HTMLLexer'],
32
+
33
+ mjs: ['JavascriptLexer'],
34
+ js: ['JavascriptLexer'], // if you're writing jsx inside .js files, change this to JsxLexer
35
+ ts: ['JavascriptLexer'],
36
+ jsx: ['JsxLexer'],
37
+ tsx: ['JsxLexer'],
38
+
39
+ default: ['JavascriptLexer'],
40
+ },
41
+
42
+ lineEnding: 'auto',
43
+ // Control the line ending. See options at https://github.com/ryanve/eol
44
+
45
+ locales: ['en'],
46
+ // An array of the locales in your applications
47
+
48
+ namespaceSeparator: ':',
49
+ // Namespace separator used in your translation keys
50
+ // If you want to use plain english keys, separators such as `.` and `:` will conflict. You might want to set `keySeparator: false` and `namespaceSeparator: false`. That way, `t('Status: Loading...')` will not think that there are a namespace and three separator dots for instance.
51
+
52
+ output: '$NAMESPACE/$LOCALE.json',
53
+ // Supports $LOCALE and $NAMESPACE injection
54
+ // Supports JSON (.json) and YAML (.yml) file formats
55
+ // Where to write the locale files relative to process.cwd()
56
+
57
+ pluralSeparator: '_',
58
+ // Plural separator used in your translation keys
59
+ // If you want to use plain english keys, separators such as `_` might conflict. You might want to set `pluralSeparator` to a different string that does not occur in your keys.
60
+
61
+ input: undefined,
62
+ // An array of globs that describe where to look for source files
63
+ // relative to the location of the configuration file
64
+
65
+ sort: true,
66
+ // Whether or not to sort the catalog
67
+
68
+ useKeysAsDefaultValue: false,
69
+ // Whether to use the keys as the default value; ex. "Hello": "Hello", "World": "World"
70
+ // This option takes precedence over the `defaultValue` and `skipDefaultValues` options
71
+ // You may also specify a function accepting the locale and namespace as arguments
72
+
73
+ verbose: false,
74
+ // Display info about the parsing including some stats
75
+
76
+ failOnWarnings: false,
77
+ // Exit with an exit code of 1 on warnings
78
+
79
+ customValueTemplate: null,
80
+ // If you wish to customize the value output the value as an object, you can set your own format.
81
+ // ${defaultValue} is the default value you set in your translation function.
82
+ // Any other custom property will be automatically extracted.
83
+ //
84
+ // Example:
85
+ // {
86
+ // message: "${defaultValue}",
87
+ // description: "${maxLength}", // t('my-key', {maxLength: 150})
88
+ // }
89
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-dispensing-app",
3
- "version": "1.5.1-pre.367",
3
+ "version": "1.6.0",
4
4
  "license": "MPL-2.0",
5
5
  "description": "Medication dispensing application",
6
6
  "browser": "dist/openmrs-esm-dispensing-app.js",
@@ -16,6 +16,7 @@
16
16
  "test:watch": "jest --config jest.config.js --watch",
17
17
  "typescript": "tsc",
18
18
  "verify": "concurrently 'yarn:lint' 'yarn:test' 'yarn:typescript'",
19
+ "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.workspace.tsx' 'src/index.ts' --config ./i18next-parser.config.js",
19
20
  "coverage": "yarn test --coverage",
20
21
  "postinstall": "husky install"
21
22
  },
@@ -43,7 +44,8 @@
43
44
  "dependencies": {
44
45
  "@carbon/react": "1.12.0",
45
46
  "classnames": "^2.5.1",
46
- "lodash-es": "^4.17.21"
47
+ "lodash-es": "^4.17.21",
48
+ "react-to-print": "^2.14.13"
47
49
  },
48
50
  "peerDependencies": {
49
51
  "@openmrs/esm-framework": "*",
@@ -77,6 +79,8 @@
77
79
  "eslint-plugin-react-hooks": "^5.0.0",
78
80
  "eslint-plugin-unused-imports": "^2.0.0",
79
81
  "husky": "^6.0.0",
82
+ "i18next": "^21.10.0",
83
+ "i18next-parser": "^9.0.2",
80
84
  "identity-obj-proxy": "^3.0.0",
81
85
  "jest": "^28.1.3",
82
86
  "jest-cli": "^28.1.3",
@@ -97,6 +101,5 @@
97
101
  "*.{ts,tsx}": "eslint --cache --fix --max-warnings 0",
98
102
  "*.{css,scss,ts,tsx}": "prettier --write --list-different"
99
103
  },
100
- "packageManager": "yarn@4.4.0",
101
- "stableVersion": "1.5.0"
104
+ "packageManager": "yarn@4.4.0"
102
105
  }
@@ -1,11 +1,9 @@
1
1
  import React from 'react';
2
2
  import { Button } from '@carbon/react';
3
- import CloseDispenseForm from '../../forms/close-dispense-form.component';
4
- import { launchOverlay } from '../../hooks/useOverlay';
5
3
  import { useTranslation } from 'react-i18next';
6
4
  import { initiateMedicationDispenseBody } from '../../medication-dispense/medication-dispense.resource';
7
5
  import { type Provider, type MedicationRequestBundle } from '../../types';
8
- import { type Session } from '@openmrs/esm-framework';
6
+ import { launchWorkspace, type Session } from '@openmrs/esm-framework';
9
7
 
10
8
  type CloseActionButtonProps = {
11
9
  patientUuid: string;
@@ -25,28 +23,23 @@ const CloseActionButton: React.FC<CloseActionButtonProps> = ({
25
23
  closeable,
26
24
  }) => {
27
25
  const { t } = useTranslation();
26
+
27
+ const closeDispenseFormProps = {
28
+ patientUuid,
29
+ encounterUuid,
30
+ medicationDispense: initiateMedicationDispenseBody(medicationRequestBundle.request, session, providers, false),
31
+ mode: 'enter',
32
+ };
33
+
34
+ const handleLaunchWorkspace = () => {
35
+ launchWorkspace('close-dispense-workspace', closeDispenseFormProps);
36
+ };
37
+
28
38
  if (!closeable) {
29
39
  return null;
30
40
  }
31
41
  return (
32
- <Button
33
- kind="danger"
34
- onClick={() =>
35
- launchOverlay(
36
- t('closePrescription', 'Close prescription'),
37
- <CloseDispenseForm
38
- patientUuid={patientUuid}
39
- encounterUuid={encounterUuid}
40
- medicationDispense={initiateMedicationDispenseBody(
41
- medicationRequestBundle.request,
42
- session,
43
- providers,
44
- false,
45
- )}
46
- mode="enter"
47
- />,
48
- )
49
- }>
42
+ <Button kind="danger" onClick={handleLaunchWorkspace}>
50
43
  {t('close', 'Close')}
51
44
  </Button>
52
45
  );
@@ -1,11 +1,9 @@
1
1
  import React from 'react';
2
2
  import { Button } from '@carbon/react';
3
- import { launchOverlay } from '../../hooks/useOverlay';
4
3
  import { useTranslation } from 'react-i18next';
5
4
  import { initiateMedicationDispenseBody } from '../../medication-dispense/medication-dispense.resource';
6
5
  import { type Provider, type MedicationRequestBundle } from '../../types';
7
- import { type Session } from '@openmrs/esm-framework';
8
- import DispenseForm from '../../forms/dispense-form.component';
6
+ import { launchWorkspace, type Session } from '@openmrs/esm-framework';
9
7
 
10
8
  type DispenseActionButtonProps = {
11
9
  patientUuid: string;
@@ -27,30 +25,25 @@ const DispenseActionButton: React.FC<DispenseActionButtonProps> = ({
27
25
  quantityRemaining,
28
26
  }) => {
29
27
  const { t } = useTranslation();
28
+ const dispenseWorkspaceProps = {
29
+ patientUuid,
30
+ encounterUuid,
31
+ medicationDispense: initiateMedicationDispenseBody(medicationRequestBundle.request, session, providers, true),
32
+ medicationRequestBundle,
33
+ quantityRemaining,
34
+ mode: 'enter',
35
+ };
36
+
37
+ const handleLaunchWorkspace = () => {
38
+ launchWorkspace('dispense-workspace', dispenseWorkspaceProps);
39
+ };
40
+
30
41
  if (!dispensable) {
31
42
  return null;
32
43
  }
44
+
33
45
  return (
34
- <Button
35
- kind="primary"
36
- onClick={() =>
37
- launchOverlay(
38
- t('dispensePrescription', 'Dispense prescription'),
39
- <DispenseForm
40
- patientUuid={patientUuid}
41
- encounterUuid={encounterUuid}
42
- medicationDispense={initiateMedicationDispenseBody(
43
- medicationRequestBundle.request,
44
- session,
45
- providers,
46
- true,
47
- )}
48
- medicationRequestBundle={medicationRequestBundle}
49
- quantityRemaining={quantityRemaining}
50
- mode="enter"
51
- />,
52
- )
53
- }>
46
+ <Button kind="primary" onClick={handleLaunchWorkspace}>
54
47
  {t('dispense', 'Dispense')}
55
48
  </Button>
56
49
  );
@@ -1,11 +1,9 @@
1
1
  import React from 'react';
2
2
  import { Button } from '@carbon/react';
3
- import { launchOverlay } from '../../hooks/useOverlay';
4
3
  import { useTranslation } from 'react-i18next';
5
4
  import { initiateMedicationDispenseBody } from '../../medication-dispense/medication-dispense.resource';
6
5
  import { type Provider, type MedicationRequestBundle } from '../../types';
7
- import { type Session } from '@openmrs/esm-framework';
8
- import PauseDispenseForm from '../../forms/pause-dispense-form.component';
6
+ import { launchWorkspace, type Session } from '@openmrs/esm-framework';
9
7
 
10
8
  type PauseActionButtonProps = {
11
9
  patientUuid: string;
@@ -25,28 +23,22 @@ const PauseActionButton: React.FC<PauseActionButtonProps> = ({
25
23
  pauseable,
26
24
  }) => {
27
25
  const { t } = useTranslation();
26
+ const pauseWorkspaceProps = {
27
+ patientUuid,
28
+ encounterUuid,
29
+ medicationDispense: initiateMedicationDispenseBody(medicationRequestBundle.request, session, providers, false),
30
+ mode: 'enter',
31
+ };
32
+
33
+ const handleLaunchWorkspace = () => {
34
+ launchWorkspace('pause-dispense-workspace', pauseWorkspaceProps);
35
+ };
36
+
28
37
  if (!pauseable) {
29
38
  return null;
30
39
  }
31
40
  return (
32
- <Button
33
- kind="secondary"
34
- onClick={() =>
35
- launchOverlay(
36
- t('pausePrescription', 'Pause prescription'),
37
- <PauseDispenseForm
38
- patientUuid={patientUuid}
39
- encounterUuid={encounterUuid}
40
- medicationDispense={initiateMedicationDispenseBody(
41
- medicationRequestBundle.request,
42
- session,
43
- providers,
44
- false,
45
- )}
46
- mode="enter"
47
- />,
48
- )
49
- }>
41
+ <Button kind="secondary" onClick={handleLaunchWorkspace}>
50
42
  {t('pause', 'Pause')}
51
43
  </Button>
52
44
  );
@@ -1,25 +1,5 @@
1
1
  import { Type } from '@openmrs/esm-framework';
2
2
 
3
- /**
4
- * This is the config schema. It expects a configuration object which
5
- * looks like this:
6
- *
7
- * ```json
8
- * { "casualGreeting": true, "whoToGreet": ["Mom"] }
9
- * ```
10
- *
11
- * In OpenMRS Microfrontends, all config parameters are optional. Thus,
12
- * all elements must have a reasonable default. A good default is one
13
- * that works well with the reference application.
14
- *
15
- * To understand the schema below, please read the configuration system
16
- * documentation:
17
- * https://openmrs.github.io/openmrs-esm-core/#/main/config
18
- * Note especially the section "How do I make my module configurable?"
19
- * https://openmrs.github.io/openmrs-esm-core/#/main/config?id=im-developing-an-esm-module-how-do-i-make-it-configurable
20
- * and the Schema Reference
21
- * https://openmrs.github.io/openmrs-esm-core/#/main/config?id=schema-reference
22
- */
23
3
  export const configSchema = {
24
4
  appName: {
25
5
  _type: Type.String,
@@ -99,7 +79,7 @@ export const configSchema = {
99
79
  _type: Type.UUID,
100
80
  _description:
101
81
  "UUID for the Value Set of valid answers to the 'Reason for Pause' question. Defaults to CIEL value set: https://app.openconceptlab.org/#/orgs/CIEL/sources/CIEL/concepts/168099/",
102
- _default: '2dd3e5c0-3d3f-4f3d-9860-19b3f9ab26ff',
82
+ _default: '2462a9d7-61fb-4bf5-9359-aedecb8d03cb',
103
83
  },
104
84
  },
105
85
  reasonForClose: {
@@ -107,7 +87,7 @@ export const configSchema = {
107
87
  _type: Type.UUID,
108
88
  _description:
109
89
  "UUID for the Value Set of valid answers to the 'Reason for Close' question. Defaults to CIEL value set: https://app.openconceptlab.org/#/orgs/CIEL/sources/CIEL/concepts/168099/",
110
- _default: 'bd6c1fc2-7cfc-4562-94a0-e4765e5e977e',
90
+ _default: '2462a9d7-61fb-4bf5-9359-aedecb8d03cb',
111
91
  },
112
92
  },
113
93
  substitutionReason: {
@@ -115,7 +95,7 @@ export const configSchema = {
115
95
  _type: Type.UUID,
116
96
  _description:
117
97
  "UUID for the Value Set of valid answers to the 'Reason for Substitution' question. Defaults to CIEL value set: https://app.openconceptlab.org/#/orgs/CIEL/sources/CIEL/concepts/167862/",
118
- _default: 'de8671b8-ed2e-4f7e-a9f8-dcd00878f2eb',
98
+ _default: '2de6e1be-f2dd-4ba0-9516-8a611aa2af9b',
119
99
  },
120
100
  },
121
101
  substitutionType: {
@@ -1,9 +1,8 @@
1
1
  import React from 'react';
2
2
  import { InlineNotification } from '@carbon/react';
3
- import Overlay from '../forms/overlay/overlay.component';
4
3
  import { PharmacyHeader } from '../pharmacy-header/pharmacy-header.component';
5
4
  import PrescriptionTabLists from '../prescriptions/prescription-tab-lists.component';
6
- import { useConfig } from '@openmrs/esm-framework';
5
+ import { useConfig, WorkspaceContainer } from '@openmrs/esm-framework';
7
6
  import { useTranslation } from 'react-i18next';
8
7
  import { type PharmacyConfig } from '../config-schema';
9
8
 
@@ -28,7 +27,7 @@ export default function DispensingDashboard() {
28
27
  <PharmacyHeader />
29
28
  {/* <DispensingTiles /> */}
30
29
  <PrescriptionTabLists />
31
- <Overlay />
30
+ <WorkspaceContainer key="dispensing" contextKey="dispensing" />
32
31
  </div>
33
32
  );
34
33
  }
@@ -7,7 +7,7 @@ import styles from './dispensing-tiles.scss';
7
7
 
8
8
  const DispensingTiles: React.FC = () => {
9
9
  const { t } = useTranslation();
10
- const { metrics, isError, isLoading } = useMetrics();
10
+ const { metrics, error, isLoading } = useMetrics();
11
11
 
12
12
  if (isLoading) {
13
13
  return <DataTableSkeleton role="progressbar" />;
@@ -14,7 +14,7 @@ export function useMetrics() {
14
14
 
15
15
  return {
16
16
  metrics: metrics,
17
- isError: error,
17
+ error,
18
18
  isLoading: !data && !error,
19
19
  };
20
20
  }
@@ -1,25 +1,3 @@
1
- /**
2
- * This is the root test for this page. It simply checks that the page
3
- * renders. If the components of your page are highly interdependent,
4
- * (e.g., if the `Hello` component had state that communicated
5
- * information between `Greeter` and `PatientGetter`) then you might
6
- * want to do most of your testing here. If those components are
7
- * instead quite independent (as is the case in this example), then
8
- * it would make more sense to test those components independently.
9
- *
10
- * The key thing to remember, always, is: write tests that behave like
11
- * users. They should *look* for elements by their visual
12
- * characteristics, *interact* with them, and (mostly) *assert* based
13
- * on things that would be visually apparent to a user.
14
- *
15
- * To learn more about how we do testing, see the following resources:
16
- * https://kentcdodds.com/blog/how-to-know-what-to-test
17
- * https://kentcdodds.com/blog/testing-implementation-details
18
- * https://kentcdodds.com/blog/common-mistakes-with-react-testing-library
19
- *
20
- * Kent C. Dodds is the inventor of `@testing-library`:
21
- * https://testing-library.com/docs/guiding-principles
22
- */
23
1
  import React from 'react';
24
2
  import { render } from '@testing-library/react';
25
3
  import Dispensing from './dispensing.component';
@@ -1,34 +1,36 @@
1
1
  import React, { useEffect, useMemo, useState } from 'react';
2
2
  import { useTranslation } from 'react-i18next';
3
+ import { Button, ComboBox, Form, InlineLoading } from '@carbon/react';
3
4
  import {
5
+ type DefaultWorkspaceProps,
4
6
  ExtensionSlot,
5
- showNotification,
6
- showToast,
7
+ getCoreTranslation,
8
+ showSnackbar,
7
9
  useConfig,
8
10
  useLayoutType,
9
11
  usePatient,
10
12
  } from '@openmrs/esm-framework';
11
- import { Button, ComboBox, InlineLoading } from '@carbon/react';
12
13
  import { saveMedicationDispense, useReasonForCloseValueSet } from '../medication-dispense/medication-dispense.resource';
13
- import { closeOverlay } from '../hooks/useOverlay';
14
- import styles from './forms.scss';
15
14
  import { updateMedicationRequestFulfillerStatus } from '../medication-request/medication-request.resource';
16
15
  import { type MedicationDispense, MedicationDispenseStatus, MedicationRequestFulfillerStatus } from '../types';
17
16
  import { type PharmacyConfig } from '../config-schema';
18
17
  import { getUuidFromReference, revalidate } from '../utils';
18
+ import styles from './forms.scss';
19
19
 
20
- interface CloseDispenseFormProps {
20
+ type CloseDispenseFormProps = DefaultWorkspaceProps & {
21
21
  medicationDispense: MedicationDispense;
22
22
  mode: 'enter' | 'edit';
23
23
  patientUuid?: string;
24
24
  encounterUuid: string;
25
- }
25
+ };
26
26
 
27
27
  const CloseDispenseForm: React.FC<CloseDispenseFormProps> = ({
28
28
  medicationDispense,
29
29
  mode,
30
30
  patientUuid,
31
31
  encounterUuid,
32
+ closeWorkspace,
33
+ closeWorkspaceWithSavedChanges,
32
34
  }) => {
33
35
  const { t } = useTranslation();
34
36
  const config = useConfig<PharmacyConfig>();
@@ -84,12 +86,10 @@ const CloseDispenseForm: React.FC<CloseDispenseFormProps> = ({
84
86
  })
85
87
  .then((response) => {
86
88
  if (response.ok) {
87
- closeOverlay();
88
89
  revalidate(encounterUuid);
89
- showToast({
90
- critical: true,
90
+ showSnackbar({
91
91
  kind: 'success',
92
- description: t(
92
+ subtitle: t(
93
93
  mode === 'enter' ? 'medicationDispenseClosed' : 'medicationDispenseUpdated',
94
94
  mode === 'enter' ? 'Medication dispense closed.' : 'Dispense record successfully updated.',
95
95
  ),
@@ -98,17 +98,17 @@ const CloseDispenseForm: React.FC<CloseDispenseFormProps> = ({
98
98
  mode === 'enter' ? 'Medication dispense closed.' : 'Dispense record successfully updated.',
99
99
  ),
100
100
  });
101
+ closeWorkspaceWithSavedChanges();
101
102
  }
102
103
  })
103
104
  .catch((error) => {
104
- showNotification({
105
+ showSnackbar({
105
106
  title: t(
106
107
  mode === 'enter' ? 'medicationDispenseCloseError' : 'medicationDispenseUpdatedError',
107
108
  mode === 'enter' ? 'Error closing medication dispense.' : 'Error updating dispense record',
108
109
  ),
109
110
  kind: 'error',
110
- critical: true,
111
- description: error?.message,
111
+ subtitle: error?.message,
112
112
  });
113
113
  setIsSubmitting(false);
114
114
  });
@@ -140,8 +140,8 @@ const CloseDispenseForm: React.FC<CloseDispenseFormProps> = ({
140
140
  }, [patient, patientUuid]);
141
141
 
142
142
  return (
143
- <div className="">
144
- <div className={styles.formWrapper}>
143
+ <Form className={styles.formWrapper}>
144
+ <div>
145
145
  {isLoading && (
146
146
  <InlineLoading
147
147
  className={styles.bannerLoading}
@@ -176,16 +176,16 @@ const CloseDispenseForm: React.FC<CloseDispenseFormProps> = ({
176
176
  }}
177
177
  />
178
178
  </section>
179
- <section className={styles.buttonGroup}>
180
- <Button disabled={isSubmitting} onClick={() => closeOverlay()} kind="secondary">
181
- {t('cancel', 'Cancel')}
182
- </Button>
183
- <Button disabled={!isValid || isSubmitting} onClick={handleSubmit}>
184
- {t(mode === 'enter' ? 'close' : 'saveChanges', mode === 'enter' ? 'Close' : 'Save changes')}
185
- </Button>
186
- </section>
187
179
  </div>
188
- </div>
180
+ <section className={styles.buttonGroup}>
181
+ <Button disabled={isSubmitting} onClick={closeWorkspace} kind="secondary">
182
+ {getCoreTranslation('cancel', 'Cancel')}
183
+ </Button>
184
+ <Button disabled={!isValid || isSubmitting} onClick={handleSubmit}>
185
+ {t(mode === 'enter' ? 'close' : 'saveChanges', mode === 'enter' ? 'Close' : 'Save changes')}
186
+ </Button>
187
+ </section>
188
+ </Form>
189
189
  );
190
190
  };
191
191