@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.
- package/.turbo/turbo-build.log +4 -1
- package/dist/openmrs-esm-framework.js +2 -2
- package/dist/openmrs-esm-framework.js.map +1 -1
- package/docs/functions/closeWorkspaceGroup2.md +1 -1
- package/docs/functions/createUseStore.md +1 -1
- package/docs/functions/getRegisteredWorkspace2Names.md +13 -0
- package/docs/functions/launchWorkspace2.md +1 -1
- package/docs/functions/launchWorkspaceGroup2.md +1 -1
- package/docs/functions/useStore.md +4 -4
- package/docs/functions/useStoreWithActions.md +1 -1
- package/docs/functions/useWorkspace2Context.md +14 -0
- package/docs/interfaces/FeatureFlagDefinition.md +4 -4
- package/docs/interfaces/OpenmrsAppRoutes.md +13 -13
- package/docs/interfaces/ResourceLoader.md +2 -2
- package/docs/interfaces/Workspace2DefinitionProps.md +27 -7
- package/docs/interfaces/WorkspaceDefinition2.md +4 -4
- package/docs/interfaces/WorkspaceGroupDefinition2.md +16 -0
- package/docs/interfaces/WorkspaceWindowDefinition2.md +9 -25
- package/docs/type-aliases/ActionFunction.md +1 -1
- package/docs/type-aliases/Actions.md +1 -1
- package/docs/type-aliases/BoundActions.md +1 -1
- package/docs/type-aliases/NameUse.md +1 -1
- package/docs/type-aliases/OpenmrsRoutes.md +1 -1
- package/docs/type-aliases/Workspace2Definition.md +1 -1
- package/docs/variables/Workspace2.md +1 -1
- package/mock-jest.tsx +1 -0
- package/mock.tsx +1 -0
- package/package.json +20 -20
- package/setup-tests.ts +20 -1
- package/src/integration-tests/extension-config-expressions.test.tsx +7 -11
- 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.
|
|
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.
|
|
63
|
-
"@openmrs/esm-config": "8.0.1-pre.
|
|
64
|
-
"@openmrs/esm-context": "8.0.1-pre.
|
|
65
|
-
"@openmrs/esm-dynamic-loading": "8.0.1-pre.
|
|
66
|
-
"@openmrs/esm-emr-api": "8.0.1-pre.
|
|
67
|
-
"@openmrs/esm-error-handling": "8.0.1-pre.
|
|
68
|
-
"@openmrs/esm-expression-evaluator": "8.0.1-pre.
|
|
69
|
-
"@openmrs/esm-extensions": "8.0.1-pre.
|
|
70
|
-
"@openmrs/esm-feature-flags": "8.0.1-pre.
|
|
71
|
-
"@openmrs/esm-globals": "8.0.1-pre.
|
|
72
|
-
"@openmrs/esm-navigation": "8.0.1-pre.
|
|
73
|
-
"@openmrs/esm-offline": "8.0.1-pre.
|
|
74
|
-
"@openmrs/esm-react-utils": "8.0.1-pre.
|
|
75
|
-
"@openmrs/esm-routes": "8.0.1-pre.
|
|
76
|
-
"@openmrs/esm-state": "8.0.1-pre.
|
|
77
|
-
"@openmrs/esm-styleguide": "8.0.1-pre.
|
|
78
|
-
"@openmrs/esm-translations": "8.0.1-pre.
|
|
79
|
-
"@openmrs/esm-utils": "8.0.1-pre.
|
|
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.
|
|
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
|
-
|
|
87
|
-
|
|
88
|
-
|
|
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
|
-
|
|
124
|
-
|
|
125
|
-
|
|
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
|
-
|
|
83
|
-
|
|
84
|
-
|
|
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
|
-
|
|
135
|
-
|
|
136
|
-
|
|
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
|
-
|
|
187
|
-
|
|
188
|
-
|
|
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
|
-
|
|
213
|
-
|
|
214
|
-
|
|
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
|
-
|
|
249
|
-
|
|
250
|
-
|
|
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
|
-
|
|
301
|
-
|
|
302
|
-
|
|
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
|
-
|
|
383
|
-
|
|
384
|
-
|
|
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
|
-
|
|
443
|
-
|
|
444
|
-
|
|
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
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
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
|
-
|
|
488
|
+
act(() => {
|
|
489
|
+
render(<App />);
|
|
490
|
+
});
|
|
501
491
|
|
|
502
492
|
await waitFor(() => {
|
|
503
493
|
const slot = screen.getByTestId('slot');
|