@openmrs/esm-styleguide 8.0.1-pre.3723 → 8.0.1-pre.3727
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 +2 -2
- package/dist/dashboard-extension/index.d.ts.map +1 -1
- package/dist/openmrs-esm-styleguide.js +1 -1
- package/dist/openmrs-esm-styleguide.js.map +1 -1
- package/package.json +12 -12
- package/src/dashboard-extension/dashboard.test.tsx +70 -0
- package/src/dashboard-extension/index.tsx +6 -6
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@openmrs/esm-styleguide",
|
|
3
|
-
"version": "8.0.1-pre.
|
|
3
|
+
"version": "8.0.1-pre.3727",
|
|
4
4
|
"license": "MPL-2.0",
|
|
5
5
|
"description": "The styleguide for OpenMRS SPA",
|
|
6
6
|
"main": "dist/openmrs-esm-styleguide.js",
|
|
@@ -98,17 +98,17 @@
|
|
|
98
98
|
"swr": "2.x"
|
|
99
99
|
},
|
|
100
100
|
"devDependencies": {
|
|
101
|
-
"@openmrs/esm-api": "8.0.1-pre.
|
|
102
|
-
"@openmrs/esm-config": "8.0.1-pre.
|
|
103
|
-
"@openmrs/esm-emr-api": "8.0.1-pre.
|
|
104
|
-
"@openmrs/esm-error-handling": "8.0.1-pre.
|
|
105
|
-
"@openmrs/esm-extensions": "8.0.1-pre.
|
|
106
|
-
"@openmrs/esm-globals": "8.0.1-pre.
|
|
107
|
-
"@openmrs/esm-navigation": "8.0.1-pre.
|
|
108
|
-
"@openmrs/esm-react-utils": "8.0.1-pre.
|
|
109
|
-
"@openmrs/esm-state": "8.0.1-pre.
|
|
110
|
-
"@openmrs/esm-translations": "8.0.1-pre.
|
|
111
|
-
"@openmrs/esm-utils": "8.0.1-pre.
|
|
101
|
+
"@openmrs/esm-api": "8.0.1-pre.3727",
|
|
102
|
+
"@openmrs/esm-config": "8.0.1-pre.3727",
|
|
103
|
+
"@openmrs/esm-emr-api": "8.0.1-pre.3727",
|
|
104
|
+
"@openmrs/esm-error-handling": "8.0.1-pre.3727",
|
|
105
|
+
"@openmrs/esm-extensions": "8.0.1-pre.3727",
|
|
106
|
+
"@openmrs/esm-globals": "8.0.1-pre.3727",
|
|
107
|
+
"@openmrs/esm-navigation": "8.0.1-pre.3727",
|
|
108
|
+
"@openmrs/esm-react-utils": "8.0.1-pre.3727",
|
|
109
|
+
"@openmrs/esm-state": "8.0.1-pre.3727",
|
|
110
|
+
"@openmrs/esm-translations": "8.0.1-pre.3727",
|
|
111
|
+
"@openmrs/esm-utils": "8.0.1-pre.3727",
|
|
112
112
|
"@rspack/cli": "^1.3.11",
|
|
113
113
|
"@rspack/core": "^1.3.11",
|
|
114
114
|
"@types/geopattern": "^1.2.9",
|
|
@@ -0,0 +1,70 @@
|
|
|
1
|
+
import React from 'react';
|
|
2
|
+
import { describe, expect, it } from 'vitest';
|
|
3
|
+
import '@testing-library/jest-dom/vitest';
|
|
4
|
+
import { render, screen } from '@testing-library/react';
|
|
5
|
+
import { MemoryRouter } from 'react-router-dom';
|
|
6
|
+
import { DashboardExtension } from './index';
|
|
7
|
+
|
|
8
|
+
describe('DashboardExtension', () => {
|
|
9
|
+
describe('Basic Rendering', () => {
|
|
10
|
+
it('renders with required props (path and title)', () => {
|
|
11
|
+
renderDashboardExtension('/base', 'dashboard', 'Dashboard', '/base');
|
|
12
|
+
expect(screen.getByText('Dashboard')).toBeInTheDocument();
|
|
13
|
+
const link = screen.getByRole('link');
|
|
14
|
+
expect(link).toBeInTheDocument();
|
|
15
|
+
});
|
|
16
|
+
|
|
17
|
+
it('renders ConfigurableLink with correct href', () => {
|
|
18
|
+
renderDashboardExtension('/base', 'dashboard', 'Dashboard', '/base');
|
|
19
|
+
|
|
20
|
+
const link = screen.getByRole('link');
|
|
21
|
+
expect(link).toHaveAttribute('href', '/base/dashboard');
|
|
22
|
+
});
|
|
23
|
+
});
|
|
24
|
+
|
|
25
|
+
describe('Active State Logic', () => {
|
|
26
|
+
it('is active when current pathname matches dashboard path', () => {
|
|
27
|
+
renderDashboardExtension('/base/dashboard', 'dashboard', 'Dashboard', '/base');
|
|
28
|
+
|
|
29
|
+
const link = screen.getByRole('link');
|
|
30
|
+
expect(link).toHaveClass('active-left-nav-link');
|
|
31
|
+
});
|
|
32
|
+
|
|
33
|
+
it('is active when path segments match (partial match)', () => {
|
|
34
|
+
renderDashboardExtension('/base/dashboard/patients', 'patients', 'Dashboard', '/base');
|
|
35
|
+
|
|
36
|
+
const link = screen.getByRole('link');
|
|
37
|
+
expect(link).toHaveClass('active-left-nav-link');
|
|
38
|
+
});
|
|
39
|
+
|
|
40
|
+
it('is not active when path does not match', () => {
|
|
41
|
+
renderDashboardExtension('/base/other', 'dashboard', 'Dashboard', '/base');
|
|
42
|
+
|
|
43
|
+
const link = screen.getByRole('link');
|
|
44
|
+
expect(link).not.toHaveClass('active-left-nav-link');
|
|
45
|
+
});
|
|
46
|
+
|
|
47
|
+
it('handles empty path (returns false)', () => {
|
|
48
|
+
renderDashboardExtension('/base', '', 'Dashboard', '/base');
|
|
49
|
+
|
|
50
|
+
const link = screen.getByRole('link');
|
|
51
|
+
expect(link).not.toHaveClass('active-left-nav-link');
|
|
52
|
+
});
|
|
53
|
+
|
|
54
|
+
it('handles path with encoded characters in location', () => {
|
|
55
|
+
renderDashboardExtension('/base/dashboard%20%26%20test', 'dashboard & test', 'Dashboard', '/base');
|
|
56
|
+
|
|
57
|
+
const link = screen.getByRole('link');
|
|
58
|
+
expect(link).toHaveClass('active-left-nav-link');
|
|
59
|
+
expect(link).toHaveAttribute('href', '/base/dashboard%20%26%20test');
|
|
60
|
+
});
|
|
61
|
+
});
|
|
62
|
+
});
|
|
63
|
+
|
|
64
|
+
const renderDashboardExtension = (browserPath: string, path: string, title: string, basePath: string) => {
|
|
65
|
+
render(
|
|
66
|
+
<MemoryRouter initialEntries={[browserPath]}>
|
|
67
|
+
<DashboardExtension path={path} title={title} basePath={basePath} />
|
|
68
|
+
</MemoryRouter>,
|
|
69
|
+
);
|
|
70
|
+
};
|
|
@@ -2,7 +2,6 @@ import React, { useMemo } from 'react';
|
|
|
2
2
|
import classNames from 'classnames';
|
|
3
3
|
import { useTranslation } from 'react-i18next';
|
|
4
4
|
import { BrowserRouter, useLocation } from 'react-router-dom';
|
|
5
|
-
import { shallowEqual } from '@openmrs/esm-utils';
|
|
6
5
|
import { ConfigurableLink, MaybeIcon } from '@openmrs/esm-framework';
|
|
7
6
|
import { type IconId } from '../icons';
|
|
8
7
|
import styles from './dashboard.module.scss';
|
|
@@ -26,13 +25,14 @@ export const DashboardExtension = ({ path, title, basePath, icon }: DashboardExt
|
|
|
26
25
|
if (p.startsWith('http')) {
|
|
27
26
|
return p === window.location.href;
|
|
28
27
|
}
|
|
29
|
-
const
|
|
30
|
-
|
|
31
|
-
const localPath = (location.pathname ?? '')
|
|
28
|
+
const pathSegments = p.split('/').map((s) => decodeURIComponent(s));
|
|
29
|
+
const localSegments = (location.pathname ?? '')
|
|
32
30
|
.split('/')
|
|
33
|
-
.slice(
|
|
31
|
+
.slice(1)
|
|
34
32
|
.map((s) => decodeURIComponent(s));
|
|
35
|
-
|
|
33
|
+
|
|
34
|
+
// Check if pathSegments appear as a contiguous slice anywhere in localSegments
|
|
35
|
+
return localSegments.some((_, i) => pathSegments.every((seg, j) => localSegments[i + j] === seg));
|
|
36
36
|
}, [location.pathname, path]);
|
|
37
37
|
|
|
38
38
|
return (
|