@openmrs/esm-framework 8.0.1-pre.3473 → 8.0.1-pre.3498

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 (31) hide show
  1. package/.turbo/turbo-build.log +4 -1
  2. package/dist/openmrs-esm-framework.js +2 -2
  3. package/dist/openmrs-esm-framework.js.map +1 -1
  4. package/docs/functions/closeWorkspaceGroup2.md +1 -1
  5. package/docs/functions/createUseStore.md +1 -1
  6. package/docs/functions/getRegisteredWorkspace2Names.md +13 -0
  7. package/docs/functions/launchWorkspace2.md +1 -1
  8. package/docs/functions/launchWorkspaceGroup2.md +1 -1
  9. package/docs/functions/useStore.md +4 -4
  10. package/docs/functions/useStoreWithActions.md +1 -1
  11. package/docs/functions/useWorkspace2Context.md +14 -0
  12. package/docs/interfaces/FeatureFlagDefinition.md +4 -4
  13. package/docs/interfaces/OpenmrsAppRoutes.md +13 -13
  14. package/docs/interfaces/ResourceLoader.md +2 -2
  15. package/docs/interfaces/Workspace2DefinitionProps.md +27 -7
  16. package/docs/interfaces/WorkspaceDefinition2.md +4 -4
  17. package/docs/interfaces/WorkspaceGroupDefinition2.md +16 -0
  18. package/docs/interfaces/WorkspaceWindowDefinition2.md +9 -25
  19. package/docs/type-aliases/ActionFunction.md +1 -1
  20. package/docs/type-aliases/Actions.md +1 -1
  21. package/docs/type-aliases/BoundActions.md +1 -1
  22. package/docs/type-aliases/NameUse.md +1 -1
  23. package/docs/type-aliases/OpenmrsRoutes.md +1 -1
  24. package/docs/type-aliases/Workspace2Definition.md +1 -1
  25. package/docs/variables/Workspace2.md +1 -1
  26. package/mock-jest.tsx +1 -0
  27. package/mock.tsx +1 -0
  28. package/package.json +20 -20
  29. package/setup-tests.ts +20 -1
  30. package/src/integration-tests/extension-config-expressions.test.tsx +7 -11
  31. package/src/integration-tests/extension-config.test.tsx +49 -59
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@openmrs/esm-framework",
3
- "version": "8.0.1-pre.3473",
3
+ "version": "8.0.1-pre.3498",
4
4
  "license": "MPL-2.0",
5
5
  "type": "module",
6
6
  "module": "dist/openmrs-esm-framework.js",
@@ -59,24 +59,24 @@
59
59
  "access": "public"
60
60
  },
61
61
  "dependencies": {
62
- "@openmrs/esm-api": "8.0.1-pre.3473",
63
- "@openmrs/esm-config": "8.0.1-pre.3473",
64
- "@openmrs/esm-context": "8.0.1-pre.3473",
65
- "@openmrs/esm-dynamic-loading": "8.0.1-pre.3473",
66
- "@openmrs/esm-emr-api": "8.0.1-pre.3473",
67
- "@openmrs/esm-error-handling": "8.0.1-pre.3473",
68
- "@openmrs/esm-expression-evaluator": "8.0.1-pre.3473",
69
- "@openmrs/esm-extensions": "8.0.1-pre.3473",
70
- "@openmrs/esm-feature-flags": "8.0.1-pre.3473",
71
- "@openmrs/esm-globals": "8.0.1-pre.3473",
72
- "@openmrs/esm-navigation": "8.0.1-pre.3473",
73
- "@openmrs/esm-offline": "8.0.1-pre.3473",
74
- "@openmrs/esm-react-utils": "8.0.1-pre.3473",
75
- "@openmrs/esm-routes": "8.0.1-pre.3473",
76
- "@openmrs/esm-state": "8.0.1-pre.3473",
77
- "@openmrs/esm-styleguide": "8.0.1-pre.3473",
78
- "@openmrs/esm-translations": "8.0.1-pre.3473",
79
- "@openmrs/esm-utils": "8.0.1-pre.3473"
62
+ "@openmrs/esm-api": "8.0.1-pre.3498",
63
+ "@openmrs/esm-config": "8.0.1-pre.3498",
64
+ "@openmrs/esm-context": "8.0.1-pre.3498",
65
+ "@openmrs/esm-dynamic-loading": "8.0.1-pre.3498",
66
+ "@openmrs/esm-emr-api": "8.0.1-pre.3498",
67
+ "@openmrs/esm-error-handling": "8.0.1-pre.3498",
68
+ "@openmrs/esm-expression-evaluator": "8.0.1-pre.3498",
69
+ "@openmrs/esm-extensions": "8.0.1-pre.3498",
70
+ "@openmrs/esm-feature-flags": "8.0.1-pre.3498",
71
+ "@openmrs/esm-globals": "8.0.1-pre.3498",
72
+ "@openmrs/esm-navigation": "8.0.1-pre.3498",
73
+ "@openmrs/esm-offline": "8.0.1-pre.3498",
74
+ "@openmrs/esm-react-utils": "8.0.1-pre.3498",
75
+ "@openmrs/esm-routes": "8.0.1-pre.3498",
76
+ "@openmrs/esm-state": "8.0.1-pre.3498",
77
+ "@openmrs/esm-styleguide": "8.0.1-pre.3498",
78
+ "@openmrs/esm-translations": "8.0.1-pre.3498",
79
+ "@openmrs/esm-utils": "8.0.1-pre.3498"
80
80
  },
81
81
  "peerDependencies": {
82
82
  "dayjs": "1.x",
@@ -89,7 +89,7 @@
89
89
  "swr": "2.x"
90
90
  },
91
91
  "devDependencies": {
92
- "@openmrs/typedoc-plugin-file-categories": "8.0.1-pre.3473",
92
+ "@openmrs/typedoc-plugin-file-categories": "8.0.1-pre.3498",
93
93
  "@rspack/cli": "^1.3.11",
94
94
  "@rspack/core": "^1.3.11",
95
95
  "concurrently": "^9.1.2",
package/setup-tests.ts CHANGED
@@ -1,6 +1,21 @@
1
+ // Suppress act() warnings BEFORE any React code loads
2
+ // These warnings are expected due to store-to-store subscriptions in the data layer
3
+ const originalError = console.error;
4
+ console.error = (...args: any[]) => {
5
+ const message = args[0];
6
+ if (
7
+ typeof message === 'string' &&
8
+ message.includes('Warning: An update to') &&
9
+ message.includes('was not wrapped in act')
10
+ ) {
11
+ return;
12
+ }
13
+ originalError.call(console, ...args);
14
+ };
15
+
16
+ import { afterAll, afterEach } from 'vitest';
1
17
  import '@testing-library/jest-dom/vitest';
2
18
  import { cleanup } from '@testing-library/react';
3
- import { afterEach } from 'vitest';
4
19
  import type {} from '@openmrs/esm-globals';
5
20
 
6
21
  declare global {
@@ -37,3 +52,7 @@ window.getComputedStyle = (elt) => getComputedStyle(elt);
37
52
  afterEach(() => {
38
53
  cleanup();
39
54
  });
55
+
56
+ afterAll(() => {
57
+ console.error = originalError;
58
+ });
@@ -55,8 +55,6 @@ describe('Expression evaluation in extension display conditions', () => {
55
55
  });
56
56
 
57
57
  it('should show extension when the expression evalutes to true', async () => {
58
- const promise = Promise.resolve();
59
-
60
58
  registerSimpleExtension('Schmoo', 'esm-bedrock', true);
61
59
  attach('A slot', 'Schmoo');
62
60
  defineConfigSchema('esm-bedrock', {});
@@ -83,17 +81,15 @@ describe('Expression evaluation in extension display conditions', () => {
83
81
  disableTranslations: true,
84
82
  })(RootComponent);
85
83
 
86
- await act(async () => await promise);
87
-
88
- render(<App />);
84
+ act(() => {
85
+ render(<App />);
86
+ });
89
87
 
90
88
  await screen.findByTestId(/slot/);
91
89
  expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Schmoo');
92
90
  });
93
91
 
94
92
  it('should hide extension when the expression evaluates to false', async () => {
95
- const promise = Promise.resolve();
96
-
97
93
  registerSimpleExtension('Schmoo', 'esm-bedrock', true);
98
94
  attach('A slot', 'Schmoo');
99
95
  defineConfigSchema('esm-bedrock', {});
@@ -120,9 +116,9 @@ describe('Expression evaluation in extension display conditions', () => {
120
116
  disableTranslations: true,
121
117
  })(RootComponent);
122
118
 
123
- await act(async () => await promise);
124
-
125
- render(<App />);
119
+ act(() => {
120
+ render(<App />);
121
+ });
126
122
 
127
123
  await screen.findByTestId(/slot/);
128
124
  expect(screen.getByTestId('slot').firstChild).toBeNull();
@@ -136,7 +132,7 @@ describe('Expression evaluation in extension display conditions', () => {
136
132
  provide({
137
133
  'esm-bedrock': {
138
134
  'Display conditions': {
139
- expression: 'session.user.privileges.some(p => p.display === "YOWTCH!")',
135
+ expression: 'session.user ? session.user.privileges.some(p => p.display === "YOWTCH!") : false',
140
136
  },
141
137
  },
142
138
  });
@@ -50,7 +50,6 @@ describe('Interaction between configuration and extension systems', () => {
50
50
  });
51
51
 
52
52
  it('Config should add, order, and remove extensions within slots', async () => {
53
- const promise = Promise.resolve();
54
53
  registerSimpleExtension('Fred', 'esm-flintstone');
55
54
  registerSimpleExtension('Wilma', 'esm-flintstone');
56
55
  registerSimpleExtension('Barney', 'esm-rubble');
@@ -79,15 +78,14 @@ describe('Interaction between configuration and extension systems', () => {
79
78
  disableTranslations: true,
80
79
  })(() => <ExtensionSlot data-testid="slot" name="A slot" />);
81
80
 
82
- await act(async () => await promise);
83
-
84
- render(<App />);
85
-
86
- await screen.findByText('Betty');
87
- const slot = screen.getByTestId('slot');
88
- const extensions = slot.childNodes;
81
+ act(() => {
82
+ render(<App />);
83
+ });
89
84
 
90
- await waitFor(() => {
85
+ await waitFor(async () => {
86
+ await screen.findByText('Betty');
87
+ const slot = screen.getByTestId('slot');
88
+ const extensions = slot.childNodes;
91
89
  expect(extensions[0]).toHaveTextContent('Betty');
92
90
  expect(extensions[1]).toHaveTextContent('Wilma');
93
91
  expect(extensions[2]).toHaveTextContent('Barney');
@@ -96,7 +94,6 @@ describe('Interaction between configuration and extension systems', () => {
96
94
  });
97
95
 
98
96
  it("Extensions should recieve config from module and from 'configure' key", async () => {
99
- const promise = Promise.resolve();
100
97
  registerSimpleExtension('Pebbles', 'esm-flintstone', true);
101
98
  defineConfigSchema('esm-flintstone', {
102
99
  town: { _type: Type.String, _default: 'Bedrock' },
@@ -131,9 +128,9 @@ describe('Interaction between configuration and extension systems', () => {
131
128
  </>
132
129
  ));
133
130
 
134
- await act(async () => await promise);
135
-
136
- render(<App />);
131
+ act(() => {
132
+ render(<App />);
133
+ });
137
134
 
138
135
  screen.findAllByText(/.*Pebbles.*/);
139
136
  const flintstonePebbles = screen.getByTestId('flintstone-slot');
@@ -146,8 +143,6 @@ describe('Interaction between configuration and extension systems', () => {
146
143
  });
147
144
 
148
145
  it('Should be possible to attach the same extension twice with different configurations', async () => {
149
- const promise = Promise.resolve();
150
-
151
146
  registerSimpleExtension('pet', 'esm-characters', true);
152
147
  defineConfigSchema('esm-characters', {
153
148
  name: { _type: Type.String, _default: '(no-name)' },
@@ -183,9 +178,9 @@ describe('Interaction between configuration and extension systems', () => {
183
178
  </>
184
179
  ));
185
180
 
186
- await act(async () => await promise);
187
-
188
- render(<App />);
181
+ act(() => {
182
+ render(<App />);
183
+ });
189
184
 
190
185
  screen.findAllByText(/.*Dino.*/);
191
186
  const slot = screen.getByTestId('flintstone-slot');
@@ -197,7 +192,6 @@ describe('Interaction between configuration and extension systems', () => {
197
192
  });
198
193
 
199
194
  it('Slot config should update with temporary config', async () => {
200
- const promise = Promise.resolve();
201
195
  registerSimpleExtension('Pearl', 'esm-slaghoople');
202
196
  attach('A slot', 'Pearl');
203
197
  defineConfigSchema('esm-slaghoople', {});
@@ -209,9 +203,9 @@ describe('Interaction between configuration and extension systems', () => {
209
203
  disableTranslations: true,
210
204
  })(() => <ExtensionSlot data-testid="slot" name="A slot" />);
211
205
 
212
- await act(async () => await promise);
213
-
214
- render(<App />);
206
+ act(() => {
207
+ render(<App />);
208
+ });
215
209
 
216
210
  await screen.findByText('Pearl');
217
211
 
@@ -233,7 +227,6 @@ describe('Interaction between configuration and extension systems', () => {
233
227
  });
234
228
 
235
229
  it('Extension config should update with temporary config', async () => {
236
- const promise = Promise.resolve();
237
230
  registerSimpleExtension('Mr. Slate', 'esm-flintstone', true);
238
231
  attach('A slot', 'Mr. Slate');
239
232
  defineConfigSchema('esm-flintstone', { tie: { _default: 'green' } });
@@ -245,9 +238,9 @@ describe('Interaction between configuration and extension systems', () => {
245
238
  disableTranslations: true,
246
239
  })(() => <ExtensionSlot data-testid="slot" name="A slot" />);
247
240
 
248
- await act(async () => await promise);
249
-
250
- render(<App />);
241
+ act(() => {
242
+ render(<App />);
243
+ });
251
244
  await screen.findByText(/Mr. Slate/);
252
245
  expect(screen.getByTestId('slot')).toHaveTextContent(/green/);
253
246
 
@@ -273,7 +266,6 @@ describe('Interaction between configuration and extension systems', () => {
273
266
 
274
267
  // TODO restore this test
275
268
  it.skip('Extension config should be available in extension store', async () => {
276
- const promise = Promise.resolve();
277
269
  registerSimpleExtension('Bamm-Bamm', 'esm-flintstone', false);
278
270
  attach('A slot', 'Bamm-Bamm');
279
271
  defineConfigSchema('esm-flintstone', { clothes: { _default: 'leopard' } });
@@ -297,9 +289,9 @@ describe('Interaction between configuration and extension systems', () => {
297
289
  disableTranslations: true,
298
290
  })(RootComponent);
299
291
 
300
- await act(async () => await promise);
301
-
302
- render(<App />);
292
+ act(() => {
293
+ render(<App />);
294
+ });
303
295
 
304
296
  await screen.findByTestId(/slot/);
305
297
  expect(screen.getByText(/clothes/)).toHaveTextContent(/leopard/);
@@ -324,7 +316,6 @@ describe('Interaction between configuration and extension systems', () => {
324
316
  });
325
317
 
326
318
  it('should not show extension when user lacks configured privilege', async () => {
327
- const promise = Promise.resolve();
328
319
  mockSessionStore.setState({
329
320
  loaded: true,
330
321
  session: {
@@ -379,9 +370,9 @@ describe('Interaction between configuration and extension systems', () => {
379
370
  disableTranslations: true,
380
371
  })(RootComponent);
381
372
 
382
- await act(async () => await promise);
383
-
384
- render(<App />);
373
+ act(() => {
374
+ render(<App />);
375
+ });
385
376
 
386
377
  await waitFor(() => {
387
378
  const slot = screen.getByTestId('slot');
@@ -391,7 +382,6 @@ describe('Interaction between configuration and extension systems', () => {
391
382
  });
392
383
 
393
384
  it('should show extension when user has configured privilege', async () => {
394
- const promise = Promise.resolve();
395
385
  mockSessionStore.setState({
396
386
  loaded: true,
397
387
  session: {
@@ -439,9 +429,9 @@ describe('Interaction between configuration and extension systems', () => {
439
429
  disableTranslations: true,
440
430
  })(RootComponent);
441
431
 
442
- await act(async () => await promise);
443
-
444
- render(<App />);
432
+ act(() => {
433
+ render(<App />);
434
+ });
445
435
 
446
436
  await screen.findByTestId(/slot/);
447
437
  expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Schmoo');
@@ -449,27 +439,25 @@ describe('Interaction between configuration and extension systems', () => {
449
439
 
450
440
  it('should only show extensions users have default privilege for', async () => {
451
441
  // Set up initial session state before registering extensions
452
- await act(async () => {
453
- mockSessionStore.setState({
454
- loaded: true,
455
- session: {
456
- authenticated: true,
457
- sessionId: '1',
458
- user: {
459
- uuid: '1',
460
- display: 'Non-Admin',
461
- username: 'nonadmin',
462
- systemId: 'nonadmin',
463
- userProperties: {},
464
- person: {} as Person,
465
- privileges: [{ uuid: '1', display: 'YOWTCH!' }],
466
- roles: [],
467
- retired: false,
468
- locale: 'en',
469
- allowedLocales: ['en'],
470
- },
442
+ mockSessionStore.setState({
443
+ loaded: true,
444
+ session: {
445
+ authenticated: true,
446
+ sessionId: '1',
447
+ user: {
448
+ uuid: '1',
449
+ display: 'Non-Admin',
450
+ username: 'nonadmin',
451
+ systemId: 'nonadmin',
452
+ userProperties: {},
453
+ person: {} as Person,
454
+ privileges: [{ uuid: '1', display: 'YOWTCH!' }],
455
+ roles: [],
456
+ retired: false,
457
+ locale: 'en',
458
+ allowedLocales: ['en'],
471
459
  },
472
- });
460
+ },
473
461
  });
474
462
 
475
463
  registerSimpleExtension('Schmoo', 'esm-bedrock', true, 'Yabadabadoo!');
@@ -497,7 +485,9 @@ describe('Interaction between configuration and extension systems', () => {
497
485
  disableTranslations: true,
498
486
  })(RootComponent);
499
487
 
500
- render(<App />);
488
+ act(() => {
489
+ render(<App />);
490
+ });
501
491
 
502
492
  await waitFor(() => {
503
493
  const slot = screen.getByTestId('slot');