@openmrs/esm-react-utils 5.3.3-pre.1237 → 5.3.3-pre.1247

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 (48) hide show
  1. package/.turbo/turbo-build.log +2 -2
  2. package/__mocks__/openmrs-esm-state.mock.ts +8 -20
  3. package/dist/openmrs-esm-react-utils.js.map +1 -1
  4. package/jest.config.js +9 -11
  5. package/package.json +7 -7
  6. package/src/ComponentContext.ts +2 -2
  7. package/src/ConfigurableLink.test.tsx +19 -23
  8. package/src/ConfigurableLink.tsx +5 -19
  9. package/src/Extension.tsx +36 -76
  10. package/src/ExtensionSlot.tsx +15 -24
  11. package/src/UserHasAccess.tsx +3 -7
  12. package/src/extensions.test.tsx +100 -179
  13. package/src/getLifecycle.ts +8 -18
  14. package/src/index.ts +31 -31
  15. package/src/openmrsComponentDecorator.test.tsx +12 -12
  16. package/src/openmrsComponentDecorator.tsx +12 -26
  17. package/src/public.ts +27 -27
  18. package/src/setup-tests.js +4 -4
  19. package/src/useAbortController.test.tsx +8 -8
  20. package/src/useAbortController.ts +1 -1
  21. package/src/useAssignedExtensionIds.ts +4 -5
  22. package/src/useAssignedExtensions.ts +3 -7
  23. package/src/useBodyScrollLock.ts +2 -2
  24. package/src/useConfig.test.tsx +96 -112
  25. package/src/useConfig.ts +15 -43
  26. package/src/useConnectedExtensions.ts +8 -17
  27. package/src/useConnectivity.ts +3 -6
  28. package/src/useDebounce.ts +1 -1
  29. package/src/useExtensionInternalStore.ts +3 -8
  30. package/src/useExtensionSlot.ts +5 -7
  31. package/src/useExtensionSlotMeta.ts +5 -11
  32. package/src/useExtensionStore.ts +3 -5
  33. package/src/useFeatureFlag.ts +4 -4
  34. package/src/useForceUpdate.ts +1 -1
  35. package/src/useLayoutType.ts +12 -13
  36. package/src/useLocations.tsx +3 -3
  37. package/src/useOnClickOutside.test.tsx +10 -10
  38. package/src/useOnClickOutside.ts +2 -5
  39. package/src/useOpenmrsSWR.ts +9 -9
  40. package/src/usePagination.ts +6 -18
  41. package/src/usePatient.ts +9 -13
  42. package/src/useSession.test.tsx +35 -43
  43. package/src/useSession.ts +9 -13
  44. package/src/useStore.test.ts +11 -13
  45. package/src/useStore.ts +10 -31
  46. package/src/useVisit.ts +14 -37
  47. package/src/useVisitTypes.ts +3 -3
  48. package/webpack.config.js +14 -14
@@ -1,12 +1,12 @@
1
- import React, { useCallback, useReducer } from "react";
2
- import { act, render, screen, waitFor, within } from "@testing-library/react";
1
+ import React, { useCallback, useReducer } from 'react';
2
+ import { act, render, screen, waitFor, within } from '@testing-library/react';
3
3
  import {
4
4
  attach,
5
5
  ConnectedExtension,
6
6
  getExtensionNameFromId,
7
7
  registerExtension,
8
8
  updateInternalExtensionStore,
9
- } from "@openmrs/esm-extensions";
9
+ } from '@openmrs/esm-extensions';
10
10
  import {
11
11
  getSyncLifecycle,
12
12
  Extension,
@@ -14,41 +14,32 @@ import {
14
14
  openmrsComponentDecorator,
15
15
  useExtensionSlotMeta,
16
16
  ExtensionData,
17
- } from ".";
18
- import userEvent from "@testing-library/user-event";
19
- import {
20
- registerFeatureFlag,
21
- setFeatureFlag,
22
- } from "@openmrs/esm-feature-flags";
17
+ } from '.';
18
+ import userEvent from '@testing-library/user-event';
19
+ import { registerFeatureFlag, setFeatureFlag } from '@openmrs/esm-feature-flags';
23
20
 
24
21
  // For some reason in the text context `isEqual` always returns true
25
22
  // when using the import substitution in jest.config.js. Here's a custom
26
23
  // mock.
27
- jest.mock(
28
- "lodash-es/isEqual",
29
- () => (a, b) => JSON.stringify(a) == JSON.stringify(b)
30
- );
24
+ jest.mock('lodash-es/isEqual', () => (a, b) => JSON.stringify(a) == JSON.stringify(b));
31
25
 
32
- describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
26
+ describe('ExtensionSlot, Extension, and useExtensionSlotMeta', () => {
33
27
  beforeEach(() => {
34
28
  updateInternalExtensionStore(() => ({ slots: {}, extensions: {} }));
35
29
  });
36
30
 
37
- test("Extension receives state changes passed through (not using <Extension>)", async () => {
31
+ test('Extension receives state changes passed through (not using <Extension>)', async () => {
38
32
  function EnglishExtension({ suffix }) {
39
33
  return <div>English{suffix}</div>;
40
34
  }
41
- registerSimpleExtension("English", "esm-languages-app", EnglishExtension);
42
- attach("Box", "English");
35
+ registerSimpleExtension('English', 'esm-languages-app', EnglishExtension);
36
+ attach('Box', 'English');
43
37
  const App = openmrsComponentDecorator({
44
- moduleName: "esm-languages-app",
45
- featureName: "Languages",
38
+ moduleName: 'esm-languages-app',
39
+ featureName: 'Languages',
46
40
  disableTranslations: true,
47
41
  })(() => {
48
- const [suffix, toggleSuffix] = useReducer(
49
- (suffix) => (suffix == "!" ? "?" : "!"),
50
- "!"
51
- );
42
+ const [suffix, toggleSuffix] = useReducer((suffix) => (suffix == '!' ? '?' : '!'), '!');
52
43
  return (
53
44
  <div>
54
45
  <ExtensionSlot name="Box" state={{ suffix }} />
@@ -58,35 +49,24 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
58
49
  });
59
50
  render(<App />);
60
51
 
61
- await waitFor(() =>
62
- expect(screen.getByText(/English/)).toBeInTheDocument()
63
- );
64
- expect(screen.getByText(/English/)).toHaveTextContent("English!");
65
- userEvent.click(screen.getByText("Toggle suffix"));
66
- await waitFor(() =>
67
- expect(screen.getByText(/English/)).toHaveTextContent("English?")
68
- );
52
+ await waitFor(() => expect(screen.getByText(/English/)).toBeInTheDocument());
53
+ expect(screen.getByText(/English/)).toHaveTextContent('English!');
54
+ userEvent.click(screen.getByText('Toggle suffix'));
55
+ await waitFor(() => expect(screen.getByText(/English/)).toHaveTextContent('English?'));
69
56
  });
70
57
 
71
- test("Extension receives state changes (using <Extension>)", async () => {
58
+ test('Extension receives state changes (using <Extension>)', async () => {
72
59
  function HaitianCreoleExtension({ suffix }) {
73
60
  return <div>Haitian Creole{suffix}</div>;
74
61
  }
75
- registerSimpleExtension(
76
- "Haitian",
77
- "esm-languages-app",
78
- HaitianCreoleExtension
79
- );
80
- attach("Box", "Haitian");
62
+ registerSimpleExtension('Haitian', 'esm-languages-app', HaitianCreoleExtension);
63
+ attach('Box', 'Haitian');
81
64
  const App = openmrsComponentDecorator({
82
- moduleName: "esm-languages-app",
83
- featureName: "Languages",
65
+ moduleName: 'esm-languages-app',
66
+ featureName: 'Languages',
84
67
  disableTranslations: true,
85
68
  })(() => {
86
- const [suffix, toggleSuffix] = useReducer(
87
- (suffix) => (suffix == "!" ? "?" : "!"),
88
- "!"
89
- );
69
+ const [suffix, toggleSuffix] = useReducer((suffix) => (suffix == '!' ? '?' : '!'), '!');
90
70
 
91
71
  return (
92
72
  <div>
@@ -100,52 +80,46 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
100
80
  });
101
81
  render(<App />);
102
82
 
103
- await waitFor(() =>
104
- expect(screen.getByText(/Haitian/)).toBeInTheDocument()
105
- );
106
- expect(screen.getByText(/Haitian/)).toHaveTextContent("Haitian Creole!");
107
- userEvent.click(screen.getByText("Toggle suffix"));
108
- await waitFor(() =>
109
- expect(screen.getByText(/Haitian/)).toHaveTextContent("Haitian Creole?")
110
- );
83
+ await waitFor(() => expect(screen.getByText(/Haitian/)).toBeInTheDocument());
84
+ expect(screen.getByText(/Haitian/)).toHaveTextContent('Haitian Creole!');
85
+ userEvent.click(screen.getByText('Toggle suffix'));
86
+ await waitFor(() => expect(screen.getByText(/Haitian/)).toHaveTextContent('Haitian Creole?'));
111
87
  });
112
88
 
113
- test("ExtensionSlot throws error if both state and children provided", () => {
89
+ test('ExtensionSlot throws error if both state and children provided', () => {
114
90
  const App = () => (
115
- <ExtensionSlot name="Box" state={{ color: "red" }}>
91
+ <ExtensionSlot name="Box" state={{ color: 'red' }}>
116
92
  <Extension />
117
93
  </ExtensionSlot>
118
94
  );
119
95
  expect(() => render(<App />)).toThrowError(
120
96
  expect.objectContaining({
121
97
  message: expect.stringMatching(/children.*state/),
122
- })
98
+ }),
123
99
  );
124
100
  });
125
101
 
126
- test("Extension Slot receives meta", async () => {
127
- registerSimpleExtension("Spanish", "esm-languages-app", undefined, {
128
- code: "es",
102
+ test('Extension Slot receives meta', async () => {
103
+ registerSimpleExtension('Spanish', 'esm-languages-app', undefined, {
104
+ code: 'es',
129
105
  });
130
- attach("Box", "Spanish");
106
+ attach('Box', 'Spanish');
131
107
  const App = openmrsComponentDecorator({
132
- moduleName: "esm-languages-app",
133
- featureName: "Languages",
108
+ moduleName: 'esm-languages-app',
109
+ featureName: 'Languages',
134
110
  disableTranslations: true,
135
111
  })(() => {
136
- const metas = useExtensionSlotMeta("Box");
112
+ const metas = useExtensionSlotMeta('Box');
137
113
  const wrapItem = useCallback(
138
114
  (slot: React.ReactNode, extension: ExtensionData) => {
139
115
  return (
140
116
  <div>
141
- <h1>
142
- {metas[getExtensionNameFromId(extension.extensionId)].code}
143
- </h1>
117
+ <h1>{metas[getExtensionNameFromId(extension.extensionId)].code}</h1>
144
118
  {slot}
145
119
  </div>
146
120
  );
147
121
  },
148
- [metas]
122
+ [metas],
149
123
  );
150
124
  return (
151
125
  <div>
@@ -157,48 +131,36 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
157
131
  });
158
132
  render(<App />);
159
133
 
160
- await waitFor(() =>
161
- expect(screen.getByRole("heading")).toBeInTheDocument()
162
- );
163
- expect(screen.getByRole("heading")).toHaveTextContent("es");
164
- await waitFor(() =>
165
- expect(screen.getByText("Spanish")).toBeInTheDocument()
166
- );
134
+ await waitFor(() => expect(screen.getByRole('heading')).toBeInTheDocument());
135
+ expect(screen.getByRole('heading')).toHaveTextContent('es');
136
+ await waitFor(() => expect(screen.getByText('Spanish')).toBeInTheDocument());
167
137
  });
168
138
 
169
- test("Both meta and state can be used at the same time", async () => {
139
+ test('Both meta and state can be used at the same time', async () => {
170
140
  function SwahiliExtension({ suffix }) {
171
141
  return <div>Swahili{suffix}</div>;
172
142
  }
173
- registerSimpleExtension("Swahili", "esm-languages-app", SwahiliExtension, {
174
- code: "sw",
143
+ registerSimpleExtension('Swahili', 'esm-languages-app', SwahiliExtension, {
144
+ code: 'sw',
175
145
  });
176
- attach("Box", "Swahili");
146
+ attach('Box', 'Swahili');
177
147
  const App = openmrsComponentDecorator({
178
- moduleName: "esm-languages-app",
179
- featureName: "Languages",
148
+ moduleName: 'esm-languages-app',
149
+ featureName: 'Languages',
180
150
  disableTranslations: true,
181
151
  })(() => {
182
- const [suffix, toggleSuffix] = useReducer(
183
- (suffix) => (suffix == "!" ? "?" : "!"),
184
- "!"
185
- );
186
- const metas = useExtensionSlotMeta("Box");
152
+ const [suffix, toggleSuffix] = useReducer((suffix) => (suffix == '!' ? '?' : '!'), '!');
153
+ const metas = useExtensionSlotMeta('Box');
187
154
  const wrapItem = useCallback(
188
155
  (slot: React.ReactNode, extension?: ExtensionData) => {
189
156
  return (
190
157
  <div>
191
- <h1>
192
- {
193
- metas[getExtensionNameFromId(extension?.extensionId ?? "")]
194
- .code
195
- }
196
- </h1>
158
+ <h1>{metas[getExtensionNameFromId(extension?.extensionId ?? '')].code}</h1>
197
159
  {slot}
198
160
  </div>
199
161
  );
200
162
  },
201
- [metas]
163
+ [metas],
202
164
  );
203
165
  return (
204
166
  <div>
@@ -211,31 +173,25 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
211
173
  });
212
174
  render(<App />);
213
175
 
214
- await waitFor(() =>
215
- expect(screen.getByRole("heading")).toBeInTheDocument()
216
- );
217
- expect(screen.getByRole("heading")).toHaveTextContent("sw");
218
- await waitFor(() =>
219
- expect(screen.getByText(/Swahili/)).toHaveTextContent("Swahili!")
220
- );
221
- userEvent.click(screen.getByText("Toggle suffix"));
222
- await waitFor(() =>
223
- expect(screen.getByText(/Swahili/)).toHaveTextContent("Swahili?")
224
- );
176
+ await waitFor(() => expect(screen.getByRole('heading')).toBeInTheDocument());
177
+ expect(screen.getByRole('heading')).toHaveTextContent('sw');
178
+ await waitFor(() => expect(screen.getByText(/Swahili/)).toHaveTextContent('Swahili!'));
179
+ userEvent.click(screen.getByText('Toggle suffix'));
180
+ await waitFor(() => expect(screen.getByText(/Swahili/)).toHaveTextContent('Swahili?'));
225
181
  });
226
182
 
227
- test("Extension Slot renders function children", async () => {
228
- registerSimpleExtension("Urdu", "esm-languages-app", undefined, {
229
- code: "urd",
183
+ test('Extension Slot renders function children', async () => {
184
+ registerSimpleExtension('Urdu', 'esm-languages-app', undefined, {
185
+ code: 'urd',
230
186
  });
231
- registerSimpleExtension("Hindi", "esm-languages-app", undefined, {
232
- code: "hi",
187
+ registerSimpleExtension('Hindi', 'esm-languages-app', undefined, {
188
+ code: 'hi',
233
189
  });
234
- attach("Box", "Urdu");
235
- attach("Box", "Hindi");
190
+ attach('Box', 'Urdu');
191
+ attach('Box', 'Hindi');
236
192
  const App = openmrsComponentDecorator({
237
- moduleName: "esm-languages-app",
238
- featureName: "Languages",
193
+ moduleName: 'esm-languages-app',
194
+ featureName: 'Languages',
239
195
  disableTranslations: true,
240
196
  })(() => {
241
197
  return (
@@ -253,33 +209,25 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
253
209
  });
254
210
  render(<App />);
255
211
 
256
- await waitFor(() => expect(screen.getByTestId("Urdu")).toBeInTheDocument());
257
- expect(
258
- within(screen.getByTestId("Urdu")).getByRole("heading")
259
- ).toHaveTextContent("urd");
260
- expect(
261
- within(screen.getByTestId("Hindi")).getByRole("heading")
262
- ).toHaveTextContent("hi");
212
+ await waitFor(() => expect(screen.getByTestId('Urdu')).toBeInTheDocument());
213
+ expect(within(screen.getByTestId('Urdu')).getByRole('heading')).toHaveTextContent('urd');
214
+ expect(within(screen.getByTestId('Hindi')).getByRole('heading')).toHaveTextContent('hi');
263
215
  });
264
216
 
265
- test("Extension renders with child function", async () => {
266
- registerSimpleExtension("Hindi", "esm-languages-app", undefined, {
267
- code: "hi",
217
+ test('Extension renders with child function', async () => {
218
+ registerSimpleExtension('Hindi', 'esm-languages-app', undefined, {
219
+ code: 'hi',
268
220
  });
269
- attach("Box", "Hindi");
221
+ attach('Box', 'Hindi');
270
222
  const App = openmrsComponentDecorator({
271
- moduleName: "esm-languages-app",
272
- featureName: "Languages",
223
+ moduleName: 'esm-languages-app',
224
+ featureName: 'Languages',
273
225
  disableTranslations: true,
274
226
  })(() => {
275
227
  return (
276
228
  <div>
277
229
  <ExtensionSlot name="Box">
278
- {() => (
279
- <Extension>
280
- {(slot) => <div data-testid="custom-wrapper">{slot}</div>}
281
- </Extension>
282
- )}
230
+ {() => <Extension>{(slot) => <div data-testid="custom-wrapper">{slot}</div>}</Extension>}
283
231
  </ExtensionSlot>
284
232
  </div>
285
233
  );
@@ -287,64 +235,37 @@ describe("ExtensionSlot, Extension, and useExtensionSlotMeta", () => {
287
235
 
288
236
  render(<App />);
289
237
 
290
- await waitFor(() =>
291
- expect(screen.getByTestId("custom-wrapper")).toBeInTheDocument()
292
- );
238
+ await waitFor(() => expect(screen.getByTestId('custom-wrapper')).toBeInTheDocument());
293
239
 
294
240
  // essentially: is the first child of custom-wrapper the extension?
295
- expect(screen.getByTestId("custom-wrapper").children[0]).toHaveAttribute(
296
- "data-extension-id",
297
- "Hindi"
298
- );
241
+ expect(screen.getByTestId('custom-wrapper').children[0]).toHaveAttribute('data-extension-id', 'Hindi');
299
242
  });
300
243
 
301
- test("Extensions behind feature flags only render when their feature flag is enabled", async () => {
302
- registerSimpleExtension("Arabic", "esm-languages-app");
303
- registerSimpleExtension(
304
- "Turkish",
305
- "esm-languages-app",
306
- undefined,
307
- undefined,
308
- "turkic"
309
- );
310
- registerSimpleExtension(
311
- "Turkmeni",
312
- "esm-languages-app",
313
- undefined,
314
- undefined,
315
- "turkic"
316
- );
317
- registerSimpleExtension(
318
- "Kurmanji",
319
- "esm-languages-app",
320
- undefined,
321
- undefined,
322
- "kurdish"
323
- );
324
- attach("Box", "Arabic");
325
- attach("Box", "Turkish");
326
- attach("Box", "Turkmeni");
327
- attach("Box", "Kurmanji");
328
- registerFeatureFlag("turkic", "", "");
329
- registerFeatureFlag("kurdish", "", "");
330
- setFeatureFlag("turkic", true);
244
+ test('Extensions behind feature flags only render when their feature flag is enabled', async () => {
245
+ registerSimpleExtension('Arabic', 'esm-languages-app');
246
+ registerSimpleExtension('Turkish', 'esm-languages-app', undefined, undefined, 'turkic');
247
+ registerSimpleExtension('Turkmeni', 'esm-languages-app', undefined, undefined, 'turkic');
248
+ registerSimpleExtension('Kurmanji', 'esm-languages-app', undefined, undefined, 'kurdish');
249
+ attach('Box', 'Arabic');
250
+ attach('Box', 'Turkish');
251
+ attach('Box', 'Turkmeni');
252
+ attach('Box', 'Kurmanji');
253
+ registerFeatureFlag('turkic', '', '');
254
+ registerFeatureFlag('kurdish', '', '');
255
+ setFeatureFlag('turkic', true);
331
256
  const App = openmrsComponentDecorator({
332
- moduleName: "esm-languages-app",
333
- featureName: "Languages",
257
+ moduleName: 'esm-languages-app',
258
+ featureName: 'Languages',
334
259
  disableTranslations: true,
335
260
  })(() => <ExtensionSlot name="Box" />);
336
261
  render(<App />);
337
262
 
338
- await waitFor(() =>
339
- expect(screen.getByText(/Turkmeni/)).toBeInTheDocument()
340
- );
341
- expect(screen.getByText("Arabic")).toBeInTheDocument();
342
- expect(screen.getByText("Turkish")).toBeInTheDocument();
343
- expect(screen.queryByText("Kurmanji")).not.toBeInTheDocument();
344
- act(() => setFeatureFlag("kurdish", true));
345
- await waitFor(() =>
346
- expect(screen.getByText("Kurmanji")).toBeInTheDocument()
347
- );
263
+ await waitFor(() => expect(screen.getByText(/Turkmeni/)).toBeInTheDocument());
264
+ expect(screen.getByText('Arabic')).toBeInTheDocument();
265
+ expect(screen.getByText('Turkish')).toBeInTheDocument();
266
+ expect(screen.queryByText('Kurmanji')).not.toBeInTheDocument();
267
+ act(() => setFeatureFlag('kurdish', true));
268
+ await waitFor(() => expect(screen.getByText('Kurmanji')).toBeInTheDocument());
348
269
  });
349
270
  });
350
271
 
@@ -353,7 +274,7 @@ function registerSimpleExtension(
353
274
  moduleName: string,
354
275
  Component?: React.ComponentType<any>,
355
276
  meta: object = {},
356
- featureFlag?: string
277
+ featureFlag?: string,
357
278
  ) {
358
279
  const SimpleComponent = () => <div>{name}</div>;
359
280
  registerExtension({
@@ -1,16 +1,10 @@
1
1
  /** @module @category Framework */
2
- import React, { ComponentType } from "react";
3
- import ReactDOMClient from "react-dom/client";
4
- import singleSpaReact from "single-spa-react";
5
- import {
6
- openmrsComponentDecorator,
7
- ComponentDecoratorOptions,
8
- } from "./openmrsComponentDecorator";
2
+ import React, { ComponentType } from 'react';
3
+ import ReactDOMClient from 'react-dom/client';
4
+ import singleSpaReact from 'single-spa-react';
5
+ import { openmrsComponentDecorator, ComponentDecoratorOptions } from './openmrsComponentDecorator';
9
6
 
10
- export function getLifecycle<T>(
11
- Component: ComponentType<T>,
12
- options: ComponentDecoratorOptions
13
- ) {
7
+ export function getLifecycle<T>(Component: ComponentType<T>, options: ComponentDecoratorOptions) {
14
8
  return singleSpaReact({
15
9
  React,
16
10
  ReactDOMClient,
@@ -20,16 +14,12 @@ export function getLifecycle<T>(
20
14
 
21
15
  export function getAsyncLifecycle<T>(
22
16
  lazy: () => Promise<{ default: ComponentType<T> }>,
23
- options: ComponentDecoratorOptions
17
+ options: ComponentDecoratorOptions,
24
18
  ) {
25
- return () =>
26
- lazy().then(({ default: Component }) => getLifecycle(Component, options));
19
+ return () => lazy().then(({ default: Component }) => getLifecycle(Component, options));
27
20
  }
28
21
 
29
- export function getSyncLifecycle<T>(
30
- Component: ComponentType<T>,
31
- options: ComponentDecoratorOptions
32
- ) {
22
+ export function getSyncLifecycle<T>(Component: ComponentType<T>, options: ComponentDecoratorOptions) {
33
23
  return () => Promise.resolve(getLifecycle(Component, options));
34
24
  }
35
25
 
package/src/index.ts CHANGED
@@ -1,31 +1,31 @@
1
- export * from "./ComponentContext";
2
- export * from "./ConfigurableLink";
3
- export * from "./Extension";
4
- export * from "./ExtensionSlot";
5
- export * from "./UserHasAccess";
6
- export * from "./getLifecycle";
7
- export * from "./openmrsComponentDecorator";
8
- export * from "./useAbortController";
9
- export * from "./useAssignedExtensions";
10
- export * from "./useAssignedExtensionIds";
11
- export * from "./useBodyScrollLock";
12
- export * from "./useConfig";
13
- export * from "./useConnectedExtensions";
14
- export * from "./useConnectivity";
15
- export * from "./useDebounce";
16
- export * from "./useExtensionInternalStore";
17
- export * from "./useExtensionSlot";
18
- export * from "./useExtensionSlotMeta";
19
- export * from "./useExtensionStore";
20
- export * from "./useFeatureFlag";
21
- export * from "./useForceUpdate";
22
- export * from "./useLayoutType";
23
- export * from "./useLocations";
24
- export * from "./useOnClickOutside";
25
- export * from "./useOpenmrsSWR";
26
- export * from "./usePatient";
27
- export { useSession } from "./useSession";
28
- export * from "./useStore";
29
- export * from "./useVisit";
30
- export * from "./useVisitTypes";
31
- export * from "./usePagination";
1
+ export * from './ComponentContext';
2
+ export * from './ConfigurableLink';
3
+ export * from './Extension';
4
+ export * from './ExtensionSlot';
5
+ export * from './UserHasAccess';
6
+ export * from './getLifecycle';
7
+ export * from './openmrsComponentDecorator';
8
+ export * from './useAbortController';
9
+ export * from './useAssignedExtensions';
10
+ export * from './useAssignedExtensionIds';
11
+ export * from './useBodyScrollLock';
12
+ export * from './useConfig';
13
+ export * from './useConnectedExtensions';
14
+ export * from './useConnectivity';
15
+ export * from './useDebounce';
16
+ export * from './useExtensionInternalStore';
17
+ export * from './useExtensionSlot';
18
+ export * from './useExtensionSlotMeta';
19
+ export * from './useExtensionStore';
20
+ export * from './useFeatureFlag';
21
+ export * from './useForceUpdate';
22
+ export * from './useLayoutType';
23
+ export * from './useLocations';
24
+ export * from './useOnClickOutside';
25
+ export * from './useOpenmrsSWR';
26
+ export * from './usePatient';
27
+ export { useSession } from './useSession';
28
+ export * from './useStore';
29
+ export * from './useVisit';
30
+ export * from './useVisitTypes';
31
+ export * from './usePagination';
@@ -1,30 +1,30 @@
1
- import React from "react";
2
- import { render, screen, waitFor } from "@testing-library/react";
3
- import { openmrsComponentDecorator } from "./openmrsComponentDecorator";
4
- import { ComponentContext } from "./ComponentContext";
1
+ import React from 'react';
2
+ import { render, screen, waitFor } from '@testing-library/react';
3
+ import { openmrsComponentDecorator } from './openmrsComponentDecorator';
4
+ import { ComponentContext } from './ComponentContext';
5
5
 
6
- describe("openmrs-component-decorator", () => {
6
+ describe('openmrs-component-decorator', () => {
7
7
  const opts = {
8
- featureName: "Test",
8
+ featureName: 'Test',
9
9
  throwErrorsToConsole: false,
10
- moduleName: "test",
10
+ moduleName: 'test',
11
11
  };
12
12
 
13
- it("renders a component", () => {
13
+ it('renders a component', () => {
14
14
  const DecoratedComp = openmrsComponentDecorator(opts)(CompThatWorks);
15
15
  render(<DecoratedComp />);
16
16
  waitFor(() => {
17
- expect(screen.getByText("The button")).toBeTruthy();
17
+ expect(screen.getByText('The button')).toBeTruthy();
18
18
  });
19
19
  });
20
20
 
21
- it("catches any errors in the component tree and renders a ui explaining something bad happened", () => {
21
+ it('catches any errors in the component tree and renders a ui explaining something bad happened', () => {
22
22
  const DecoratedComp = openmrsComponentDecorator(opts)(CompThatThrows);
23
23
  render(<DecoratedComp />);
24
24
  // TO-DO assert the UX for broken react app is showing
25
25
  });
26
26
 
27
- it("provides ComponentContext", () => {
27
+ it('provides ComponentContext', () => {
28
28
  const DecoratedComp = openmrsComponentDecorator(opts)(CompWithConfig);
29
29
  render(<DecoratedComp />);
30
30
  });
@@ -35,7 +35,7 @@ function CompThatWorks() {
35
35
  }
36
36
 
37
37
  let CompThatThrows = function () {
38
- throw Error("ahahaa");
38
+ throw Error('ahahaa');
39
39
  };
40
40
 
41
41
  function CompWithConfig() {
@@ -1,11 +1,7 @@
1
- import React, { type ComponentType, Suspense } from "react";
2
- import { I18nextProvider } from "react-i18next";
3
- import type {} from "@openmrs/esm-globals";
4
- import {
5
- ComponentConfig,
6
- ComponentContext,
7
- ExtensionData,
8
- } from "./ComponentContext";
1
+ import React, { type ComponentType, Suspense } from 'react';
2
+ import { I18nextProvider } from 'react-i18next';
3
+ import type {} from '@openmrs/esm-globals';
4
+ import { ComponentConfig, ComponentContext, ExtensionData } from './ComponentContext';
9
5
 
10
6
  const defaultOpts = {
11
7
  strictMode: true,
@@ -32,22 +28,17 @@ export interface OpenmrsReactComponentState {
32
28
 
33
29
  export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) {
34
30
  if (
35
- typeof userOpts !== "object" ||
36
- typeof userOpts.featureName !== "string" ||
37
- typeof userOpts.moduleName !== "string"
31
+ typeof userOpts !== 'object' ||
32
+ typeof userOpts.featureName !== 'string' ||
33
+ typeof userOpts.moduleName !== 'string'
38
34
  ) {
39
- throw new Error("Invalid options");
35
+ throw new Error('Invalid options');
40
36
  }
41
37
 
42
38
  const opts = Object.assign({}, defaultOpts, userOpts);
43
39
 
44
- return function decorateComponent(
45
- Comp: ComponentType<any>
46
- ): ComponentType<any> {
47
- return class OpenmrsReactComponent extends React.Component<
48
- OpenmrsReactComponentProps,
49
- OpenmrsReactComponentState
50
- > {
40
+ return function decorateComponent(Comp: ComponentType<any>): ComponentType<any> {
41
+ return class OpenmrsReactComponent extends React.Component<OpenmrsReactComponentProps, OpenmrsReactComponentState> {
51
42
  static displayName = `OpenmrsReactComponent(${opts.featureName})`;
52
43
 
53
44
  constructor(props: OpenmrsReactComponentProps) {
@@ -84,9 +75,7 @@ export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) {
84
75
  render() {
85
76
  if (this.state.caughtError) {
86
77
  // TO-DO have a UX designed for when a catastrophic error occurs
87
- return (
88
- <div>An error has occurred. Please try reloading the page.</div>
89
- );
78
+ return <div>An error has occurred. Please try reloading the page.</div>;
90
79
  } else {
91
80
  const content = (
92
81
  <Suspense fallback={null}>
@@ -94,10 +83,7 @@ export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) {
94
83
  {opts.disableTranslations ? (
95
84
  <Comp {...this.props} />
96
85
  ) : (
97
- <I18nextProvider
98
- i18n={window.i18next}
99
- defaultNS={opts.moduleName}
100
- >
86
+ <I18nextProvider i18n={window.i18next} defaultNS={opts.moduleName}>
101
87
  <Comp {...this.props} />
102
88
  </I18nextProvider>
103
89
  )}