From b22020c8221830feb10cf7cb3ec7b337e7e97a64 Mon Sep 17 00:00:00 2001 From: suubi-joshua <78343336+suubi-joshua@users.noreply.github.com> Date: Mon, 18 Dec 2023 12:23:50 +0300 Subject: [PATCH 01/37] (chore) O3-2628: Decrease the timeout of the E2E workflow (#847) * Added time-out of 15 minutes for e2e tests level in the github workflow file * Changed the timeout for the Job to 15 minutes --- .github/workflows/e2e.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 6de40bba6..736e1717f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -11,7 +11,7 @@ on: jobs: main: runs-on: ubuntu-latest - timeout-minutes: 60 + timeout-minutes: 15 steps: - name: Checkout repo uses: actions/checkout@v3 From f1d8002b89cfe042580e6825b4b4d7def3ba1628 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Tue, 19 Dec 2023 16:44:19 +0300 Subject: [PATCH 02/37] (chore) Bump testing dependencies and fix test console warnings (#855) --- package.json | 14 +- packages/apps/esm-devtools-app/jest.config.js | 12 +- .../src/{setup-tests.tsx => setup-tests.ts} | 0 .../esm-implementer-tools-app/jest.config.js | 1 + .../esm-implementer-tools-app/setup-tests.ts | 3 + .../src/configuration/configuration.test.tsx | 24 +- .../change-location-link.test.tsx | 8 +- .../location-picker/location-picker.test.tsx | 159 +++--- .../redirect-logout/redirect-logout.test.tsx | 16 +- .../choose-locale/change-locale.test.tsx | 12 +- .../src/setupTests.ts | 2 +- .../esm-api/src/openmrs-fetch.test.ts | 10 +- .../extension-config.test.tsx | 200 ++++---- .../src/integration-tests/setup-tests.ts | 2 +- .../src/dynamic-offline-data.test.ts | 11 + .../src/ConfigurableLink.test.tsx | 2 +- .../esm-react-utils/src/extensions.test.tsx | 20 +- .../src/openmrsComponentDecorator.test.tsx | 13 +- .../esm-react-utils/src/setup-tests.js | 2 +- .../src/useAbortController.test.tsx | 2 +- .../src/useOnClickOutside.test.tsx | 13 +- .../src/error-state/error-state.component.tsx | 34 +- yarn.lock | 466 +++++++++++++++--- 23 files changed, 713 insertions(+), 313 deletions(-) rename packages/apps/esm-devtools-app/src/{setup-tests.tsx => setup-tests.ts} (100%) create mode 100644 packages/apps/esm-implementer-tools-app/setup-tests.ts diff --git a/package.json b/package.json index ce4dab5f7..2502bf385 100644 --- a/package.json +++ b/package.json @@ -27,14 +27,14 @@ "coverage": "yarn test --coverage" }, "devDependencies": { - "@jest/types": "^29.6.3", - "@playwright/test": "1.39.0", + "@playwright/test": "1.40.1", "@swc/core": "^1.3.58", - "@swc/jest": "^0.2.22", - "@testing-library/dom": "^8.16.0", - "@testing-library/jest-dom": "^5.16.4", - "@testing-library/react": "^13.3.0", - "@testing-library/user-event": "^14.2.1", + "@swc/jest": "^0.2.29", + "@testing-library/dom": "^9.3.3", + "@testing-library/jest-dom": "^6.1.5", + "@testing-library/react": "^14.1.2", + "@testing-library/user-event": "^14.5.1", + "@types/jest": "^29.5.11", "@types/react-dom": "^18.0.6", "@types/systemjs": "^6.1.0", "@types/webpack-env": "^1.16.4", diff --git a/packages/apps/esm-devtools-app/jest.config.js b/packages/apps/esm-devtools-app/jest.config.js index 9b904a649..d2c66915b 100644 --- a/packages/apps/esm-devtools-app/jest.config.js +++ b/packages/apps/esm-devtools-app/jest.config.js @@ -1,13 +1,13 @@ module.exports = { transform: { - "\\.(m?j|t)sx?$": ["@swc/jest"], + '\\.(m?j|t)sx?$': ['@swc/jest'], }, - setupFiles: ['/src/setup-tests.tsx'], + setupFiles: ['/src/setup-tests.ts'], moduleNameMapper: { - "lodash-es": "lodash", - "\\.(s?css)$": "identity-obj-proxy", - "@openmrs/esm-framework": "@openmrs/esm-framework/mock.tsx", - dexie: require.resolve("dexie"), + 'lodash-es': 'lodash', + '\\.(s?css)$': 'identity-obj-proxy', + '@openmrs/esm-framework': '@openmrs/esm-framework/mock.tsx', + dexie: require.resolve('dexie'), }, globals: { System: { diff --git a/packages/apps/esm-devtools-app/src/setup-tests.tsx b/packages/apps/esm-devtools-app/src/setup-tests.ts similarity index 100% rename from packages/apps/esm-devtools-app/src/setup-tests.tsx rename to packages/apps/esm-devtools-app/src/setup-tests.ts diff --git a/packages/apps/esm-implementer-tools-app/jest.config.js b/packages/apps/esm-implementer-tools-app/jest.config.js index c6ab0249e..f877ef2d6 100644 --- a/packages/apps/esm-implementer-tools-app/jest.config.js +++ b/packages/apps/esm-implementer-tools-app/jest.config.js @@ -5,6 +5,7 @@ module.exports = { globals: { System: {}, }, + setupFilesAfterEnv: ['/setup-tests.ts'], moduleNameMapper: { 'lodash-es': 'lodash', '\\.(s?css)$': 'identity-obj-proxy', diff --git a/packages/apps/esm-implementer-tools-app/setup-tests.ts b/packages/apps/esm-implementer-tools-app/setup-tests.ts new file mode 100644 index 000000000..84159b404 --- /dev/null +++ b/packages/apps/esm-implementer-tools-app/setup-tests.ts @@ -0,0 +1,3 @@ +import '@testing-library/jest-dom'; + +window.URL.createObjectURL = jest.fn(); diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.test.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.test.tsx index 86f2148c1..f605eb98c 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.test.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import '@testing-library/jest-dom'; + import { render, screen, within } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { implementerToolsConfigStore, temporaryConfigStore, Type } from '@openmrs/esm-framework/src/internal'; @@ -23,8 +23,6 @@ jest.mock('./interactive-editor/value-editors/concept-search.resource', () => ({ })), })); -window.URL.createObjectURL = jest.fn(); - const mockImplToolsConfig = { '@openmrs/mario': { hasHat: { @@ -104,11 +102,12 @@ describe('Configuration', () => { it('renders the configuration component inside the implementer tools panel', () => { renderConfiguration(); + + screen.findByRole('textbox', { name: /search configuration/i }); screen.getByRole('switch', { name: /json editor/i }); screen.getByRole('switch', { name: /ui editor/i }); screen.getByRole('button', { name: /clear local config/i }); screen.getByRole('button', { name: /download config/i }); - screen.getByRole('textbox', { name: /search configuration/i }); }); it('displays correct boolean value and editor', async () => { @@ -122,6 +121,7 @@ describe('Configuration', () => { renderConfiguration(); + screen.findByText('hasHat'); const rowElement = screen.getByText('hasHat').closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); @@ -164,6 +164,7 @@ describe('Configuration', () => { renderConfiguration(); + screen.findByText('hatUuid'); const rowElement = (await screen.findByText('hatUuid')).closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); @@ -205,7 +206,8 @@ describe('Configuration', () => { renderConfiguration(); - const rowElement = (await screen.findByText('numberFingers')).closest('.cds--structured-list-row'); + screen.findByText('numberFingers'); + const rowElement = screen.getByText('numberFingers').closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); if (rowElement) { @@ -242,7 +244,8 @@ describe('Configuration', () => { renderConfiguration(); - const rowElement = (await screen.findByText('nemesisName')).closest('.cds--structured-list-row'); + screen.findByText('nemesisName'); + const rowElement = screen.getByText('nemesisName').closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); if (rowElement) { @@ -274,7 +277,8 @@ describe('Configuration', () => { renderConfiguration(); - const rowElement = (await screen.findByText('mustacheUuid')).closest('.cds--structured-list-row'); + screen.findByText('mustacheUuid'); + const rowElement = screen.getByText('mustacheUuid').closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); if (rowElement) { @@ -306,9 +310,13 @@ describe('Configuration', () => { '@openmrs/luigi': mockImplToolsConfig['@openmrs/luigi'], }, }); + renderConfiguration(); - const rowElement = (await screen.findByText('favoriteNumbers')).closest('.cds--structured-list-row'); + + screen.findByText('favoriteNumbers'); + const rowElement = screen.getByText('favoriteNumbers').closest('.cds--structured-list-row'); expect(rowElement).toBeInTheDocument(); + if (rowElement) { const row = within(rowElement as HTMLElement); diff --git a/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx b/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx index 2dbbf080a..37cc9d7a7 100644 --- a/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx +++ b/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx @@ -1,6 +1,7 @@ import React from 'react'; import ChangeLocationLink from './change-location-link.component'; -import { fireEvent, render, screen } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { navigate } from '@openmrs/esm-framework'; const navigateMock = navigate as jest.Mock; @@ -8,7 +9,7 @@ const navigateMock = navigate as jest.Mock; describe('', () => { const mockChangeLocationProps = { referer: '/openmrs/spa/home', - currentLocation: 'UnKnown Location', + currentLocation: 'Unknown Location', }; beforeEach(() => { @@ -21,11 +22,12 @@ describe('', () => { }); it('should display the `Change location` link', async () => { + const user = userEvent.setup(); const changeLocationButton = await screen.findByRole('button', { name: /Change/i, }); - fireEvent.click(changeLocationButton); + await user.click(changeLocationButton); expect(navigateMock).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login/location?returnToUrl=/openmrs/spa/home&update=true', diff --git a/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx b/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx index 9f919def3..19c39dc37 100644 --- a/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx +++ b/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx @@ -1,4 +1,5 @@ -import { cleanup, fireEvent, screen, waitFor } from '@testing-library/react'; +import { act, screen, waitFor } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { openmrsFetch, useConfig, @@ -15,7 +16,6 @@ import { import { mockConfig } from '../../__mocks__/config.mock'; import renderWithRouter from '../test-helpers/render-with-router'; import LocationPicker from './location-picker.component'; -import { act } from 'react-dom/test-utils'; const validLocationUuid = '1ce1b7d4-c865-4178-82b0-5932e51503d6'; const invalidLocationUuid = '2gf1b7d4-c865-4178-82b0-5932e51503d6'; @@ -53,7 +53,6 @@ jest.mock('@openmrs/esm-framework', () => ({ describe('LocationPicker', () => { beforeEach(() => { - cleanup(); jest.clearAllMocks(); }); @@ -66,7 +65,7 @@ describe('LocationPicker', () => { }); }); - expect(screen.getByText(/welcome testy mctesterface/i)).toBeInTheDocument(); + screen.findByText(/welcome testy mctesterface/i); expect(screen.getByText(/select your location from the list below/i)).toBeInTheDocument(); expect(screen.getByText(/use the search bar to find your location/i)).toBeInTheDocument(); expect(screen.getByRole('button', { name: /confirm/i })).toBeInTheDocument(); @@ -87,25 +86,34 @@ describe('LocationPicker', () => { describe('Testing setting user preference workflow', () => { it('should save user preference if the user checks the checkbox and submit', async () => { + const user = userEvent.setup(); + await act(() => { renderWithRouter(LocationPicker, {}); }); + + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); const communityOutreachLocation = await screen.findByRole('radio', { name: 'Community Outreach', }); expect(communityOutreachLocation).toBeInTheDocument(); - fireEvent.click(communityOutreachLocation); + + await user.click(communityOutreachLocation); expect(checkbox).toBeInTheDocument(); - fireEvent.click(checkbox); + + await user.click(checkbox); + const submitButton = screen.getByText('Confirm'); - fireEvent.click(submitButton); - expect(setSessionLocation).toBeCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); - expect(setUserProperties).toBeCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { + await user.click(submitButton); + + expect(setSessionLocation).toHaveBeenCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + expect(setUserProperties).toHaveBeenCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { defaultLocation: '1ce1b7d4-c865-4178-82b0-5932e51503d6', }); + await waitFor(() => - expect(showToast).toBeCalledWith({ + expect(showToast).toHaveBeenCalledWith({ kind: 'success', title: 'Selected location will be used for your next logins', description: 'You can change your preference from the user dashboard', @@ -114,22 +122,26 @@ describe('LocationPicker', () => { }); it("should not save user preference if the user doesn't checks the checkbox and submit", async () => { + const user = userEvent.setup(); + await act(() => { renderWithRouter(LocationPicker, {}); }); + screen.findByText(/welcome testy mctesterface/i); const communityOutreachLocation = await screen.findByRole('radio', { name: 'Community Outreach', }); + expect(communityOutreachLocation).toBeInTheDocument(); - fireEvent.click(communityOutreachLocation); - const submitButton = screen.getByText('Confirm'); - fireEvent.click(submitButton); + await user.click(communityOutreachLocation); - expect(setSessionLocation).toBeCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + const submitButton = screen.getByText('Confirm'); + await user.click(submitButton); - expect(setUserProperties).not.toBeCalled(); - expect(showToast).not.toBeCalled(); + expect(setSessionLocation).toHaveBeenCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + expect(setUserProperties).not.toHaveBeenCalled(); + expect(showToast).not.toHaveBeenCalled(); }); it('should redirect to home if user preference in the userProperties is present and the location preference is valid', async () => { @@ -143,10 +155,9 @@ describe('LocationPicker', () => { }, }); - await act(() => { - renderWithRouter(LocationPicker, {}); - }); + renderWithRouter(LocationPicker, {}); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); @@ -156,11 +167,11 @@ describe('LocationPicker', () => { }); expect(communityOutreachLocation).toBeInTheDocument(); - expect(setSessionLocation).toBeCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + expect(setSessionLocation).toHaveBeenCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); // Since the user prop and the default login location is the same, // it shouldn't send a hit to the backend. - expect(setUserProperties).not.toBeCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { + expect(setUserProperties).not.toHaveBeenCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { defaultLocation: '1ce1b7d4-c865-4178-82b0-5932e51503d6', }); }); @@ -180,6 +191,7 @@ describe('LocationPicker', () => { renderWithRouter(LocationPicker, {}); }); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); @@ -189,7 +201,7 @@ describe('LocationPicker', () => { }); expect(communityOutreachLocation).toBeInTheDocument(); - expect(setSessionLocation).not.toBeCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + expect(setSessionLocation).not.toHaveBeenCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); }); }); @@ -204,10 +216,12 @@ describe('LocationPicker', () => { }, }, }); + await act(() => { renderWithRouter(LocationPicker, {}, { routes: ['?update=true'] }); }); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); @@ -215,10 +229,12 @@ describe('LocationPicker', () => { name: 'Community Outreach', }); expect(communityOutreachLocation).toBeInTheDocument(); - expect(setSessionLocation).not.toBeCalled(); + expect(setSessionLocation).not.toHaveBeenCalled(); }); it('should remove the saved preference if the login location page has a searchParam `update=true` and when submitting the user unchecks the checkbox ', async () => { + const user = userEvent.setup(); + mockUseSession.mockReturnValue({ user: { display: 'Testy McTesterface', @@ -228,10 +244,12 @@ describe('LocationPicker', () => { }, }, }); + await act(() => { renderWithRouter(LocationPicker, {}, { routes: ['?update=true'] }); }); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); @@ -239,20 +257,21 @@ describe('LocationPicker', () => { name: 'Community Outreach', }); expect(communityOutreachLocation).toBeInTheDocument(); - expect(setSessionLocation).not.toBeCalled(); + expect(setSessionLocation).not.toHaveBeenCalled(); + + await user.click(communityOutreachLocation); + await user.click(checkbox); - fireEvent.click(communityOutreachLocation); - fireEvent.click(checkbox); expect(checkbox).not.toBeChecked(); - const submitButton = screen.getByText('Confirm'); - fireEvent.click(submitButton); - expect(setSessionLocation).toBeCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + const submitButton = screen.getByText('Confirm'); + await user.click(submitButton); - expect(setUserProperties).toBeCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', {}); + expect(setSessionLocation).toHaveBeenCalledWith('1ce1b7d4-c865-4178-82b0-5932e51503d6', expect.anything()); + expect(setUserProperties).toHaveBeenCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', {}); await waitFor(() => - expect(showToast).toBeCalledWith({ + expect(showToast).toHaveBeenCalledWith({ title: 'Login location preference removed', kind: 'success', description: 'The login location preference has been removed.', @@ -261,6 +280,8 @@ describe('LocationPicker', () => { }); it('should update the user preference with new selection', async () => { + const user = userEvent.setup(); + mockUseSession.mockReturnValue({ user: { display: 'Testy McTesterface', @@ -270,25 +291,31 @@ describe('LocationPicker', () => { }, }, }); + await act(() => { renderWithRouter(LocationPicker, {}, { routes: ['?update=true'] }); }); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); const mobileClinicRadio = await screen.findByRole('radio', { name: 'Mobile Clinic', }); - fireEvent.click(mobileClinicRadio); + + await user.click(mobileClinicRadio); + const submitButton = screen.getByText('Confirm'); - fireEvent.click(submitButton); - expect(setSessionLocation).toBeCalledWith('8d9045ad-50f0-45b8-93c8-3ed4bce19dbf', expect.anything()); - expect(setUserProperties).toBeCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { + await user.click(submitButton); + + expect(setSessionLocation).toHaveBeenCalledWith('8d9045ad-50f0-45b8-93c8-3ed4bce19dbf', expect.anything()); + expect(setUserProperties).toHaveBeenCalledWith('90bd24b3-e700-46b0-a5ef-c85afdfededd', { defaultLocation: '8d9045ad-50f0-45b8-93c8-3ed4bce19dbf', }); + await waitFor(() => - expect(showToast).toBeCalledWith({ + expect(showToast).toHaveBeenCalledWith({ description: 'Selected location will be used for your next logins', kind: 'success', title: 'Login location preference updated', @@ -297,6 +324,8 @@ describe('LocationPicker', () => { }); it('should not update the user preference with same selection', async () => { + const user = userEvent.setup(); + mockUseSession.mockReturnValue({ user: { display: 'Testy McTesterface', @@ -306,45 +335,53 @@ describe('LocationPicker', () => { }, }, }); + await act(() => { renderWithRouter(LocationPicker, {}, { routes: ['?update=true'] }); }); + screen.findByText(/welcome testy mctesterface/i); const checkbox = await screen.findByLabelText('Remember my location for future logins'); expect(checkbox).toBeChecked(); const communityOutreachLocation = await screen.findByRole('radio', { name: 'Community Outreach', }); - fireEvent.click(communityOutreachLocation); + + await user.click(communityOutreachLocation); + const submitButton = screen.getByText('Confirm'); - fireEvent.click(submitButton); - expect(setSessionLocation).toBeCalledWith(validLocationUuid, expect.anything()); - expect(setUserProperties).not.toBeCalled(); - }); - }); + await user.click(submitButton); - it('should have the defaultLocation presented at the top of the list', async () => { - Object.defineProperty(window, 'location', { - value: { - search: '?update=true', - }, + expect(setSessionLocation).toHaveBeenCalledWith(validLocationUuid, expect.anything()); + expect(setUserProperties).not.toHaveBeenCalled(); }); - mockUseSession.mockReturnValue({ - user: { - display: 'Testy McTesterface', - uuid: '90bd24b3-e700-46b0-a5ef-c85afdfededd', - userProperties: { - defaultLocation: validLocationUuid, + + it('should have the defaultLocation presented at the top of the list', async () => { + Object.defineProperty(window, 'location', { + value: { + search: '?update=true', }, - }, - }); - await act(() => { - renderWithRouter(LocationPicker, {}); - }); + }); + + mockUseSession.mockReturnValue({ + user: { + display: 'Testy McTesterface', + uuid: '90bd24b3-e700-46b0-a5ef-c85afdfededd', + userProperties: { + defaultLocation: validLocationUuid, + }, + }, + }); + + await act(() => { + renderWithRouter(LocationPicker, {}); + }); - const radios = screen.getAllByRole('radio'); - expect(radios[0].getAttribute('id')).toBe('Community Outreach'); - expect(radios[0]).toHaveAttribute('checked'); + screen.findByText(/welcome testy mctesterface/i); + const radios = screen.getAllByRole('radio'); + expect(radios[0].getAttribute('id')).toBe('Community Outreach'); + expect(radios[0]).toHaveAttribute('checked'); + }); }); }); diff --git a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx index a3c550097..60c90afac 100644 --- a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx +++ b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx @@ -54,18 +54,18 @@ describe('Testing Logout', () => { }); it('should render Logout and redirect to login page', async () => { render(); - expect(openmrsFetch).toBeCalledWith('/ws/rest/v1/session', { + expect(openmrsFetch).toHaveBeenCalledWith('/ws/rest/v1/session', { method: 'DELETE', }); await waitFor(() => expect(mutate).toBeCalled()); expect(clearCurrentUser).toBeCalled(); expect(refetchCurrentUser).toBeCalled(); - expect(setUserLanguage).toBeCalledWith({ + expect(setUserLanguage).toHaveBeenCalledWith({ locale: 'km', authenticated: false, sessionId: '', }); - expect(navigate).toBeCalledWith({ to: '${openmrsSpaBase}/login' }); + expect(navigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' }); }); it('should render Logout and redirect to provider.logoutUrl if provider.type === oauth2', async () => { @@ -76,18 +76,18 @@ describe('Testing Logout', () => { }, }); render(); - expect(openmrsFetch).toBeCalledWith('/ws/rest/v1/session', { + expect(openmrsFetch).toHaveBeenCalledWith('/ws/rest/v1/session', { method: 'DELETE', }); await waitFor(() => expect(mutate).toBeCalled()); expect(clearCurrentUser).toBeCalled(); expect(refetchCurrentUser).toBeCalled(); - expect(setUserLanguage).toBeCalledWith({ + expect(setUserLanguage).toHaveBeenCalledWith({ locale: 'km', authenticated: false, sessionId: '', }); - expect(navigate).toBeCalledWith({ to: '/oauth/logout' }); + expect(navigate).toHaveBeenCalledWith({ to: '/oauth/logout' }); }); it('should redirect to login if the session is already unauthenticated', async () => { @@ -95,12 +95,12 @@ describe('Testing Logout', () => { authenticated: false, } as Session); render(); - expect(navigate).toBeCalledWith({ to: '${openmrsSpaBase}/login' }); + expect(navigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' }); }); it('should redirect to login if the application is Offline', async () => { (useConnectivity as jest.Mock).mockReturnValue(false); render(); - expect(navigate).toBeCalledWith({ to: '${openmrsSpaBase}/login' }); + expect(navigate).toHaveBeenCalledWith({ to: '${openmrsSpaBase}/login' }); }); }); diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx index 35fd5ae4d..effd7253b 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx @@ -1,5 +1,6 @@ import React from 'react'; -import { fireEvent, render, screen, waitFor } from '@testing-library/react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { ChangeLocale } from './change-locale.component'; import type { PostUserProperties } from './change-locale.resource'; @@ -15,6 +16,7 @@ describe(``, () => { let postUserPropertiesMock: PostUserProperties = jest.fn(() => Promise.resolve()); it('should change user locale', async () => { + const userSetup = userEvent.setup(); postUserPropertiesMock = jest.fn(() => Promise.resolve()); render( @@ -26,11 +28,7 @@ describe(``, () => { />, ); expect(screen.getByLabelText(/Select locale/)).toHaveValue('fr'); - fireEvent.change(screen.getByLabelText(/Select locale/i), { - target: { value: 'en' }, - }); - await waitFor(() => { - expect(postUserPropertiesMock).toHaveBeenCalledWith(user.uuid, { defaultLocale: 'en' }, expect.anything()); - }); + await userSetup.selectOptions(screen.getByLabelText(/Select locale/i), 'en'); + expect(postUserPropertiesMock).toHaveBeenCalledWith(user.uuid, { defaultLocale: 'en' }, expect.anything()); }); }); diff --git a/packages/apps/esm-primary-navigation-app/src/setupTests.ts b/packages/apps/esm-primary-navigation-app/src/setupTests.ts index 2d04b7c5b..187e74f47 100644 --- a/packages/apps/esm-primary-navigation-app/src/setupTests.ts +++ b/packages/apps/esm-primary-navigation-app/src/setupTests.ts @@ -1,4 +1,4 @@ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; const { getComputedStyle } = window; diff --git a/packages/framework/esm-api/src/openmrs-fetch.test.ts b/packages/framework/esm-api/src/openmrs-fetch.test.ts index 24d882f72..d8287dd15 100644 --- a/packages/framework/esm-api/src/openmrs-fetch.test.ts +++ b/packages/framework/esm-api/src/openmrs-fetch.test.ts @@ -25,24 +25,24 @@ describe('openmrsFetch', () => { it(`throws an error if you don't pass in a url string`, () => { // @ts-ignore - expect(() => openmrsFetch()).toThrowError(/first argument/); + expect(() => openmrsFetch()).toThrow(/first argument/); // @ts-ignore - expect(() => openmrsFetch({})).toThrowError(/first argument/); + expect(() => openmrsFetch({})).toThrow(/first argument/); }); it(`throws an error if you pass in an invalid fetchInit object`, () => { // @ts-ignore - expect(() => openmrsFetch('/session', 'invalid second arg')).toThrowError(/second argument/); + expect(() => openmrsFetch('/session', 'invalid second arg')).toThrow(/second argument/); // @ts-ignore - expect(() => openmrsFetch('/session', 123)).toThrowError(/second argument/); + expect(() => openmrsFetch('/session', 123)).toThrow(/second argument/); }); it(`throws an Error if there is no openmrsBase`, () => { // @ts-ignore delete window.openmrsBase; - expect(() => openmrsFetch('/session')).toThrowError(/openmrsBase/); + expect(() => openmrsFetch('/session')).toThrow(/openmrsBase/); }); it(`calls window.fetch with the correct arguments for a basic GET request`, () => { diff --git a/packages/framework/esm-framework/src/integration-tests/extension-config.test.tsx b/packages/framework/esm-framework/src/integration-tests/extension-config.test.tsx index 783e74eb5..2b7a96deb 100644 --- a/packages/framework/esm-framework/src/integration-tests/extension-config.test.tsx +++ b/packages/framework/esm-framework/src/integration-tests/extension-config.test.tsx @@ -37,13 +37,16 @@ describe('Interaction between configuration and extension systems', () => { }); test('Config should add, order, and remove extensions within slots', async () => { + const promise = Promise.resolve(); registerSimpleExtension('Fred', 'esm-flintstone'); registerSimpleExtension('Wilma', 'esm-flintstone'); registerSimpleExtension('Barney', 'esm-rubble'); registerSimpleExtension('Betty', 'esm-rubble'); + attach('A slot', 'Fred'); attach('A slot', 'Wilma'); defineConfigSchema('esm-flintstone', {}); + provide({ 'esm-flintstone': { extensionSlots: { @@ -56,18 +59,17 @@ describe('Interaction between configuration and extension systems', () => { }, }); - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-flintstone', - featureName: 'The Flintstones', - disableTranslations: true, - })(() => ); + const App = openmrsComponentDecorator({ + moduleName: 'esm-flintstone', + featureName: 'The Flintstones', + disableTranslations: true, + })(() => ); - render(); - }); + await act(async () => await promise); - await waitFor(() => expect(screen.getByText('Betty')).toBeInTheDocument()); + render(); + screen.findByText('Betty'); const slot = screen.getByTestId('slot'); const extensions = slot.childNodes; @@ -80,6 +82,7 @@ describe('Interaction between configuration and extension systems', () => { }); test("Extensions should recieve config from module and from 'configure' key", async () => { + const promise = Promise.resolve(); registerSimpleExtension('Pebbles', 'esm-flintstone', true); defineConfigSchema('esm-flintstone', { town: { _type: Type.String, _default: 'Bedrock' }, @@ -101,23 +104,22 @@ describe('Interaction between configuration and extension systems', () => { }, }); - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-flintstone', - featureName: 'The Flintstones', - disableTranslations: true, - })(() => ( - <> - - - - )); - - render(); - }); + const App = openmrsComponentDecorator({ + moduleName: 'esm-flintstone', + featureName: 'The Flintstones', + disableTranslations: true, + })(() => ( + <> + + + + )); + + await act(async () => await promise); - await screen.findAllByText(/.*Pebbles.*/); + render(); + screen.findAllByText(/.*Pebbles.*/); const flintstonePebbles = screen.getByTestId('flintstone-slot'); const futurePebbles = screen.getByTestId('future-slot'); @@ -128,6 +130,8 @@ describe('Interaction between configuration and extension systems', () => { }); test('Should be possible to attach the same extension twice with different configurations', async () => { + const promise = Promise.resolve(); + registerSimpleExtension('pet', 'esm-characters', true); defineConfigSchema('esm-characters', { name: { _type: Type.String, _default: '(no-name)' }, @@ -151,22 +155,21 @@ describe('Interaction between configuration and extension systems', () => { }, }); - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-flintstone', - featureName: 'The Flintstones', - disableTranslations: true, - })(() => ( - <> - - - )); - - render(); - }); + const App = openmrsComponentDecorator({ + moduleName: 'esm-flintstone', + featureName: 'The Flintstones', + disableTranslations: true, + })(() => ( + <> + + + )); + + await act(async () => await promise); - await screen.findAllByText(/.*Dino.*/); + render(); + screen.findAllByText(/.*Dino.*/); const slot = screen.getByTestId('flintstone-slot'); await waitFor(() => { @@ -176,19 +179,20 @@ describe('Interaction between configuration and extension systems', () => { }); test('Slot config should update with temporary config', async () => { + const promise = Promise.resolve(); registerSimpleExtension('Pearl', 'esm-slaghoople'); attach('A slot', 'Pearl'); defineConfigSchema('esm-slaghoople', {}); - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-slaghoople', - featureName: 'The Slaghooples', - disableTranslations: true, - })(() => ); + const App = openmrsComponentDecorator({ + moduleName: 'esm-slaghoople', + featureName: 'The Slaghooples', + disableTranslations: true, + })(() => ); - render(); - }); + await act(async () => await promise); + + render(); await waitFor(() => expect(screen.getByText('Pearl')).toBeInTheDocument()); @@ -210,22 +214,21 @@ describe('Interaction between configuration and extension systems', () => { }); test('Extension config should update with temporary config', async () => { + const promise = Promise.resolve(); registerSimpleExtension('Mr. Slate', 'esm-flintstone', true); attach('A slot', 'Mr. Slate'); defineConfigSchema('esm-flintstone', { tie: { _default: 'green' } }); - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-quarry', - featureName: 'The Flintstones', - disableTranslations: true, - })(() => ); + const App = openmrsComponentDecorator({ + moduleName: 'esm-quarry', + featureName: 'The Flintstones', + disableTranslations: true, + })(() => ); - render(); - }); + await act(async () => await promise); + render(); await waitFor(() => expect(screen.getByText(/Mr. Slate/)).toBeInTheDocument()); - expect(screen.getByTestId('slot')).toHaveTextContent(/green/); act(() => { @@ -244,13 +247,12 @@ describe('Interaction between configuration and extension systems', () => { }); }); - await waitFor(() => { - expect(screen.getByTestId('slot')).toHaveTextContent(/black/); - expect(screen.queryByText('green')).not.toBeInTheDocument(); - }); + expect(screen.getByTestId('slot')).toHaveTextContent(/black/); + expect(screen.queryByText('green')).not.toBeInTheDocument(); }); test('Extension config should be available in extension store', async () => { + const promise = Promise.resolve(); registerSimpleExtension('Bamm-Bamm', 'esm-flintstone', false); attach('A slot', 'Bamm-Bamm'); defineConfigSchema('esm-flintstone', { clothes: { _default: 'leopard' } }); @@ -266,18 +268,17 @@ describe('Interaction between configuration and extension systems', () => { ); } - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-flintstone', - featureName: 'The Flintstones', - disableTranslations: true, - })(RootComponent); + const App = openmrsComponentDecorator({ + moduleName: 'esm-flintstone', + featureName: 'The Flintstones', + disableTranslations: true, + })(RootComponent); - render(); - }); + await act(async () => await promise); - await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument()); + render(); + screen.findByTestId(/slot/); expect(screen.getByText(/clothes/)).toHaveTextContent(/leopard/); act(() => { @@ -300,6 +301,7 @@ describe('Interaction between configuration and extension systems', () => { }); test('should not show extension when user lacks configured privilege', async () => { + const promise = Promise.resolve(); mockSessionStore.setState({ loaded: true, session: { @@ -346,22 +348,23 @@ describe('Interaction between configuration and extension systems', () => { ); } - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-bedrock', - featureName: 'Bedrock', - disableTranslations: true, - })(RootComponent); + const App = openmrsComponentDecorator({ + moduleName: 'esm-bedrock', + featureName: 'Bedrock', + disableTranslations: true, + })(RootComponent); - render(); - }); + await act(async () => await promise); - await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument()); + render(); + + screen.findByTestId(/slot/); expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Wilma'); expect(screen.queryAllByText(/\bSchmoo\b/)).toHaveLength(0); }); test('should show extension when user has configured privilege', async () => { + const promise = Promise.resolve(); mockSessionStore.setState({ loaded: true, session: { @@ -402,21 +405,22 @@ describe('Interaction between configuration and extension systems', () => { ); } - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-bedrock', - featureName: 'Bedrock', - disableTranslations: true, - })(RootComponent); + const App = openmrsComponentDecorator({ + moduleName: 'esm-bedrock', + featureName: 'Bedrock', + disableTranslations: true, + })(RootComponent); - render(); - }); + await act(async () => await promise); + + render(); await waitFor(() => expect(screen.getByTestId(/slot/)).toBeInTheDocument()); expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Schmoo'); }); test('should only show extensions users have default privilege for', async () => { + const promise = Promise.resolve(); mockSessionStore.setState({ loaded: true, session: { @@ -455,25 +459,23 @@ describe('Interaction between configuration and extension systems', () => { ); } - act(() => { - const App = openmrsComponentDecorator({ - moduleName: 'esm-bedrock', - featureName: 'Bedrock', - disableTranslations: true, - })(RootComponent); + const App = openmrsComponentDecorator({ + moduleName: 'esm-bedrock', + featureName: 'Bedrock', + disableTranslations: true, + })(RootComponent); - render(); - }); + await act(async () => await promise); - await waitFor(() => { - expect(screen.getByTestId(/slot/)).toBeInTheDocument(); - expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Wilma'); - expect(screen.queryAllByText(/\bSchmoo\b/)).toHaveLength(0); - }); + render(); + + screen.findByTestId(/slot/); + expect(screen.getByTestId('slot').firstChild).toHaveAttribute('data-extension-id', 'Wilma'); + expect(screen.queryAllByText(/\bSchmoo\b/)).toHaveLength(0); }); }); -function registerSimpleExtension( +async function registerSimpleExtension( name: string, moduleName: string, takesConfig: boolean = false, diff --git a/packages/framework/esm-framework/src/integration-tests/setup-tests.ts b/packages/framework/esm-framework/src/integration-tests/setup-tests.ts index 4fad1f874..2a3228cd2 100644 --- a/packages/framework/esm-framework/src/integration-tests/setup-tests.ts +++ b/packages/framework/esm-framework/src/integration-tests/setup-tests.ts @@ -1,4 +1,4 @@ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; window.openmrsBase = '/openmrs'; window.spaBase = '/spa'; diff --git a/packages/framework/esm-offline/src/dynamic-offline-data.test.ts b/packages/framework/esm-offline/src/dynamic-offline-data.test.ts index c8260b922..7881f3c41 100644 --- a/packages/framework/esm-offline/src/dynamic-offline-data.test.ts +++ b/packages/framework/esm-offline/src/dynamic-offline-data.test.ts @@ -15,6 +15,17 @@ jest.mock('@openmrs/esm-api', () => ({ getLoggedInUser: jest.fn(async () => ({ uuid: mockUserId })), })); +let consoleWarn; + +beforeAll(() => { + // Hide dexie warnings about missing indexes. + consoleWarn = jest.spyOn(console, 'warn').mockImplementation(() => {}); +}); + +afterAll(() => { + consoleWarn.mockRestore(); +}); + afterEach(async () => { // We want each test case to start fresh with a clean sync queue. await new OfflineDb().dynamicOfflineData.clear(); diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx index 9f0e54ef7..3f4e3f8cb 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; import { navigate, interpolateUrl } from '@openmrs/esm-config'; diff --git a/packages/framework/esm-react-utils/src/extensions.test.tsx b/packages/framework/esm-react-utils/src/extensions.test.tsx index bdcd0525a..024162900 100644 --- a/packages/framework/esm-react-utils/src/extensions.test.tsx +++ b/packages/framework/esm-react-utils/src/extensions.test.tsx @@ -28,6 +28,10 @@ describe('ExtensionSlot, Extension, and useExtensionSlotMeta', () => { updateInternalExtensionStore(() => ({ slots: {}, extensions: {} })); }); + afterEach(() => { + jest.clearAllMocks(); + }); + test('Extension receives state changes passed through (not using )', async () => { function EnglishExtension({ suffix }) { return
English{suffix}
; @@ -87,16 +91,22 @@ describe('ExtensionSlot, Extension, and useExtensionSlotMeta', () => { }); test('ExtensionSlot throws error if both state and children provided', () => { + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); const App = () => ( ); - expect(() => render()).toThrowError( + expect(() => render()).toThrow(); + expect(consoleError).toHaveBeenNthCalledWith( + 1, expect.objectContaining({ - message: expect.stringMatching(/children.*state/), + message: expect.stringMatching( + /Both children and state have been provided. If children are provided, the state must be passed as a prop to the `Extension` component/i, + ), }), ); + consoleError.mockRestore(); }); test('Extension Slot receives meta', async () => { @@ -111,10 +121,10 @@ describe('ExtensionSlot, Extension, and useExtensionSlotMeta', () => { })(() => { const metas = useExtensionSlotMeta('Box'); const wrapItem = useCallback( - (slot: React.ReactNode, extension: ExtensionData) => { + (slot: React.ReactNode, extension?: ExtensionData) => { return (
-

{metas[getExtensionNameFromId(extension.extensionId)].code}

+

{metas[getExtensionNameFromId(extension?.extensionId ?? '')].code}

{slot}
); @@ -124,7 +134,7 @@ describe('ExtensionSlot, Extension, and useExtensionSlotMeta', () => { return (
- + {wrapItem}
); diff --git a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.test.tsx b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.test.tsx index 2a3a9999e..dd084c8d3 100644 --- a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.test.tsx +++ b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.test.tsx @@ -13,15 +13,22 @@ describe('openmrs-component-decorator', () => { it('renders a component', () => { const DecoratedComp = openmrsComponentDecorator(opts)(CompThatWorks); render(); - waitFor(() => { - expect(screen.getByText('The button')).toBeTruthy(); - }); + + screen.findByText('The button'); }); it('catches any errors in the component tree and renders a ui explaining something bad happened', () => { + const consoleError = jest.spyOn(console, 'error').mockImplementation(() => {}); const DecoratedComp = openmrsComponentDecorator(opts)(CompThatThrows); render(); // TO-DO assert the UX for broken react app is showing + expect(consoleError).toHaveBeenNthCalledWith( + 1, + expect.objectContaining({ + message: expect.stringContaining('ahahaa'), + }), + ); + consoleError.mockRestore(); }); it('provides ComponentContext', () => { diff --git a/packages/framework/esm-react-utils/src/setup-tests.js b/packages/framework/esm-react-utils/src/setup-tests.js index c847bd97f..1fbe98c3c 100644 --- a/packages/framework/esm-react-utils/src/setup-tests.js +++ b/packages/framework/esm-react-utils/src/setup-tests.js @@ -1,4 +1,4 @@ -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; window.openmrsBase = '/openmrs'; window.spaBase = '/spa'; diff --git a/packages/framework/esm-react-utils/src/useAbortController.test.tsx b/packages/framework/esm-react-utils/src/useAbortController.test.tsx index d88c4f82e..5674395d2 100644 --- a/packages/framework/esm-react-utils/src/useAbortController.test.tsx +++ b/packages/framework/esm-react-utils/src/useAbortController.test.tsx @@ -1,5 +1,5 @@ import { renderHook, cleanup } from '@testing-library/react'; -import '@testing-library/jest-dom/extend-expect'; +import '@testing-library/jest-dom'; import useAbortController from './useAbortController'; describe('useAbortController', () => { diff --git a/packages/framework/esm-react-utils/src/useOnClickOutside.test.tsx b/packages/framework/esm-react-utils/src/useOnClickOutside.test.tsx index 22dd59217..aea6b81c7 100644 --- a/packages/framework/esm-react-utils/src/useOnClickOutside.test.tsx +++ b/packages/framework/esm-react-utils/src/useOnClickOutside.test.tsx @@ -1,12 +1,14 @@ import React, { PropsWithChildren } from 'react'; -import { render, fireEvent } from '@testing-library/react'; +import { render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import { useOnClickOutside } from './useOnClickOutside'; describe('useOnClickOutside', () => { const handler: (e: Event) => void = jest.fn(); afterEach(() => (handler as jest.Mock).mockClear()); - it('should call the handler when clicking outside', () => { + it('should call the handler when clicking outside', async () => { + const user = userEvent.setup(); // setup const Component: React.FC = ({ children }) => { const ref = useOnClickOutside(handler); @@ -15,14 +17,15 @@ describe('useOnClickOutside', () => { const ref = render(); // act - fireEvent.click(ref.container); + await user.click(ref.container); // verify expect(handler).toHaveBeenCalledTimes(1); }); - it('should not call the handler when clicking on the element', () => { + it('should not call the handler when clicking on the element', async () => { // setup + const user = userEvent.setup(); const Component: React.FC = ({ children }) => { const ref = useOnClickOutside(handler); return
{children}
; @@ -36,7 +39,7 @@ describe('useOnClickOutside', () => { // act if (mutableRef.current) { - fireEvent.click(mutableRef.current); + await user.click(mutableRef.current); } // verify diff --git a/packages/framework/esm-styleguide/src/error-state/error-state.component.tsx b/packages/framework/esm-styleguide/src/error-state/error-state.component.tsx index dbdb59c5f..afe76321f 100644 --- a/packages/framework/esm-styleguide/src/error-state/error-state.component.tsx +++ b/packages/framework/esm-styleguide/src/error-state/error-state.component.tsx @@ -1,5 +1,5 @@ import React from 'react'; -import { Tile } from '@carbon/react'; +import { Layer, Tile } from '@carbon/react'; import { useTranslation } from 'react-i18next'; import { useLayoutType } from '@openmrs/esm-react-utils'; import styles from './error-state.module.scss'; @@ -14,20 +14,22 @@ export const ErrorState: React.FC = ({ error, headerTitle }) => const isTablet = useLayoutType() === 'tablet'; return ( - -
-

{headerTitle}

-
-

- {t('error', 'Error')} {`${error?.response?.status}: `} - {error?.response?.statusText} -

-

- {t( - 'errorCopy', - 'Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.', - )} -

-
+ + +
+

{headerTitle}

+
+

+ {t('error', 'Error')} {`${error?.response?.status}: `} + {error?.response?.statusText} +

+

+ {t( + 'errorCopy', + 'Sorry, there was a problem displaying this information. You can try to reload this page, or contact the site administrator and quote the error code above.', + )} +

+
+
); }; diff --git a/yarn.lock b/yarn.lock index 8ec899391..c1579a56a 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,10 +5,10 @@ __metadata: version: 8 cacheKey: 10 -"@adobe/css-tools@npm:^4.0.1": - version: 4.0.1 - resolution: "@adobe/css-tools@npm:4.0.1" - checksum: 4a50ce9b839a7ee92d003212d92fb8570e521c1114236d84144eb35003ccc843a6a3e6d9f016942147d2ea060983c442701941d20242df104bc6db863d55222b +"@adobe/css-tools@npm:^4.3.1": + version: 4.3.2 + resolution: "@adobe/css-tools@npm:4.3.2" + checksum: 973dcb7ba5141f57ec726ddec2e94e8947361bb0c5f0e8ebd1e8aa3a84b28e66db4ad843908825f99730d59784ff3c43868b014a7268676a65950cdb850c42cc languageName: node linkType: hard @@ -2667,14 +2667,14 @@ __metadata: version: 0.0.0-use.local resolution: "@openmrs/esm-core@workspace:." dependencies: - "@jest/types": "npm:^29.6.3" - "@playwright/test": "npm:1.39.0" + "@playwright/test": "npm:1.40.1" "@swc/core": "npm:^1.3.58" - "@swc/jest": "npm:^0.2.22" - "@testing-library/dom": "npm:^8.16.0" - "@testing-library/jest-dom": "npm:^5.16.4" - "@testing-library/react": "npm:^13.3.0" - "@testing-library/user-event": "npm:^14.2.1" + "@swc/jest": "npm:^0.2.29" + "@testing-library/dom": "npm:^9.3.3" + "@testing-library/jest-dom": "npm:^6.1.5" + "@testing-library/react": "npm:^14.1.2" + "@testing-library/user-event": "npm:^14.5.1" + "@types/jest": "npm:^29.5.11" "@types/react-dom": "npm:^18.0.6" "@types/systemjs": "npm:^6.1.0" "@types/webpack-env": "npm:^1.16.4" @@ -3096,14 +3096,14 @@ __metadata: languageName: unknown linkType: soft -"@playwright/test@npm:1.39.0": - version: 1.39.0 - resolution: "@playwright/test@npm:1.39.0" +"@playwright/test@npm:1.40.1": + version: 1.40.1 + resolution: "@playwright/test@npm:1.40.1" dependencies: - playwright: "npm:1.39.0" + playwright: "npm:1.40.1" bin: playwright: cli.js - checksum: 5d039234609395f3eab46b5954b259bdd80dacf79efe531369c1633647dcafce25a78d497e61e671d661274bf66076426a1bd46be585c44addf23bb5bfaa15a2 + checksum: 77bfc3d4a101fd996309de3a67256117f671952764404727e520a4d512ba2e528d8f9e0b28ef9b2851664a651a5d002a0b05993e313077a2fa640bb430f38b25 languageName: node linkType: hard @@ -4246,71 +4246,84 @@ __metadata: languageName: node linkType: hard -"@swc/jest@npm:^0.2.22": - version: 0.2.23 - resolution: "@swc/jest@npm:0.2.23" +"@swc/jest@npm:^0.2.29": + version: 0.2.29 + resolution: "@swc/jest@npm:0.2.29" dependencies: "@jest/create-cache-key-function": "npm:^27.4.2" jsonc-parser: "npm:^3.2.0" peerDependencies: "@swc/core": "*" - checksum: bfd7d2c1308fa4a654274f5e67ad4eb44010b9fb0ca302f2a17d5eaf41676ec5bd96fc247f09921ff58c43f63676e7c3e8efefda3315e4e0e6f646e7cce5fe86 + checksum: a9cec28769ccbd3f007c56992b431e27490a6baa9f025656f3d1e2e786ebd3afabf4b66e7a79a0b5ed2dc192182a7a2652c7e2d533aa246a8dd1a2cdaac4b630 languageName: node linkType: hard -"@testing-library/dom@npm:^8.16.0, @testing-library/dom@npm:^8.5.0": - version: 8.19.0 - resolution: "@testing-library/dom@npm:8.19.0" +"@testing-library/dom@npm:^9.0.0, @testing-library/dom@npm:^9.3.3": + version: 9.3.3 + resolution: "@testing-library/dom@npm:9.3.3" dependencies: "@babel/code-frame": "npm:^7.10.4" "@babel/runtime": "npm:^7.12.5" - "@types/aria-query": "npm:^4.2.0" - aria-query: "npm:^5.0.0" + "@types/aria-query": "npm:^5.0.1" + aria-query: "npm:5.1.3" chalk: "npm:^4.1.0" dom-accessibility-api: "npm:^0.5.9" - lz-string: "npm:^1.4.4" + lz-string: "npm:^1.5.0" pretty-format: "npm:^27.0.2" - checksum: a5d6baa58c27272364ed8d80df05e944c077a2b0498da0be61ba922cc87ff0df37cbc548d8d327ba0c5a31a087b3679bdc7fbe7847ff857d9504eea376f3c8c0 + checksum: 1ebd1672226600049ce16509d6964bdad8ee71b10f7e68f98126e00638c08ebefb6b7c729a0f2a41cffc77902c3081a95fc2bc1a097cae442ed4a5c481f348b7 languageName: node linkType: hard -"@testing-library/jest-dom@npm:^5.16.4": - version: 5.16.5 - resolution: "@testing-library/jest-dom@npm:5.16.5" +"@testing-library/jest-dom@npm:^6.1.5": + version: 6.1.5 + resolution: "@testing-library/jest-dom@npm:6.1.5" dependencies: - "@adobe/css-tools": "npm:^4.0.1" + "@adobe/css-tools": "npm:^4.3.1" "@babel/runtime": "npm:^7.9.2" - "@types/testing-library__jest-dom": "npm:^5.9.1" aria-query: "npm:^5.0.0" chalk: "npm:^3.0.0" css.escape: "npm:^1.5.1" dom-accessibility-api: "npm:^0.5.6" lodash: "npm:^4.17.15" redent: "npm:^3.0.0" - checksum: 472a14b6295a18af28b5133ecaf4d22a7bb9c50bf05e1f04a076b2e2d7c596e76cdd56a95387ad6d2a4dda0c46bc93d95cbca5b314fabe0fd13362f29118749e + peerDependencies: + "@jest/globals": ">= 28" + "@types/jest": ">= 28" + jest: ">= 28" + vitest: ">= 0.32" + peerDependenciesMeta: + "@jest/globals": + optional: true + "@types/jest": + optional: true + jest: + optional: true + vitest: + optional: true + checksum: 3bc45dc9cb6dc49134e79ef636612b8639014bdd8c85c3741a78a92345147d03f9efeefc2f02ad306764a62f8c236b0e0ef3d5a68c16af1c51887be45d253f6b languageName: node linkType: hard -"@testing-library/react@npm:^13.3.0": - version: 13.4.0 - resolution: "@testing-library/react@npm:13.4.0" +"@testing-library/react@npm:^14.1.2": + version: 14.1.2 + resolution: "@testing-library/react@npm:14.1.2" dependencies: "@babel/runtime": "npm:^7.12.5" - "@testing-library/dom": "npm:^8.5.0" + "@testing-library/dom": "npm:^9.0.0" "@types/react-dom": "npm:^18.0.0" peerDependencies: react: ^18.0.0 react-dom: ^18.0.0 - checksum: 788249aad25a0161b197b7d387011e2578701ab18451b69a987eb073b2d24eb1041f242581c3dd4800f5abcf4f11811f5f6b1e682a45f1840a08fdde3ce559b7 + checksum: 1664990ad9673403ee1d74c1c1b60ec30591d42a3fe1e2175c28cb935cd49bc9a4ba398707f702acc3278c3b0cb492ee57fe66f41ceb040c5da57de98cba5414 languageName: node linkType: hard -"@testing-library/user-event@npm:^14.2.1": - version: 14.4.3 - resolution: "@testing-library/user-event@npm:14.4.3" +"@testing-library/user-event@npm:^14.5.1": + version: 14.5.1 + resolution: "@testing-library/user-event@npm:14.5.1" peerDependencies: "@testing-library/dom": ">=7.21.4" - checksum: 0c7c1ee6bacd8faf15e00624ff6815f0cdf2529493c3a0d8ec6878bbedfc7bd4c7600b7a4b7a07302737e71400dc560ee17dc5706291505da09905c8ea3f3cd7 + checksum: 696e1328c230b0a7063a41d82b5350c6be926696106809a4d79d446d190ff56bebb850fe564ff0952cb74ae81e59a6f10534a88ecbb3792083271a249e04e728 languageName: node linkType: hard @@ -4328,10 +4341,10 @@ __metadata: languageName: node linkType: hard -"@types/aria-query@npm:^4.2.0": - version: 4.2.2 - resolution: "@types/aria-query@npm:4.2.2" - checksum: 3ab0476e1d90a83350f75b7df57edf955c142d4e270fb0d41ab1cf0f1d032ce26dc78d2a12fb4f4c317dba39f0776fb262f5bcff2a9796605f40ba853c407c11 +"@types/aria-query@npm:^5.0.1": + version: 5.0.4 + resolution: "@types/aria-query@npm:5.0.4" + checksum: c0084c389dc030daeaf0115a92ce43a3f4d42fc8fef2d0e22112d87a42798d4a15aac413019d4a63f868327d52ad6740ab99609462b442fe6b9286b172d2e82e languageName: node linkType: hard @@ -4558,13 +4571,13 @@ __metadata: languageName: node linkType: hard -"@types/jest@npm:*": - version: 29.1.2 - resolution: "@types/jest@npm:29.1.2" +"@types/jest@npm:^29.5.11": + version: 29.5.11 + resolution: "@types/jest@npm:29.5.11" dependencies: expect: "npm:^29.0.0" pretty-format: "npm:^29.0.0" - checksum: 8908cdd41f31a4ea17aa34663c2c696b77df61de6103d0701c76b020780b5adfc5e14a0388420a44f28335fe31285ec626c84853a8a85d0ec51c665a79d4a55a + checksum: 798f4c89407d9457bea1256de74c26f2b279f6c789c0e3311cd604cc75cdab333b9a29b00c51b0090d31abdf11cc788b4103282851a653bef6daf72edf97eef2 languageName: node linkType: hard @@ -4866,15 +4879,6 @@ __metadata: languageName: node linkType: hard -"@types/testing-library__jest-dom@npm:^5.9.1": - version: 5.14.5 - resolution: "@types/testing-library__jest-dom@npm:5.14.5" - dependencies: - "@types/jest": "npm:*" - checksum: 8c4d3dfd8011d9cf57ca6a15962fc02fcf0f506088a126dfacb7b8197f5ef593fce8f57aa878904b1e100e31fff571fca6f022a789482684dac2661b83c6721d - languageName: node - linkType: hard - "@types/through@npm:*": version: 0.0.30 resolution: "@types/through@npm:0.0.30" @@ -5524,6 +5528,15 @@ __metadata: languageName: node linkType: hard +"aria-query@npm:5.1.3": + version: 5.1.3 + resolution: "aria-query@npm:5.1.3" + dependencies: + deep-equal: "npm:^2.0.5" + checksum: e5da608a7c4954bfece2d879342b6c218b6b207e2d9e5af270b5e38ef8418f02d122afdc948b68e32649b849a38377785252059090d66fa8081da95d1609c0d2 + languageName: node + linkType: hard + "aria-query@npm:^4.2.2": version: 4.2.2 resolution: "aria-query@npm:4.2.2" @@ -5541,6 +5554,16 @@ __metadata: languageName: node linkType: hard +"array-buffer-byte-length@npm:^1.0.0": + version: 1.0.0 + resolution: "array-buffer-byte-length@npm:1.0.0" + dependencies: + call-bind: "npm:^1.0.2" + is-array-buffer: "npm:^3.0.1" + checksum: 044e101ce150f4804ad19c51d6c4d4cfa505c5b2577bd179256e4aa3f3f6a0a5e9874c78cd428ee566ac574c8a04d7ce21af9fe52e844abfdccb82b33035a7c3 + languageName: node + linkType: hard + "array-flatten@npm:1.1.1": version: 1.1.1 resolution: "array-flatten@npm:1.1.1" @@ -5674,6 +5697,13 @@ __metadata: languageName: node linkType: hard +"available-typed-arrays@npm:^1.0.5": + version: 1.0.5 + resolution: "available-typed-arrays@npm:1.0.5" + checksum: 4d4d5e86ea0425696f40717882f66a570647b94ac8d273ddc7549a9b61e5da099e149bf431530ccbd776bd74e02039eb8b5edf426e3e2211ee61af16698a9064 + languageName: node + linkType: hard + "axe-core@npm:^4.4.3": version: 4.4.3 resolution: "axe-core@npm:4.4.3" @@ -6156,6 +6186,17 @@ __metadata: languageName: node linkType: hard +"call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": + version: 1.0.5 + resolution: "call-bind@npm:1.0.5" + dependencies: + function-bind: "npm:^1.1.2" + get-intrinsic: "npm:^1.2.1" + set-function-length: "npm:^1.1.1" + checksum: 246d44db6ef9bbd418828dbd5337f80b46be4398d522eded015f31554cbb2ea33025b0203b75c7ab05a1a255b56ef218880cca1743e4121e306729f9e414da39 + languageName: node + linkType: hard + "caller-callsite@npm:^2.0.0": version: 2.0.0 resolution: "caller-callsite@npm:2.0.0" @@ -7775,6 +7816,32 @@ __metadata: languageName: node linkType: hard +"deep-equal@npm:^2.0.5": + version: 2.2.3 + resolution: "deep-equal@npm:2.2.3" + dependencies: + array-buffer-byte-length: "npm:^1.0.0" + call-bind: "npm:^1.0.5" + es-get-iterator: "npm:^1.1.3" + get-intrinsic: "npm:^1.2.2" + is-arguments: "npm:^1.1.1" + is-array-buffer: "npm:^3.0.2" + is-date-object: "npm:^1.0.5" + is-regex: "npm:^1.1.4" + is-shared-array-buffer: "npm:^1.0.2" + isarray: "npm:^2.0.5" + object-is: "npm:^1.1.5" + object-keys: "npm:^1.1.1" + object.assign: "npm:^4.1.4" + regexp.prototype.flags: "npm:^1.5.1" + side-channel: "npm:^1.0.4" + which-boxed-primitive: "npm:^1.0.2" + which-collection: "npm:^1.0.1" + which-typed-array: "npm:^1.1.13" + checksum: 1ce49d0b71d0f14d8ef991a742665eccd488dfc9b3cada069d4d7a86291e591c92d2589c832811dea182b4015736b210acaaebce6184be356c1060d176f5a05f + languageName: node + linkType: hard + "deep-is@npm:^0.1.3, deep-is@npm:~0.1.3": version: 0.1.4 resolution: "deep-is@npm:0.1.4" @@ -7798,6 +7865,17 @@ __metadata: languageName: node linkType: hard +"define-data-property@npm:^1.0.1, define-data-property@npm:^1.1.1": + version: 1.1.1 + resolution: "define-data-property@npm:1.1.1" + dependencies: + get-intrinsic: "npm:^1.2.1" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + checksum: 5573c8df96b5857408cad64d9b91b69152e305ce4b06218e5f49b59c6cafdbb90a8bd8a0bb83c7bc67a8d479c04aa697063c9bc28d849b7282f9327586d6bc7b + languageName: node + linkType: hard + "define-lazy-prop@npm:^2.0.0": version: 2.0.0 resolution: "define-lazy-prop@npm:2.0.0" @@ -7815,6 +7893,17 @@ __metadata: languageName: node linkType: hard +"define-properties@npm:^1.2.0": + version: 1.2.1 + resolution: "define-properties@npm:1.2.1" + dependencies: + define-data-property: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + object-keys: "npm:^1.1.1" + checksum: b4ccd00597dd46cb2d4a379398f5b19fca84a16f3374e2249201992f36b30f6835949a9429669ee6b41b6e837205a163eadd745e472069e70dfc10f03e5fcc12 + languageName: node + linkType: hard + "del@npm:^4.1.1": version: 4.1.1 resolution: "del@npm:4.1.1" @@ -8353,6 +8442,23 @@ __metadata: languageName: node linkType: hard +"es-get-iterator@npm:^1.1.3": + version: 1.1.3 + resolution: "es-get-iterator@npm:1.1.3" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.1.3" + has-symbols: "npm:^1.0.3" + is-arguments: "npm:^1.1.1" + is-map: "npm:^2.0.2" + is-set: "npm:^2.0.2" + is-string: "npm:^1.0.7" + isarray: "npm:^2.0.5" + stop-iteration-iterator: "npm:^1.0.0" + checksum: bc2194befbe55725f9489098626479deee3c801eda7e83ce0dff2eb266a28dc808edb9b623ff01d31ebc1328f09d661333d86b601036692c2e3c1a6942319433 + languageName: node + linkType: hard + "es-module-lexer@npm:^1.2.1": version: 1.3.0 resolution: "es-module-lexer@npm:1.3.0" @@ -9046,6 +9152,15 @@ __metadata: languageName: node linkType: hard +"for-each@npm:^0.3.3": + version: 0.3.3 + resolution: "for-each@npm:0.3.3" + dependencies: + is-callable: "npm:^1.1.3" + checksum: fdac0cde1be35610bd635ae958422e8ce0cc1313e8d32ea6d34cfda7b60850940c1fd07c36456ad76bd9c24aef6ff5e03b02beb58c83af5ef6c968a64eada676 + languageName: node + linkType: hard + "fork-ts-checker-webpack-plugin@npm:^6.5.0": version: 6.5.2 resolution: "fork-ts-checker-webpack-plugin@npm:6.5.2" @@ -9264,6 +9379,13 @@ __metadata: languageName: node linkType: hard +"function-bind@npm:^1.1.2": + version: 1.1.2 + resolution: "function-bind@npm:1.1.2" + checksum: 185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 + languageName: node + linkType: hard + "function.prototype.name@npm:^1.1.5": version: 1.1.5 resolution: "function.prototype.name@npm:1.1.5" @@ -9283,7 +9405,7 @@ __metadata: languageName: node linkType: hard -"functions-have-names@npm:^1.2.2": +"functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" checksum: 0ddfd3ed1066a55984aaecebf5419fbd9344a5c38dd120ffb0739fac4496758dcf371297440528b115e4367fc46e3abc86a2cc0ff44612181b175ae967a11a05 @@ -9345,6 +9467,18 @@ __metadata: languageName: node linkType: hard +"get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": + version: 1.2.2 + resolution: "get-intrinsic@npm:1.2.2" + dependencies: + function-bind: "npm:^1.1.2" + has-proto: "npm:^1.0.1" + has-symbols: "npm:^1.0.3" + hasown: "npm:^2.0.0" + checksum: aa96db4f809734d26d49b59bc8669d73a0ae792da561514e987735573a1dfaede516cd102f217a078ea2b42d4c4fb1f83d487932cb15d49826b726cc9cd4470b + languageName: node + linkType: hard + "get-own-enumerable-property-symbols@npm:^3.0.0": version: 3.0.2 resolution: "get-own-enumerable-property-symbols@npm:3.0.2" @@ -9546,6 +9680,15 @@ __metadata: languageName: node linkType: hard +"gopd@npm:^1.0.1": + version: 1.0.1 + resolution: "gopd@npm:1.0.1" + dependencies: + get-intrinsic: "npm:^1.1.3" + checksum: 5fbc7ad57b368ae4cd2f41214bd947b045c1a4be2f194a7be1778d71f8af9dbf4004221f3b6f23e30820eb0d052b4f819fe6ebe8221e2a3c6f0ee4ef173421ca + languageName: node + linkType: hard + "graceful-fs@npm:4.2.10, graceful-fs@npm:^4.0.0, graceful-fs@npm:^4.1.11, graceful-fs@npm:^4.1.2, graceful-fs@npm:^4.1.6, graceful-fs@npm:^4.2.0, graceful-fs@npm:^4.2.4, graceful-fs@npm:^4.2.6, graceful-fs@npm:^4.2.9": version: 4.2.10 resolution: "graceful-fs@npm:4.2.10" @@ -9633,6 +9776,13 @@ __metadata: languageName: node linkType: hard +"has-proto@npm:^1.0.1": + version: 1.0.1 + resolution: "has-proto@npm:1.0.1" + checksum: eab2ab0ed1eae6d058b9bbc4c1d99d2751b29717be80d02fd03ead8b62675488de0c7359bc1fdd4b87ef6fd11e796a9631ad4d7452d9324fdada70158c2e5be7 + languageName: node + linkType: hard + "has-symbols@npm:^1.0.1, has-symbols@npm:^1.0.2, has-symbols@npm:^1.0.3": version: 1.0.3 resolution: "has-symbols@npm:1.0.3" @@ -9665,6 +9815,15 @@ __metadata: languageName: node linkType: hard +"hasown@npm:^2.0.0": + version: 2.0.0 + resolution: "hasown@npm:2.0.0" + dependencies: + function-bind: "npm:^1.1.2" + checksum: c330f8d93f9d23fe632c719d4db3d698ef7d7c367d51548b836069e06a90fa9151e868c8e67353cfe98d67865bf7354855db28fa36eb1b18fa5d4a3f4e7f1c90 + languageName: node + linkType: hard + "he@npm:^1.2.0": version: 1.2.0 resolution: "he@npm:1.2.0" @@ -10234,6 +10393,17 @@ __metadata: languageName: node linkType: hard +"internal-slot@npm:^1.0.4": + version: 1.0.6 + resolution: "internal-slot@npm:1.0.6" + dependencies: + get-intrinsic: "npm:^1.2.2" + hasown: "npm:^2.0.0" + side-channel: "npm:^1.0.4" + checksum: bc2022eb1f277f2fcb2a60e7ced451c7ffc7a769b12e63c7a3fb247af8b5a1bed06428ce724046a8bca39ed6eb5b6832501a42f2e9a5ec4a9a7dc4e634431616 + languageName: node + linkType: hard + "internmap@npm:1 - 2": version: 2.0.3 resolution: "internmap@npm:2.0.3" @@ -10314,6 +10484,27 @@ __metadata: languageName: node linkType: hard +"is-arguments@npm:^1.1.1": + version: 1.1.1 + resolution: "is-arguments@npm:1.1.1" + dependencies: + call-bind: "npm:^1.0.2" + has-tostringtag: "npm:^1.0.0" + checksum: a170c7e26082e10de9be6e96d32ae3db4d5906194051b792e85fae3393b53cf2cb5b3557863e5c8ccbab55e2fd8f2f75aa643d437613f72052cf0356615c34be + languageName: node + linkType: hard + +"is-array-buffer@npm:^3.0.1, is-array-buffer@npm:^3.0.2": + version: 3.0.2 + resolution: "is-array-buffer@npm:3.0.2" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.2.0" + is-typed-array: "npm:^1.1.10" + checksum: dcac9dda66ff17df9cabdc58214172bf41082f956eab30bb0d86bc0fab1e44b690fc8e1f855cf2481245caf4e8a5a006a982a71ddccec84032ed41f9d8da8c14 + languageName: node + linkType: hard + "is-arrayish@npm:^0.2.1": version: 0.2.1 resolution: "is-arrayish@npm:0.2.1" @@ -10363,7 +10554,7 @@ __metadata: languageName: node linkType: hard -"is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": +"is-callable@npm:^1.1.3, is-callable@npm:^1.1.4, is-callable@npm:^1.2.7": version: 1.2.7 resolution: "is-callable@npm:1.2.7" checksum: 48a9297fb92c99e9df48706241a189da362bff3003354aea4048bd5f7b2eb0d823cd16d0a383cece3d76166ba16d85d9659165ac6fcce1ac12e6c649d66dbdb9 @@ -10393,7 +10584,7 @@ __metadata: languageName: node linkType: hard -"is-date-object@npm:^1.0.1": +"is-date-object@npm:^1.0.1, is-date-object@npm:^1.0.5": version: 1.0.5 resolution: "is-date-object@npm:1.0.5" dependencies: @@ -10487,6 +10678,13 @@ __metadata: languageName: node linkType: hard +"is-map@npm:^2.0.1, is-map@npm:^2.0.2": + version: 2.0.2 + resolution: "is-map@npm:2.0.2" + checksum: 60ba910f835f2eacb1fdf5b5a6c60fe1c702d012a7673e6546992bcc0c873f62ada6e13d327f9e48f1720d49c152d6cdecae1fa47a261ef3d247c3ce6f0e1d39 + languageName: node + linkType: hard + "is-module@npm:^1.0.0": version: 1.0.0 resolution: "is-module@npm:1.0.0" @@ -10626,6 +10824,13 @@ __metadata: languageName: node linkType: hard +"is-set@npm:^2.0.1, is-set@npm:^2.0.2": + version: 2.0.2 + resolution: "is-set@npm:2.0.2" + checksum: d89e82acdc7760993474f529e043f9c4a1d63ed4774d21cc2e331d0e401e5c91c27743cd7c889137028f6a742234759a4bd602368fbdbf0b0321994aefd5603f + languageName: node + linkType: hard + "is-shared-array-buffer@npm:^1.0.2": version: 1.0.2 resolution: "is-shared-array-buffer@npm:1.0.2" @@ -10667,6 +10872,15 @@ __metadata: languageName: node linkType: hard +"is-typed-array@npm:^1.1.10": + version: 1.1.12 + resolution: "is-typed-array@npm:1.1.12" + dependencies: + which-typed-array: "npm:^1.1.11" + checksum: d953adfd3c41618d5e01b2a10f21817e4cdc9572772fa17211100aebb3811b6e3c2e308a0558cc87d218a30504cb90154b833013437776551bfb70606fb088ca + languageName: node + linkType: hard + "is-unc-path@npm:^1.0.0": version: 1.0.0 resolution: "is-unc-path@npm:1.0.0" @@ -10690,6 +10904,13 @@ __metadata: languageName: node linkType: hard +"is-weakmap@npm:^2.0.1": + version: 2.0.1 + resolution: "is-weakmap@npm:2.0.1" + checksum: 289fa4e8ba1bdda40ca78481266f6925b7c46a85599e6a41a77010bf91e5a24dfb660db96863bbf655ecdbda0ab517204d6a4e0c151dbec9d022c556321f3776 + languageName: node + linkType: hard + "is-weakref@npm:^1.0.2": version: 1.0.2 resolution: "is-weakref@npm:1.0.2" @@ -10699,6 +10920,16 @@ __metadata: languageName: node linkType: hard +"is-weakset@npm:^2.0.1": + version: 2.0.2 + resolution: "is-weakset@npm:2.0.2" + dependencies: + call-bind: "npm:^1.0.2" + get-intrinsic: "npm:^1.1.1" + checksum: 8f2ddb9639716fd7936784e175ea1183c5c4c05274c34f34f6a53175313cb1c9c35a8b795623306995e2f7cc8f25aa46302f15a2113e51c5052d447be427195c + languageName: node + linkType: hard + "is-windows@npm:^1.0.1": version: 1.0.2 resolution: "is-windows@npm:1.0.2" @@ -10715,6 +10946,13 @@ __metadata: languageName: node linkType: hard +"isarray@npm:^2.0.5": + version: 2.0.5 + resolution: "isarray@npm:2.0.5" + checksum: 1d8bc7911e13bb9f105b1b3e0b396c787a9e63046af0b8fe0ab1414488ab06b2b099b87a2d8a9e31d21c9a6fad773c7fc8b257c4880f2d957274479d28ca3414 + languageName: node + linkType: hard + "isarray@npm:~1.0.0": version: 1.0.0 resolution: "isarray@npm:1.0.0" @@ -11855,12 +12093,12 @@ __metadata: languageName: node linkType: hard -"lz-string@npm:^1.4.4": - version: 1.4.4 - resolution: "lz-string@npm:1.4.4" +"lz-string@npm:^1.5.0": + version: 1.5.0 + resolution: "lz-string@npm:1.5.0" bin: lz-string: bin/bin.js - checksum: da3abc3c15b3f91ab0fba0fe8ea3bb53d3c758d5c50d88d97b759e52d9b5224f8b05edc0e6423bfd448e6bcbe30f79236b7f2e6e7f8a321be62ae77b88092581 + checksum: e86f0280e99a8d8cd4eef24d8601ddae15ce54e43ac9990dfcb79e1e081c255ad24424a30d78d2ad8e51a8ce82a66a930047fed4b4aa38c6f0b392ff9300edfc languageName: node linkType: hard @@ -12694,6 +12932,16 @@ __metadata: languageName: node linkType: hard +"object-is@npm:^1.1.5": + version: 1.1.5 + resolution: "object-is@npm:1.1.5" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.1.3" + checksum: 75365aff5da4bebad5d20efd9f9a7a13597e603f5eb03d89da8f578c3f3937fe01c6cb5fce86c0611c48795c0841401fd37c943821db0de703c7b30a290576ad + languageName: node + linkType: hard + "object-keys@npm:^1.1.1": version: 1.1.1 resolution: "object-keys@npm:1.1.1" @@ -13277,27 +13525,27 @@ __metadata: languageName: node linkType: hard -"playwright-core@npm:1.39.0": - version: 1.39.0 - resolution: "playwright-core@npm:1.39.0" +"playwright-core@npm:1.40.1": + version: 1.40.1 + resolution: "playwright-core@npm:1.40.1" bin: playwright-core: cli.js - checksum: e4e01ddea024c7564bbfacdba5f545b004a4017b466af08ae90e5184da4f5bc61e74c96e37cc5e30b7d4f97341c0883cfb2038c8cfbfab65316d714f65b82d83 + checksum: b8945a5eec68a2772be537219c81f74b8fbd1545650c908c41fdcb2b9eb40f488968d1fb59c61ca58afb923af1e390dd621bba3099521fcd3d9a63ef3645a203 languageName: node linkType: hard -"playwright@npm:1.39.0": - version: 1.39.0 - resolution: "playwright@npm:1.39.0" +"playwright@npm:1.40.1": + version: 1.40.1 + resolution: "playwright@npm:1.40.1" dependencies: fsevents: "npm:2.3.2" - playwright-core: "npm:1.39.0" + playwright-core: "npm:1.40.1" dependenciesMeta: fsevents: optional: true bin: playwright: cli.js - checksum: 6f6b2f4381fccfbc560c4cd25e164f5093fec4e2046990587282e18618151d723b299b56c16741ce08e44a759c22e38c3e705b716d31238320e08e6ffcfa7319 + checksum: 95cf79f1574accbff18fac4b876aa3811640314ee74cf4cd1c249398cd49824e55dc664039342a18d2d2fa4f5ad460ce91a97cb15942ab5d71c8ab04f442dc32 languageName: node linkType: hard @@ -14589,6 +14837,17 @@ __metadata: languageName: node linkType: hard +"regexp.prototype.flags@npm:^1.5.1": + version: 1.5.1 + resolution: "regexp.prototype.flags@npm:1.5.1" + dependencies: + call-bind: "npm:^1.0.2" + define-properties: "npm:^1.2.0" + set-function-name: "npm:^2.0.0" + checksum: 3fa5610b8e411bbc3a43ddfd13162f3a817beb43155fbd8caa24d4fd0ce2f431a8197541808772a5a06e5946cebfb68464c827827115bde0d11720a92fe2981a + languageName: node + linkType: hard + "regexpp@npm:^3.1.0": version: 3.2.0 resolution: "regexpp@npm:3.2.0" @@ -15211,6 +15470,29 @@ __metadata: languageName: node linkType: hard +"set-function-length@npm:^1.1.1": + version: 1.1.1 + resolution: "set-function-length@npm:1.1.1" + dependencies: + define-data-property: "npm:^1.1.1" + get-intrinsic: "npm:^1.2.1" + gopd: "npm:^1.0.1" + has-property-descriptors: "npm:^1.0.0" + checksum: 745ed1d7dc69a6185e0820082fe73838ab3dfd01e75cce83a41e4c1d68bbf34bc5fb38f32ded542ae0b557536b5d2781594499b5dcd19e7db138e06292a76c7b + languageName: node + linkType: hard + +"set-function-name@npm:^2.0.0": + version: 2.0.1 + resolution: "set-function-name@npm:2.0.1" + dependencies: + define-data-property: "npm:^1.0.1" + functions-have-names: "npm:^1.2.3" + has-property-descriptors: "npm:^1.0.0" + checksum: 4975d17d90c40168eee2c7c9c59d023429f0a1690a89d75656306481ece0c3c1fb1ebcc0150ea546d1913e35fbd037bace91372c69e543e51fc5d1f31a9fa126 + languageName: node + linkType: hard + "setprototypeof@npm:1.1.0": version: 1.1.0 resolution: "setprototypeof@npm:1.1.0" @@ -15620,6 +15902,15 @@ __metadata: languageName: node linkType: hard +"stop-iteration-iterator@npm:^1.0.0": + version: 1.0.0 + resolution: "stop-iteration-iterator@npm:1.0.0" + dependencies: + internal-slot: "npm:^1.0.4" + checksum: 2a23a36f4f6bfa63f46ae2d53a3f80fe8276110b95a55345d8ed3d92125413494033bc8697eb774e8f7aeb5725f70e3d69753caa2ecacdac6258c16fa8aa8b0f + languageName: node + linkType: hard + "stream-shift@npm:^1.0.0": version: 1.0.1 resolution: "stream-shift@npm:1.0.1" @@ -17399,6 +17690,31 @@ __metadata: languageName: node linkType: hard +"which-collection@npm:^1.0.1": + version: 1.0.1 + resolution: "which-collection@npm:1.0.1" + dependencies: + is-map: "npm:^2.0.1" + is-set: "npm:^2.0.1" + is-weakmap: "npm:^2.0.1" + is-weakset: "npm:^2.0.1" + checksum: 85c95fcf92df7972ce66bed879e53d9dc752a30ef08e1ca4696df56bcf1c302e3b9965a39b04a20fa280a997fad6c170eb0b4d62435569b7f6c0bc7be910572b + languageName: node + linkType: hard + +"which-typed-array@npm:^1.1.11, which-typed-array@npm:^1.1.13": + version: 1.1.13 + resolution: "which-typed-array@npm:1.1.13" + dependencies: + available-typed-arrays: "npm:^1.0.5" + call-bind: "npm:^1.0.4" + for-each: "npm:^0.3.3" + gopd: "npm:^1.0.1" + has-tostringtag: "npm:^1.0.0" + checksum: 605e3e10b7118af904a0e79d0d50b95275102f06ec902734024989cd71354929f7acee50de43529d3baf5858e2e4eb32c75e6ebd226c888ad976d8140e4a3e71 + languageName: node + linkType: hard + "which@npm:^2.0.1, which@npm:^2.0.2": version: 2.0.2 resolution: "which@npm:2.0.2" From 9b84bb26d842f2b2869d9a510d3e3081f594cbe3 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Wed, 20 Dec 2023 22:22:57 +0300 Subject: [PATCH 03/37] (chore) Extend ESLint configuration (#837) --- .eslintrc | 42 +- package.json | 10 +- .../import-map-list/modal.component.tsx | 3 +- .../backend-dependencies.component.tsx | 2 +- .../useBackendDependencies.ts | 3 +- .../configuration/configuration.component.tsx | 5 +- .../editable-value.component.tsx | 9 +- .../extension-configure-tree.tsx | 2 +- .../extension-slots-config-tree.tsx | 3 +- .../layout/tree-container.component.tsx | 3 +- .../interactive-editor/value-editor.tsx | 4 +- .../value-editors/array-editor.tsx | 2 +- .../value-editors/concept-search.tsx | 3 +- .../value-editors/extension-slot-add.tsx | 3 +- .../value-editors/object-editor.tsx | 2 +- .../patient-identifier-type-search.tsx | 3 +- .../patient-identifier-type.resource.tsx | 3 +- .../value-editors/value-editor-field.tsx | 4 +- .../src/ui-editor/ui-editor.tsx | 3 +- .../apps/esm-login-app/src/declarations.d.ts | 2 - .../location-picker.component.tsx | 2 +- .../apps/esm-login-app/src/login.resource.ts | 13 +- .../src/login/login.component.tsx | 2 +- .../redirect-logout.component.tsx | 3 +- .../confirmation-modal.component.tsx | 3 +- .../headered-quick-info.component.tsx | 3 +- .../components/overview-card.component.tsx | 3 +- .../shared-page-layout.component.tsx | 3 +- .../esm-offline-tools-app/src/constants.ts | 3 +- .../src/hooks/offline-actions.ts | 2 +- .../src/hooks/offline-patient-data-hooks.ts | 3 +- .../offline-actions-table.component.tsx | 2 +- .../offline-actions.component.tsx | 2 +- .../synchronizing-notification.tsx | 8 +- .../last-updated-table-cell.component.tsx | 3 +- .../offline-patient-table.component.tsx | 2 +- .../offline-tools-page.component.tsx | 2 +- .../choose-locale/change-locale.component.tsx | 6 +- .../notifications-menu-panel.component.tsx | 3 +- .../user-menu-panel.component.tsx | 6 +- .../components/navbar/navbar.component.tsx | 2 +- .../user-panel-switcher.component.tsx | 2 +- .../esm-primary-navigation-app/src/offline.ts | 3 +- .../esm-primary-navigation-app/src/utils.ts | 2 +- .../framework/esm-api/src/openmrs-fetch.ts | 2 +- .../src/shared-api-objects/current-patient.ts | 5 +- .../src/shared-api-objects/location.ts | 4 +- .../src/shared-api-objects/visit-type.ts | 4 +- .../src/shared-api-objects/visit-utils.ts | 5 +- packages/framework/esm-api/src/types/fetch.ts | 2 +- .../esm-api/src/types/visit-resource.ts | 2 +- packages/framework/esm-breadcrumbs/src/db.ts | 2 +- .../framework/esm-breadcrumbs/src/filter.ts | 2 +- .../src/module-config/module-config.test.ts | 7 +- .../src/module-config/module-config.ts | 9 +- .../esm-config/src/module-config/state.ts | 2 +- .../esm-config/src/validators/validator.ts | 2 +- .../esm-extensions/src/extensions.ts | 25 +- .../framework/esm-extensions/src/store.ts | 8 +- packages/framework/esm-framework/docs/API.md | 122 +-- .../esm-framework/docs/enums/VisitMode.md | 6 +- .../esm-framework/docs/enums/VisitStatus.md | 4 +- .../docs/interfaces/AssignedExtension.md | 16 +- .../docs/interfaces/ConfigurableLinkProps.md | 4 +- .../docs/interfaces/ConnectedExtension.md | 10 +- .../docs/interfaces/CurrentPatientOptions.md | 2 +- .../docs/interfaces/ExtensionRegistration.md | 18 +- .../docs/interfaces/ExtensionSlotState.md | 4 +- .../docs/interfaces/ExtensionStore.md | 2 +- .../docs/interfaces/ImportMap.md | 2 +- .../docs/interfaces/OnlyThePatient.md | 2 +- .../docs/interfaces/OpenmrsAppRoutes.md | 8 +- .../interfaces/PatientWithFullResponse.md | 2 +- .../docs/interfaces/ResourceLoader.md | 2 +- .../docs/interfaces/SpaConfig.md | 10 +- .../docs/interfaces/UserHasAccessProps.md | 6 +- .../docs/interfaces/VisitItem.md | 8 +- .../docs/interfaces/VisitReturnType.md | 14 +- .../docs/interfaces/VisitStoreState.md | 4 +- packages/framework/esm-globals/src/types.ts | 1 + .../framework/esm-offline/src/offline-db.ts | 3 +- .../src/service-worker-messaging.ts | 2 +- .../framework/esm-offline/src/sync.test.ts | 2 +- .../esm-react-utils/src/ConfigurableLink.tsx | 3 +- .../esm-react-utils/src/Extension.tsx | 2 - .../esm-react-utils/src/UserHasAccess.tsx | 3 +- .../esm-react-utils/src/getLifecycle.ts | 6 +- .../src/openmrsComponentDecorator.tsx | 3 +- .../esm-react-utils/src/setup-tests.js | 6 +- .../src/useAssignedExtensions.ts | 3 +- .../esm-react-utils/src/useConfig.ts | 13 +- .../src/useConnectedExtensions.ts | 3 +- .../src/useExtensionInternalStore.ts | 3 +- .../src/useExtensionSlotMeta.ts | 2 +- .../esm-react-utils/src/useExtensionStore.ts | 3 +- .../esm-react-utils/src/useLocations.tsx | 3 +- .../esm-react-utils/src/useOpenmrsSWR.ts | 3 +- .../esm-react-utils/src/usePatient.ts | 3 +- .../esm-react-utils/src/useSession.ts | 3 +- .../framework/esm-react-utils/src/useStore.ts | 9 +- .../framework/esm-react-utils/src/useVisit.ts | 3 +- .../esm-react-utils/src/useVisitTypes.ts | 3 +- packages/framework/esm-routes/src/routes.ts | 4 +- packages/framework/esm-state/src/state.ts | 3 +- ...-react-spectrum-date-wrapper.component.tsx | 3 +- .../esm-styleguide/src/icons/svgs.test.js | 61 -- .../esm-styleguide/src/left-nav/index.tsx | 3 +- .../esm-styleguide/src/modals/index.tsx | 3 +- ...ive-actionable-notifications.component.tsx | 5 +- .../active-notifications.component.tsx | 5 +- .../src/notifications/index.tsx | 4 +- .../snackbars/active-snackbar.component.tsx | 5 +- .../esm-styleguide/src/snackbars/index.tsx | 2 +- .../src/toasts/active-toasts.component.tsx | 5 +- .../esm-styleguide/src/toasts/index.tsx | 2 +- .../esm-utils/src/omrs-dates.test.ts | 6 +- .../framework/esm-utils/src/omrs-dates.ts | 2 +- packages/shell/esm-app-shell/src/apps.ts | 7 +- packages/shell/esm-app-shell/src/helpers.ts | 2 +- packages/shell/esm-app-shell/src/run.ts | 2 +- .../src/service-worker/import-map-utils.ts | 2 +- .../src/service-worker/message.ts | 3 +- .../src/service-worker/routing.ts | 2 +- .../src/service-worker/storage.ts | 3 +- .../esm-app-shell/src/ui/breadcrumbs.tsx | 3 +- .../tooling/openmrs/src/commands/assemble.ts | 6 +- .../tooling/openmrs/src/commands/debug.ts | 3 +- .../tooling/openmrs/src/commands/develop.ts | 3 +- .../tooling/openmrs/src/utils/importmap.ts | 12 +- .../tooling/openmrs/src/utils/npmConfig.ts | 2 +- packages/tooling/openmrs/src/utils/untar.ts | 2 +- yarn.lock | 955 ++++++++++-------- 132 files changed, 891 insertions(+), 835 deletions(-) delete mode 100644 packages/framework/esm-styleguide/src/icons/svgs.test.js diff --git a/.eslintrc b/.eslintrc index b7d095bea..d09f649a1 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,28 +1,54 @@ { - "extends": ["ts-react-important-stuff"], + "env": { + "node": true + }, + "extends": ["eslint:recommended", "plugin:prettier/recommended", "plugin:@typescript-eslint/recommended"], "parser": "@typescript-eslint/parser", + "plugins": ["@typescript-eslint"], "ignorePatterns": ["**/*.test.tsx"], "rules": { + // Disabling these rules for now just to keep the diff small. I'll enable them in a future PR that fixes lint issues. + "@typescript-eslint/ban-ts-comment": "off", + "@typescript-eslint/ban-types": "off", + "@typescript-eslint/no-explicit-any": "off", + "@typescript-eslint/no-unused-vars": "off", + "@typescript-eslint/no-var-requires": "off", + "@typescript-eslint/triple-slash-reference": "off", + // Use `import type` instead of `import` for type imports https://typescript-eslint.io/blog/consistent-type-imports-and-exports-why-and-how + "@typescript-eslint/consistent-type-imports": [ + "error", + { + "fixStyle": "inline-type-imports" + } + ], + "prefer-const": "off", + "no-console": ["error", { "allow": ["warn", "error"] }], + "no-unsafe-optional-chaining": "off", + "no-explicit-any": "off", + "no-extra-boolean-cast": "off", + "no-prototype-builtins": "off", + "no-useless-escape": "off", "no-restricted-imports": [ "error", { "paths": [ + // These two rules ensure that we're importing lodash and lodash-es correctly. Not doing so can bloat our bundle size significantly. { "name": "lodash", - "message": "Import specific methods from `lodash-es`. e.g. `import map from 'lodash-es/map'`" + "message": "Import specific methods from `lodash`. e.g. `import map from 'lodash/map'`" }, { "name": "lodash-es", - "message": "Import specific methods from `lodash-es`. e.g. `import map from 'lodash-es/map'`" - } - ], - "patterns": [ + "importNames": ["default"], + "message": "Import specific methods from `lodash-es`. e.g. `import { map } from 'lodash-es'`" + }, + // These two rules ensure that we're importing Carbon components and icons from the correct packages (after v10). May be removed in the future. { - "group": ["carbon-components-react"], + "name": "carbon-components-react", "message": "Import from `@carbon/react` directly. e.g. `import { Toggle } from '@carbon/react'`" }, { - "group": ["@carbon/icons-react"], + "name": "@carbon/icons-react", "message": "Import from `@carbon/react/icons`. e.g. `import { ChevronUp } from '@carbon/react/icons'`" } ] diff --git a/package.json b/package.json index 2502bf385..bd67059d6 100644 --- a/package.json +++ b/package.json @@ -38,15 +38,15 @@ "@types/react-dom": "^18.0.6", "@types/systemjs": "^6.1.0", "@types/webpack-env": "^1.16.4", - "@typescript-eslint/parser": "^5.18.0", + "@typescript-eslint/eslint-plugin": "^6.13.2", + "@typescript-eslint/parser": "^6.13.2", "autoprefixer": "^10.4.2", "classnames": "^2.3.2", "cross-env": "7.0.2", "dotenv": "^16.0.3", - "eslint": "^7.10.0", - "eslint-config-prettier": "^6.11.0", - "eslint-config-ts-react-important-stuff": "^3.0.0", - "eslint-plugin-prettier": "^3.1.4", + "eslint": "^8.55.0", + "eslint-config-prettier": "^9.1.0", + "eslint-plugin-prettier": "^5.0.1", "fake-indexeddb": "^4.0.1", "fork-ts-checker-webpack-plugin": "^7.2.13", "husky": "^8.0.1", diff --git a/packages/apps/esm-devtools-app/src/devtools/import-map-list/modal.component.tsx b/packages/apps/esm-devtools-app/src/devtools/import-map-list/modal.component.tsx index f84e63da7..06f5594d6 100644 --- a/packages/apps/esm-devtools-app/src/devtools/import-map-list/modal.component.tsx +++ b/packages/apps/esm-devtools-app/src/devtools/import-map-list/modal.component.tsx @@ -2,7 +2,7 @@ import React, { useCallback, useEffect, useRef, useState } from 'react'; import { useTranslation } from 'react-i18next'; import { addRoutesOverride, removeRoutesOverride } from '@openmrs/esm-framework/src/internal'; import { Button, Form, ModalHeader, ModalBody, ModalFooter, TextInput } from '@carbon/react'; -import { Module } from './types'; +import type { Module } from './types'; import styles from './modal.scss'; type ImportMapModalProps = ({ module: Module; isNew: false } | { module: never; isNew: true }) & { close: () => void }; @@ -51,7 +51,6 @@ const ImportMapModal: React.FC = ({ module, isNew, close }) useEffect( () => (isNew ? moduleNameRef.current?.focus() : inputRef.current?.focus()), // Only fired on initial mount - // eslint-disable-next-line react-hooks/exhaustive-deps [], ); diff --git a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/backend-dependencies.component.tsx b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/backend-dependencies.component.tsx index e1e6d5141..b8d2b6c4f 100644 --- a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/backend-dependencies.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/backend-dependencies.component.tsx @@ -10,7 +10,7 @@ import { TableCell, TableContainer, } from '@carbon/react'; -import { ResolvedDependenciesModule } from './openmrs-backend-dependencies'; +import type { ResolvedDependenciesModule } from './openmrs-backend-dependencies'; import styles from './backend-dependencies.styles.scss'; export interface BackendDependencies { diff --git a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/useBackendDependencies.ts b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/useBackendDependencies.ts index 0b73c26b9..fd4614346 100644 --- a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/useBackendDependencies.ts +++ b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/useBackendDependencies.ts @@ -1,5 +1,6 @@ import { useEffect, useState } from 'react'; -import { checkModules, ResolvedDependenciesModule } from './openmrs-backend-dependencies'; +import type { ResolvedDependenciesModule } from './openmrs-backend-dependencies'; +import { checkModules } from './openmrs-backend-dependencies'; export function useBackendDependencies() { const [modulesWithMissingBackendModules, setModulesWithMissingBackendModules] = useState< diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx index f15f92de5..1acccb9b7 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx @@ -4,8 +4,8 @@ import { useTranslation } from 'react-i18next'; import { ChevronDown, ChevronUp, Download, TrashCan } from '@carbon/react/icons'; import cloneDeep from 'lodash-es/cloneDeep'; import isEmpty from 'lodash-es/isEmpty'; +import type { Config } from '@openmrs/esm-framework/src/internal'; import { - Config, getExtensionInternalStore, implementerToolsConfigStore, temporaryConfigStore, @@ -14,7 +14,8 @@ import { } from '@openmrs/esm-framework/src/internal'; import { ConfigTree } from './interactive-editor/config-tree.component'; import { Description } from './interactive-editor/description.component'; -import { implementerToolsStore, ImplementerToolsStore } from '../store'; +import type { ImplementerToolsStore } from '../store'; +import { implementerToolsStore } from '../store'; import styles from './configuration.styles.scss'; const JsonEditor = React.lazy(() => import('./json-editor/json-editor.component')); diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/editable-value.component.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/editable-value.component.tsx index ac7a981bf..c3f4b743e 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/editable-value.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/editable-value.component.tsx @@ -5,9 +5,12 @@ import cloneDeep from 'lodash-es/cloneDeep'; import styles from './editable-value.styles.scss'; import { Button } from '@carbon/react'; import { Edit, Reset } from '@carbon/react/icons'; -import { ConfigValue, Validator, Type, Config, temporaryConfigStore } from '@openmrs/esm-framework/src/internal'; -import { ValueEditor, CustomValueType } from './value-editor'; -import { implementerToolsStore, ImplementerToolsStore } from '../../store'; +import type { ConfigValue, Validator, Type, Config } from '@openmrs/esm-framework/src/internal'; +import { temporaryConfigStore } from '@openmrs/esm-framework/src/internal'; +import type { CustomValueType } from './value-editor'; +import { ValueEditor } from './value-editor'; +import type { ImplementerToolsStore } from '../../store'; +import { implementerToolsStore } from '../../store'; import { DisplayValue } from './display-value'; import { useTranslation } from 'react-i18next'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-configure-tree.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-configure-tree.tsx index 6796928ca..b6c9d3da2 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-configure-tree.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-configure-tree.tsx @@ -1,6 +1,6 @@ import React from 'react'; import EditableValue from './editable-value.component'; -import { ExtensionSlotConfigureValueObject } from '@openmrs/esm-framework'; +import type { ExtensionSlotConfigureValueObject } from '@openmrs/esm-framework'; export interface ExtensionConfigureTreeProps { moduleName: string; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-slots-config-tree.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-slots-config-tree.tsx index b585b6f3d..10b4f7071 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-slots-config-tree.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/extension-slots-config-tree.tsx @@ -1,7 +1,8 @@ import React from 'react'; import EditableValue from './editable-value.component'; import isEqual from 'lodash-es/isEqual'; -import { ExtensionSlotConfigureValueObject, useAssignedExtensions } from '@openmrs/esm-framework'; +import type { ExtensionSlotConfigureValueObject } from '@openmrs/esm-framework'; +import { useAssignedExtensions } from '@openmrs/esm-framework'; import { ExtensionConfigureTree } from './extension-configure-tree'; import { Subtree } from './layout/subtree.component'; import { implementerToolsStore } from '../../store'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/layout/tree-container.component.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/layout/tree-container.component.tsx index cfbf90341..fcb889371 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/layout/tree-container.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/layout/tree-container.component.tsx @@ -1,4 +1,5 @@ -import React, { ReactNode } from 'react'; +import type { ReactNode } from 'react'; +import React from 'react'; import { StructuredListBody, StructuredListWrapper } from '@carbon/react'; import styles from './layout.styles.css'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editor.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editor.tsx index d3f0473c8..ca037a698 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editor.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editor.tsx @@ -2,8 +2,8 @@ import React, { useEffect, useState, useRef } from 'react'; import { useTranslation } from 'react-i18next'; import { Button } from '@carbon/react'; import { Close, Save } from '@carbon/react/icons'; -import { Type } from '@openmrs/esm-framework'; -import { ConfigValueDescriptor } from './editable-value.component'; +import type { Type } from '@openmrs/esm-framework'; +import type { ConfigValueDescriptor } from './editable-value.component'; import { ValueEditorField } from './value-editors/value-editor-field'; import styles from './value-editor.scss'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/array-editor.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/array-editor.tsx index 4c04775ce..242968efa 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/array-editor.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/array-editor.tsx @@ -12,7 +12,7 @@ import { } from '@carbon/react'; import { Add, TrashCan } from '@carbon/react/icons'; import { ValueEditorField } from './value-editor-field'; -import { ConfigValueDescriptor } from '../editable-value.component'; +import type { ConfigValueDescriptor } from '../editable-value.component'; import styles from './array-editor.styles.css'; interface ArrayEditorProps { diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/concept-search.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/concept-search.tsx index 5ae454166..5e600c656 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/concept-search.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/concept-search.tsx @@ -9,7 +9,8 @@ import { StructuredListWrapper, Tile, } from '@carbon/react'; -import { Concept, useConceptLookup } from './concept-search.resource'; +import type { Concept } from './concept-search.resource'; +import { useConceptLookup } from './concept-search.resource'; import styles from './uuid-search.scss'; interface ConceptSearchBoxProps { diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/extension-slot-add.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/extension-slot-add.tsx index 52474ac5d..3f238a6cf 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/extension-slot-add.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/extension-slot-add.tsx @@ -1,6 +1,7 @@ import React, { useState, useEffect } from 'react'; import { FilterableMultiSelect } from '@carbon/react'; -import { ExtensionInternalStore, getExtensionInternalStore } from '@openmrs/esm-framework/src/internal'; +import type { ExtensionInternalStore } from '@openmrs/esm-framework/src/internal'; +import { getExtensionInternalStore } from '@openmrs/esm-framework/src/internal'; const extensionInternalStore = getExtensionInternalStore(); diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/object-editor.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/object-editor.tsx index 1eb2345ad..358e25322 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/object-editor.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/object-editor.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { StructuredListBody, StructuredListCell, StructuredListRow, StructuredListWrapper, Tile } from '@carbon/react'; import { ValueEditorField } from './value-editor-field'; -import { ConfigValueDescriptor } from '../editable-value.component'; +import type { ConfigValueDescriptor } from '../editable-value.component'; import { Type } from '@openmrs/esm-framework'; import cloneDeep from 'lodash-es/cloneDeep'; import styles from './object-editor.styles.css'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type-search.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type-search.tsx index ec51865e8..7c6a5114e 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type-search.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type-search.tsx @@ -1,6 +1,7 @@ import React, { useState, useMemo } from 'react'; import uniqueId from 'lodash-es/uniqueId'; -import { usePatientIdentifierTypes, PatientIdentifierType } from './patient-identifier-type.resource'; +import type { PatientIdentifierType } from './patient-identifier-type.resource'; +import { usePatientIdentifierTypes } from './patient-identifier-type.resource'; import styles from './uuid-search.scss'; import { useTranslation } from 'react-i18next'; import { Search, StructuredListCell, StructuredListRow, StructuredListWrapper } from '@carbon/react'; diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type.resource.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type.resource.tsx index b368ef0a7..acc64fb84 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type.resource.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/patient-identifier-type.resource.tsx @@ -1,5 +1,6 @@ import useSWR from 'swr'; -import { FetchResponse, openmrsFetch } from '@openmrs/esm-framework'; +import type { FetchResponse } from '@openmrs/esm-framework'; +import { openmrsFetch } from '@openmrs/esm-framework'; import { useMemo } from 'react'; export interface PatientIdentifierType { diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/value-editor-field.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/value-editor-field.tsx index 45dae3cd5..22b5058de 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/value-editor-field.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/interactive-editor/value-editors/value-editor-field.tsx @@ -2,8 +2,8 @@ import React, { useState } from 'react'; import uniqueId from 'lodash-es/uniqueId'; import { Checkbox, NumberInput, TextInput } from '@carbon/react'; import { Type } from '@openmrs/esm-framework'; -import { ConfigValueDescriptor } from '../editable-value.component'; -import { ValueType } from '../value-editor'; +import type { ConfigValueDescriptor } from '../editable-value.component'; +import type { ValueType } from '../value-editor'; import { ArrayEditor } from './array-editor'; import { ConceptSearchBox } from './concept-search'; import { ExtensionSlotAdd } from './extension-slot-add'; diff --git a/packages/apps/esm-implementer-tools-app/src/ui-editor/ui-editor.tsx b/packages/apps/esm-implementer-tools-app/src/ui-editor/ui-editor.tsx index 6610e5bd3..3650fc1e0 100644 --- a/packages/apps/esm-implementer-tools-app/src/ui-editor/ui-editor.tsx +++ b/packages/apps/esm-implementer-tools-app/src/ui-editor/ui-editor.tsx @@ -5,7 +5,8 @@ import { Button } from '@carbon/react'; import { Close } from '@carbon/react/icons'; import { Portal } from './portal'; import { ExtensionOverlay } from './extension-overlay.component'; -import { ImplementerToolsStore, implementerToolsStore } from '../store'; +import type { ImplementerToolsStore } from '../store'; +import { implementerToolsStore } from '../store'; export default function UiEditor() { const { slots, extensions } = useStore(getExtensionInternalStore()); diff --git a/packages/apps/esm-login-app/src/declarations.d.ts b/packages/apps/esm-login-app/src/declarations.d.ts index ca5acd734..1897a9ef9 100644 --- a/packages/apps/esm-login-app/src/declarations.d.ts +++ b/packages/apps/esm-login-app/src/declarations.d.ts @@ -1,7 +1,5 @@ // This entire file will be deleted once we have typescript definitions // for @openmrs/esm-framework published to npm -declare type Observable = import('rxjs').Observable; - declare module '*.css'; declare module '*.scss'; declare module '@carbon/react'; diff --git a/packages/apps/esm-login-app/src/location-picker/location-picker.component.tsx b/packages/apps/esm-login-app/src/location-picker/location-picker.component.tsx index 5dbd883fd..d1a821bf7 100644 --- a/packages/apps/esm-login-app/src/location-picker/location-picker.component.tsx +++ b/packages/apps/esm-login-app/src/location-picker/location-picker.component.tsx @@ -15,7 +15,7 @@ import type { LoginReferrer } from '../login/login.component'; import { useLoginLocations } from '../login.resource'; import styles from './location-picker.scss'; import { useDefaultLocation } from './location-picker.resource'; -import { ConfigSchema } from '../config-schema'; +import type { ConfigSchema } from '../config-schema'; interface LocationPickerProps { hideWelcomeMessage?: boolean; diff --git a/packages/apps/esm-login-app/src/login.resource.ts b/packages/apps/esm-login-app/src/login.resource.ts index 730f609dd..cb8bfd7a7 100644 --- a/packages/apps/esm-login-app/src/login.resource.ts +++ b/packages/apps/esm-login-app/src/login.resource.ts @@ -2,16 +2,9 @@ import { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; import useSwrInfinite from 'swr/infinite'; import useSwrImmutable from 'swr/immutable'; -import { - FetchResponse, - fhirBaseUrl, - openmrsFetch, - refetchCurrentUser, - Session, - showNotification, - useDebounce, -} from '@openmrs/esm-framework'; -import { LocationEntry, LocationResponse } from './types'; +import type { FetchResponse, Session } from '@openmrs/esm-framework'; +import { fhirBaseUrl, openmrsFetch, refetchCurrentUser, showNotification, useDebounce } from '@openmrs/esm-framework'; +import type { LocationEntry, LocationResponse } from './types'; export async function performLogin(username: string, password: string): Promise<{ data: Session }> { const abortController = new AbortController(); diff --git a/packages/apps/esm-login-app/src/login/login.component.tsx b/packages/apps/esm-login-app/src/login/login.component.tsx index 5f6630494..9534092c3 100644 --- a/packages/apps/esm-login-app/src/login/login.component.tsx +++ b/packages/apps/esm-login-app/src/login/login.component.tsx @@ -4,6 +4,7 @@ import { useLocation, useNavigate } from 'react-router-dom'; import { Button, InlineLoading, InlineNotification, PasswordInput, TextInput, Tile } from '@carbon/react'; import { ArrowLeft, ArrowRight } from '@carbon/react/icons'; import { useTranslation } from 'react-i18next'; +import type { Session } from '@openmrs/esm-framework'; import { useConfig, interpolateUrl, @@ -13,7 +14,6 @@ import { getSessionStore, useConnectivity, navigate as openmrsNavigate, - Session, } from '@openmrs/esm-framework'; import { performLogin } from '../login.resource'; import styles from './login.scss'; diff --git a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx index 678db82d9..a9926e4f9 100644 --- a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx +++ b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx @@ -1,4 +1,5 @@ -import React, { useEffect } from 'react'; +import type React from 'react'; +import { useEffect } from 'react'; import { navigate, setUserLanguage, useConfig, useConnectivity, useSession } from '@openmrs/esm-framework'; import { performLogout } from './logout.resource'; diff --git a/packages/apps/esm-offline-tools-app/src/components/confirmation-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/confirmation-modal.component.tsx index 95ad5fa31..55ae46c4a 100644 --- a/packages/apps/esm-offline-tools-app/src/components/confirmation-modal.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/confirmation-modal.component.tsx @@ -1,4 +1,5 @@ -import React, { ReactNode } from 'react'; +import type { ReactNode } from 'react'; +import React from 'react'; import { ModalBody, ModalFooter, ModalHeader } from '@carbon/react'; export interface ConfirmationModalProps { diff --git a/packages/apps/esm-offline-tools-app/src/components/headered-quick-info.component.tsx b/packages/apps/esm-offline-tools-app/src/components/headered-quick-info.component.tsx index 92d897287..d1ad31bc7 100644 --- a/packages/apps/esm-offline-tools-app/src/components/headered-quick-info.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/headered-quick-info.component.tsx @@ -1,4 +1,5 @@ -import React, { ReactNode } from 'react'; +import type { ReactNode } from 'react'; +import React from 'react'; import { SkeletonText } from '@carbon/react'; import styles from './headered-quick-info.styles.scss'; diff --git a/packages/apps/esm-offline-tools-app/src/components/overview-card.component.tsx b/packages/apps/esm-offline-tools-app/src/components/overview-card.component.tsx index 054d2f714..d7d0a8fb7 100644 --- a/packages/apps/esm-offline-tools-app/src/components/overview-card.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/overview-card.component.tsx @@ -1,6 +1,7 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Layer, Tile, TileProps } from '@carbon/react'; +import type { TileProps } from '@carbon/react'; +import { Button, Layer, Tile } from '@carbon/react'; import { ArrowRight } from '@carbon/react/icons'; import { navigate } from '@openmrs/esm-framework'; import styles from './overview-card.styles.scss'; diff --git a/packages/apps/esm-offline-tools-app/src/components/shared-page-layout.component.tsx b/packages/apps/esm-offline-tools-app/src/components/shared-page-layout.component.tsx index 0e72f355f..63a0ad0e0 100644 --- a/packages/apps/esm-offline-tools-app/src/components/shared-page-layout.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/components/shared-page-layout.component.tsx @@ -1,4 +1,5 @@ -import React, { ReactNode } from 'react'; +import type { ReactNode } from 'react'; +import React from 'react'; import styles from './shared-page-layout.styles.scss'; export interface SharedPageLayoutProps { diff --git a/packages/apps/esm-offline-tools-app/src/constants.ts b/packages/apps/esm-offline-tools-app/src/constants.ts index d43f23135..ac73dd156 100644 --- a/packages/apps/esm-offline-tools-app/src/constants.ts +++ b/packages/apps/esm-offline-tools-app/src/constants.ts @@ -1,4 +1,5 @@ -import { omrsOfflineCachingStrategyHttpHeaderName, OmrsOfflineHttpHeaders } from '@openmrs/esm-framework'; +import type { OmrsOfflineHttpHeaders } from '@openmrs/esm-framework'; +import { omrsOfflineCachingStrategyHttpHeaderName } from '@openmrs/esm-framework'; export const routes = { home: `home`, diff --git a/packages/apps/esm-offline-tools-app/src/hooks/offline-actions.ts b/packages/apps/esm-offline-tools-app/src/hooks/offline-actions.ts index f1574d198..c16eaa008 100644 --- a/packages/apps/esm-offline-tools-app/src/hooks/offline-actions.ts +++ b/packages/apps/esm-offline-tools-app/src/hooks/offline-actions.ts @@ -1,8 +1,8 @@ +import type { SyncItem } from '@openmrs/esm-framework/src/internal'; import { fetchCurrentPatient, getFullSynchronizationItems, getSynchronizationItems, - SyncItem, } from '@openmrs/esm-framework/src/internal'; import uniq from 'lodash-es/uniq'; import useSWR from 'swr'; diff --git a/packages/apps/esm-offline-tools-app/src/hooks/offline-patient-data-hooks.ts b/packages/apps/esm-offline-tools-app/src/hooks/offline-patient-data-hooks.ts index f3fd815fa..7013b881c 100644 --- a/packages/apps/esm-offline-tools-app/src/hooks/offline-patient-data-hooks.ts +++ b/packages/apps/esm-offline-tools-app/src/hooks/offline-patient-data-hooks.ts @@ -1,7 +1,8 @@ import { fetchCurrentPatient, getSynchronizationItems, getDynamicOfflineDataEntries } from '@openmrs/esm-framework'; import merge from 'lodash-es/merge'; import { useMemo } from 'react'; -import useSWR, { SWRResponse } from 'swr'; +import type { SWRResponse } from 'swr'; +import useSWR from 'swr'; function useDynamicOfflineDataEntries(type: string) { return useSWR(`dynamicOfflineData/entries/${type}`, () => getDynamicOfflineDataEntries(type)); diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-table.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-table.component.tsx index 1bd29529c..e269cf821 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-table.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-table.component.tsx @@ -19,13 +19,13 @@ import { TableSelectAll, TableSelectRow, } from '@carbon/react'; +import type { SyncItem } from '@openmrs/esm-framework'; import { beginEditSynchronizationItem, canBeginEditSynchronizationItemsOfType, createErrorHandler, isDesktop, navigate, - SyncItem, useLayoutType, usePagination, } from '@openmrs/esm-framework'; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions.component.tsx index dce3f9b37..7417a22a5 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions.component.tsx @@ -1,8 +1,8 @@ +import type { SyncItem } from '@openmrs/esm-framework/src/internal'; import { deleteSynchronizationItem, getOfflineSynchronizationStore, showModal, - SyncItem, useStore, } from '@openmrs/esm-framework/src/internal'; import React from 'react'; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx index 2d1df0774..5a179a0fd 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx @@ -1,10 +1,6 @@ import React, { useEffect, useState } from 'react'; -import { - getOfflineSynchronizationStore, - OfflineSynchronizationStore, - showNotification, - useStore, -} from '@openmrs/esm-framework/src/internal'; +import type { OfflineSynchronizationStore } from '@openmrs/esm-framework/src/internal'; +import { getOfflineSynchronizationStore, showNotification, useStore } from '@openmrs/esm-framework/src/internal'; import { getI18n, useTranslation } from 'react-i18next'; import { Loading, NotificationActionButton } from '@carbon/react'; import styles from './synchronizing-notification.styles.scss'; diff --git a/packages/apps/esm-offline-tools-app/src/offline-patients/last-updated-table-cell.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-patients/last-updated-table-cell.component.tsx index bf6ab24be..854aef22b 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-patients/last-updated-table-cell.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-patients/last-updated-table-cell.component.tsx @@ -2,7 +2,8 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; import { Link } from '@carbon/react'; import { PendingFilled, WarningAltFilled, CheckmarkOutline } from '@carbon/react/icons'; -import { DynamicOfflineDataSyncState, getDynamicOfflineDataHandlers, navigate } from '@openmrs/esm-framework'; +import type { DynamicOfflineDataSyncState } from '@openmrs/esm-framework'; +import { getDynamicOfflineDataHandlers, navigate } from '@openmrs/esm-framework'; import styles from './last-updated-table-cell.scss'; export interface LastUpdatedTableCellProps { diff --git a/packages/apps/esm-offline-tools-app/src/offline-patients/offline-patient-table.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-patients/offline-patient-table.component.tsx index 0f68b9571..d386abc89 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-patients/offline-patient-table.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-patients/offline-patient-table.component.tsx @@ -18,6 +18,7 @@ import { TableSelectRow, } from '@carbon/react'; import { Renew } from '@carbon/react/icons'; +import type { DynamicOfflineDataSyncState } from '@openmrs/esm-framework'; import { age, isDesktop, @@ -27,7 +28,6 @@ import { removeDynamicOfflineData, syncDynamicOfflineData, getDynamicOfflineDataEntries, - DynamicOfflineDataSyncState, useLayoutType, } from '@openmrs/esm-framework'; import { useTranslation } from 'react-i18next'; diff --git a/packages/apps/esm-offline-tools-app/src/offline-tools-page/offline-tools-page.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-tools-page/offline-tools-page.component.tsx index fd60ec54e..ea6005538 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-tools-page/offline-tools-page.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-tools-page/offline-tools-page.component.tsx @@ -1,6 +1,6 @@ import { ExtensionSlot, useExtensionSlotMeta } from '@openmrs/esm-framework'; import React from 'react'; -import { OfflineToolsPageConfig } from '../types'; +import type { OfflineToolsPageConfig } from '../types'; import trimEnd from 'lodash-es/trimEnd'; import { useLocation, useMatch, useParams } from 'react-router-dom'; diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx index af95ed0b4..df8d5e168 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx @@ -2,8 +2,10 @@ import React, { useCallback, useEffect, useMemo, useState } from 'react'; import classNames from 'classnames'; import { useTranslation } from 'react-i18next'; import { Select, SelectItem } from '@carbon/react'; -import { ExtensionSlot, LoggedInUser, useConnectivity } from '@openmrs/esm-framework'; -import { PostUserProperties, postUserPropertiesOnline, postUserPropertiesOffline } from './change-locale.resource'; +import type { LoggedInUser } from '@openmrs/esm-framework'; +import { ExtensionSlot, useConnectivity } from '@openmrs/esm-framework'; +import type { PostUserProperties } from './change-locale.resource'; +import { postUserPropertiesOnline, postUserPropertiesOffline } from './change-locale.resource'; import styles from './change-locale.scss'; export interface ChangeLocaleProps { diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/notifications-menu-panel.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/notifications-menu-panel.component.tsx index 256a18493..155d59bb6 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/notifications-menu-panel.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/notifications-menu-panel.component.tsx @@ -1,6 +1,7 @@ import React, { useMemo } from 'react'; import { useTranslation } from 'react-i18next'; -import { HeaderPanel, HeaderPanelProps } from '@carbon/react'; +import type { HeaderPanelProps } from '@carbon/react'; +import { HeaderPanel } from '@carbon/react'; import { ExtensionSlot } from '@openmrs/esm-framework'; import styles from './notifications-menu.panel.scss'; diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx index 6b1a116ef..b7909a734 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx @@ -1,6 +1,8 @@ import React from 'react'; -import { ExtensionSlot, LoggedInUser, Session, useOnClickOutside } from '@openmrs/esm-framework'; -import { HeaderPanel, HeaderPanelProps } from '@carbon/react'; +import type { LoggedInUser, Session } from '@openmrs/esm-framework'; +import { ExtensionSlot, useOnClickOutside } from '@openmrs/esm-framework'; +import type { HeaderPanelProps } from '@carbon/react'; +import { HeaderPanel } from '@carbon/react'; import styles from '../../root.scss'; interface UserMenuPanelProps extends HeaderPanelProps { diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx index 3bda9f0ee..faaf974c4 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx @@ -3,8 +3,8 @@ import { Navigate } from 'react-router-dom'; import classNames from 'classnames'; import { HeaderContainer, Header, HeaderMenuButton, HeaderGlobalBar, HeaderGlobalAction } from '@carbon/react'; import { Close, Switcher, UserAvatarFilledAlt } from '@carbon/react/icons'; +import type { LoggedInUser } from '@openmrs/esm-framework'; import { - LoggedInUser, useLayoutType, ExtensionSlot, ConfigurableLink, diff --git a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx index bfcc86d21..44eda95ce 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx @@ -1,7 +1,7 @@ import React from 'react'; import { Switcher } from '@carbon/react'; import { UserAvatarFilledAlt } from '@carbon/react/icons'; -import { LoggedInUser } from '@openmrs/esm-framework'; +import type { LoggedInUser } from '@openmrs/esm-framework'; import styles from './user-panel-switcher.scss'; export interface UserPanelSwitcherItemProps { diff --git a/packages/apps/esm-primary-navigation-app/src/offline.ts b/packages/apps/esm-primary-navigation-app/src/offline.ts index 86c95b2db..1c8b15ee3 100644 --- a/packages/apps/esm-primary-navigation-app/src/offline.ts +++ b/packages/apps/esm-primary-navigation-app/src/offline.ts @@ -1,4 +1,5 @@ -import { refetchCurrentUser, getLoggedInUser, SyncProcessOptions } from '@openmrs/esm-framework/src/internal'; +import type { SyncProcessOptions } from '@openmrs/esm-framework/src/internal'; +import { refetchCurrentUser, getLoggedInUser } from '@openmrs/esm-framework/src/internal'; import { postUserPropertiesOnline } from './components/choose-locale/change-locale.resource'; export async function syncUserLanguagePreference(_: any, options: SyncProcessOptions) { diff --git a/packages/apps/esm-primary-navigation-app/src/utils.ts b/packages/apps/esm-primary-navigation-app/src/utils.ts index c0be4ad7b..69c9e433f 100644 --- a/packages/apps/esm-primary-navigation-app/src/utils.ts +++ b/packages/apps/esm-primary-navigation-app/src/utils.ts @@ -1,3 +1,3 @@ -import { LayoutType } from '@openmrs/esm-framework'; +import type { LayoutType } from '@openmrs/esm-framework'; export const isDesktop = (layout: LayoutType) => layout === 'small-desktop' || layout === 'large-desktop'; diff --git a/packages/framework/esm-api/src/openmrs-fetch.ts b/packages/framework/esm-api/src/openmrs-fetch.ts index a31c0cc5d..475810ae8 100644 --- a/packages/framework/esm-api/src/openmrs-fetch.ts +++ b/packages/framework/esm-api/src/openmrs-fetch.ts @@ -2,7 +2,7 @@ import { Observable } from 'rxjs'; import isPlainObject from 'lodash-es/isPlainObject'; import { getConfig, navigate } from '@openmrs/esm-config'; -import { FetchResponse } from './types'; +import type { FetchResponse } from './types'; export const restBaseUrl = '/ws/rest/v1/'; diff --git a/packages/framework/esm-api/src/shared-api-objects/current-patient.ts b/packages/framework/esm-api/src/shared-api-objects/current-patient.ts index cf3e552e1..6a4d6ed09 100644 --- a/packages/framework/esm-api/src/shared-api-objects/current-patient.ts +++ b/packages/framework/esm-api/src/shared-api-objects/current-patient.ts @@ -1,7 +1,8 @@ /** @module @category API */ import { getSynchronizationItems } from '@openmrs/esm-offline'; -import { FetchConfig, fhirBaseUrl, openmrsFetch } from '../openmrs-fetch'; -import { FetchResponse } from '../types'; +import type { FetchConfig } from '../openmrs-fetch'; +import { fhirBaseUrl, openmrsFetch } from '../openmrs-fetch'; +import type { FetchResponse } from '../types'; export type CurrentPatient = fhir.Patient | FetchResponse; export interface CurrentPatientOptions { diff --git a/packages/framework/esm-api/src/shared-api-objects/location.ts b/packages/framework/esm-api/src/shared-api-objects/location.ts index f9acceebe..e15001a3b 100644 --- a/packages/framework/esm-api/src/shared-api-objects/location.ts +++ b/packages/framework/esm-api/src/shared-api-objects/location.ts @@ -1,8 +1,8 @@ /** @module @category API */ -import { Observable } from 'rxjs'; +import type { Observable } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { openmrsObservableFetch } from '../openmrs-fetch'; -import { Location } from '../types'; +import type { Location } from '../types'; export function toLocationObject(openmrsRestForm: any): Location { return { diff --git a/packages/framework/esm-api/src/shared-api-objects/visit-type.ts b/packages/framework/esm-api/src/shared-api-objects/visit-type.ts index 77185616e..42d666041 100644 --- a/packages/framework/esm-api/src/shared-api-objects/visit-type.ts +++ b/packages/framework/esm-api/src/shared-api-objects/visit-type.ts @@ -1,8 +1,8 @@ /** @module @category API */ -import { Observable } from 'rxjs'; +import type { Observable } from 'rxjs'; import { map, take } from 'rxjs/operators'; import { openmrsObservableFetch } from '../openmrs-fetch'; -import { VisitType } from '../types'; +import type { VisitType } from '../types'; export function toVisitTypeObject(openmrsRestForm: any): VisitType { return { diff --git a/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts b/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts index 1764e54b1..4097f2848 100644 --- a/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts +++ b/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts @@ -1,8 +1,9 @@ /** @module @category API */ -import { Observable, BehaviorSubject } from 'rxjs'; +import type { Observable } from 'rxjs'; +import { BehaviorSubject } from 'rxjs'; import { take, map } from 'rxjs/operators'; import { openmrsObservableFetch } from '../openmrs-fetch'; -import { FetchResponse, NewVisitPayload, UpdateVisitPayload, Visit } from '../types'; +import type { FetchResponse, NewVisitPayload, UpdateVisitPayload, Visit } from '../types'; import { getGlobalStore } from '@openmrs/esm-state'; export const defaultVisitCustomRepresentation = diff --git a/packages/framework/esm-api/src/types/fetch.ts b/packages/framework/esm-api/src/types/fetch.ts index 1b1f126f6..22436ffd1 100644 --- a/packages/framework/esm-api/src/types/fetch.ts +++ b/packages/framework/esm-api/src/types/fetch.ts @@ -1,4 +1,4 @@ -import { Session } from './user-resource'; +import type { Session } from './user-resource'; export interface FetchResponse extends Response { data: T; diff --git a/packages/framework/esm-api/src/types/visit-resource.ts b/packages/framework/esm-api/src/types/visit-resource.ts index 6288864ea..26f4d1499 100644 --- a/packages/framework/esm-api/src/types/visit-resource.ts +++ b/packages/framework/esm-api/src/types/visit-resource.ts @@ -1,4 +1,4 @@ -import { OpenmrsResource } from './openmrs-resource'; +import type { OpenmrsResource } from './openmrs-resource'; export interface NewVisitPayload { uuid?: string; diff --git a/packages/framework/esm-breadcrumbs/src/db.ts b/packages/framework/esm-breadcrumbs/src/db.ts index 45a2aeeff..a5395d8e8 100644 --- a/packages/framework/esm-breadcrumbs/src/db.ts +++ b/packages/framework/esm-breadcrumbs/src/db.ts @@ -1,7 +1,7 @@ /** @module @category Breadcrumb */ import { pathToRegexp } from 'path-to-regexp'; import { createGlobalStore } from '@openmrs/esm-state'; -import { BreadcrumbSettings, BreadcrumbRegistration } from './types'; +import type { BreadcrumbSettings, BreadcrumbRegistration } from './types'; const store = createGlobalStore>('breadcrumbs', []); diff --git a/packages/framework/esm-breadcrumbs/src/filter.ts b/packages/framework/esm-breadcrumbs/src/filter.ts index 4e98d9915..2118786f9 100644 --- a/packages/framework/esm-breadcrumbs/src/filter.ts +++ b/packages/framework/esm-breadcrumbs/src/filter.ts @@ -1,6 +1,6 @@ /** @module @category Breadcrumb */ import { getBreadcrumbs } from './db'; -import { BreadcrumbRegistration } from './types'; +import type { BreadcrumbRegistration } from './types'; function getExact(breadcrumbs: Array, path: string): BreadcrumbRegistration { const [bc] = breadcrumbs.filter((m) => m.matcher.test(path)); diff --git a/packages/framework/esm-config/src/module-config/module-config.test.ts b/packages/framework/esm-config/src/module-config/module-config.test.ts index 09869f555..4bca44733 100644 --- a/packages/framework/esm-config/src/module-config/module-config.test.ts +++ b/packages/framework/esm-config/src/module-config/module-config.test.ts @@ -1,15 +1,14 @@ import unset from 'lodash/unset'; import * as Config from './module-config'; -import { MockedStore, mockStores } from '../../__mocks__/openmrs-esm-state.mock'; +import type { MockedStore } from '../../__mocks__/openmrs-esm-state.mock'; +import { mockStores } from '../../__mocks__/openmrs-esm-state.mock'; import { validator } from '../validators/validator'; import { validators, isUrl } from '../validators/validators'; +import type { ConfigExtensionStore, ConfigInternalStore, ImplementerToolsConfigStore } from './state'; import { - ConfigExtensionStore, configExtensionStore, - ConfigInternalStore, configInternalStore, getExtensionConfig, - ImplementerToolsConfigStore, implementerToolsConfigStore, temporaryConfigStore, } from './state'; diff --git a/packages/framework/esm-config/src/module-config/module-config.ts b/packages/framework/esm-config/src/module-config/module-config.ts index da717422a..1fc517582 100644 --- a/packages/framework/esm-config/src/module-config/module-config.ts +++ b/packages/framework/esm-config/src/module-config/module-config.ts @@ -1,12 +1,11 @@ /** @module @category Config */ import { clone, reduce, mergeDeepRight, equals, omit } from 'ramda'; -import { Config, ConfigObject, ConfigSchema, ExtensionSlotConfig, ExtensionSlotConfigObject, Type } from '../types'; +import type { Config, ConfigObject, ConfigSchema, ExtensionSlotConfig, ExtensionSlotConfigObject } from '../types'; +import { Type } from '../types'; import { isArray, isBoolean, isUuid, isNumber, isObject, isString } from '../validators/type-validators'; +import type { ConfigExtensionStore, ConfigInternalStore, ConfigStore } from './state'; import { - ConfigExtensionStore, - ConfigInternalStore, configInternalStore, - ConfigStore, configExtensionStore, getConfigStore, getExtensionsConfigStore, @@ -15,7 +14,7 @@ import { getExtensionSlotsConfigStore, } from './state'; import type {} from '@openmrs/esm-globals'; -import { TemporaryConfigStore } from '..'; +import type { TemporaryConfigStore } from '..'; /** * Store setup diff --git a/packages/framework/esm-config/src/module-config/state.ts b/packages/framework/esm-config/src/module-config/state.ts index 785ed91e1..9ebc0bad7 100644 --- a/packages/framework/esm-config/src/module-config/state.ts +++ b/packages/framework/esm-config/src/module-config/state.ts @@ -1,7 +1,7 @@ /** @module @category Config */ import { createGlobalStore, getGlobalStore } from '@openmrs/esm-state'; import { omit } from 'ramda'; -import { Config, ConfigObject, ConfigSchema, ExtensionSlotConfigObject, ProvidedConfig } from '../types'; +import type { Config, ConfigObject, ConfigSchema, ExtensionSlotConfigObject, ProvidedConfig } from '../types'; /** * Internal store diff --git a/packages/framework/esm-config/src/validators/validator.ts b/packages/framework/esm-config/src/validators/validator.ts index f4d701c96..3c89c1c87 100644 --- a/packages/framework/esm-config/src/validators/validator.ts +++ b/packages/framework/esm-config/src/validators/validator.ts @@ -1,5 +1,5 @@ /** @module @category Config Validation */ -import { Validator, ValidatorFunction } from '../types'; +import type { Validator, ValidatorFunction } from '../types'; /** * Constructs a custom validator. diff --git a/packages/framework/esm-extensions/src/extensions.ts b/packages/framework/esm-extensions/src/extensions.ts index a15b962f8..e0b114b73 100644 --- a/packages/framework/esm-extensions/src/extensions.ts +++ b/packages/framework/esm-extensions/src/extensions.ts @@ -8,11 +8,10 @@ * - connected (computed from assigned using connectivity and online / offline) */ -import { getSessionStore, LoggedInUser, userHasAccess } from '@openmrs/esm-api'; +import type { LoggedInUser } from '@openmrs/esm-api'; +import { getSessionStore, userHasAccess } from '@openmrs/esm-api'; +import type { ExtensionsConfigStore, ExtensionSlotConfigObject, ExtensionSlotsConfigStore } from '@openmrs/esm-config'; import { - ExtensionsConfigStore, - ExtensionSlotConfigObject, - ExtensionSlotsConfigStore, getExtensionConfigFromStore, getExtensionsConfigStore, getExtensionSlotConfig, @@ -22,20 +21,10 @@ import { import { featureFlagsStore } from '@openmrs/esm-feature-flags'; import isEqual from 'lodash-es/isEqual'; import isUndefined from 'lodash-es/isUndefined'; -import { - getExtensionInternalStore, - ExtensionSlotState, - AssignedExtension, - checkStatusFor, - ConnectedExtension, -} from '.'; -import { - ExtensionRegistration, - ExtensionSlotInfo, - ExtensionInternalStore, - getExtensionStore, - updateInternalExtensionStore, -} from './store'; +import type { ExtensionSlotState, AssignedExtension, ConnectedExtension } from '.'; +import { getExtensionInternalStore, checkStatusFor } from '.'; +import type { ExtensionRegistration, ExtensionSlotInfo, ExtensionInternalStore } from './store'; +import { getExtensionStore, updateInternalExtensionStore } from './store'; const extensionInternalStore = getExtensionInternalStore(); const extensionStore = getExtensionStore(); diff --git a/packages/framework/esm-extensions/src/store.ts b/packages/framework/esm-extensions/src/store.ts index 2d3f98cf6..9b7955eab 100644 --- a/packages/framework/esm-extensions/src/store.ts +++ b/packages/framework/esm-extensions/src/store.ts @@ -1,11 +1,7 @@ /** @module @category Extension */ import isEqual from 'lodash-es/isEqual'; -import { - configExtensionStore, - ConfigExtensionStoreElement, - ConfigObject, - ExtensionSlotConfigObject, -} from '@openmrs/esm-config'; +import type { ConfigExtensionStoreElement, ConfigObject, ExtensionSlotConfigObject } from '@openmrs/esm-config'; +import { configExtensionStore } from '@openmrs/esm-config'; import { createGlobalStore, getGlobalStore } from '@openmrs/esm-state'; import type { LifeCycles } from 'single-spa'; diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index a02c0b8ce..64ae9601a 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -210,7 +210,7 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L6) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L7) ___ @@ -237,7 +237,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/usePatient.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/usePatient.ts#L5) +[packages/framework/esm-react-utils/src/usePatient.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/usePatient.ts#L6) ___ @@ -247,7 +247,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L19) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L20) ___ @@ -425,7 +425,7 @@ A definition of an extension as extracted from an app's routes.json #### Defined in -[packages/framework/esm-globals/src/types.ts:171](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L171) +[packages/framework/esm-globals/src/types.ts:172](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L172) ___ @@ -458,7 +458,7 @@ Basically, this is the same as the app routes, with each routes definition keyed #### Defined in -[packages/framework/esm-globals/src/types.ts:259](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L259) +[packages/framework/esm-globals/src/types.ts:260](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L260) ___ @@ -470,7 +470,7 @@ A definition of a page extracted from an app's routes.json #### Defined in -[packages/framework/esm-globals/src/types.ts:115](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L115) +[packages/framework/esm-globals/src/types.ts:116](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L116) ___ @@ -499,7 +499,7 @@ A definition of a page after the app has been registered. #### Defined in -[packages/framework/esm-globals/src/types.ts:166](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L166) +[packages/framework/esm-globals/src/types.ts:167](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L167) ___ @@ -509,7 +509,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/types.ts:70](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L70) +[packages/framework/esm-globals/src/types.ts:71](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L71) ___ @@ -694,7 +694,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L7) +[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L8) ___ @@ -704,7 +704,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L8) +[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L9) ___ @@ -723,7 +723,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L9) +[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L10) ## API Variables @@ -733,7 +733,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/UserHasAccess.tsx:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L11) +[packages/framework/esm-react-utils/src/UserHasAccess.tsx:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L12) ___ @@ -743,7 +743,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L8) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L9) ___ @@ -765,7 +765,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:99](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L99) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:100](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L100) ___ @@ -917,7 +917,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/left-nav/index.tsx:30](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L30) +[packages/framework/esm-styleguide/src/left-nav/index.tsx:31](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L31) ## API Functions @@ -953,7 +953,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L21) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L22) ___ @@ -1108,7 +1108,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:26](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L26) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:27](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L27) ___ @@ -1144,7 +1144,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:50](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L50) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:51](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L51) ___ @@ -1338,7 +1338,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L72) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L73) ___ @@ -1359,7 +1359,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:30](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L30) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:31](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L31) ___ @@ -1484,7 +1484,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:83](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L83) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:84](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L84) ___ @@ -1504,7 +1504,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useLocations.tsx:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useLocations.tsx#L5) +[packages/framework/esm-react-utils/src/useLocations.tsx:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useLocations.tsx#L6) ___ @@ -1536,7 +1536,7 @@ a route listener is set up to update the patient whenever the route changes. #### Defined in -[packages/framework/esm-react-utils/src/usePatient.ts:89](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/usePatient.ts#L89) +[packages/framework/esm-react-utils/src/usePatient.ts:90](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/usePatient.ts#L90) ___ @@ -1558,7 +1558,7 @@ Current user session information #### Defined in -[packages/framework/esm-react-utils/src/useSession.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useSession.ts#L16) +[packages/framework/esm-react-utils/src/useSession.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useSession.ts#L17) ___ @@ -1594,7 +1594,7 @@ API call is in progress. `mutate` refreshes the data from both API calls. #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:40](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L40) +[packages/framework/esm-react-utils/src/useVisit.ts:41](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L41) ___ @@ -1608,7 +1608,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisitTypes.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisitTypes.ts#L5) +[packages/framework/esm-react-utils/src/useVisitTypes.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisitTypes.ts#L6) ___ @@ -1758,7 +1758,7 @@ for more information about defining a config schema. #### Defined in -[packages/framework/esm-config/src/module-config/module-config.ts:143](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L143) +[packages/framework/esm-config/src/module-config/module-config.ts:142](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L142) ___ @@ -1790,7 +1790,7 @@ for more information about defining a config schema. #### Defined in -[packages/framework/esm-config/src/module-config/module-config.ts:170](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L170) +[packages/framework/esm-config/src/module-config/module-config.ts:169](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L169) ___ @@ -1816,7 +1816,7 @@ of the execution of a function. #### Defined in -[packages/framework/esm-config/src/module-config/module-config.ts:202](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L202) +[packages/framework/esm-config/src/module-config/module-config.ts:201](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L201) ___ @@ -1837,7 +1837,7 @@ ___ #### Defined in -[packages/framework/esm-config/src/module-config/module-config.ts:186](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L186) +[packages/framework/esm-config/src/module-config/module-config.ts:185](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/module-config/module-config.ts#L185) ___ @@ -1865,7 +1865,7 @@ Use this React Hook to obtain your module's configuration. #### Defined in -[packages/framework/esm-react-utils/src/useConfig.ts:144](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useConfig.ts#L144) +[packages/framework/esm-react-utils/src/useConfig.ts:139](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useConfig.ts#L139) ___ @@ -2508,7 +2508,7 @@ writing a module for a specific implementation. #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:153](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L153) +[packages/framework/esm-extensions/src/extensions.ts:142](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L142) ___ @@ -2531,7 +2531,7 @@ Avoid using this. Extension attachments should be considered declarative. #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:184](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L184) +[packages/framework/esm-extensions/src/extensions.ts:173](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L173) ___ @@ -2553,7 +2553,7 @@ Avoid using this. Extension attachments should be considered declarative. #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:206](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L206) +[packages/framework/esm-extensions/src/extensions.ts:195](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L195) ___ @@ -2577,7 +2577,7 @@ An array of extensions assigned to the named slot #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:340](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L340) +[packages/framework/esm-extensions/src/extensions.ts:329](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L329) ___ @@ -2604,7 +2604,7 @@ A list of extensions that should be rendered #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:266](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L266) +[packages/framework/esm-extensions/src/extensions.ts:255](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L255) ___ @@ -2636,7 +2636,7 @@ getExtensionNameFromId("baz") #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:101](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L101) +[packages/framework/esm-extensions/src/extensions.ts:90](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L90) ___ @@ -2653,7 +2653,7 @@ state of the extension system. #### Defined in -[packages/framework/esm-extensions/src/store.ts:128](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L128) +[packages/framework/esm-extensions/src/store.ts:124](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L124) ___ @@ -2730,7 +2730,7 @@ Does not consider if offline or online. #### Defined in -[packages/framework/esm-react-utils/src/useAssignedExtensions.ts:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useAssignedExtensions.ts#L11) +[packages/framework/esm-react-utils/src/useAssignedExtensions.ts:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useAssignedExtensions.ts#L12) ___ @@ -2753,7 +2753,7 @@ Considers if offline or online, and what feature flags are enabled. #### Defined in -[packages/framework/esm-react-utils/src/useConnectedExtensions.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useConnectedExtensions.ts#L14) +[packages/framework/esm-react-utils/src/useConnectedExtensions.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useConnectedExtensions.ts#L15) ___ @@ -2795,7 +2795,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useExtensionStore.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L5) +[packages/framework/esm-react-utils/src/useExtensionStore.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L6) ▸ **useExtensionStore**(`actions`): `T` & [`BoundActions`](API.md#boundactions) @@ -2811,7 +2811,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useExtensionStore.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L5) +[packages/framework/esm-react-utils/src/useExtensionStore.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L6) ▸ **useExtensionStore**(`actions?`): `T` & [`BoundActions`](API.md#boundactions) @@ -2827,7 +2827,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useExtensionStore.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L5) +[packages/framework/esm-react-utils/src/useExtensionStore.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useExtensionStore.ts#L6) ___ @@ -2950,7 +2950,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L29) +[packages/framework/esm-react-utils/src/getLifecycle.ts:31](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L31) ___ @@ -2983,7 +2983,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L15) +[packages/framework/esm-react-utils/src/getLifecycle.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L17) ___ @@ -3010,7 +3010,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L7) +[packages/framework/esm-react-utils/src/getLifecycle.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L9) ___ @@ -3043,7 +3043,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L22) +[packages/framework/esm-react-utils/src/getLifecycle.ts:24](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L24) ___ @@ -3067,7 +3067,7 @@ A React link component which calls [navigate](API.md#navigate) when clicked #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:28](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L28) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L29) ___ @@ -3986,7 +3986,7 @@ The newly created store. #### Defined in -[packages/framework/esm-state/src/state.ts:28](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L28) +[packages/framework/esm-state/src/state.ts:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L29) ___ @@ -4045,7 +4045,7 @@ custom hook for a specific store. #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:65](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L65) +[packages/framework/esm-react-utils/src/useStore.ts:60](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L60) ___ @@ -4077,7 +4077,7 @@ The found or newly created store. #### Defined in -[packages/framework/esm-state/src/state.ts:60](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L60) +[packages/framework/esm-state/src/state.ts:61](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L61) ___ @@ -4112,7 +4112,7 @@ ___ #### Defined in -[packages/framework/esm-state/src/state.ts:77](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L77) +[packages/framework/esm-state/src/state.ts:78](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-state/src/state.ts#L78) ___ @@ -4139,7 +4139,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:38](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L38) +[packages/framework/esm-react-utils/src/useStore.ts:33](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L33) ▸ **useStore**<`T`, `U`\>(`store`, `select`): `U` @@ -4163,7 +4163,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:39](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L39) +[packages/framework/esm-react-utils/src/useStore.ts:34](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L34) ▸ **useStore**<`T`, `U`\>(`store`, `select`, `actions`): `T` & [`BoundActions`](API.md#boundactions) @@ -4188,7 +4188,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:40](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L40) +[packages/framework/esm-react-utils/src/useStore.ts:35](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L35) ▸ **useStore**<`T`, `U`\>(`store`, `select`, `actions`): `U` & [`BoundActions`](API.md#boundactions) @@ -4213,7 +4213,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:41](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L41) +[packages/framework/esm-react-utils/src/useStore.ts:36](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L36) ___ @@ -4240,7 +4240,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useStore.ts:57](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L57) +[packages/framework/esm-react-utils/src/useStore.ts:52](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useStore.ts#L52) ___ @@ -4282,7 +4282,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/left-nav/index.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L18) +[packages/framework/esm-styleguide/src/left-nav/index.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L19) ___ @@ -4336,7 +4336,7 @@ The dispose function to force closing the modal dialog. #### Defined in -[packages/framework/esm-styleguide/src/modals/index.tsx:159](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/modals/index.tsx#L159) +[packages/framework/esm-styleguide/src/modals/index.tsx:160](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/modals/index.tsx#L160) ___ @@ -4526,7 +4526,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/left-nav/index.tsx:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L22) +[packages/framework/esm-styleguide/src/left-nav/index.tsx:23](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/left-nav/index.tsx#L23) ___ @@ -4979,4 +4979,4 @@ function MyComponent() { #### Defined in -[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:69](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L69) +[packages/framework/esm-react-utils/src/useOpenmrsSWR.ts:70](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts#L70) diff --git a/packages/framework/esm-framework/docs/enums/VisitMode.md b/packages/framework/esm-framework/docs/enums/VisitMode.md index 111091f2b..d9d0b3471 100644 --- a/packages/framework/esm-framework/docs/enums/VisitMode.md +++ b/packages/framework/esm-framework/docs/enums/VisitMode.md @@ -18,7 +18,7 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:110](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L110) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:111](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L111) ___ @@ -28,7 +28,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:111](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L111) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:112](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L112) ___ @@ -38,4 +38,4 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:109](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L109) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:110](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L110) diff --git a/packages/framework/esm-framework/docs/enums/VisitStatus.md b/packages/framework/esm-framework/docs/enums/VisitStatus.md index 7a20defa0..a49d4281a 100644 --- a/packages/framework/esm-framework/docs/enums/VisitStatus.md +++ b/packages/framework/esm-framework/docs/enums/VisitStatus.md @@ -17,7 +17,7 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:115](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L115) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:116](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L116) ___ @@ -27,4 +27,4 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:116](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L116) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:117](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L117) diff --git a/packages/framework/esm-framework/docs/interfaces/AssignedExtension.md b/packages/framework/esm-framework/docs/interfaces/AssignedExtension.md index b1622679c..5a1849149 100644 --- a/packages/framework/esm-framework/docs/interfaces/AssignedExtension.md +++ b/packages/framework/esm-framework/docs/interfaces/AssignedExtension.md @@ -25,7 +25,7 @@ The extension's config. Note that this will be `null` until the slot is mounted. #### Defined in -[packages/framework/esm-extensions/src/store.ts:82](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L82) +[packages/framework/esm-extensions/src/store.ts:78](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L78) ___ @@ -35,7 +35,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:85](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L85) +[packages/framework/esm-extensions/src/store.ts:81](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L81) ___ @@ -45,7 +45,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:77](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L77) +[packages/framework/esm-extensions/src/store.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L73) ___ @@ -55,7 +55,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:80](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L80) +[packages/framework/esm-extensions/src/store.ts:76](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L76) ___ @@ -65,7 +65,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:79](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L79) +[packages/framework/esm-extensions/src/store.ts:75](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L75) ___ @@ -75,7 +75,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:78](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L78) +[packages/framework/esm-extensions/src/store.ts:74](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L74) ___ @@ -85,7 +85,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:84](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L84) +[packages/framework/esm-extensions/src/store.ts:80](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L80) ___ @@ -95,4 +95,4 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:83](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L83) +[packages/framework/esm-extensions/src/store.ts:79](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L79) diff --git a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md index 72d3328d6..93fefddb5 100644 --- a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md +++ b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md @@ -291,7 +291,7 @@ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L17) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L18) ___ @@ -301,7 +301,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L16) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L17) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/ConnectedExtension.md b/packages/framework/esm-framework/docs/interfaces/ConnectedExtension.md index 3bc0e5830..e649272ef 100644 --- a/packages/framework/esm-framework/docs/interfaces/ConnectedExtension.md +++ b/packages/framework/esm-framework/docs/interfaces/ConnectedExtension.md @@ -22,7 +22,7 @@ The extension's config. Note that this will be `null` until the slot is mounted. #### Defined in -[packages/framework/esm-extensions/src/store.ts:94](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L94) +[packages/framework/esm-extensions/src/store.ts:90](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L90) ___ @@ -32,7 +32,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:89](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L89) +[packages/framework/esm-extensions/src/store.ts:85](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L85) ___ @@ -42,7 +42,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:92](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L92) +[packages/framework/esm-extensions/src/store.ts:88](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L88) ___ @@ -52,7 +52,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:91](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L91) +[packages/framework/esm-extensions/src/store.ts:87](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L87) ___ @@ -62,4 +62,4 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:90](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L90) +[packages/framework/esm-extensions/src/store.ts:86](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L86) diff --git a/packages/framework/esm-framework/docs/interfaces/CurrentPatientOptions.md b/packages/framework/esm-framework/docs/interfaces/CurrentPatientOptions.md index 7c3a3d4f4..d2199e96d 100644 --- a/packages/framework/esm-framework/docs/interfaces/CurrentPatientOptions.md +++ b/packages/framework/esm-framework/docs/interfaces/CurrentPatientOptions.md @@ -24,4 +24,4 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L8) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L9) diff --git a/packages/framework/esm-framework/docs/interfaces/ExtensionRegistration.md b/packages/framework/esm-framework/docs/interfaces/ExtensionRegistration.md index d1b90c3bd..a5a8829cd 100644 --- a/packages/framework/esm-framework/docs/interfaces/ExtensionRegistration.md +++ b/packages/framework/esm-framework/docs/interfaces/ExtensionRegistration.md @@ -27,7 +27,7 @@ #### Defined in -[packages/framework/esm-extensions/src/store.ts:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L25) +[packages/framework/esm-extensions/src/store.ts:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L21) ___ @@ -37,7 +37,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L20) +[packages/framework/esm-extensions/src/store.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L16) ___ @@ -47,7 +47,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L19) +[packages/framework/esm-extensions/src/store.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L15) ___ @@ -57,7 +57,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L17) +[packages/framework/esm-extensions/src/store.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L13) ___ @@ -67,7 +67,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:23](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L23) +[packages/framework/esm-extensions/src/store.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L19) ___ @@ -77,7 +77,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L22) +[packages/framework/esm-extensions/src/store.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L18) ___ @@ -87,7 +87,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L21) +[packages/framework/esm-extensions/src/store.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L17) ___ @@ -97,7 +97,7 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:24](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L24) +[packages/framework/esm-extensions/src/store.ts:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L20) ## Methods @@ -111,4 +111,4 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L18) +[packages/framework/esm-extensions/src/store.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L14) diff --git a/packages/framework/esm-framework/docs/interfaces/ExtensionSlotState.md b/packages/framework/esm-framework/docs/interfaces/ExtensionSlotState.md index 7aa12d6a7..f2326fc60 100644 --- a/packages/framework/esm-framework/docs/interfaces/ExtensionSlotState.md +++ b/packages/framework/esm-framework/docs/interfaces/ExtensionSlotState.md @@ -17,7 +17,7 @@ #### Defined in -[packages/framework/esm-extensions/src/store.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L73) +[packages/framework/esm-extensions/src/store.ts:69](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L69) ___ @@ -27,4 +27,4 @@ ___ #### Defined in -[packages/framework/esm-extensions/src/store.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L72) +[packages/framework/esm-extensions/src/store.ts:68](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L68) diff --git a/packages/framework/esm-framework/docs/interfaces/ExtensionStore.md b/packages/framework/esm-framework/docs/interfaces/ExtensionStore.md index ac468a615..4f9e859c7 100644 --- a/packages/framework/esm-framework/docs/interfaces/ExtensionStore.md +++ b/packages/framework/esm-framework/docs/interfaces/ExtensionStore.md @@ -16,4 +16,4 @@ #### Defined in -[packages/framework/esm-extensions/src/store.ts:68](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L68) +[packages/framework/esm-extensions/src/store.ts:64](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/store.ts#L64) diff --git a/packages/framework/esm-framework/docs/interfaces/ImportMap.md b/packages/framework/esm-framework/docs/interfaces/ImportMap.md index 9964e0d96..e9fd4be0b 100644 --- a/packages/framework/esm-framework/docs/interfaces/ImportMap.md +++ b/packages/framework/esm-framework/docs/interfaces/ImportMap.md @@ -16,4 +16,4 @@ #### Defined in -[packages/framework/esm-globals/src/types.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L73) +[packages/framework/esm-globals/src/types.ts:74](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L74) diff --git a/packages/framework/esm-framework/docs/interfaces/OnlyThePatient.md b/packages/framework/esm-framework/docs/interfaces/OnlyThePatient.md index aac6dc9ab..b2f6acddb 100644 --- a/packages/framework/esm-framework/docs/interfaces/OnlyThePatient.md +++ b/packages/framework/esm-framework/docs/interfaces/OnlyThePatient.md @@ -26,4 +26,4 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L16) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L17) diff --git a/packages/framework/esm-framework/docs/interfaces/OpenmrsAppRoutes.md b/packages/framework/esm-framework/docs/interfaces/OpenmrsAppRoutes.md index 49b4aaf11..e4786c5d0 100644 --- a/packages/framework/esm-framework/docs/interfaces/OpenmrsAppRoutes.md +++ b/packages/framework/esm-framework/docs/interfaces/OpenmrsAppRoutes.md @@ -23,7 +23,7 @@ A list of backend modules necessary for this frontend module and the correspondi #### Defined in -[packages/framework/esm-globals/src/types.ts:244](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L244) +[packages/framework/esm-globals/src/types.ts:245](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L245) ___ @@ -35,7 +35,7 @@ An array of all extensions supported by this frontend module. Extensions can be #### Defined in -[packages/framework/esm-globals/src/types.ts:252](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L252) +[packages/framework/esm-globals/src/types.ts:253](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L253) ___ @@ -47,7 +47,7 @@ An array of all pages supported by this frontend module. Pages are automatically #### Defined in -[packages/framework/esm-globals/src/types.ts:248](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L248) +[packages/framework/esm-globals/src/types.ts:249](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L249) ___ @@ -59,4 +59,4 @@ The version of this frontend module. #### Defined in -[packages/framework/esm-globals/src/types.ts:240](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L240) +[packages/framework/esm-globals/src/types.ts:241](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L241) diff --git a/packages/framework/esm-framework/docs/interfaces/PatientWithFullResponse.md b/packages/framework/esm-framework/docs/interfaces/PatientWithFullResponse.md index f529aa774..5aaf782f2 100644 --- a/packages/framework/esm-framework/docs/interfaces/PatientWithFullResponse.md +++ b/packages/framework/esm-framework/docs/interfaces/PatientWithFullResponse.md @@ -26,4 +26,4 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L12) +[packages/framework/esm-api/src/shared-api-objects/current-patient.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/current-patient.ts#L13) diff --git a/packages/framework/esm-framework/docs/interfaces/ResourceLoader.md b/packages/framework/esm-framework/docs/interfaces/ResourceLoader.md index 140c6fc72..6921586e3 100644 --- a/packages/framework/esm-framework/docs/interfaces/ResourceLoader.md +++ b/packages/framework/esm-framework/docs/interfaces/ResourceLoader.md @@ -20,4 +20,4 @@ #### Defined in -[packages/framework/esm-globals/src/types.ts:262](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L262) +[packages/framework/esm-globals/src/types.ts:263](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L263) diff --git a/packages/framework/esm-framework/docs/interfaces/SpaConfig.md b/packages/framework/esm-framework/docs/interfaces/SpaConfig.md index 093e68ab6..7e0d2d386 100644 --- a/packages/framework/esm-framework/docs/interfaces/SpaConfig.md +++ b/packages/framework/esm-framework/docs/interfaces/SpaConfig.md @@ -24,7 +24,7 @@ The base path or URL for the OpenMRS API / endpoints. #### Defined in -[packages/framework/esm-globals/src/types.ts:83](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L83) +[packages/framework/esm-globals/src/types.ts:84](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L84) ___ @@ -36,7 +36,7 @@ URLs of configurations to load in the system. #### Defined in -[packages/framework/esm-globals/src/types.ts:96](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L96) +[packages/framework/esm-globals/src/types.ts:97](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L97) ___ @@ -50,7 +50,7 @@ The environment to use. #### Defined in -[packages/framework/esm-globals/src/types.ts:92](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L92) +[packages/framework/esm-globals/src/types.ts:93](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L93) ___ @@ -64,7 +64,7 @@ Defines if offline should be supported by installing a service worker. #### Defined in -[packages/framework/esm-globals/src/types.ts:101](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L101) +[packages/framework/esm-globals/src/types.ts:102](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L102) ___ @@ -76,4 +76,4 @@ The base path for the SPA root path. #### Defined in -[packages/framework/esm-globals/src/types.ts:87](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L87) +[packages/framework/esm-globals/src/types.ts:88](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/types.ts#L88) diff --git a/packages/framework/esm-framework/docs/interfaces/UserHasAccessProps.md b/packages/framework/esm-framework/docs/interfaces/UserHasAccessProps.md index 7d0967d24..050dc2717 100644 --- a/packages/framework/esm-framework/docs/interfaces/UserHasAccessProps.md +++ b/packages/framework/esm-framework/docs/interfaces/UserHasAccessProps.md @@ -18,7 +18,7 @@ #### Defined in -[packages/framework/esm-react-utils/src/UserHasAccess.tsx:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L8) +[packages/framework/esm-react-utils/src/UserHasAccess.tsx:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L9) ___ @@ -28,7 +28,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/UserHasAccess.tsx:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L7) +[packages/framework/esm-react-utils/src/UserHasAccess.tsx:8](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L8) ___ @@ -38,4 +38,4 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/UserHasAccess.tsx:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L6) +[packages/framework/esm-react-utils/src/UserHasAccess.tsx:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/UserHasAccess.tsx#L7) diff --git a/packages/framework/esm-framework/docs/interfaces/VisitItem.md b/packages/framework/esm-framework/docs/interfaces/VisitItem.md index 9270b58c7..c12c499dc 100644 --- a/packages/framework/esm-framework/docs/interfaces/VisitItem.md +++ b/packages/framework/esm-framework/docs/interfaces/VisitItem.md @@ -19,7 +19,7 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:105](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L105) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:106](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L106) ___ @@ -29,7 +29,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:102](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L102) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:103](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L103) ___ @@ -39,7 +39,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:104](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L104) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:105](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L105) ___ @@ -49,4 +49,4 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:103](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L103) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:104](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L104) diff --git a/packages/framework/esm-framework/docs/interfaces/VisitReturnType.md b/packages/framework/esm-framework/docs/interfaces/VisitReturnType.md index 8c9a99e23..72d9f651e 100644 --- a/packages/framework/esm-framework/docs/interfaces/VisitReturnType.md +++ b/packages/framework/esm-framework/docs/interfaces/VisitReturnType.md @@ -25,7 +25,7 @@ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L15) +[packages/framework/esm-react-utils/src/useVisit.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L16) ___ @@ -35,7 +35,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L16) +[packages/framework/esm-react-utils/src/useVisit.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L17) ___ @@ -45,7 +45,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L17) +[packages/framework/esm-react-utils/src/useVisit.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L18) ___ @@ -55,7 +55,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L12) +[packages/framework/esm-react-utils/src/useVisit.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L13) ___ @@ -65,7 +65,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L18) +[packages/framework/esm-react-utils/src/useVisit.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L19) ___ @@ -75,7 +75,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L14) +[packages/framework/esm-react-utils/src/useVisit.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L15) ## API Methods @@ -89,4 +89,4 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/useVisit.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L13) +[packages/framework/esm-react-utils/src/useVisit.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useVisit.ts#L14) diff --git a/packages/framework/esm-framework/docs/interfaces/VisitStoreState.md b/packages/framework/esm-framework/docs/interfaces/VisitStoreState.md index 9a31591cb..f97e26270 100644 --- a/packages/framework/esm-framework/docs/interfaces/VisitStoreState.md +++ b/packages/framework/esm-framework/docs/interfaces/VisitStoreState.md @@ -17,7 +17,7 @@ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L19) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L20) ___ @@ -27,4 +27,4 @@ ___ #### Defined in -[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L18) +[packages/framework/esm-api/src/shared-api-objects/visit-utils.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/shared-api-objects/visit-utils.ts#L19) diff --git a/packages/framework/esm-globals/src/types.ts b/packages/framework/esm-globals/src/types.ts index a666fef73..b9357766e 100644 --- a/packages/framework/esm-globals/src/types.ts +++ b/packages/framework/esm-globals/src/types.ts @@ -7,6 +7,7 @@ declare global { Record Promise; from: string; eager: boolean }> >; + // eslint-disable-next-line no-var var __webpack_init_sharing__: (scope: string) => Promise; interface Window { diff --git a/packages/framework/esm-offline/src/offline-db.ts b/packages/framework/esm-offline/src/offline-db.ts index e64a72e99..928adf15a 100644 --- a/packages/framework/esm-offline/src/offline-db.ts +++ b/packages/framework/esm-offline/src/offline-db.ts @@ -1,4 +1,5 @@ -import Dexie, { Table } from 'dexie'; +import type { Table } from 'dexie'; +import Dexie from 'dexie'; import type { DynamicOfflineData } from './dynamic-offline-data'; import type { SyncItem } from './sync'; diff --git a/packages/framework/esm-offline/src/service-worker-messaging.ts b/packages/framework/esm-offline/src/service-worker-messaging.ts index b264a6d35..d08bffbff 100644 --- a/packages/framework/esm-offline/src/service-worker-messaging.ts +++ b/packages/framework/esm-offline/src/service-worker-messaging.ts @@ -1,6 +1,6 @@ /** @module @category Offline */ import type { ImportMap } from '@openmrs/esm-globals'; -import { OmrsOfflineCachingStrategy } from './service-worker-http-headers'; +import type { OmrsOfflineCachingStrategy } from './service-worker-http-headers'; import { getOmrsServiceWorker } from './service-worker'; /** diff --git a/packages/framework/esm-offline/src/sync.test.ts b/packages/framework/esm-offline/src/sync.test.ts index 59f0b2e10..78675376b 100644 --- a/packages/framework/esm-offline/src/sync.test.ts +++ b/packages/framework/esm-offline/src/sync.test.ts @@ -1,11 +1,11 @@ import 'fake-indexeddb/auto'; import { getLoggedInUser } from '@openmrs/esm-api'; +import type { QueueItemDescriptor } from './sync'; import { getFullSynchronizationItems, getFullSynchronizationItemsFor, getSynchronizationItems, getSynchronizationItemsFor, - QueueItemDescriptor, queueSynchronizationItem, queueSynchronizationItemFor, deleteSynchronizationItem, diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx index d6efa9158..0dbca708b 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx @@ -1,6 +1,7 @@ /** @module @category Navigation */ import React, { type MouseEvent, type AnchorHTMLAttributes, type PropsWithChildren } from 'react'; -import { navigate, interpolateUrl, TemplateParams } from '@openmrs/esm-config'; +import type { TemplateParams } from '@openmrs/esm-config'; +import { navigate, interpolateUrl } from '@openmrs/esm-config'; function handleClick(event: MouseEvent, to: string, templateParams?: TemplateParams) { if (!event.metaKey && !event.ctrlKey && !event.shiftKey && event.button == 0) { diff --git a/packages/framework/esm-react-utils/src/Extension.tsx b/packages/framework/esm-react-utils/src/Extension.tsx index 72062e231..22df4802c 100644 --- a/packages/framework/esm-react-utils/src/Extension.tsx +++ b/packages/framework/esm-react-utils/src/Extension.tsx @@ -37,7 +37,6 @@ export const Extension: React.FC = ({ state, children, wrap, ... ); } // we only warn when component mounts - // eslint-disable-next-line react-hooks/exhaustive-deps }, []); const ref = useCallback( @@ -98,7 +97,6 @@ export const Extension: React.FC = ({ state, children, wrap, ... // we intentionally do not re-run this hook if state gets updated // state updates are handled in the next useEffect hook - // eslint-disable-next-line react-hooks/exhaustive-deps }, [extension?.extensionSlotName, extension?.extensionId, extension?.extensionSlotModuleName, domElement]); useEffect(() => { diff --git a/packages/framework/esm-react-utils/src/UserHasAccess.tsx b/packages/framework/esm-react-utils/src/UserHasAccess.tsx index becc12145..f7310d131 100644 --- a/packages/framework/esm-react-utils/src/UserHasAccess.tsx +++ b/packages/framework/esm-react-utils/src/UserHasAccess.tsx @@ -1,5 +1,6 @@ /** @module @category API */ -import { getCurrentUser, LoggedInUser, userHasAccess } from '@openmrs/esm-api'; +import type { LoggedInUser } from '@openmrs/esm-api'; +import { getCurrentUser, userHasAccess } from '@openmrs/esm-api'; import React, { useEffect, useState } from 'react'; export interface UserHasAccessProps { diff --git a/packages/framework/esm-react-utils/src/getLifecycle.ts b/packages/framework/esm-react-utils/src/getLifecycle.ts index f60d69358..751d15ee5 100644 --- a/packages/framework/esm-react-utils/src/getLifecycle.ts +++ b/packages/framework/esm-react-utils/src/getLifecycle.ts @@ -1,8 +1,10 @@ /** @module @category Framework */ -import React, { ComponentType } from 'react'; +import type { ComponentType } from 'react'; +import React from 'react'; import ReactDOMClient from 'react-dom/client'; import singleSpaReact from 'single-spa-react'; -import { openmrsComponentDecorator, ComponentDecoratorOptions } from './openmrsComponentDecorator'; +import type { ComponentDecoratorOptions } from './openmrsComponentDecorator'; +import { openmrsComponentDecorator } from './openmrsComponentDecorator'; export function getLifecycle(Component: ComponentType, options: ComponentDecoratorOptions) { return singleSpaReact({ diff --git a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx index 39a1b4efd..a5f0e184b 100644 --- a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx +++ b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx @@ -1,7 +1,8 @@ import React, { type ComponentType, Suspense } from 'react'; import { I18nextProvider } from 'react-i18next'; import type {} from '@openmrs/esm-globals'; -import { ComponentConfig, ComponentContext, ExtensionData } from './ComponentContext'; +import type { ComponentConfig, ExtensionData } from './ComponentContext'; +import { ComponentContext } from './ComponentContext'; const defaultOpts = { strictMode: true, diff --git a/packages/framework/esm-react-utils/src/setup-tests.js b/packages/framework/esm-react-utils/src/setup-tests.js index 1fbe98c3c..436aecd89 100644 --- a/packages/framework/esm-react-utils/src/setup-tests.js +++ b/packages/framework/esm-react-utils/src/setup-tests.js @@ -1,5 +1,5 @@ import '@testing-library/jest-dom'; -window.openmrsBase = '/openmrs'; -window.spaBase = '/spa'; -window.getOpenmrsSpaBase = () => '/openmrs/spa/'; +global.window.openmrsBase = '/openmrs'; +global.window.spaBase = '/spa'; +global.window.getOpenmrsSpaBase = () => '/openmrs/spa/'; diff --git a/packages/framework/esm-react-utils/src/useAssignedExtensions.ts b/packages/framework/esm-react-utils/src/useAssignedExtensions.ts index 304cf32da..09737f1e8 100644 --- a/packages/framework/esm-react-utils/src/useAssignedExtensions.ts +++ b/packages/framework/esm-react-utils/src/useAssignedExtensions.ts @@ -1,6 +1,7 @@ /** @module @category Extension */ import { useEffect, useState } from 'react'; -import { AssignedExtension, ExtensionStore, getExtensionStore } from '@openmrs/esm-extensions'; +import type { AssignedExtension, ExtensionStore } from '@openmrs/esm-extensions'; +import { getExtensionStore } from '@openmrs/esm-extensions'; import isEqual from 'lodash-es/isEqual'; /** diff --git a/packages/framework/esm-react-utils/src/useConfig.ts b/packages/framework/esm-react-utils/src/useConfig.ts index aea12ad8a..4f76e47c0 100644 --- a/packages/framework/esm-react-utils/src/useConfig.ts +++ b/packages/framework/esm-react-utils/src/useConfig.ts @@ -1,16 +1,11 @@ /** @module @category Config */ import { useContext, useEffect, useMemo, useState } from 'react'; -import { - getConfigStore, - getExtensionsConfigStore, - ConfigStore, - ConfigObject, - ExtensionsConfigStore, - getExtensionConfigFromStore, -} from '@openmrs/esm-config'; +import type { ConfigStore, ConfigObject, ExtensionsConfigStore } from '@openmrs/esm-config'; +import { getConfigStore, getExtensionsConfigStore, getExtensionConfigFromStore } from '@openmrs/esm-config'; import type { StoreApi } from 'zustand'; import isEqual from 'lodash-es/isEqual'; -import { ComponentContext, ExtensionData } from './ComponentContext'; +import type { ExtensionData } from './ComponentContext'; +import { ComponentContext } from './ComponentContext'; const promises: Record> = {}; const errorMessage = `No ComponentContext has been provided. This should come from "openmrsComponentDecorator". diff --git a/packages/framework/esm-react-utils/src/useConnectedExtensions.ts b/packages/framework/esm-react-utils/src/useConnectedExtensions.ts index de1174bf8..20b808df6 100644 --- a/packages/framework/esm-react-utils/src/useConnectedExtensions.ts +++ b/packages/framework/esm-react-utils/src/useConnectedExtensions.ts @@ -1,6 +1,7 @@ /** @module @category Extension */ import { useMemo } from 'react'; -import { ConnectedExtension, getConnectedExtensions } from '@openmrs/esm-extensions'; +import type { ConnectedExtension } from '@openmrs/esm-extensions'; +import { getConnectedExtensions } from '@openmrs/esm-extensions'; import { useConnectivity } from './useConnectivity'; import { useAssignedExtensions } from './useAssignedExtensions'; import { useStore } from './useStore'; diff --git a/packages/framework/esm-react-utils/src/useExtensionInternalStore.ts b/packages/framework/esm-react-utils/src/useExtensionInternalStore.ts index d4fe20c44..6b52fa534 100644 --- a/packages/framework/esm-react-utils/src/useExtensionInternalStore.ts +++ b/packages/framework/esm-react-utils/src/useExtensionInternalStore.ts @@ -1,4 +1,5 @@ -import { ExtensionInternalStore, getExtensionInternalStore } from '@openmrs/esm-extensions'; +import type { ExtensionInternalStore } from '@openmrs/esm-extensions'; +import { getExtensionInternalStore } from '@openmrs/esm-extensions'; import { createUseStore } from './useStore'; /** @internal diff --git a/packages/framework/esm-react-utils/src/useExtensionSlotMeta.ts b/packages/framework/esm-react-utils/src/useExtensionSlotMeta.ts index b9bc6c396..59fbbf76b 100644 --- a/packages/framework/esm-react-utils/src/useExtensionSlotMeta.ts +++ b/packages/framework/esm-react-utils/src/useExtensionSlotMeta.ts @@ -1,5 +1,5 @@ /** @module @category Extension */ -import { ExtensionMeta } from '@openmrs/esm-extensions'; +import type { ExtensionMeta } from '@openmrs/esm-extensions'; import { useMemo } from 'react'; import { useConnectedExtensions } from './useConnectedExtensions'; diff --git a/packages/framework/esm-react-utils/src/useExtensionStore.ts b/packages/framework/esm-react-utils/src/useExtensionStore.ts index 4721c428d..c5f6781ba 100644 --- a/packages/framework/esm-react-utils/src/useExtensionStore.ts +++ b/packages/framework/esm-react-utils/src/useExtensionStore.ts @@ -1,5 +1,6 @@ /** @module @category Extension */ -import { ExtensionStore, getExtensionStore } from '@openmrs/esm-extensions'; +import type { ExtensionStore } from '@openmrs/esm-extensions'; +import { getExtensionStore } from '@openmrs/esm-extensions'; import { createUseStore } from './useStore'; export const useExtensionStore = createUseStore(getExtensionStore()); diff --git a/packages/framework/esm-react-utils/src/useLocations.tsx b/packages/framework/esm-react-utils/src/useLocations.tsx index 1c9f130ea..993208f68 100644 --- a/packages/framework/esm-react-utils/src/useLocations.tsx +++ b/packages/framework/esm-react-utils/src/useLocations.tsx @@ -1,5 +1,6 @@ /** @module @category API */ -import { getLocations, Location } from '@openmrs/esm-api'; +import type { Location } from '@openmrs/esm-api'; +import { getLocations } from '@openmrs/esm-api'; import { useState, useEffect } from 'react'; export function useLocations(tagUuidOrName: string | null = null) { diff --git a/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts b/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts index 0c1a7f8d1..d493e4340 100644 --- a/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts +++ b/packages/framework/esm-react-utils/src/useOpenmrsSWR.ts @@ -1,6 +1,7 @@ /** @module @category Utility */ import { useCallback, useMemo } from 'react'; -import useSWR, { SWRConfiguration } from 'swr'; +import type { SWRConfiguration } from 'swr'; +import useSWR from 'swr'; import { type FetchConfig, openmrsFetch } from '@openmrs/esm-api'; import useAbortController from './useAbortController'; diff --git a/packages/framework/esm-react-utils/src/usePatient.ts b/packages/framework/esm-react-utils/src/usePatient.ts index 867e2d1b4..2de4d9b3f 100644 --- a/packages/framework/esm-react-utils/src/usePatient.ts +++ b/packages/framework/esm-react-utils/src/usePatient.ts @@ -1,6 +1,7 @@ /** @module @category API */ import { useEffect, useReducer } from 'react'; -import { fetchCurrentPatient, PatientUuid } from '@openmrs/esm-api'; +import type { PatientUuid } from '@openmrs/esm-api'; +import { fetchCurrentPatient } from '@openmrs/esm-api'; export type NullablePatient = fhir.Patient | null; diff --git a/packages/framework/esm-react-utils/src/useSession.ts b/packages/framework/esm-react-utils/src/useSession.ts index 9203a6c97..80d849fc5 100644 --- a/packages/framework/esm-react-utils/src/useSession.ts +++ b/packages/framework/esm-react-utils/src/useSession.ts @@ -1,5 +1,6 @@ /** @module @category API */ -import { getSessionStore, Session } from '@openmrs/esm-api'; +import type { Session } from '@openmrs/esm-api'; +import { getSessionStore } from '@openmrs/esm-api'; import { useState, useEffect, useRef } from 'react'; let promise: undefined | Promise; diff --git a/packages/framework/esm-react-utils/src/useStore.ts b/packages/framework/esm-react-utils/src/useStore.ts index bef44657f..c4d7e6f92 100644 --- a/packages/framework/esm-react-utils/src/useStore.ts +++ b/packages/framework/esm-react-utils/src/useStore.ts @@ -17,14 +17,9 @@ function bindActions(store: StoreApi, actions: Actions): BoundActions { const bound = {}; for (let i in actions) { - bound[i] = function () { - const args = arguments; + bound[i] = function (...args) { store.setState((state) => { - let _args = [state]; - for (let i = 0; i < args.length; i++) { - _args.push(args[i]); - } - + let _args = [state, ...args]; return actions[i](..._args); }); }; diff --git a/packages/framework/esm-react-utils/src/useVisit.ts b/packages/framework/esm-react-utils/src/useVisit.ts index 136a351b8..ec15d93cb 100644 --- a/packages/framework/esm-react-utils/src/useVisit.ts +++ b/packages/framework/esm-react-utils/src/useVisit.ts @@ -1,5 +1,6 @@ /** @module @category API */ -import { defaultVisitCustomRepresentation, getVisitStore, openmrsFetch, Visit } from '@openmrs/esm-api'; +import type { Visit } from '@openmrs/esm-api'; +import { defaultVisitCustomRepresentation, getVisitStore, openmrsFetch } from '@openmrs/esm-api'; import useSWR from 'swr'; import dayjs from 'dayjs'; import isToday from 'dayjs/plugin/isToday'; diff --git a/packages/framework/esm-react-utils/src/useVisitTypes.ts b/packages/framework/esm-react-utils/src/useVisitTypes.ts index e124710a8..701afc17e 100644 --- a/packages/framework/esm-react-utils/src/useVisitTypes.ts +++ b/packages/framework/esm-react-utils/src/useVisitTypes.ts @@ -1,5 +1,6 @@ /** @module @category API */ -import { getVisitTypes, VisitType } from '@openmrs/esm-api'; +import type { VisitType } from '@openmrs/esm-api'; +import { getVisitTypes } from '@openmrs/esm-api'; import { useEffect, useState } from 'react'; export function useVisitTypes() { diff --git a/packages/framework/esm-routes/src/routes.ts b/packages/framework/esm-routes/src/routes.ts index 30a989d2e..61ed095fc 100644 --- a/packages/framework/esm-routes/src/routes.ts +++ b/packages/framework/esm-routes/src/routes.ts @@ -31,7 +31,9 @@ export function addRoutesOverride(moduleName: string, routes: OpenmrsAppRoutes | } else { console.error(`The supplied routes for ${moduleName} is not a valid OpenmrsAppRoutes object`, routes); } - } catch {} + } catch (e) { + console.error(`Could not add routes override for ${moduleName}: `, e); + } } } else if (routes instanceof URL) { return addRouteOverrideInternal(moduleName, routes.toString()); diff --git a/packages/framework/esm-state/src/state.ts b/packages/framework/esm-state/src/state.ts index 5eaa76253..f475d2aed 100644 --- a/packages/framework/esm-state/src/state.ts +++ b/packages/framework/esm-state/src/state.ts @@ -1,5 +1,6 @@ /** @module @category Store */ -import { createStore, StoreApi } from 'zustand/vanilla'; +import type { StoreApi } from 'zustand/vanilla'; +import { createStore } from 'zustand/vanilla'; import type {} from '@openmrs/esm-globals'; interface StoreEntity { diff --git a/packages/framework/esm-styleguide/src/datepicker/react-spectrum/adobe-react-spectrum-date-wrapper.component.tsx b/packages/framework/esm-styleguide/src/datepicker/react-spectrum/adobe-react-spectrum-date-wrapper.component.tsx index b1e7d69b6..ad8a1e68b 100644 --- a/packages/framework/esm-styleguide/src/datepicker/react-spectrum/adobe-react-spectrum-date-wrapper.component.tsx +++ b/packages/framework/esm-styleguide/src/datepicker/react-spectrum/adobe-react-spectrum-date-wrapper.component.tsx @@ -1,5 +1,6 @@ import React, { useMemo } from 'react'; -import { CalendarDate, parseDate } from '@internationalized/date'; +import type { CalendarDate } from '@internationalized/date'; +import { parseDate } from '@internationalized/date'; import { DatePicker } from '@react-spectrum/datepicker'; import { Provider } from '@react-spectrum/provider'; import { theme as defaultTheme } from '@react-spectrum/theme-default'; diff --git a/packages/framework/esm-styleguide/src/icons/svgs.test.js b/packages/framework/esm-styleguide/src/icons/svgs.test.js deleted file mode 100644 index 7d4edaea7..000000000 --- a/packages/framework/esm-styleguide/src/icons/svgs.test.js +++ /dev/null @@ -1,61 +0,0 @@ -const path = require('path'); -const fs = require('fs'); - -describe('svgs', () => { - const svgs = []; - - beforeAll(() => { - // eslint-disable-next-line no-undef - const svgFilePaths = fs.readdirSync(path.join(__dirname, 'svgs')); - const domParser = new DOMParser(); - - svgFilePaths.forEach((filePath) => { - const svgString = fs.readFileSync( - // eslint-disable-next-line no-undef - path.resolve(__dirname, 'svgs', filePath), - ); - const svgDoc = domParser.parseFromString(svgString, 'text/html'); - const svgEl = svgDoc.querySelector('svg'); - if (svgEl) { - svgs.push({ filePath, svgEl: svgEl, svgDoc }); - } - }); - }); - - it('does not have a specified fill color, so that the color can be specified by css', () => { - svgs.forEach((svg) => { - if (svg.svgDoc.querySelector('[fill]')) { - fail( - `svg ${svg.filePath} has a "fill" attribute in it, which makes it impossible for CSS to change its color\n${svg.svgEl.outerHTML}`, - ); - } - }); - }); - - it('has a viewBox="0 0 24 24" attribute on the svg', () => { - svgs.forEach((svg) => { - if (svg.svgEl.getAttribute('viewBox') !== '0 0 24 24') { - // If we get an svg that isn't based on a 24px grid, we can update this test to allow for other viewBoxes. - fail( - `svg ${svg.filePath} does not have viewBox="0 0 24 24", which makes it impossible for CSS to change its size\n${svg.svgEl.outerHTML}`, - ); - } - }); - }); - - it('should have a title tag defined for the svg', () => { - svgs.forEach((svg) => { - if (svg.svgEl.querySelector('title') === null) { - fail(`svg ${svg.filePath} does not have a title defined for it`); - } - }); - }); - - it('should have a text description on the title tag', () => { - svgs.forEach((svg) => { - if (svg.svgEl.querySelector('title').innerHTML === '') { - fail(`svg ${svg.filePath} does not have a title defined for it`); - } - }); - }); -}); diff --git a/packages/framework/esm-styleguide/src/left-nav/index.tsx b/packages/framework/esm-styleguide/src/left-nav/index.tsx index 5c3fabe8a..34f26f412 100644 --- a/packages/framework/esm-styleguide/src/left-nav/index.tsx +++ b/packages/framework/esm-styleguide/src/left-nav/index.tsx @@ -2,7 +2,8 @@ import React from 'react'; import { ExtensionSlot, useStore } from '@openmrs/esm-react-utils'; import { createGlobalStore } from '@openmrs/esm-state'; -import { SideNav, SideNavProps } from '@carbon/react'; +import type { SideNavProps } from '@carbon/react'; +import { SideNav } from '@carbon/react'; import styles from './left-nav.module.scss'; interface LeftNavStore { diff --git a/packages/framework/esm-styleguide/src/modals/index.tsx b/packages/framework/esm-styleguide/src/modals/index.tsx index 54d6df178..b3fe6ea04 100644 --- a/packages/framework/esm-styleguide/src/modals/index.tsx +++ b/packages/framework/esm-styleguide/src/modals/index.tsx @@ -66,7 +66,7 @@ function handleModalStateUpdate({ modalStack, modalContainer }: ModalState) { modalStack.forEach((instance, index) => { switch (instance.state) { - case 'NEW': + case 'NEW': { const { outer, contentContainer } = createModalFrame(); instance.container = outer; renderExtension(contentContainer, '', '', instance.extensionId, undefined, instance.props).then((parcel) => { @@ -76,6 +76,7 @@ function handleModalStateUpdate({ modalStack, modalContainer }: ModalState) { outer.style.visibility = 'unset'; }); break; + } case 'MOUNTED': if (instance.container) { diff --git a/packages/framework/esm-styleguide/src/notifications/active-actionable-notifications.component.tsx b/packages/framework/esm-styleguide/src/notifications/active-actionable-notifications.component.tsx index a8fcd5f6d..43ed3e48e 100644 --- a/packages/framework/esm-styleguide/src/notifications/active-actionable-notifications.component.tsx +++ b/packages/framework/esm-styleguide/src/notifications/active-actionable-notifications.component.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; -import { Subject } from 'rxjs'; -import { ActionableNotificationMeta, ActionableNotificationComponent } from './actionable-notification.component'; +import type { Subject } from 'rxjs'; +import type { ActionableNotificationMeta } from './actionable-notification.component'; +import { ActionableNotificationComponent } from './actionable-notification.component'; interface ActionableActiveNotificationProps { subject: Subject; diff --git a/packages/framework/esm-styleguide/src/notifications/active-notifications.component.tsx b/packages/framework/esm-styleguide/src/notifications/active-notifications.component.tsx index 04abf8860..69cb73805 100644 --- a/packages/framework/esm-styleguide/src/notifications/active-notifications.component.tsx +++ b/packages/framework/esm-styleguide/src/notifications/active-notifications.component.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; -import { Subject } from 'rxjs'; -import { InlineNotificationMeta, Notification } from './notification.component'; +import type { Subject } from 'rxjs'; +import type { InlineNotificationMeta } from './notification.component'; +import { Notification } from './notification.component'; interface ActiveNotificationProps { subject: Subject; diff --git a/packages/framework/esm-styleguide/src/notifications/index.tsx b/packages/framework/esm-styleguide/src/notifications/index.tsx index f1d1858d5..94813b626 100644 --- a/packages/framework/esm-styleguide/src/notifications/index.tsx +++ b/packages/framework/esm-styleguide/src/notifications/index.tsx @@ -1,8 +1,8 @@ /** @module @category UI */ import React from 'react'; import { Subject } from 'rxjs'; -import { InlineNotificationMeta, NotificationDescriptor } from './notification.component'; -import { ActionableNotificationMeta, ActionableNotificationDescriptor } from './actionable-notification.component'; +import type { InlineNotificationMeta, NotificationDescriptor } from './notification.component'; +import type { ActionableNotificationMeta, ActionableNotificationDescriptor } from './actionable-notification.component'; import ActiveNotifications from './active-notifications.component'; import ActionableActiveNotifications from './active-actionable-notifications.component'; import isEmpty from 'lodash-es/isEmpty'; diff --git a/packages/framework/esm-styleguide/src/snackbars/active-snackbar.component.tsx b/packages/framework/esm-styleguide/src/snackbars/active-snackbar.component.tsx index 9be70a0c2..e7943cd80 100644 --- a/packages/framework/esm-styleguide/src/snackbars/active-snackbar.component.tsx +++ b/packages/framework/esm-styleguide/src/snackbars/active-snackbar.component.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState, useCallback } from 'react'; -import { Subject } from 'rxjs'; -import { Snackbar, SnackbarMeta } from './snackbar.component'; +import type { Subject } from 'rxjs'; +import type { SnackbarMeta } from './snackbar.component'; +import { Snackbar } from './snackbar.component'; interface ActiveSnackbarProps { subject: Subject; diff --git a/packages/framework/esm-styleguide/src/snackbars/index.tsx b/packages/framework/esm-styleguide/src/snackbars/index.tsx index 89f8c07aa..5b23397f7 100644 --- a/packages/framework/esm-styleguide/src/snackbars/index.tsx +++ b/packages/framework/esm-styleguide/src/snackbars/index.tsx @@ -3,7 +3,7 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { Subject } from 'rxjs'; -import { SnackbarDescriptor, SnackbarMeta } from './snackbar.component'; +import type { SnackbarDescriptor, SnackbarMeta } from './snackbar.component'; import ActiveSnackbars from './active-snackbar.component'; const snackbarsSubject = new Subject(); diff --git a/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx b/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx index d6fe7eac9..0484ee689 100644 --- a/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx +++ b/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx @@ -1,6 +1,7 @@ import React, { useCallback, useEffect, useState } from 'react'; -import { Subject } from 'rxjs'; -import { Toast, ToastNotificationMeta } from './toast.component'; +import type { Subject } from 'rxjs'; +import type { ToastNotificationMeta } from './toast.component'; +import { Toast } from './toast.component'; interface ActiveToastsProps { subject: Subject; diff --git a/packages/framework/esm-styleguide/src/toasts/index.tsx b/packages/framework/esm-styleguide/src/toasts/index.tsx index e681d8b36..85883d847 100644 --- a/packages/framework/esm-styleguide/src/toasts/index.tsx +++ b/packages/framework/esm-styleguide/src/toasts/index.tsx @@ -2,7 +2,7 @@ import React from 'react'; import { createRoot } from 'react-dom/client'; import { Subject } from 'rxjs'; -import { ToastDescriptor, ToastNotificationMeta } from './toast.component'; +import type { ToastDescriptor, ToastNotificationMeta } from './toast.component'; import ActiveToasts from './active-toasts.component'; import isEmpty from 'lodash-es/isEmpty'; diff --git a/packages/framework/esm-utils/src/omrs-dates.test.ts b/packages/framework/esm-utils/src/omrs-dates.test.ts index ece4ef1ee..0af1201ca 100644 --- a/packages/framework/esm-utils/src/omrs-dates.test.ts +++ b/packages/framework/esm-utils/src/omrs-dates.test.ts @@ -2,13 +2,13 @@ import { toOmrsIsoString, toDateObjectStrict, isOmrsDateStrict } from './omrs-da import dayjs from 'dayjs'; import timezoneMock from 'timezone-mock'; import { formatDate, formatDatetime, formatTime } from '.'; -import { i18n } from 'i18next'; +import type { i18n } from 'i18next'; window.i18next = { language: 'en' } as i18n; describe('Openmrs Dates', () => { it('converts js Date object to omrs date string version', () => { - var date = dayjs('2018-03-19T00:05:03.999+0300', 'YYYY-MM-DDTHH:mm:ss.SSSZZ').toDate(); + let date = dayjs('2018-03-19T00:05:03.999+0300', 'YYYY-MM-DDTHH:mm:ss.SSSZZ').toDate(); expect(toOmrsIsoString(date, true)).toEqual('2018-03-18T21:05:03.999+0000'); }); @@ -33,7 +33,7 @@ describe('Openmrs Dates', () => { }); it('converts js Date object to omrs date string version', () => { - var date = dayjs('2018-03-19T00:05:03.999+0300', 'YYYY-MM-DDTHH:mm:ss.SSSZZ').toDate(); + let date = dayjs('2018-03-19T00:05:03.999+0300', 'YYYY-MM-DDTHH:mm:ss.SSSZZ').toDate(); expect(toOmrsIsoString(date, true)).toEqual('2018-03-18T21:05:03.999+0000'); }); diff --git a/packages/framework/esm-utils/src/omrs-dates.ts b/packages/framework/esm-utils/src/omrs-dates.ts index dbe807844..b3e2d3c6f 100644 --- a/packages/framework/esm-utils/src/omrs-dates.ts +++ b/packages/framework/esm-utils/src/omrs-dates.ts @@ -2,7 +2,7 @@ * @module * @category Date and Time */ -import { i18n } from 'i18next'; +import type { i18n } from 'i18next'; import dayjs from 'dayjs'; import utc from 'dayjs/plugin/utc'; import isToday from 'dayjs/plugin/isToday'; diff --git a/packages/shell/esm-app-shell/src/apps.ts b/packages/shell/esm-app-shell/src/apps.ts index 5c1fb49a0..70503d1be 100644 --- a/packages/shell/esm-app-shell/src/apps.ts +++ b/packages/shell/esm-app-shell/src/apps.ts @@ -1,14 +1,11 @@ -import { - attach, - registerExtension, - defineConfigSchema, - importDynamic, +import type { RegisteredPageDefinition, ExtensionDefinition, OpenmrsAppRoutes, RouteDefinition, ExtensionRegistration, } from '@openmrs/esm-framework'; +import { attach, registerExtension, defineConfigSchema, importDynamic } from '@openmrs/esm-framework'; import { type ActivityFn, type LifeCycles, pathToActiveWhen, registerApplication } from 'single-spa'; import { emptyLifecycle, routeRegex } from './helpers'; diff --git a/packages/shell/esm-app-shell/src/helpers.ts b/packages/shell/esm-app-shell/src/helpers.ts index 1a87b00bc..54dd511db 100644 --- a/packages/shell/esm-app-shell/src/helpers.ts +++ b/packages/shell/esm-app-shell/src/helpers.ts @@ -1,4 +1,4 @@ -import { LifeCycles } from 'single-spa'; +import type { LifeCycles } from 'single-spa'; export const emptyLifecycle: LifeCycles = { bootstrap() { diff --git a/packages/shell/esm-app-shell/src/run.ts b/packages/shell/esm-app-shell/src/run.ts index b9c8559f5..80c10d376 100644 --- a/packages/shell/esm-app-shell/src/run.ts +++ b/packages/shell/esm-app-shell/src/run.ts @@ -1,4 +1,5 @@ import { start, triggerAppChange } from 'single-spa'; +import type { OpenmrsAppRoutes } from '@openmrs/esm-framework/src/internal'; import { setupApiModule, renderLoadingSpinner, @@ -33,7 +34,6 @@ import { importDynamic, canAccessStorage, localStorageRoutesPrefix, - OpenmrsAppRoutes, isOpenmrsAppRoutes, isOpenmrsRoutes, } from '@openmrs/esm-framework/src/internal'; diff --git a/packages/shell/esm-app-shell/src/service-worker/import-map-utils.ts b/packages/shell/esm-app-shell/src/service-worker/import-map-utils.ts index a6e089358..8462fd86f 100644 --- a/packages/shell/esm-app-shell/src/service-worker/import-map-utils.ts +++ b/packages/shell/esm-app-shell/src/service-worker/import-map-utils.ts @@ -1,6 +1,6 @@ import type { ImportMap } from '@openmrs/esm-globals'; import { buildManifestSuffix } from './constants'; -import { BuildManifest } from './types'; +import type { BuildManifest } from './types'; import flatten from 'lodash-es/flatten'; /** diff --git a/packages/shell/esm-app-shell/src/service-worker/message.ts b/packages/shell/esm-app-shell/src/service-worker/message.ts index cfae0bed0..53948149b 100644 --- a/packages/shell/esm-app-shell/src/service-worker/message.ts +++ b/packages/shell/esm-app-shell/src/service-worker/message.ts @@ -5,7 +5,8 @@ import type { } from '@openmrs/esm-offline'; import escapeRegExp from 'lodash-es/escapeRegExp'; import { cacheImportMapReferences } from './caching'; -import { DynamicRouteRegistration, ServiceWorkerDb } from './storage'; +import type { DynamicRouteRegistration } from './storage'; +import { ServiceWorkerDb } from './storage'; const messageHandlers = { onImportMapChanged, diff --git a/packages/shell/esm-app-shell/src/service-worker/routing.ts b/packages/shell/esm-app-shell/src/service-worker/routing.ts index 00c7c299a..adc5915b7 100644 --- a/packages/shell/esm-app-shell/src/service-worker/routing.ts +++ b/packages/shell/esm-app-shell/src/service-worker/routing.ts @@ -1,4 +1,4 @@ -import { RouteHandlerCallbackOptions } from 'workbox-core'; +import type { RouteHandlerCallbackOptions } from 'workbox-core'; import { registerRoute } from 'workbox-routing'; import { getOrCreateDefaultRouter } from 'workbox-routing/utils/getOrCreateDefaultRouter'; import { validMethods } from 'workbox-routing/utils/constants'; diff --git a/packages/shell/esm-app-shell/src/service-worker/storage.ts b/packages/shell/esm-app-shell/src/service-worker/storage.ts index 6c7e3a291..711063a82 100644 --- a/packages/shell/esm-app-shell/src/service-worker/storage.ts +++ b/packages/shell/esm-app-shell/src/service-worker/storage.ts @@ -1,5 +1,6 @@ import type { OmrsOfflineCachingStrategy } from '@openmrs/esm-offline'; -import Dexie, { Table } from 'dexie'; +import type { Table } from 'dexie'; +import Dexie from 'dexie'; /** * Contains information about dynamic route registrations. diff --git a/packages/shell/esm-app-shell/src/ui/breadcrumbs.tsx b/packages/shell/esm-app-shell/src/ui/breadcrumbs.tsx index 2ef18a921..bd1b8a7de 100644 --- a/packages/shell/esm-app-shell/src/ui/breadcrumbs.tsx +++ b/packages/shell/esm-app-shell/src/ui/breadcrumbs.tsx @@ -1,6 +1,7 @@ import React, { useEffect, useState } from 'react'; import { Breadcrumb, BreadcrumbItem, InlineLoading } from '@carbon/react'; -import { getBreadcrumbsFor, ConfigurableLink, BreadcrumbRegistration } from '@openmrs/esm-framework'; +import type { BreadcrumbRegistration } from '@openmrs/esm-framework'; +import { getBreadcrumbsFor, ConfigurableLink } from '@openmrs/esm-framework'; function getPath(path: string, params: Array) { const parts = [...params]; diff --git a/packages/tooling/openmrs/src/commands/assemble.ts b/packages/tooling/openmrs/src/commands/assemble.ts index f3088f717..b80a975cb 100644 --- a/packages/tooling/openmrs/src/commands/assemble.ts +++ b/packages/tooling/openmrs/src/commands/assemble.ts @@ -1,6 +1,6 @@ import { copyFile, mkdir, readFile, unlink, writeFile } from 'fs/promises'; import { resolve, dirname, basename } from 'path'; -import { prompt, Question } from 'inquirer'; +import { prompt, type Question } from 'inquirer'; import rimraf from 'rimraf'; import axios from 'axios'; import npmRegistryFetch from 'npm-registry-fetch'; @@ -54,7 +54,8 @@ async function readConfig( baseDir: dirname(config), ...JSON.parse(await readFile(config, 'utf8')), }; - case 'survey': + + case 'survey': { logInfo(`Loading available frontend modules ...`); const packages = await npmRegistryFetch @@ -103,6 +104,7 @@ async function readConfig( return prev; }, {}), }; + } } return { diff --git a/packages/tooling/openmrs/src/commands/debug.ts b/packages/tooling/openmrs/src/commands/debug.ts index c30a3b849..2132f7a6b 100644 --- a/packages/tooling/openmrs/src/commands/debug.ts +++ b/packages/tooling/openmrs/src/commands/debug.ts @@ -1,4 +1,5 @@ -import { ImportmapDeclaration, loadWebpackConfig, logInfo, logWarn } from '../utils'; +import type { ImportmapDeclaration } from '../utils'; +import { loadWebpackConfig, logInfo, logWarn } from '../utils'; export interface DebugArgs { port: number; diff --git a/packages/tooling/openmrs/src/commands/develop.ts b/packages/tooling/openmrs/src/commands/develop.ts index 29f6540be..ca2b92d7f 100644 --- a/packages/tooling/openmrs/src/commands/develop.ts +++ b/packages/tooling/openmrs/src/commands/develop.ts @@ -2,7 +2,8 @@ import express from 'express'; import { createProxyMiddleware } from 'http-proxy-middleware'; import { resolve } from 'path'; import { readFileSync } from 'fs'; -import { ImportmapDeclaration, logInfo, logWarn, removeTrailingSlash } from '../utils'; +import type { ImportmapDeclaration } from '../utils'; +import { logInfo, logWarn, removeTrailingSlash } from '../utils'; /* eslint-disable no-console */ diff --git a/packages/tooling/openmrs/src/utils/importmap.ts b/packages/tooling/openmrs/src/utils/importmap.ts index ba6879d1f..38c9d83cd 100644 --- a/packages/tooling/openmrs/src/utils/importmap.ts +++ b/packages/tooling/openmrs/src/utils/importmap.ts @@ -15,7 +15,11 @@ async function readImportmap(path: string, backend?: string, spaPath?: string) { if (backend && spaPath) { try { return await fetchRemoteImportmap(`${backend}${spaPath}importmap.json`); - } catch {} + } catch (e) { + logWarn( + `Could not read importmap from ${backend}${spaPath}importmap.json. Falling back to import map from https://dev3.openmrs.org/openmrs/spa/importmap.json: ${e}`, + ); + } } return fetchRemoteImportmap('https://dev3.openmrs.org/openmrs/spa/importmap.json'); @@ -31,7 +35,11 @@ async function readRoutes(path: string, backend?: string, spaPath?: string) { if (backend && spaPath) { try { return await fetchRemoteRoutes(`${backend}${spaPath}routes.registry.json`); - } catch {} + } catch (e) { + logWarn( + `Could not read routes registry from ${backend}${spaPath}routes.registry.json. Falling back to routes registry from https://dev3.openmrs.org/openmrs/spa/routes.registry.json: ${e}`, + ); + } } return fetchRemoteRoutes('https://dev3.openmrs.org/openmrs/spa/routes.registry.json'); diff --git a/packages/tooling/openmrs/src/utils/npmConfig.ts b/packages/tooling/openmrs/src/utils/npmConfig.ts index 62cc48d66..f01f74d02 100644 --- a/packages/tooling/openmrs/src/utils/npmConfig.ts +++ b/packages/tooling/openmrs/src/utils/npmConfig.ts @@ -1,4 +1,4 @@ -import npmRegistryFetch from 'npm-registry-fetch'; +import type npmRegistryFetch from 'npm-registry-fetch'; import npmConfig from '@pnpm/npm-conf'; /** diff --git a/packages/tooling/openmrs/src/utils/untar.ts b/packages/tooling/openmrs/src/utils/untar.ts index 6769da751..a4cbee581 100644 --- a/packages/tooling/openmrs/src/utils/untar.ts +++ b/packages/tooling/openmrs/src/utils/untar.ts @@ -1,6 +1,6 @@ import * as tar from 'tar'; import { createGunzip } from 'zlib'; -import { EventEmitter } from 'events'; +import type { EventEmitter } from 'events'; const TarParser = tar.Parse as any; diff --git a/yarn.lock b/yarn.lock index c1579a56a..fc2c6ba8b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5,6 +5,13 @@ __metadata: version: 8 cacheKey: 10 +"@aashutoshrathi/word-wrap@npm:^1.2.3": + version: 1.2.6 + resolution: "@aashutoshrathi/word-wrap@npm:1.2.6" + checksum: 6eebd12a5cd03cee38fcb915ef9f4ea557df6a06f642dfc7fe8eb4839eb5c9ca55a382f3604d52c14200b0c214c12af5e1f23d2a6d8e23ef2d016b105a9d6c0a + languageName: node + linkType: hard + "@adobe/css-tools@npm:^4.3.1": version: 4.3.2 resolution: "@adobe/css-tools@npm:4.3.2" @@ -55,15 +62,6 @@ __metadata: languageName: node linkType: hard -"@babel/code-frame@npm:7.12.11": - version: 7.12.11 - resolution: "@babel/code-frame@npm:7.12.11" - dependencies: - "@babel/highlight": "npm:^7.10.4" - checksum: d243f0b1e475f5953ae452f70c0b4bd47a106df59733631b9ae36fb9ad1ae068c3a11d936ed22117084ec7439e843a4b75700922b507aac723ad84a257ae94f9 - languageName: node - linkType: hard - "@babel/code-frame@npm:^7.0.0, @babel/code-frame@npm:^7.10.4, @babel/code-frame@npm:^7.12.13, @babel/code-frame@npm:^7.16.7, @babel/code-frame@npm:^7.18.6, @babel/code-frame@npm:^7.8.3": version: 7.18.6 resolution: "@babel/code-frame@npm:7.18.6" @@ -375,7 +373,7 @@ __metadata: languageName: node linkType: hard -"@babel/highlight@npm:^7.10.4, @babel/highlight@npm:^7.18.6": +"@babel/highlight@npm:^7.18.6": version: 7.18.6 resolution: "@babel/highlight@npm:7.18.6" dependencies: @@ -1298,17 +1296,7 @@ __metadata: languageName: node linkType: hard -"@babel/runtime-corejs3@npm:^7.10.2": - version: 7.19.4 - resolution: "@babel/runtime-corejs3@npm:7.19.4" - dependencies: - core-js-pure: "npm:^3.25.1" - regenerator-runtime: "npm:^0.13.4" - checksum: d9dd4896d3498eaeb1ddf44cd4ca49f98c59bdbbbba24439d894eafbd9ceb8f4b1d9583957f53c0c531df63e6ad281b8169ef8dfbb036c0fa808bb2501671d53 - languageName: node - linkType: hard - -"@babel/runtime@npm:^7.10.2, @babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.5, @babel/runtime@npm:^7.14.8, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.18.9, @babel/runtime@npm:^7.19.0, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": +"@babel/runtime@npm:^7.11.2, @babel/runtime@npm:^7.12.5, @babel/runtime@npm:^7.14.5, @babel/runtime@npm:^7.14.8, @babel/runtime@npm:^7.15.4, @babel/runtime@npm:^7.17.2, @babel/runtime@npm:^7.18.3, @babel/runtime@npm:^7.19.0, @babel/runtime@npm:^7.21.0, @babel/runtime@npm:^7.5.5, @babel/runtime@npm:^7.7.2, @babel/runtime@npm:^7.8.4, @babel/runtime@npm:^7.8.7, @babel/runtime@npm:^7.9.2": version: 7.23.2 resolution: "@babel/runtime@npm:7.23.2" dependencies: @@ -1549,20 +1537,45 @@ __metadata: languageName: node linkType: hard -"@eslint/eslintrc@npm:^0.4.3": - version: 0.4.3 - resolution: "@eslint/eslintrc@npm:0.4.3" +"@eslint-community/eslint-utils@npm:^4.2.0, @eslint-community/eslint-utils@npm:^4.4.0": + version: 4.4.0 + resolution: "@eslint-community/eslint-utils@npm:4.4.0" + dependencies: + eslint-visitor-keys: "npm:^3.3.0" + peerDependencies: + eslint: ^6.0.0 || ^7.0.0 || >=8.0.0 + checksum: 8d70bcdcd8cd279049183aca747d6c2ed7092a5cf0cf5916faac1ef37ffa74f0c245c2a3a3d3b9979d9dfdd4ca59257b4c5621db699d637b847a2c5e02f491c2 + languageName: node + linkType: hard + +"@eslint-community/regexpp@npm:^4.5.1, @eslint-community/regexpp@npm:^4.6.1": + version: 4.10.0 + resolution: "@eslint-community/regexpp@npm:4.10.0" + checksum: 8c36169c815fc5d726078e8c71a5b592957ee60d08c6470f9ce0187c8046af1a00afbda0a065cc40ff18d5d83f82aed9793c6818f7304a74a7488dc9f3ecbd42 + languageName: node + linkType: hard + +"@eslint/eslintrc@npm:^2.1.4": + version: 2.1.4 + resolution: "@eslint/eslintrc@npm:2.1.4" dependencies: ajv: "npm:^6.12.4" - debug: "npm:^4.1.1" - espree: "npm:^7.3.0" - globals: "npm:^13.9.0" - ignore: "npm:^4.0.6" + debug: "npm:^4.3.2" + espree: "npm:^9.6.0" + globals: "npm:^13.19.0" + ignore: "npm:^5.2.0" import-fresh: "npm:^3.2.1" - js-yaml: "npm:^3.13.1" - minimatch: "npm:^3.0.4" + js-yaml: "npm:^4.1.0" + minimatch: "npm:^3.1.2" strip-json-comments: "npm:^3.1.1" - checksum: d41857d255e75870a523b9d88a0367e576cd51acb87732dc5f1ec1857efa56ef82f1c46873fab1fc6944aafaf0a6902ce3eb47c8a55abf8de135558f6f5405f5 + checksum: 7a3b14f4b40fc1a22624c3f84d9f467a3d9ea1ca6e9a372116cb92507e485260359465b58e25bcb6c9981b155416b98c9973ad9b796053fd7b3f776a6946bce8 + languageName: node + linkType: hard + +"@eslint/js@npm:8.56.0": + version: 8.56.0 + resolution: "@eslint/js@npm:8.56.0" + checksum: 97a4b5ccf7e24f4d205a1fb0f21cdcd610348ecf685f6798a48dd41ba443f2c1eedd3050ff5a0b8f30b8cf6501ab512aa9b76e531db15e59c9ebaa41f3162e37 languageName: node linkType: hard @@ -1622,21 +1635,28 @@ __metadata: languageName: node linkType: hard -"@humanwhocodes/config-array@npm:^0.5.0": - version: 0.5.0 - resolution: "@humanwhocodes/config-array@npm:0.5.0" +"@humanwhocodes/config-array@npm:^0.11.13": + version: 0.11.13 + resolution: "@humanwhocodes/config-array@npm:0.11.13" dependencies: - "@humanwhocodes/object-schema": "npm:^1.2.0" + "@humanwhocodes/object-schema": "npm:^2.0.1" debug: "npm:^4.1.1" - minimatch: "npm:^3.0.4" - checksum: 478ad89d87e6a4aa7ea5626024f24efe0ec695e8d0393e22e5c495e1070fd562220ab74b5cd7a428882eec751126ec4e4e5883c2b1ec1740eb1af2bf4f3329f0 + minimatch: "npm:^3.0.5" + checksum: 9f655e1df7efa5a86822cd149ca5cef57240bb8ffd728f0c07cc682cc0a15c6bdce68425fbfd58f9b3e8b16f79b3fd8cb1e96b10c434c9a76f20b2a89f213272 languageName: node linkType: hard -"@humanwhocodes/object-schema@npm:^1.2.0": - version: 1.2.1 - resolution: "@humanwhocodes/object-schema@npm:1.2.1" - checksum: b48a8f87fcd5fdc4ac60a31a8bf710d19cc64556050575e6a35a4a48a8543cf8cde1598a65640ff2cdfbfd165b38f9db4fa3782bea7848eb585cc3db824002e6 +"@humanwhocodes/module-importer@npm:^1.0.1": + version: 1.0.1 + resolution: "@humanwhocodes/module-importer@npm:1.0.1" + checksum: e993950e346331e5a32eefb27948ecdee2a2c4ab3f072b8f566cd213ef485dd50a3ca497050608db91006f5479e43f91a439aef68d2a313bd3ded06909c7c5b3 + languageName: node + linkType: hard + +"@humanwhocodes/object-schema@npm:^2.0.1": + version: 2.0.1 + resolution: "@humanwhocodes/object-schema@npm:2.0.1" + checksum: dbddfd0465aecf92ed845ec30d06dba3f7bb2496d544b33b53dac7abc40370c0e46b8787b268d24a366730d5eeb5336ac88967232072a183905ee4abf7df4dab languageName: node linkType: hard @@ -2466,7 +2486,7 @@ __metadata: languageName: node linkType: hard -"@nodelib/fs.walk@npm:^1.2.3": +"@nodelib/fs.walk@npm:^1.2.3, @nodelib/fs.walk@npm:^1.2.8": version: 1.2.8 resolution: "@nodelib/fs.walk@npm:1.2.8" dependencies: @@ -2678,15 +2698,15 @@ __metadata: "@types/react-dom": "npm:^18.0.6" "@types/systemjs": "npm:^6.1.0" "@types/webpack-env": "npm:^1.16.4" - "@typescript-eslint/parser": "npm:^5.18.0" + "@typescript-eslint/eslint-plugin": "npm:^6.13.2" + "@typescript-eslint/parser": "npm:^6.13.2" autoprefixer: "npm:^10.4.2" classnames: "npm:^2.3.2" cross-env: "npm:7.0.2" dotenv: "npm:^16.0.3" - eslint: "npm:^7.10.0" - eslint-config-prettier: "npm:^6.11.0" - eslint-config-ts-react-important-stuff: "npm:^3.0.0" - eslint-plugin-prettier: "npm:^3.1.4" + eslint: "npm:^8.55.0" + eslint-config-prettier: "npm:^9.1.0" + eslint-plugin-prettier: "npm:^5.0.1" fake-indexeddb: "npm:^4.0.1" fork-ts-checker-webpack-plugin: "npm:^7.2.13" husky: "npm:^8.0.1" @@ -3096,6 +3116,20 @@ __metadata: languageName: unknown linkType: soft +"@pkgr/utils@npm:^2.4.2": + version: 2.4.2 + resolution: "@pkgr/utils@npm:2.4.2" + dependencies: + cross-spawn: "npm:^7.0.3" + fast-glob: "npm:^3.3.0" + is-glob: "npm:^4.0.3" + open: "npm:^9.1.0" + picocolors: "npm:^1.0.0" + tslib: "npm:^2.6.0" + checksum: f0b0b305a83bd65fac5637d28ad3e33f19194043e03ceef6b4e13d260bfa2678b73df76dc56ed906469ffe0494d4bd214e6b92ca80684f38547982edf982dd15 + languageName: node + linkType: hard + "@playwright/test@npm:1.40.1": version: 1.40.1 resolution: "@playwright/test@npm:1.40.1" @@ -4599,6 +4633,13 @@ __metadata: languageName: node linkType: hard +"@types/json-schema@npm:^7.0.12": + version: 7.0.15 + resolution: "@types/json-schema@npm:7.0.15" + checksum: 1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 + languageName: node + linkType: hard + "@types/lodash-es@npm:^4.17.5": version: 4.17.6 resolution: "@types/lodash-es@npm:4.17.6" @@ -4811,6 +4852,13 @@ __metadata: languageName: node linkType: hard +"@types/semver@npm:^7.5.0": + version: 7.5.6 + resolution: "@types/semver@npm:7.5.6" + checksum: e77282b17f74354e17e771c0035cccb54b94cc53d0433fa7e9ba9d23fd5d7edcd14b6c8b7327d58bbd89e83b1c5eda71dfe408e06b929007e2b89586e9b63459 + languageName: node + linkType: hard + "@types/serve-index@npm:^1.9.1": version: 1.9.1 resolution: "@types/serve-index@npm:1.9.1" @@ -4950,65 +4998,132 @@ __metadata: languageName: node linkType: hard -"@typescript-eslint/parser@npm:^5.18.0": - version: 5.40.0 - resolution: "@typescript-eslint/parser@npm:5.40.0" +"@typescript-eslint/eslint-plugin@npm:^6.13.2": + version: 6.15.0 + resolution: "@typescript-eslint/eslint-plugin@npm:6.15.0" dependencies: - "@typescript-eslint/scope-manager": "npm:5.40.0" - "@typescript-eslint/types": "npm:5.40.0" - "@typescript-eslint/typescript-estree": "npm:5.40.0" + "@eslint-community/regexpp": "npm:^4.5.1" + "@typescript-eslint/scope-manager": "npm:6.15.0" + "@typescript-eslint/type-utils": "npm:6.15.0" + "@typescript-eslint/utils": "npm:6.15.0" + "@typescript-eslint/visitor-keys": "npm:6.15.0" debug: "npm:^4.3.4" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.2.4" + natural-compare: "npm:^1.4.0" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" peerDependencies: - eslint: ^6.0.0 || ^7.0.0 || ^8.0.0 + "@typescript-eslint/parser": ^6.0.0 || ^6.0.0-alpha + eslint: ^7.0.0 || ^8.0.0 peerDependenciesMeta: typescript: optional: true - checksum: 63cb72f055d10d611d9618c43aff6b535538427c9fea8589b6d8ace8a3a32601febe4b60a06d2bf313b9c819a4e57be3c0ba69a5712fb3956b668dd456a3211b + checksum: 9020370c5e89b52b65ed2373c755d4b70f57ec7ebcf02d3e2f323f31ec81717af110d8e5f903b189b71e0a952f042e0fe2b637e77959c3102907efed4ba55512 languageName: node linkType: hard -"@typescript-eslint/scope-manager@npm:5.40.0": - version: 5.40.0 - resolution: "@typescript-eslint/scope-manager@npm:5.40.0" +"@typescript-eslint/parser@npm:^6.13.2": + version: 6.15.0 + resolution: "@typescript-eslint/parser@npm:6.15.0" dependencies: - "@typescript-eslint/types": "npm:5.40.0" - "@typescript-eslint/visitor-keys": "npm:5.40.0" - checksum: 15cbd31428888fc5704744ee8ee4b657c2919623add9682544af6bfbbca4be50d6efd446d751a6a8ac82f67347ea26b447211246fd8d40619e908fa2f9779cbe + "@typescript-eslint/scope-manager": "npm:6.15.0" + "@typescript-eslint/types": "npm:6.15.0" + "@typescript-eslint/typescript-estree": "npm:6.15.0" + "@typescript-eslint/visitor-keys": "npm:6.15.0" + debug: "npm:^4.3.4" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: fdd1f584e5068216c36a01e40750950ef309b36a522f6ecde36931690558a319960a702b4b4a806f335fb28ca99f8a07bb206571141550aaab1f6f40066f6605 languageName: node linkType: hard -"@typescript-eslint/types@npm:5.40.0": - version: 5.40.0 - resolution: "@typescript-eslint/types@npm:5.40.0" - checksum: a54e60f19e23177492f022b0e52b71b27514c6e303754c65371e7257f766e17d963dfb5a3a7c4d479eb05d7e00a8ceefcd1615856e83fb3f5aa216f8be8f3fc8 +"@typescript-eslint/scope-manager@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/scope-manager@npm:6.15.0" + dependencies: + "@typescript-eslint/types": "npm:6.15.0" + "@typescript-eslint/visitor-keys": "npm:6.15.0" + checksum: 168d783c06a99784362e2eaaa56396b31716ee785779707ef984c2abb3e822c56440473efc6580cb8b84b2da508731ad184a00b3618bc7f3f93d8243804f2fcf languageName: node linkType: hard -"@typescript-eslint/typescript-estree@npm:5.40.0": - version: 5.40.0 - resolution: "@typescript-eslint/typescript-estree@npm:5.40.0" +"@typescript-eslint/type-utils@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/type-utils@npm:6.15.0" dependencies: - "@typescript-eslint/types": "npm:5.40.0" - "@typescript-eslint/visitor-keys": "npm:5.40.0" + "@typescript-eslint/typescript-estree": "npm:6.15.0" + "@typescript-eslint/utils": "npm:6.15.0" + debug: "npm:^4.3.4" + ts-api-utils: "npm:^1.0.1" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + peerDependenciesMeta: + typescript: + optional: true + checksum: 8dabb355f09f57de8b46d726ad95a57593e5b87427dee5182afecb490624424afec02b69a27018b352dcb5f930eb391cb8cdc12cd60a93231d4f04e63e2f2c0b + languageName: node + linkType: hard + +"@typescript-eslint/types@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/types@npm:6.15.0" + checksum: d55de64d532c9016c922cc36b86ab661d7d64d942057486a0bca7a7db07fade95c3de59bfe364bc76ab538fb979ca2e4e6744c3acf8919a2d61e73cc7f544363 + languageName: node + linkType: hard + +"@typescript-eslint/typescript-estree@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/typescript-estree@npm:6.15.0" + dependencies: + "@typescript-eslint/types": "npm:6.15.0" + "@typescript-eslint/visitor-keys": "npm:6.15.0" debug: "npm:^4.3.4" globby: "npm:^11.1.0" is-glob: "npm:^4.0.3" - semver: "npm:^7.3.7" - tsutils: "npm:^3.21.0" + semver: "npm:^7.5.4" + ts-api-utils: "npm:^1.0.1" peerDependenciesMeta: typescript: optional: true - checksum: 86056ddf0515cb0ff7bb4d5ddd20d939bbfac9b2bb97edba689361d8d105bb915607d0a05ed127f97378c42e197c6cab52bca2294693bf69ff56309860534e81 + checksum: 920f7f3bfe463a9da943e1a686b7f13ac802a5e33be52f39ac711aa53a1e274dbe173b41bba05581c560fabfc3e1fadcfd81ab53a036afe25fb1a76651fcad7a + languageName: node + linkType: hard + +"@typescript-eslint/utils@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/utils@npm:6.15.0" + dependencies: + "@eslint-community/eslint-utils": "npm:^4.4.0" + "@types/json-schema": "npm:^7.0.12" + "@types/semver": "npm:^7.5.0" + "@typescript-eslint/scope-manager": "npm:6.15.0" + "@typescript-eslint/types": "npm:6.15.0" + "@typescript-eslint/typescript-estree": "npm:6.15.0" + semver: "npm:^7.5.4" + peerDependencies: + eslint: ^7.0.0 || ^8.0.0 + checksum: 7895240933ad28295508f8c4286a8b905550a35eda83a11ecf9511e53078e0af07e75a1872f1bc757f165b41fdc84616ea97c1e2e3bf80cff985935f25596228 languageName: node linkType: hard -"@typescript-eslint/visitor-keys@npm:5.40.0": - version: 5.40.0 - resolution: "@typescript-eslint/visitor-keys@npm:5.40.0" +"@typescript-eslint/visitor-keys@npm:6.15.0": + version: 6.15.0 + resolution: "@typescript-eslint/visitor-keys@npm:6.15.0" dependencies: - "@typescript-eslint/types": "npm:5.40.0" - eslint-visitor-keys: "npm:^3.3.0" - checksum: 073ebed1e5dc208ccc8acad47d29f431593c3370984b50cc4b5461c6a5059cd08cde1b6196955121dccc8c539206ce152ee39a6dfad753b0a4c27fee7df130ba + "@typescript-eslint/types": "npm:6.15.0" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 4641a829485f67a5d9d3558aa0d152e5ab57b468cfd9653168ce9a141e1f051730669a024505183b64f7a7e5d8f62533af4ebd4ad7366b551390461e9c45ec18 + languageName: node + linkType: hard + +"@ungap/structured-clone@npm:^1.2.0": + version: 1.2.0 + resolution: "@ungap/structured-clone@npm:1.2.0" + checksum: c6fe89a505e513a7592e1438280db1c075764793a2397877ff1351721fe8792a966a5359769e30242b3cd023f2efb9e63ca2ca88019d73b564488cc20e3eab12 languageName: node linkType: hard @@ -5260,7 +5375,7 @@ __metadata: languageName: node linkType: hard -"acorn-jsx@npm:^5.3.1": +"acorn-jsx@npm:^5.3.2": version: 5.3.2 resolution: "acorn-jsx@npm:5.3.2" peerDependencies: @@ -5276,21 +5391,21 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^7.4.0": - version: 7.4.1 - resolution: "acorn@npm:7.4.1" +"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2": + version: 8.10.0 + resolution: "acorn@npm:8.10.0" bin: acorn: bin/acorn - checksum: 8be2a40714756d713dfb62544128adce3b7102c6eb94bc312af196c2cc4af76e5b93079bd66b05e9ca31b35a9b0ce12171d16bc55f366cafdb794fdab9d753ec + checksum: 522310c20fdc3c271caed3caf0f06c51d61cb42267279566edd1d58e83dbc12eebdafaab666a0f0be1b7ad04af9c6bc2a6f478690a9e6391c3c8b165ada917dd languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2": - version: 8.10.0 - resolution: "acorn@npm:8.10.0" +"acorn@npm:^8.9.0": + version: 8.11.2 + resolution: "acorn@npm:8.11.2" bin: acorn: bin/acorn - checksum: 522310c20fdc3c271caed3caf0f06c51d61cb42267279566edd1d58e83dbc12eebdafaab666a0f0be1b7ad04af9c6bc2a6f478690a9e6391c3c8b165ada917dd + checksum: ff559b891382ad4cd34cc3c493511d0a7075a51f5f9f02a03440e92be3705679367238338566c5fbd3521ecadd565d29301bc8e16cb48379206bffbff3d72500 languageName: node linkType: hard @@ -5358,7 +5473,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^6.10.0, ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": +"ajv@npm:^6.12.2, ajv@npm:^6.12.4, ajv@npm:^6.12.5": version: 6.12.6 resolution: "ajv@npm:6.12.6" dependencies: @@ -5370,7 +5485,7 @@ __metadata: languageName: node linkType: hard -"ajv@npm:^8.0.0, ajv@npm:^8.0.1, ajv@npm:^8.6.0, ajv@npm:^8.8.0": +"ajv@npm:^8.0.0, ajv@npm:^8.6.0, ajv@npm:^8.8.0": version: 8.11.0 resolution: "ajv@npm:8.11.0" dependencies: @@ -5389,13 +5504,6 @@ __metadata: languageName: node linkType: hard -"ansi-colors@npm:^4.1.1": - version: 4.1.3 - resolution: "ansi-colors@npm:4.1.3" - checksum: 43d6e2fc7b1c6e4dc373de708ee76311ec2e0433e7e8bd3194e7ff123ea6a747428fc61afdcf5969da5be3a5f0fd054602bec56fc0ebe249ce2fcde6e649e3c2 - languageName: node - linkType: hard - "ansi-escapes@npm:^4.2.1": version: 4.3.2 resolution: "ansi-escapes@npm:4.3.2" @@ -5537,16 +5645,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^4.2.2": - version: 4.2.2 - resolution: "aria-query@npm:4.2.2" - dependencies: - "@babel/runtime": "npm:^7.10.2" - "@babel/runtime-corejs3": "npm:^7.10.2" - checksum: c9f0b85c1f948fe76c60bd1e08fc61a73c9d12cae046723d31b1dd0e029a1b23f8d3badea651453475fa3ff974c801fb96065ff58a1344d9bd7eef992096116e - languageName: node - linkType: hard - "aria-query@npm:^5.0.0": version: 5.0.2 resolution: "aria-query@npm:5.0.2" @@ -5578,19 +5676,6 @@ __metadata: languageName: node linkType: hard -"array-includes@npm:^3.1.5": - version: 3.1.5 - resolution: "array-includes@npm:3.1.5" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.4" - es-abstract: "npm:^1.19.5" - get-intrinsic: "npm:^1.1.1" - is-string: "npm:^1.0.7" - checksum: 006a776c24f4f6cfa7ef108d1703213aa52cee82161acb845c8f80862656019788c115c9f3a4469028fc220dd067a6884fe01107043611d8b3de69be8c1d9e9e - languageName: node - linkType: hard - "array-union@npm:^1.0.1": version: 1.0.2 resolution: "array-union@npm:1.0.2" @@ -5627,20 +5712,6 @@ __metadata: languageName: node linkType: hard -"ast-types-flow@npm:^0.0.7": - version: 0.0.7 - resolution: "ast-types-flow@npm:0.0.7" - checksum: 663b90e99b56ee2d7f736a6b6fff8b3c5404f28fa1860bb8d83ee5a9bff9e687520d0d6d9db6edff5a34fd4d3c0c11a3beb1cf75e43c9a880cca04371cc99808 - languageName: node - linkType: hard - -"astral-regex@npm:^2.0.0": - version: 2.0.0 - resolution: "astral-regex@npm:2.0.0" - checksum: 876231688c66400473ba505731df37ea436e574dd524520294cc3bbc54ea40334865e01fa0d074d74d036ee874ee7e62f486ea38bc421ee8e6a871c06f011766 - languageName: node - linkType: hard - "async@npm:^3.2.3": version: 3.2.4 resolution: "async@npm:3.2.4" @@ -5704,13 +5775,6 @@ __metadata: languageName: node linkType: hard -"axe-core@npm:^4.4.3": - version: 4.4.3 - resolution: "axe-core@npm:4.4.3" - checksum: e4f20413cbc08690b60af075d60157a88480865d0e0b4806b651dff21a7601a575625e9c25c74c2d10fef553b964cdbcec46d5aabc70b79764cf7b5af75e4b55 - languageName: node - linkType: hard - "axios@npm:^0.21.1": version: 0.21.4 resolution: "axios@npm:0.21.4" @@ -5720,13 +5784,6 @@ __metadata: languageName: node linkType: hard -"axobject-query@npm:^2.2.0": - version: 2.2.0 - resolution: "axobject-query@npm:2.2.0" - checksum: 25de4b5ba6b28f5856fab60d86ea20fea941586bc38f33c81b78d66cd7e9c5792a9b9a9e60a38407aa634e01fee6a34133fbbd1d1d3d24cc686de83c6bb1e634 - languageName: node - linkType: hard - "babel-jest@npm:^29.7.0": version: 29.7.0 resolution: "babel-jest@npm:29.7.0" @@ -5876,6 +5933,13 @@ __metadata: languageName: node linkType: hard +"big-integer@npm:^1.6.44": + version: 1.6.52 + resolution: "big-integer@npm:1.6.52" + checksum: 4bc6ae152a96edc9f95020f5fc66b13d26a9ad9a021225a9f0213f7e3dc44269f423aa8c42e19d6ac4a63bb2b22140b95d10be8f9ca7a6d9aa1b22b330d1f514 + languageName: node + linkType: hard + "big.js@npm:^5.2.2": version: 5.2.2 resolution: "big.js@npm:5.2.2" @@ -5936,6 +6000,15 @@ __metadata: languageName: node linkType: hard +"bplist-parser@npm:^0.2.0": + version: 0.2.0 + resolution: "bplist-parser@npm:0.2.0" + dependencies: + big-integer: "npm:^1.6.44" + checksum: 15d31c1b0c7e0fb384e96349453879a33609d92d91b55a9ccee04b4be4b0645f1c823253d73326a1a23104521fbc45c2dd97fb05adf61863841b68cbb2ca7a3d + languageName: node + linkType: hard + "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -6088,6 +6161,15 @@ __metadata: languageName: node linkType: hard +"bundle-name@npm:^3.0.0": + version: 3.0.0 + resolution: "bundle-name@npm:3.0.0" + dependencies: + run-applescript: "npm:^5.0.0" + checksum: edf2b1fbe6096ed32e7566947ace2ea937ee427391744d7510a2880c4b9a5b3543d3f6c551236a29e5c87d3195f8e2912516290e638c15bcbede7b37cc375615 + languageName: node + linkType: hard + "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -6892,13 +6974,6 @@ __metadata: languageName: node linkType: hard -"core-js-pure@npm:^3.25.1": - version: 3.25.5 - resolution: "core-js-pure@npm:3.25.5" - checksum: ebe171f733cf48767187617dbf63708b1fbe8fcada2e3150c1aaec7ad3ee10052c3f38236f2ddf678af22b9f5eadccba0a8833c7fe6e4185aa5eb2598c632703 - languageName: node - linkType: hard - "core-util-is@npm:~1.0.0": version: 1.0.3 resolution: "core-util-is@npm:1.0.3" @@ -7728,13 +7803,6 @@ __metadata: languageName: node linkType: hard -"damerau-levenshtein@npm:^1.0.8": - version: 1.0.8 - resolution: "damerau-levenshtein@npm:1.0.8" - checksum: f4eba1c90170f96be25d95fa3857141b5f81e254f7e4d530da929217b19990ea9a0390fc53d3c1cafac9152fda78e722ea4894f765cf6216be413b5af1fbf821 - languageName: node - linkType: hard - "data-uri-to-buffer@npm:^4.0.0": version: 4.0.0 resolution: "data-uri-to-buffer@npm:4.0.0" @@ -7785,7 +7853,7 @@ __metadata: languageName: node linkType: hard -"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.0.1, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.3, debug@npm:^4.3.4": +"debug@npm:4, debug@npm:4.3.4, debug@npm:^4.1.0, debug@npm:^4.1.1, debug@npm:^4.3.2, debug@npm:^4.3.3, debug@npm:^4.3.4": version: 4.3.4 resolution: "debug@npm:4.3.4" dependencies: @@ -7856,6 +7924,28 @@ __metadata: languageName: node linkType: hard +"default-browser-id@npm:^3.0.0": + version: 3.0.0 + resolution: "default-browser-id@npm:3.0.0" + dependencies: + bplist-parser: "npm:^0.2.0" + untildify: "npm:^4.0.0" + checksum: 279c7ad492542e5556336b6c254a4eaf31b2c63a5433265655ae6e47301197b6cfb15c595a6fdc6463b2ff8e1a1a1ed3cba56038a60e1527ba4ab1628c6b9941 + languageName: node + linkType: hard + +"default-browser@npm:^4.0.0": + version: 4.0.0 + resolution: "default-browser@npm:4.0.0" + dependencies: + bundle-name: "npm:^3.0.0" + default-browser-id: "npm:^3.0.0" + execa: "npm:^7.1.1" + titleize: "npm:^3.0.0" + checksum: 40c5af984799042b140300be5639c9742599bda76dc9eba5ac9ad5943c83dd36cebc4471eafcfddf8e0ec817166d5ba89d56f08e66a126c7c7908a179cead1a7 + languageName: node + linkType: hard + "default-gateway@npm:^6.0.3": version: 6.0.3 resolution: "default-gateway@npm:6.0.3" @@ -7883,6 +7973,13 @@ __metadata: languageName: node linkType: hard +"define-lazy-prop@npm:^3.0.0": + version: 3.0.0 + resolution: "define-lazy-prop@npm:3.0.0" + checksum: f28421cf9ee86eecaf5f3b8fe875f13d7009c2625e97645bfff7a2a49aca678270b86c39f9c32939e5ca7ab96b551377ed4139558c795e076774287ad3af1aa4 + languageName: node + linkType: hard + "define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": version: 1.1.4 resolution: "define-properties@npm:1.1.4" @@ -8285,13 +8382,6 @@ __metadata: languageName: node linkType: hard -"emoji-regex@npm:^9.2.2": - version: 9.2.2 - resolution: "emoji-regex@npm:9.2.2" - checksum: 915acf859cea7131dac1b2b5c9c8e35c4849e325a1d114c30adb8cd615970f6dca0e27f64f3a4949d7d6ed86ecd79a1c5c63f02e697513cddd7b5835c90948b8 - languageName: node - linkType: hard - "emojis-list@npm:^3.0.0": version: 3.0.0 resolution: "emojis-list@npm:3.0.0" @@ -8334,15 +8424,6 @@ __metadata: languageName: node linkType: hard -"enquirer@npm:^2.3.5": - version: 2.3.6 - resolution: "enquirer@npm:2.3.6" - dependencies: - ansi-colors: "npm:^4.1.1" - checksum: 751d14f037eb7683997e696fb8d5fe2675e0b0cde91182c128cf598acf3f5bd9005f35f7c2a9109e291140af496ebec237b6dac86067d59a9b44f3688107f426 - languageName: node - linkType: hard - "ensure-posix-path@npm:^1.1.0": version: 1.1.1 resolution: "ensure-posix-path@npm:1.1.1" @@ -8531,94 +8612,38 @@ __metadata: languageName: node linkType: hard -"eslint-config-important-stuff@npm:^1.1.0": - version: 1.1.0 - resolution: "eslint-config-important-stuff@npm:1.1.0" - checksum: 17986ec3fda91d9b2e08603817d2ff5aaba23651fb6c722e69df02290e31075f62349e16f4f03f1772f08c678904de51e82b735945f3a895f5d29aae7ef8b397 - languageName: node - linkType: hard - -"eslint-config-prettier@npm:^6.11.0": - version: 6.15.0 - resolution: "eslint-config-prettier@npm:6.15.0" - dependencies: - get-stdin: "npm:^6.0.0" +"eslint-config-prettier@npm:^9.1.0": + version: 9.1.0 + resolution: "eslint-config-prettier@npm:9.1.0" peerDependencies: - eslint: ">=3.14.1" + eslint: ">=7.0.0" bin: - eslint-config-prettier-check: bin/cli.js - checksum: 8648ec4259066f47f0bf5b75eea6bfe67a45a7eac065a17355638ea91cb09188cbda8b9562c009424268a7ee829e7ef3418edb90327ef5ff21c0aa24e734a6ea - languageName: node - linkType: hard - -"eslint-config-react-important-stuff@npm:^3.0.0": - version: 3.0.0 - resolution: "eslint-config-react-important-stuff@npm:3.0.0" - dependencies: - eslint-config-important-stuff: "npm:^1.1.0" - eslint-plugin-jsx-a11y: "npm:^6.3.1" - eslint-plugin-react-hooks: "npm:^4.0.8" - checksum: 542547f0be617d27d828cf8d55ac3c640fa928a18b223b5865d943c575999ec8905a2bc581d184fa59f7b633f8b7d14b362ba6d9d5686d4406f03a68c4d534b7 + eslint-config-prettier: bin/cli.js + checksum: 411e3b3b1c7aa04e3e0f20d561271b3b909014956c4dba51c878bf1a23dbb8c800a3be235c46c4732c70827276e540b6eed4636d9b09b444fd0a8e07f0fcd830 languageName: node linkType: hard -"eslint-config-ts-react-important-stuff@npm:^3.0.0": - version: 3.0.0 - resolution: "eslint-config-ts-react-important-stuff@npm:3.0.0" - dependencies: - eslint-config-react-important-stuff: "npm:^3.0.0" - checksum: 47e60bd7352aa3c2d5d16af63204ec7b71681a8a61cefcb13165f0624f063030f5c5d98d6bc4704e9f7df1e104c868997727c3716eed3baeb2082d6801645efc - languageName: node - linkType: hard - -"eslint-plugin-jsx-a11y@npm:^6.3.1": - version: 6.6.1 - resolution: "eslint-plugin-jsx-a11y@npm:6.6.1" - dependencies: - "@babel/runtime": "npm:^7.18.9" - aria-query: "npm:^4.2.2" - array-includes: "npm:^3.1.5" - ast-types-flow: "npm:^0.0.7" - axe-core: "npm:^4.4.3" - axobject-query: "npm:^2.2.0" - damerau-levenshtein: "npm:^1.0.8" - emoji-regex: "npm:^9.2.2" - has: "npm:^1.0.3" - jsx-ast-utils: "npm:^3.3.2" - language-tags: "npm:^1.0.5" - minimatch: "npm:^3.1.2" - semver: "npm:^6.3.0" - peerDependencies: - eslint: ^3 || ^4 || ^5 || ^6 || ^7 || ^8 - checksum: e904ef8a914e86c6624e6126116467a5fba975bc52ffeaa381ee914d888fc3f272e6b3daa6eb398d1562673d3ce76a58676e2a105be7af4b5112bb97dcc06099 - languageName: node - linkType: hard - -"eslint-plugin-prettier@npm:^3.1.4": - version: 3.4.1 - resolution: "eslint-plugin-prettier@npm:3.4.1" +"eslint-plugin-prettier@npm:^5.0.1": + version: 5.1.0 + resolution: "eslint-plugin-prettier@npm:5.1.0" dependencies: prettier-linter-helpers: "npm:^1.0.0" + synckit: "npm:^0.8.5" peerDependencies: - eslint: ">=5.0.0" - prettier: ">=1.13.0" + "@types/eslint": ">=8.0.0" + eslint: ">=8.0.0" + eslint-config-prettier: "*" + prettier: ">=3.0.0" peerDependenciesMeta: + "@types/eslint": + optional: true eslint-config-prettier: optional: true - checksum: d7ab93df9a93f0afb9fa9c9c3cf30479075e1b56303c82ed6efbfff30c2d3d3741537b490c2b517d501bfa97a3d8d0269a1ab4b6fa741a6e966e5811efbfe8b8 + checksum: 6db5a9dade4157092e87eb876508c8b510ab9bb0e4592536933d84b351b99d7c30259bad8ba76057b5c739fa62005d26f3008745438dc785060dbaae741f7fa5 languageName: node linkType: hard -"eslint-plugin-react-hooks@npm:^4.0.8": - version: 4.6.0 - resolution: "eslint-plugin-react-hooks@npm:4.6.0" - peerDependencies: - eslint: ^3.0.0 || ^4.0.0 || ^5.0.0 || ^6.0.0 || ^7.0.0 || ^8.0.0-0 - checksum: 3c63134e056a6d98d66e2c475c81f904169db817e89316d14e36269919e31f4876a2588aa0e466ec8ef160465169c627fe823bfdaae7e213946584e4a165a3ac - languageName: node - linkType: hard - -"eslint-scope@npm:5.1.1, eslint-scope@npm:^5.1.1": +"eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" dependencies: @@ -8628,26 +8653,13 @@ __metadata: languageName: node linkType: hard -"eslint-utils@npm:^2.1.0": - version: 2.1.0 - resolution: "eslint-utils@npm:2.1.0" +"eslint-scope@npm:^7.2.2": + version: 7.2.2 + resolution: "eslint-scope@npm:7.2.2" dependencies: - eslint-visitor-keys: "npm:^1.1.0" - checksum: a7e43a5154a16a90c021cabeb160c3668cccbcf6474ccb2a7d7762698582398f3b938c5330909b858ef7c21182edfc9786dbf89ed7b294f51b7659a378bf7cec - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^1.1.0, eslint-visitor-keys@npm:^1.3.0": - version: 1.3.0 - resolution: "eslint-visitor-keys@npm:1.3.0" - checksum: 595ab230e0fcb52f86ba0986a9a473b9fcae120f3729b43f1157f88f27f8addb1e545c4e3d444185f2980e281ca15be5ada6f65b4599eec227cf30e41233b762 - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^2.0.0": - version: 2.1.0 - resolution: "eslint-visitor-keys@npm:2.1.0" - checksum: db4547eef5039122d518fa307e938ceb8589da5f6e8f5222efaf14dd62f748ce82e2d2becd3ff9412a50350b726bda95dbea8515a471074547daefa58aee8735 + esrecurse: "npm:^4.3.0" + estraverse: "npm:^5.2.0" + checksum: 5c660fb905d5883ad018a6fea2b49f3cb5b1cbf2cd4bd08e98646e9864f9bc2c74c0839bed2d292e90a4a328833accc197c8f0baed89cbe8d605d6f918465491 languageName: node linkType: hard @@ -8658,64 +8670,69 @@ __metadata: languageName: node linkType: hard -"eslint@npm:^7.10.0": - version: 7.32.0 - resolution: "eslint@npm:7.32.0" +"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": + version: 3.4.3 + resolution: "eslint-visitor-keys@npm:3.4.3" + checksum: 3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b + languageName: node + linkType: hard + +"eslint@npm:^8.55.0": + version: 8.56.0 + resolution: "eslint@npm:8.56.0" dependencies: - "@babel/code-frame": "npm:7.12.11" - "@eslint/eslintrc": "npm:^0.4.3" - "@humanwhocodes/config-array": "npm:^0.5.0" - ajv: "npm:^6.10.0" + "@eslint-community/eslint-utils": "npm:^4.2.0" + "@eslint-community/regexpp": "npm:^4.6.1" + "@eslint/eslintrc": "npm:^2.1.4" + "@eslint/js": "npm:8.56.0" + "@humanwhocodes/config-array": "npm:^0.11.13" + "@humanwhocodes/module-importer": "npm:^1.0.1" + "@nodelib/fs.walk": "npm:^1.2.8" + "@ungap/structured-clone": "npm:^1.2.0" + ajv: "npm:^6.12.4" chalk: "npm:^4.0.0" cross-spawn: "npm:^7.0.2" - debug: "npm:^4.0.1" + debug: "npm:^4.3.2" doctrine: "npm:^3.0.0" - enquirer: "npm:^2.3.5" escape-string-regexp: "npm:^4.0.0" - eslint-scope: "npm:^5.1.1" - eslint-utils: "npm:^2.1.0" - eslint-visitor-keys: "npm:^2.0.0" - espree: "npm:^7.3.1" - esquery: "npm:^1.4.0" + eslint-scope: "npm:^7.2.2" + eslint-visitor-keys: "npm:^3.4.3" + espree: "npm:^9.6.1" + esquery: "npm:^1.4.2" esutils: "npm:^2.0.2" fast-deep-equal: "npm:^3.1.3" file-entry-cache: "npm:^6.0.1" - functional-red-black-tree: "npm:^1.0.1" - glob-parent: "npm:^5.1.2" - globals: "npm:^13.6.0" - ignore: "npm:^4.0.6" - import-fresh: "npm:^3.0.0" + find-up: "npm:^5.0.0" + glob-parent: "npm:^6.0.2" + globals: "npm:^13.19.0" + graphemer: "npm:^1.4.0" + ignore: "npm:^5.2.0" imurmurhash: "npm:^0.1.4" is-glob: "npm:^4.0.0" - js-yaml: "npm:^3.13.1" + is-path-inside: "npm:^3.0.3" + js-yaml: "npm:^4.1.0" json-stable-stringify-without-jsonify: "npm:^1.0.1" levn: "npm:^0.4.1" lodash.merge: "npm:^4.6.2" - minimatch: "npm:^3.0.4" + minimatch: "npm:^3.1.2" natural-compare: "npm:^1.4.0" - optionator: "npm:^0.9.1" - progress: "npm:^2.0.0" - regexpp: "npm:^3.1.0" - semver: "npm:^7.2.1" - strip-ansi: "npm:^6.0.0" - strip-json-comments: "npm:^3.1.0" - table: "npm:^6.0.9" + optionator: "npm:^0.9.3" + strip-ansi: "npm:^6.0.1" text-table: "npm:^0.2.0" - v8-compile-cache: "npm:^2.0.3" bin: eslint: bin/eslint.js - checksum: 2015a72bc4c49a933fc7bd707bdb61b0386542c9e23d28be79434b5fd914f14355a4565a29fdcd1c69a8a3682cf20b4f2aed6b60e294b0b0d98ace69138c3a02 + checksum: ef6193c6e4cef20774b985a5cc2fd4bf6d3c4decd423117cbc4a0196617861745db291217ad3c537bc3a160650cca965bc818f55e1f3e446af1fcb293f9940a5 languageName: node linkType: hard -"espree@npm:^7.3.0, espree@npm:^7.3.1": - version: 7.3.1 - resolution: "espree@npm:7.3.1" +"espree@npm:^9.6.0, espree@npm:^9.6.1": + version: 9.6.1 + resolution: "espree@npm:9.6.1" dependencies: - acorn: "npm:^7.4.0" - acorn-jsx: "npm:^5.3.1" - eslint-visitor-keys: "npm:^1.3.0" - checksum: 7cf230d4d726f6e2c53925566ef96e78a5656eb05adbb6cd493f863341e532b491b035db7a4ce292b70243bb727722acff98b66ae751888ee51791d8389c6819 + acorn: "npm:^8.9.0" + acorn-jsx: "npm:^5.3.2" + eslint-visitor-keys: "npm:^3.4.1" + checksum: 255ab260f0d711a54096bdeda93adff0eadf02a6f9b92f02b323e83a2b7fc258797919437ad331efec3930475feb0142c5ecaaf3cdab4befebd336d47d3f3134 languageName: node linkType: hard @@ -8729,12 +8746,12 @@ __metadata: languageName: node linkType: hard -"esquery@npm:^1.4.0": - version: 1.4.0 - resolution: "esquery@npm:1.4.0" +"esquery@npm:^1.4.2": + version: 1.5.0 + resolution: "esquery@npm:1.5.0" dependencies: estraverse: "npm:^5.1.0" - checksum: 25b571ec54f186521819be48cd12643f9f5bdef6be9679161a48dec9cfd478764970a77ef563a516cf1f0f05e7e490e3ff2d514715b86cb8d03329cbb56ae4a8 + checksum: e65fcdfc1e0ff5effbf50fb4f31ea20143ae5df92bb2e4953653d8d40aa4bc148e0d06117a592ce4ea53eeab1dafdfded7ea7e22a5be87e82d73757329a1b01d languageName: node linkType: hard @@ -8837,6 +8854,23 @@ __metadata: languageName: node linkType: hard +"execa@npm:^7.1.1": + version: 7.2.0 + resolution: "execa@npm:7.2.0" + dependencies: + cross-spawn: "npm:^7.0.3" + get-stream: "npm:^6.0.1" + human-signals: "npm:^4.3.0" + is-stream: "npm:^3.0.0" + merge-stream: "npm:^2.0.0" + npm-run-path: "npm:^5.1.0" + onetime: "npm:^6.0.0" + signal-exit: "npm:^3.0.7" + strip-final-newline: "npm:^3.0.0" + checksum: 473feff60f9d4dbe799225948de48b5158c1723021d19c4b982afe37bcd111ae84e1b4c9dfe967fae5101b0894b1a62e4dd564a286dfa3e46d7b0cfdbf7fe62b + languageName: node + linkType: hard + "exif-parser@npm:^0.1.12": version: 0.1.12 resolution: "exif-parser@npm:0.1.12" @@ -8964,6 +8998,19 @@ __metadata: languageName: node linkType: hard +"fast-glob@npm:^3.3.0": + version: 3.3.2 + resolution: "fast-glob@npm:3.3.2" + dependencies: + "@nodelib/fs.stat": "npm:^2.0.2" + "@nodelib/fs.walk": "npm:^1.2.3" + glob-parent: "npm:^5.1.2" + merge2: "npm:^1.3.0" + micromatch: "npm:^4.0.4" + checksum: 222512e9315a0efca1276af9adb2127f02105d7288fa746145bf45e2716383fb79eb983c89601a72a399a56b7c18d38ce70457c5466218c5f13fad957cee16df + languageName: node + linkType: hard + "fast-json-stable-stringify@npm:^2.0.0, fast-json-stable-stringify@npm:^2.1.0": version: 2.1.0 resolution: "fast-json-stable-stringify@npm:2.1.0" @@ -9101,6 +9148,16 @@ __metadata: languageName: node linkType: hard +"find-up@npm:^5.0.0": + version: 5.0.0 + resolution: "find-up@npm:5.0.0" + dependencies: + locate-path: "npm:^6.0.0" + path-exists: "npm:^4.0.0" + checksum: 07955e357348f34660bde7920783204ff5a26ac2cafcaa28bace494027158a97b9f56faaf2d89a6106211a8174db650dd9f503f9c0d526b1202d5554a00b9095 + languageName: node + linkType: hard + "flat-cache@npm:^3.0.4": version: 3.0.4 resolution: "flat-cache@npm:3.0.4" @@ -9398,13 +9455,6 @@ __metadata: languageName: node linkType: hard -"functional-red-black-tree@npm:^1.0.1": - version: 1.0.1 - resolution: "functional-red-black-tree@npm:1.0.1" - checksum: debe73e92204341d1fa5f89614e44284d3add26dee660722978d8c50829170f87d1c74768f68c251d215ae461c11db7bac13101c77f4146ff051da75466f7a12 - languageName: node - linkType: hard - "functions-have-names@npm:^1.2.2, functions-have-names@npm:^1.2.3": version: 1.2.3 resolution: "functions-have-names@npm:1.2.3" @@ -9493,14 +9543,7 @@ __metadata: languageName: node linkType: hard -"get-stdin@npm:^6.0.0": - version: 6.0.0 - resolution: "get-stdin@npm:6.0.0" - checksum: 593f6fb4fff4c8d49ec93a07c430c1edc6bd4fe7e429d222b5da2f367276a98809af9e90467ad88a2d83722ff95b9b35bbaba02b56801421c5e3668173fe12b4 - languageName: node - linkType: hard - -"get-stream@npm:^6.0.0": +"get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": version: 6.0.1 resolution: "get-stream@npm:6.0.1" checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 @@ -9553,7 +9596,7 @@ __metadata: languageName: node linkType: hard -"glob-parent@npm:^6.0.1": +"glob-parent@npm:^6.0.1, glob-parent@npm:^6.0.2": version: 6.0.2 resolution: "glob-parent@npm:6.0.2" dependencies: @@ -9631,12 +9674,12 @@ __metadata: languageName: node linkType: hard -"globals@npm:^13.6.0, globals@npm:^13.9.0": - version: 13.17.0 - resolution: "globals@npm:13.17.0" +"globals@npm:^13.19.0": + version: 13.24.0 + resolution: "globals@npm:13.24.0" dependencies: type-fest: "npm:^0.20.2" - checksum: 1e3e0ede067a99ca16bdeb2fe241d5f8f2458d1bf64b8c17986b17e42ab0760c9a4bc190f2ae4359337d63de1d96ed07b93b29c47282f724f1a56b958c5df6f0 + checksum: 62c5b1997d06674fc7191d3e01e324d3eda4d65ac9cc4e78329fa3b5c4fd42a0e1c8722822497a6964eee075255ce21ccf1eec2d83f92ef3f06653af4d0ee28e languageName: node linkType: hard @@ -9696,6 +9739,13 @@ __metadata: languageName: node linkType: hard +"graphemer@npm:^1.4.0": + version: 1.4.0 + resolution: "graphemer@npm:1.4.0" + checksum: 6dd60dba97007b21e3a829fab3f771803cc1292977fe610e240ea72afd67e5690ac9eeaafc4a99710e78962e5936ab5a460787c2a1180f1cb0ccfac37d29f897 + languageName: node + linkType: hard + "gulp-sort@npm:^2.0.0": version: 2.0.0 resolution: "gulp-sort@npm:2.0.0" @@ -10101,6 +10151,13 @@ __metadata: languageName: node linkType: hard +"human-signals@npm:^4.3.0": + version: 4.3.1 + resolution: "human-signals@npm:4.3.1" + checksum: fa59894c358fe9f2b5549be2fb083661d5e1dff618d3ac70a49ca73495a72e873fbf6c0878561478e521e17d498292746ee391791db95ffe5747bfb5aef8765b + languageName: node + linkType: hard + "human-signals@npm:^5.0.0": version: 5.0.0 resolution: "human-signals@npm:5.0.0" @@ -10231,13 +10288,6 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^4.0.6": - version: 4.0.6 - resolution: "ignore@npm:4.0.6" - checksum: e04d6bd60d9da12cfe8896acf470824172843dddc25a9be0726199d5e031254634a69ce8479a82f194154b9b28cb3b08bb7a53e56f7f7eba2663e04791e74742 - languageName: node - linkType: hard - "ignore@npm:^5.2.0": version: 5.2.0 resolution: "ignore@npm:5.2.0" @@ -10245,6 +10295,13 @@ __metadata: languageName: node linkType: hard +"ignore@npm:^5.2.4": + version: 5.3.0 + resolution: "ignore@npm:5.3.0" + checksum: 51594355cea4c6ad6b28b3b85eb81afa7b988a1871feefd7062baf136c95aa06760ee934fa9590e43d967bd377ce84a4cf6135fbeb6063e063f1182a0e9a3bcd + languageName: node + linkType: hard + "image-q@npm:^4.0.0": version: 4.0.0 resolution: "image-q@npm:4.0.0" @@ -10271,7 +10328,7 @@ __metadata: languageName: node linkType: hard -"import-fresh@npm:^3.0.0, import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1": +"import-fresh@npm:^3.1.0, import-fresh@npm:^3.2.1": version: 3.3.0 resolution: "import-fresh@npm:3.3.0" dependencies: @@ -10609,6 +10666,15 @@ __metadata: languageName: node linkType: hard +"is-docker@npm:^3.0.0": + version: 3.0.0 + resolution: "is-docker@npm:3.0.0" + bin: + is-docker: cli.js + checksum: b698118f04feb7eaf3338922bd79cba064ea54a1c3db6ec8c0c8d8ee7613e7e5854d802d3ef646812a8a3ace81182a085dfa0a71cc68b06f3fa794b9783b3c90 + languageName: node + linkType: hard + "is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -10671,6 +10737,17 @@ __metadata: languageName: node linkType: hard +"is-inside-container@npm:^1.0.0": + version: 1.0.0 + resolution: "is-inside-container@npm:1.0.0" + dependencies: + is-docker: "npm:^3.0.0" + bin: + is-inside-container: cli.js + checksum: c50b75a2ab66ab3e8b92b3bc534e1ea72ca25766832c0623ac22d134116a98bcf012197d1caabe1d1c4bd5f84363d4aa5c36bb4b585fbcaf57be172cd10a1a03 + languageName: node + linkType: hard + "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -10761,6 +10838,13 @@ __metadata: languageName: node linkType: hard +"is-path-inside@npm:^3.0.3": + version: 3.0.3 + resolution: "is-path-inside@npm:3.0.3" + checksum: abd50f06186a052b349c15e55b182326f1936c89a78bf6c8f2b707412517c097ce04bc49a0ca221787bc44e1049f51f09a2ffb63d22899051988d3a618ba13e9 + languageName: node + linkType: hard + "is-plain-obj@npm:^3.0.0": version: 3.0.0 resolution: "is-plain-obj@npm:3.0.0" @@ -11572,7 +11656,7 @@ __metadata: languageName: node linkType: hard -"js-yaml@npm:4.1.0": +"js-yaml@npm:4.1.0, js-yaml@npm:^4.1.0": version: 4.1.0 resolution: "js-yaml@npm:4.1.0" dependencies: @@ -11756,16 +11840,6 @@ __metadata: languageName: node linkType: hard -"jsx-ast-utils@npm:^3.3.2": - version: 3.3.3 - resolution: "jsx-ast-utils@npm:3.3.3" - dependencies: - array-includes: "npm:^3.1.5" - object.assign: "npm:^4.1.3" - checksum: c85f6f239593e09d8445a7e43412234304addf4bfb5d2114dc19f5ce27dfe3a8f8b12a50ff74e94606d0ad48cf1d5aff2381c939446b3fe48a5d433bb52ccb29 - languageName: node - linkType: hard - "kind-of@npm:^6.0.2": version: 6.0.3 resolution: "kind-of@npm:6.0.3" @@ -11787,22 +11861,6 @@ __metadata: languageName: node linkType: hard -"language-subtag-registry@npm:~0.3.2": - version: 0.3.22 - resolution: "language-subtag-registry@npm:0.3.22" - checksum: 5591f4abd775d1ab5945355a5ba894327d2d94c900607bdb69aac1bc5bb921dbeeeb5f616df95e8c0ae875501d19c1cfa0e852ece822121e95048deb34f2b4d2 - languageName: node - linkType: hard - -"language-tags@npm:^1.0.5": - version: 1.0.5 - resolution: "language-tags@npm:1.0.5" - dependencies: - language-subtag-registry: "npm:~0.3.2" - checksum: 2161292ddae73ff2f5a15fd2d753b21096b81324337dff4ad78d702c63210d5beb18892cd53a3455ee6e88065807c8e285e82c40503678951d2071d101a473b4 - languageName: node - linkType: hard - "lazystream@npm:^1.0.0": version: 1.0.1 resolution: "lazystream@npm:1.0.1" @@ -11946,6 +12004,15 @@ __metadata: languageName: node linkType: hard +"locate-path@npm:^6.0.0": + version: 6.0.0 + resolution: "locate-path@npm:6.0.0" + dependencies: + p-locate: "npm:^5.0.0" + checksum: 72eb661788a0368c099a184c59d2fee760b3831c9c1c33955e8a19ae4a21b4116e53fa736dc086cdeb9fce9f7cc508f2f92d2d3aae516f133e16a2bb59a39f5a + languageName: node + linkType: hard + "lodash-es@npm:4.17.21, lodash-es@npm:^4.17.21": version: 4.17.21 resolution: "lodash-es@npm:4.17.21" @@ -12016,13 +12083,6 @@ __metadata: languageName: node linkType: hard -"lodash.truncate@npm:^4.4.2": - version: 4.4.2 - resolution: "lodash.truncate@npm:4.4.2" - checksum: 7a495616121449e5d2288c606b1025d42ab9979e8c93ba885e5c5802ffd4f1ebad4428c793ccc12f73e73237e85a9f5b67dd6415757546fbd5a4653ba83e25ac - languageName: node - linkType: hard - "lodash.uniq@npm:^4.5.0": version: 4.5.0 resolution: "lodash.uniq@npm:4.5.0" @@ -12346,7 +12406,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": +"minimatch@npm:^3.0.2, minimatch@npm:^3.0.4, minimatch@npm:^3.0.5, minimatch@npm:^3.1.1, minimatch@npm:^3.1.2": version: 3.1.2 resolution: "minimatch@npm:3.1.2" dependencies: @@ -12949,7 +13009,7 @@ __metadata: languageName: node linkType: hard -"object.assign@npm:^4.0.4, object.assign@npm:^4.1.0, object.assign@npm:^4.1.3, object.assign@npm:^4.1.4": +"object.assign@npm:^4.0.4, object.assign@npm:^4.1.0, object.assign@npm:^4.1.4": version: 4.1.4 resolution: "object.assign@npm:4.1.4" dependencies: @@ -13052,6 +13112,18 @@ __metadata: languageName: node linkType: hard +"open@npm:^9.1.0": + version: 9.1.0 + resolution: "open@npm:9.1.0" + dependencies: + default-browser: "npm:^4.0.0" + define-lazy-prop: "npm:^3.0.0" + is-inside-container: "npm:^1.0.0" + is-wsl: "npm:^2.2.0" + checksum: b45bcc7a6795804a2f560f0ca9f5e5344114bc40754d10c28a811c0c8f7027356979192931a6a7df2ab9e5bab3058988c99ae55f4fb71db2ce9fc77c40f619aa + languageName: node + linkType: hard + "opener@npm:^1.5.2": version: 1.5.2 resolution: "opener@npm:1.5.2" @@ -13122,17 +13194,17 @@ __metadata: languageName: node linkType: hard -"optionator@npm:^0.9.1": - version: 0.9.1 - resolution: "optionator@npm:0.9.1" +"optionator@npm:^0.9.3": + version: 0.9.3 + resolution: "optionator@npm:0.9.3" dependencies: + "@aashutoshrathi/word-wrap": "npm:^1.2.3" deep-is: "npm:^0.1.3" fast-levenshtein: "npm:^2.0.6" levn: "npm:^0.4.1" prelude-ls: "npm:^1.2.1" type-check: "npm:^0.4.0" - word-wrap: "npm:^1.2.3" - checksum: 19cfb625ba3cafd99c204744595a8b5111491632d379be341a8286c53a0101adac6f7ca9be4319ccecaaf5d43a55e65dde8b434620726032472833d958d43698 + checksum: fa28d3016395974f7fc087d6bbf0ac7f58ac3489f4f202a377e9c194969f329a7b88c75f8152b33fb08794a30dcd5c079db6bb465c28151357f113d80bbf67da languageName: node linkType: hard @@ -13179,6 +13251,15 @@ __metadata: languageName: node linkType: hard +"p-locate@npm:^5.0.0": + version: 5.0.0 + resolution: "p-locate@npm:5.0.0" + dependencies: + p-limit: "npm:^3.0.2" + checksum: 1623088f36cf1cbca58e9b61c4e62bf0c60a07af5ae1ca99a720837356b5b6c5ba3eb1b2127e47a06865fee59dd0453cad7cc844cda9d5a62ac1a5a51b7c86d3 + languageName: node + linkType: hard + "p-map@npm:^2.0.0": version: 2.1.0 resolution: "p-map@npm:2.1.0" @@ -14374,13 +14455,6 @@ __metadata: languageName: node linkType: hard -"progress@npm:^2.0.0": - version: 2.0.3 - resolution: "progress@npm:2.0.3" - checksum: e6f0bcb71f716eee9dfac0fe8a2606e3704d6a64dd93baaf49fbadbc8499989a610fe14cf1bc6f61b6d6653c49408d94f4a94e124538084efd8e4cf525e0293d - languageName: node - linkType: hard - "promise-inflight@npm:^1.0.1": version: 1.0.1 resolution: "promise-inflight@npm:1.0.1" @@ -14803,7 +14877,7 @@ __metadata: languageName: node linkType: hard -"regenerator-runtime@npm:^0.13.3, regenerator-runtime@npm:^0.13.4": +"regenerator-runtime@npm:^0.13.3": version: 0.13.11 resolution: "regenerator-runtime@npm:0.13.11" checksum: d493e9e118abef5b099c78170834f18540c4933cedf9bfabc32d3af94abfb59a7907bd7950259cbab0a929ebca7db77301e8024e5121e6482a82f78283dfd20c @@ -14848,13 +14922,6 @@ __metadata: languageName: node linkType: hard -"regexpp@npm:^3.1.0": - version: 3.2.0 - resolution: "regexpp@npm:3.2.0" - checksum: 3310010895a906873262f4b494fc99bcef1e71ef6720a0532c5999ca586498cbd4a284c8e3c2423f9d1d37512fd08d6064b7564e0e59508cf938f76dd15ace84 - languageName: node - linkType: hard - "regexpu-core@npm:^5.1.0": version: 5.2.1 resolution: "regexpu-core@npm:5.2.1" @@ -15182,6 +15249,15 @@ __metadata: languageName: node linkType: hard +"run-applescript@npm:^5.0.0": + version: 5.0.0 + resolution: "run-applescript@npm:5.0.0" + dependencies: + execa: "npm:^5.0.0" + checksum: d00c2dbfa5b2d774de7451194b8b125f40f65fc183de7d9dcae97f57f59433586d3c39b9001e111c38bfa24c3436c99df1bb4066a2a0c90d39a8c4cd6889af77 + languageName: node + linkType: hard + "run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -15377,7 +15453,7 @@ __metadata: languageName: node linkType: hard -"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.2.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.3.7, semver@npm:^7.5.3, semver@npm:^7.5.4": +"semver@npm:^7.0.0, semver@npm:^7.1.1, semver@npm:^7.3.2, semver@npm:^7.3.4, semver@npm:^7.3.5, semver@npm:^7.5.3, semver@npm:^7.5.4": version: 7.5.4 resolution: "semver@npm:7.5.4" dependencies: @@ -15634,17 +15710,6 @@ __metadata: languageName: node linkType: hard -"slice-ansi@npm:^4.0.0": - version: 4.0.0 - resolution: "slice-ansi@npm:4.0.0" - dependencies: - ansi-styles: "npm:^4.0.0" - astral-regex: "npm:^2.0.0" - is-fullwidth-code-point: "npm:^3.0.0" - checksum: 4a82d7f085b0e1b070e004941ada3c40d3818563ac44766cca4ceadd2080427d337554f9f99a13aaeb3b4a94d9964d9466c807b3d7b7541d1ec37ee32d308756 - languageName: node - linkType: hard - "slice-ansi@npm:^5.0.0": version: 5.0.0 resolution: "slice-ansi@npm:5.0.0" @@ -16089,7 +16154,7 @@ __metadata: languageName: node linkType: hard -"strip-json-comments@npm:^3.1.0, strip-json-comments@npm:^3.1.1": +"strip-json-comments@npm:^3.1.1": version: 3.1.1 resolution: "strip-json-comments@npm:3.1.1" checksum: 492f73e27268f9b1c122733f28ecb0e7e8d8a531a6662efbd08e22cccb3f9475e90a1b82cab06a392f6afae6d2de636f977e231296400d0ec5304ba70f166443 @@ -16238,6 +16303,16 @@ __metadata: languageName: node linkType: hard +"synckit@npm:^0.8.5": + version: 0.8.6 + resolution: "synckit@npm:0.8.6" + dependencies: + "@pkgr/utils": "npm:^2.4.2" + tslib: "npm:^2.6.2" + checksum: 565c659b5c935905e3774f8a53b013aeb1db03b69cb26cfea742021a274fba792e6ec22f1f918bfb6a7fe16dc9ab6e32a94b4289a8d5d9039b695cd9d524953d + languageName: node + linkType: hard + "systemjs-webpack-interop@npm:^2.3.7": version: 2.3.7 resolution: "systemjs-webpack-interop@npm:2.3.7" @@ -16254,19 +16329,6 @@ __metadata: languageName: node linkType: hard -"table@npm:^6.0.9": - version: 6.8.0 - resolution: "table@npm:6.8.0" - dependencies: - ajv: "npm:^8.0.1" - lodash.truncate: "npm:^4.4.2" - slice-ansi: "npm:^4.0.0" - string-width: "npm:^4.2.3" - strip-ansi: "npm:^6.0.1" - checksum: 4c2b8ebd75f36db236529680c70f41951c9c7fda3e65cb5b987164244f23f98670ded99983fdc5d62aa02405a212e90f7446efcf87e3435e472dda26d6581645 - languageName: node - linkType: hard - "tapable@npm:^1.0.0": version: 1.1.3 resolution: "tapable@npm:1.1.3" @@ -16448,6 +16510,13 @@ __metadata: languageName: node linkType: hard +"titleize@npm:^3.0.0": + version: 3.0.0 + resolution: "titleize@npm:3.0.0" + checksum: 71fbbeabbfb36ccd840559f67f21e356e1d03da2915b32d2ae1a60ddcc13a124be2739f696d2feb884983441d159a18649e8d956648d591bdad35c430a6b6d28 + languageName: node + linkType: hard + "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -16579,6 +16648,15 @@ __metadata: languageName: node linkType: hard +"ts-api-utils@npm:^1.0.1": + version: 1.0.3 + resolution: "ts-api-utils@npm:1.0.3" + peerDependencies: + typescript: ">=4.2.0" + checksum: 1350a5110eb1e534e9a6178f4081fb8a4fcc439749e19f4ad699baec9090fcb90fe532d5e191d91a062dc6e454a14a8d7eb2ad202f57135a30c4a44a3024f039 + languageName: node + linkType: hard + "ts-toolbelt@npm:^6.3.3": version: 6.15.5 resolution: "ts-toolbelt@npm:6.15.5" @@ -16586,31 +16664,20 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^1.8.1, tslib@npm:^1.9.0": +"tslib@npm:^1.9.0": version: 1.14.1 resolution: "tslib@npm:1.14.1" checksum: 7dbf34e6f55c6492637adb81b555af5e3b4f9cc6b998fb440dac82d3b42bdc91560a35a5fb75e20e24a076c651438234da6743d139e4feabf0783f3cdfe1dddb languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": +"tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca languageName: node linkType: hard -"tsutils@npm:^3.21.0": - version: 3.21.0 - resolution: "tsutils@npm:3.21.0" - dependencies: - tslib: "npm:^1.8.1" - peerDependencies: - typescript: ">=2.8.0 || >= 3.2.0-dev || >= 3.3.0-dev || >= 3.4.0-dev || >= 3.5.0-dev || >= 3.6.0-dev || >= 3.6.0-beta || >= 3.7.0-dev || >= 3.7.0-beta" - checksum: ea036bec1dd024e309939ffd49fda7a351c0e87a1b8eb049570dd119d447250e2c56e0e6c00554e8205760e7417793fdebff752a46e573fbe07d4f375502a5b2 - languageName: node - linkType: hard - "turbo-darwin-64@npm:1.5.5": version: 1.5.5 resolution: "turbo-darwin-64@npm:1.5.5" @@ -17029,6 +17096,13 @@ __metadata: languageName: node linkType: hard +"untildify@npm:^4.0.0": + version: 4.0.0 + resolution: "untildify@npm:4.0.0" + checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9 + languageName: node + linkType: hard + "upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" @@ -17150,13 +17224,6 @@ __metadata: languageName: node linkType: hard -"v8-compile-cache@npm:^2.0.3": - version: 2.3.0 - resolution: "v8-compile-cache@npm:2.3.0" - checksum: 7de7423db6f48d76cffae93d70d503e160c97fc85e55945036d719111e20b33c4be5c21aa8b123a3da203bbb3bc4c8180f9667d5ccafcff11d749fae204ec7be - languageName: node - linkType: hard - "v8-to-istanbul@npm:^9.0.1": version: 9.0.1 resolution: "v8-to-istanbul@npm:9.0.1" @@ -17756,7 +17823,7 @@ __metadata: languageName: node linkType: hard -"word-wrap@npm:^1.2.3, word-wrap@npm:~1.2.3": +"word-wrap@npm:~1.2.3": version: 1.2.3 resolution: "word-wrap@npm:1.2.3" checksum: 08a677e1578b9cc367a03d52bc51b6869fec06303f68d29439e4ed647257411f857469990c31066c1874678937dac737c9f8f20d3fd59918fb86b7d926a76b15 From 0f81b27ea8ad377b78903b1335d343bd0beb4de0 Mon Sep 17 00:00:00 2001 From: Jayasanka Weerasinghe <33048395+jayasanka-sack@users.noreply.github.com> Date: Thu, 21 Dec 2023 23:54:59 +0530 Subject: [PATCH 04/37] (chore) Bump playwright version of Playwright Dockerfile (#858) * Bump playwright version of playwright.Dockerfile * Update README.md * Update README.md * Update README.md * Update README.md --- README.md | 4 ++++ e2e/support/bamboo/playwright.Dockerfile | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) diff --git a/README.md b/README.md index 1f34a76cd..c1c5a44c1 100644 --- a/README.md +++ b/README.md @@ -212,3 +212,7 @@ The tag should be prefixed with `v` (e.g., `v3.2.1`), while the release title sh For documentation about our design patterns, please visit our design system documentation website. +## Bumping Playwright Version + +Be sure to update the Playwright version in the [Bamboo Playwright Docker image](e2e/support/bamboo/playwright.Dockerfile) whenever making version changes. +Also, ensure you specify fixed (pinned) versions of Playwright in the package.json file to maintain consistency between the Playwright version used in the Docker image for Bamboo test execution and the version used in the codebase. diff --git a/e2e/support/bamboo/playwright.Dockerfile b/e2e/support/bamboo/playwright.Dockerfile index 4fd9020ac..4249fd493 100644 --- a/e2e/support/bamboo/playwright.Dockerfile +++ b/e2e/support/bamboo/playwright.Dockerfile @@ -1,4 +1,4 @@ -FROM mcr.microsoft.com/playwright:v1.39.0-jammy +FROM mcr.microsoft.com/playwright:v1.40.1-jammy ARG USER_ID ARG GROUP_ID From c534b2ca954b0f6a94d416552a8585b6b70e5b36 Mon Sep 17 00:00:00 2001 From: CynthiaKamau Date: Fri, 22 Dec 2023 21:19:10 +0300 Subject: [PATCH 05/37] (feat )O3-2664: Allow app menu to expand based on the width of its content (#854) * O3-2664 Allow primary navigation app panel to expand based on content available * Fixup --------- Co-authored-by: Dennis Kigen --- .../navbar-header-panels/app-menu-panel.component.tsx | 4 ++-- .../src/components/navbar-header-panels/app-menu-panel.scss | 4 ++++ 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.component.tsx index 19631172d..18a457f3a 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.component.tsx @@ -18,8 +18,8 @@ const AppMenuPanel: React.FC = ({ expanded, hidePanel }) => { return ( hidePanel()} diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.scss b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.scss index 9207cea31..e251ad0e0 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.scss +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/app-menu-panel.scss @@ -24,3 +24,7 @@ .launchIcon { margin-left: spacing.$spacing-03; } + +.headerPanel { + width: fit-content; +} From 358813b6306e69e839f8ead890c25dc62b52106c Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Sun, 24 Dec 2023 09:13:59 -0500 Subject: [PATCH 06/37] fix: Better type support for getConfig (#861) --- .../esm-config/src/module-config/module-config.test.ts | 3 ++- .../esm-config/src/module-config/module-config.ts | 6 +++--- packages/framework/esm-framework/docs/API.md | 10 ++++++++-- 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/packages/framework/esm-config/src/module-config/module-config.test.ts b/packages/framework/esm-config/src/module-config/module-config.test.ts index 4bca44733..0fb18a340 100644 --- a/packages/framework/esm-config/src/module-config/module-config.test.ts +++ b/packages/framework/esm-config/src/module-config/module-config.test.ts @@ -198,9 +198,10 @@ describe('getConfig', () => { it('uses config values from the provided config file', async () => { Config.defineConfigSchema('foo-module', { foo: { _default: 'qux' } }); + type FooConfig = { foo: string }; const testConfig = { 'foo-module': { foo: 'bar' } }; Config.provide(testConfig); - const config = await Config.getConfig('foo-module'); + const config = await Config.getConfig('foo-module'); expect(config.foo).toBe('bar'); expect(console.error).not.toHaveBeenCalled(); }); diff --git a/packages/framework/esm-config/src/module-config/module-config.ts b/packages/framework/esm-config/src/module-config/module-config.ts index 1fc517582..8d12274fd 100644 --- a/packages/framework/esm-config/src/module-config/module-config.ts +++ b/packages/framework/esm-config/src/module-config/module-config.ts @@ -198,13 +198,13 @@ export function provide(config: Config, sourceName = 'provided') { * * @param moduleName The name of the module for which to look up the config */ -export function getConfig(moduleName: string): Promise { - return new Promise((resolve) => { +export function getConfig>(moduleName: string): Promise { + return new Promise((resolve) => { const store = getConfigStore(moduleName); function update(state: ConfigStore) { if (state.loaded && state.config) { const config = omit(['Display conditions', 'Translation overrides'], state.config); - resolve(config); + resolve(config as T); unsubscribe && unsubscribe(); } } diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 64ae9601a..043321dbb 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -1796,7 +1796,7 @@ ___ ### getConfig -▸ **getConfig**(`moduleName`): `Promise`<[`Config`](interfaces/Config.md)\> +▸ **getConfig**<`T`\>(`moduleName`): `Promise`<`T`\> A promise-based way to access the config as soon as it is fully loaded. If it is already loaded, resolves the config in its present state. @@ -1804,6 +1804,12 @@ If it is already loaded, resolves the config in its present state. This is a useful function if you need to get the config in the course of the execution of a function. +#### Type parameters + +| Name | Type | +| :------ | :------ | +| `T` | `Record`<`string`, `any`\> | + #### Parameters | Name | Type | Description | @@ -1812,7 +1818,7 @@ of the execution of a function. #### Returns -`Promise`<[`Config`](interfaces/Config.md)\> +`Promise`<`T`\> #### Defined in From 13a6f6b1a80eaea27b8d5c8f7092a23f745df79c Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Sun, 24 Dec 2023 10:00:36 -0500 Subject: [PATCH 07/37] Add attachments resources to esm-api and esm-react-utils (supporting O3-2618) (#860) * Add attachments resources to esm-api and esm-react-utils (supporting O3-2618) * Attachments API docs * Add attachments mocks --- packages/framework/esm-api/src/attachments.ts | 42 ++++++ packages/framework/esm-api/src/index.ts | 1 + packages/framework/esm-api/src/public.ts | 1 + .../esm-api/src/types/attachments-types.ts | 25 ++++ packages/framework/esm-api/src/types/index.ts | 1 + packages/framework/esm-framework/docs/API.md | 129 ++++++++++++++++++ .../docs/interfaces/Attachment.md | 85 ++++++++++++ .../docs/interfaces/AttachmentResponse.md | 63 +++++++++ .../docs/interfaces/UploadedFile.md | 74 ++++++++++ packages/framework/esm-framework/mock.tsx | 22 ++- .../framework/esm-react-utils/src/index.ts | 1 + .../framework/esm-react-utils/src/public.ts | 1 + .../esm-react-utils/src/useAttachments.ts | 22 +++ 13 files changed, 465 insertions(+), 2 deletions(-) create mode 100644 packages/framework/esm-api/src/attachments.ts create mode 100644 packages/framework/esm-api/src/types/attachments-types.ts create mode 100644 packages/framework/esm-framework/docs/interfaces/Attachment.md create mode 100644 packages/framework/esm-framework/docs/interfaces/AttachmentResponse.md create mode 100644 packages/framework/esm-framework/docs/interfaces/UploadedFile.md create mode 100644 packages/framework/esm-react-utils/src/useAttachments.ts diff --git a/packages/framework/esm-api/src/attachments.ts b/packages/framework/esm-api/src/attachments.ts new file mode 100644 index 000000000..4b7d45780 --- /dev/null +++ b/packages/framework/esm-api/src/attachments.ts @@ -0,0 +1,42 @@ +/** @module @category API */ +import type { UploadedFile } from './types'; +import { openmrsFetch } from './openmrs-fetch'; + +export const attachmentUrl = '/ws/rest/v1/attachment'; + +export function getAttachmentByUuid(attachmentUuid: string, abortController: AbortController) { + return openmrsFetch(`${attachmentUrl}/${attachmentUuid}`, { + signal: abortController.signal, + }); +} + +export function getAttachments(patientUuid: string, includeEncounterless: boolean, abortController: AbortController) { + return openmrsFetch(`${attachmentUrl}?patient=${patientUuid}&includeEncounterless=${includeEncounterless}`, { + signal: abortController.signal, + }); +} + +export async function createAttachment(patientUuid: string, fileToUpload: UploadedFile) { + const formData = new FormData(); + + formData.append('fileCaption', fileToUpload.fileName); + formData.append('patient', patientUuid); + + if (fileToUpload.file) { + formData.append('file', fileToUpload.file); + } else { + formData.append('file', new File([''], fileToUpload.fileName), fileToUpload.fileName); + formData.append('base64Content', fileToUpload.base64Content); + } + return openmrsFetch(`${attachmentUrl}`, { + method: 'POST', + body: formData, + }); +} + +export function deleteAttachmentPermanently(attachmentUuid: string, abortController: AbortController) { + return openmrsFetch(`${attachmentUrl}/${attachmentUuid}`, { + method: 'DELETE', + signal: abortController.signal, + }); +} diff --git a/packages/framework/esm-api/src/index.ts b/packages/framework/esm-api/src/index.ts index 819417cf6..0359cf486 100644 --- a/packages/framework/esm-api/src/index.ts +++ b/packages/framework/esm-api/src/index.ts @@ -1,4 +1,5 @@ export * from './types'; +export * from './attachments'; export * from './openmrs-fetch'; export * from './setup'; diff --git a/packages/framework/esm-api/src/public.ts b/packages/framework/esm-api/src/public.ts index 94bc6956a..7d46fdd20 100644 --- a/packages/framework/esm-api/src/public.ts +++ b/packages/framework/esm-api/src/public.ts @@ -1,5 +1,6 @@ export * from './types'; export * from './openmrs-fetch'; +export * from './attachments'; export * from './shared-api-objects/current-user'; export * from './shared-api-objects/current-patient'; diff --git a/packages/framework/esm-api/src/types/attachments-types.ts b/packages/framework/esm-api/src/types/attachments-types.ts new file mode 100644 index 000000000..3193d896e --- /dev/null +++ b/packages/framework/esm-api/src/types/attachments-types.ts @@ -0,0 +1,25 @@ +export interface UploadedFile { + file?: File; + base64Content: string; + fileName: string; + fileType: string; + fileDescription: string; + status?: 'uploading' | 'complete'; +} + +export interface Attachment { + id: string; + src: string; + title: string; + description: string; + dateTime: string; + bytesMimeType: string; + bytesContentFamily: string; +} +export interface AttachmentResponse { + bytesContentFamily: string; + bytesMimeType: string; + comment: string; + dateTime: string; + uuid: string; +} diff --git a/packages/framework/esm-api/src/types/index.ts b/packages/framework/esm-api/src/types/index.ts index 1791a78c4..2ea7a7389 100644 --- a/packages/framework/esm-api/src/types/index.ts +++ b/packages/framework/esm-api/src/types/index.ts @@ -1,3 +1,4 @@ +export * from './attachments-types'; export * from './fetch'; export * from './fhir-resource'; export * from './openmrs-resource'; diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 043321dbb..6ce39c045 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -7,7 +7,11 @@ ### API Functions - [clearCurrentUser](API.md#clearcurrentuser) +- [createAttachment](API.md#createattachment) +- [deleteAttachmentPermanently](API.md#deleteattachmentpermanently) - [fetchCurrentPatient](API.md#fetchcurrentpatient) +- [getAttachmentByUuid](API.md#getattachmentbyuuid) +- [getAttachments](API.md#getattachments) - [getCurrentUser](API.md#getcurrentuser) - [getLocations](API.md#getlocations) - [getLoggedInUser](API.md#getloggedinuser) @@ -159,6 +163,7 @@ ### Other Functions - [ExtensionSlot](API.md#extensionslot) +- [useAttachments](API.md#useattachments) ### Store Functions @@ -737,6 +742,16 @@ ___ ___ +### attachmentUrl + +• `Const` **attachmentUrl**: ``"/ws/rest/v1/attachment"`` + +#### Defined in + +[packages/framework/esm-api/src/attachments.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/attachments.ts#L5) + +___ + ### defaultVisitCustomRepresentation • `Const` **defaultVisitCustomRepresentation**: `string` @@ -935,6 +950,48 @@ ___ ___ +### createAttachment + +▸ **createAttachment**(`patientUuid`, `fileToUpload`): `Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `patientUuid` | `string` | +| `fileToUpload` | [`UploadedFile`](interfaces/UploadedFile.md) | + +#### Returns + +`Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Defined in + +[packages/framework/esm-api/src/attachments.ts:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/attachments.ts#L19) + +___ + +### deleteAttachmentPermanently + +▸ **deleteAttachmentPermanently**(`attachmentUuid`, `abortController`): `Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `attachmentUuid` | `string` | +| `abortController` | `AbortController` | + +#### Returns + +`Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Defined in + +[packages/framework/esm-api/src/attachments.ts:37](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/attachments.ts#L37) + +___ + ### fetchCurrentPatient ▸ **fetchCurrentPatient**(`patientUuid`, `fetchInit?`, `includeOfflinePatients?`): `Promise`<`fhir.Patient` \| ``null``\> @@ -957,6 +1014,49 @@ ___ ___ +### getAttachmentByUuid + +▸ **getAttachmentByUuid**(`attachmentUuid`, `abortController`): `Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `attachmentUuid` | `string` | +| `abortController` | `AbortController` | + +#### Returns + +`Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Defined in + +[packages/framework/esm-api/src/attachments.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/attachments.ts#L7) + +___ + +### getAttachments + +▸ **getAttachments**(`patientUuid`, `includeEncounterless`, `abortController`): `Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `patientUuid` | `string` | +| `includeEncounterless` | `boolean` | +| `abortController` | `AbortController` | + +#### Returns + +`Promise`<[`FetchResponse`](interfaces/FetchResponse.md)<`any`\>\> + +#### Defined in + +[packages/framework/esm-api/src/attachments.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/attachments.ts#L13) + +___ + ### getCurrentUser ▸ **getCurrentUser**(): `Observable`<[`Session`](interfaces/Session.md)\> @@ -3963,6 +4063,35 @@ Passing a function as children ___ +### useAttachments + +▸ **useAttachments**(`patientUuid`, `includeEncounterless`): `Object` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `patientUuid` | `string` | +| `includeEncounterless` | `boolean` | + +#### Returns + +`Object` + +| Name | Type | +| :------ | :------ | +| `data` | [`AttachmentResponse`](interfaces/AttachmentResponse.md)[] | +| `error` | `any` | +| `isLoading` | `boolean` | +| `isValidating` | `boolean` | +| `mutate` | `KeyedMutator`<[`FetchResponse`](interfaces/FetchResponse.md)<{ `results`: [`AttachmentResponse`](interfaces/AttachmentResponse.md)[] }\>\> | + +#### Defined in + +[packages/framework/esm-react-utils/src/useAttachments.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useAttachments.ts#L5) + +___ + ## Store Functions ### createGlobalStore diff --git a/packages/framework/esm-framework/docs/interfaces/Attachment.md b/packages/framework/esm-framework/docs/interfaces/Attachment.md new file mode 100644 index 000000000..eec6eef2b --- /dev/null +++ b/packages/framework/esm-framework/docs/interfaces/Attachment.md @@ -0,0 +1,85 @@ +[@openmrs/esm-framework](../API.md) / Attachment + +# Interface: Attachment + +## Table of contents + +### Properties + +- [bytesContentFamily](Attachment.md#bytescontentfamily) +- [bytesMimeType](Attachment.md#bytesmimetype) +- [dateTime](Attachment.md#datetime) +- [description](Attachment.md#description) +- [id](Attachment.md#id) +- [src](Attachment.md#src) +- [title](Attachment.md#title) + +## Properties + +### bytesContentFamily + +• **bytesContentFamily**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L17) + +___ + +### bytesMimeType + +• **bytesMimeType**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L16) + +___ + +### dateTime + +• **dateTime**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:15](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L15) + +___ + +### description + +• **description**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L14) + +___ + +### id + +• **id**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L11) + +___ + +### src + +• **src**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L12) + +___ + +### title + +• **title**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L13) diff --git a/packages/framework/esm-framework/docs/interfaces/AttachmentResponse.md b/packages/framework/esm-framework/docs/interfaces/AttachmentResponse.md new file mode 100644 index 000000000..5267564f2 --- /dev/null +++ b/packages/framework/esm-framework/docs/interfaces/AttachmentResponse.md @@ -0,0 +1,63 @@ +[@openmrs/esm-framework](../API.md) / AttachmentResponse + +# Interface: AttachmentResponse + +## Table of contents + +### Properties + +- [bytesContentFamily](AttachmentResponse.md#bytescontentfamily) +- [bytesMimeType](AttachmentResponse.md#bytesmimetype) +- [comment](AttachmentResponse.md#comment) +- [dateTime](AttachmentResponse.md#datetime) +- [uuid](AttachmentResponse.md#uuid) + +## Properties + +### bytesContentFamily + +• **bytesContentFamily**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L20) + +___ + +### bytesMimeType + +• **bytesMimeType**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L21) + +___ + +### comment + +• **comment**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L22) + +___ + +### dateTime + +• **dateTime**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:23](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L23) + +___ + +### uuid + +• **uuid**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:24](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L24) diff --git a/packages/framework/esm-framework/docs/interfaces/UploadedFile.md b/packages/framework/esm-framework/docs/interfaces/UploadedFile.md new file mode 100644 index 000000000..c68875f7f --- /dev/null +++ b/packages/framework/esm-framework/docs/interfaces/UploadedFile.md @@ -0,0 +1,74 @@ +[@openmrs/esm-framework](../API.md) / UploadedFile + +# Interface: UploadedFile + +## Table of contents + +### Properties + +- [base64Content](UploadedFile.md#base64content) +- [file](UploadedFile.md#file) +- [fileDescription](UploadedFile.md#filedescription) +- [fileName](UploadedFile.md#filename) +- [fileType](UploadedFile.md#filetype) +- [status](UploadedFile.md#status) + +## Properties + +### base64Content + +• **base64Content**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:3](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L3) + +___ + +### file + +• `Optional` **file**: `File` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:2](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L2) + +___ + +### fileDescription + +• **fileDescription**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:6](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L6) + +___ + +### fileName + +• **fileName**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:4](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L4) + +___ + +### fileType + +• **fileType**: `string` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:5](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L5) + +___ + +### status + +• `Optional` **status**: ``"uploading"`` \| ``"complete"`` + +#### Defined in + +[packages/framework/esm-api/src/types/attachments-types.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/types/attachments-types.ts#L7) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index d6b5149fd..c490e89ee 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -1,9 +1,9 @@ import React from 'react'; import type {} from '@openmrs/esm-globals'; -import { createStore, StoreApi } from 'zustand'; +import { createStore, type StoreApi } from 'zustand'; import { NEVER, of } from 'rxjs'; import { interpolateUrl } from '@openmrs/esm-config'; -import { SessionStore } from '@openmrs/esm-api'; +import { type SessionStore } from '@openmrs/esm-api'; export { parseDate, formatDate, formatDatetime, formatTime, age } from '@openmrs/esm-utils'; export { interpolateString, interpolateUrl, validators, validator } from '@openmrs/esm-config'; @@ -56,6 +56,16 @@ export const newWorkspaceItem = jest.fn(); export const fhirBaseUrl = '/ws/fhir2/R4'; +export const attachmentUrl = '/ws/rest/v1/attachment'; + +export const getAttachmentByUuid = jest.fn(); + +export const getAttachments = jest.fn(); + +export const createAttachment = jest.fn(); + +export const deleteAttachmentPermanently = jest.fn(); + /* esm-state */ interface StoreEntity { value: StoreApi; @@ -205,6 +215,14 @@ export const ComponentContext = React.createContext(null); export const openmrsComponentDecorator = jest.fn().mockImplementation(() => (component) => component); +export const useAttachments = jest.fn(() => ({ + isLoading: true, + data: [], + error: null, + mutate: jest.fn(), + isValidating: true, +})); + export const useCurrentPatient = jest.fn(() => []); export const usePatient = jest.fn(() => ({ diff --git a/packages/framework/esm-react-utils/src/index.ts b/packages/framework/esm-react-utils/src/index.ts index ba63c9873..8b47fd1c4 100644 --- a/packages/framework/esm-react-utils/src/index.ts +++ b/packages/framework/esm-react-utils/src/index.ts @@ -8,6 +8,7 @@ export * from './openmrsComponentDecorator'; export * from './useAbortController'; export * from './useAssignedExtensions'; export * from './useAssignedExtensionIds'; +export * from './useAttachments'; export * from './useBodyScrollLock'; export * from './useConfig'; export * from './useConnectedExtensions'; diff --git a/packages/framework/esm-react-utils/src/public.ts b/packages/framework/esm-react-utils/src/public.ts index 52097275f..a4e8eab9c 100644 --- a/packages/framework/esm-react-utils/src/public.ts +++ b/packages/framework/esm-react-utils/src/public.ts @@ -7,6 +7,7 @@ export * from './getLifecycle'; export * from './useAbortController'; export * from './useAssignedExtensions'; export * from './useAssignedExtensionIds'; +export * from './useAttachments'; export * from './useBodyScrollLock'; export * from './useConfig'; export * from './useConnectedExtensions'; diff --git a/packages/framework/esm-react-utils/src/useAttachments.ts b/packages/framework/esm-react-utils/src/useAttachments.ts new file mode 100644 index 000000000..978c5494d --- /dev/null +++ b/packages/framework/esm-react-utils/src/useAttachments.ts @@ -0,0 +1,22 @@ +import { useMemo } from 'react'; +import useSWR from 'swr'; +import type { FetchResponse, AttachmentResponse } from '@openmrs/esm-api'; +import { attachmentUrl, openmrsFetch } from '@openmrs/esm-api'; +export function useAttachments(patientUuid: string, includeEncounterless: boolean) { + const { data, error, mutate, isLoading, isValidating } = useSWR< + FetchResponse<{ results: Array }> + >(`${attachmentUrl}?patient=${patientUuid}&includeEncounterless=${includeEncounterless}`, openmrsFetch); + + const results = useMemo( + () => ({ + isLoading, + data: data?.data.results ?? [], + error, + mutate, + isValidating, + }), + [data, error, isLoading, isValidating, mutate], + ); + + return results; +} From c16d0939c0a4add9fe47b1e470dedecc09c97415 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Sun, 24 Dec 2023 12:35:02 -0500 Subject: [PATCH 08/37] fix: Fix config mocks (#862) --- packages/framework/esm-framework/mock.tsx | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index c490e89ee..22a0b1aca 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -154,9 +154,9 @@ function isOrdinaryObject(x) { return !!x && x.constructor === Object; } -export const getConfig = jest.fn().mockReturnValue(getDefaults(configSchema)); +export const getConfig = jest.fn().mockImplementation(() => Promise.resolve(getDefaults(configSchema))); -export const useConfig = jest.fn().mockReturnValue(getDefaults(configSchema)); +export const useConfig = jest.fn().mockImplementation(() => getDefaults(configSchema)); export function defineConfigSchema(moduleName, schema) { configSchema = schema; From 4a0e8abe56289bc03738cedac0caaeb6b1b3961b Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Sun, 24 Dec 2023 21:36:47 +0300 Subject: [PATCH 09/37] (chore) Fix start script by removing eslint-plugin-prettier (#859) * (chore) Remove eslint-plugin-prettier * Extend Prettier config --- .eslintrc | 2 +- package.json | 1 - yarn.lock | 348 +++------------------------------------------------ 3 files changed, 16 insertions(+), 335 deletions(-) diff --git a/.eslintrc b/.eslintrc index d09f649a1..6b26d3d70 100644 --- a/.eslintrc +++ b/.eslintrc @@ -2,7 +2,7 @@ "env": { "node": true }, - "extends": ["eslint:recommended", "plugin:prettier/recommended", "plugin:@typescript-eslint/recommended"], + "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], "parser": "@typescript-eslint/parser", "plugins": ["@typescript-eslint"], "ignorePatterns": ["**/*.test.tsx"], diff --git a/package.json b/package.json index bd67059d6..03a1e6ad4 100644 --- a/package.json +++ b/package.json @@ -46,7 +46,6 @@ "dotenv": "^16.0.3", "eslint": "^8.55.0", "eslint-config-prettier": "^9.1.0", - "eslint-plugin-prettier": "^5.0.1", "fake-indexeddb": "^4.0.1", "fork-ts-checker-webpack-plugin": "^7.2.13", "husky": "^8.0.1", diff --git a/yarn.lock b/yarn.lock index fc2c6ba8b..760739278 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2706,7 +2706,6 @@ __metadata: dotenv: "npm:^16.0.3" eslint: "npm:^8.55.0" eslint-config-prettier: "npm:^9.1.0" - eslint-plugin-prettier: "npm:^5.0.1" fake-indexeddb: "npm:^4.0.1" fork-ts-checker-webpack-plugin: "npm:^7.2.13" husky: "npm:^8.0.1" @@ -3116,20 +3115,6 @@ __metadata: languageName: unknown linkType: soft -"@pkgr/utils@npm:^2.4.2": - version: 2.4.2 - resolution: "@pkgr/utils@npm:2.4.2" - dependencies: - cross-spawn: "npm:^7.0.3" - fast-glob: "npm:^3.3.0" - is-glob: "npm:^4.0.3" - open: "npm:^9.1.0" - picocolors: "npm:^1.0.0" - tslib: "npm:^2.6.0" - checksum: f0b0b305a83bd65fac5637d28ad3e33f19194043e03ceef6b4e13d260bfa2678b73df76dc56ed906469ffe0494d4bd214e6b92ca80684f38547982edf982dd15 - languageName: node - linkType: hard - "@playwright/test@npm:1.40.1": version: 1.40.1 resolution: "@playwright/test@npm:1.40.1" @@ -4626,14 +4611,7 @@ __metadata: languageName: node linkType: hard -"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": - version: 7.0.11 - resolution: "@types/json-schema@npm:7.0.11" - checksum: e50864a93f4dcb9de64c0c605d836f5416341c824d7a8cde1aa15a5fc68bed44b33cdcb2e04e5098339e9121848378f2d0cc5b124dec41c89203c6f67d6f344a - languageName: node - linkType: hard - -"@types/json-schema@npm:^7.0.12": +"@types/json-schema@npm:*, @types/json-schema@npm:^7.0.12, @types/json-schema@npm:^7.0.4, @types/json-schema@npm:^7.0.5, @types/json-schema@npm:^7.0.8, @types/json-schema@npm:^7.0.9": version: 7.0.15 resolution: "@types/json-schema@npm:7.0.15" checksum: 1a3c3e06236e4c4aab89499c428d585527ce50c24fe8259e8b3926d3df4cfbbbcf306cfc73ddfb66cbafc973116efd15967020b0f738f63e09e64c7d260519e7 @@ -4845,14 +4823,7 @@ __metadata: languageName: node linkType: hard -"@types/semver@npm:^7.3.4": - version: 7.3.12 - resolution: "@types/semver@npm:7.3.12" - checksum: abd4bc279bd9e8323d53afc2997139b1daa14c3a4136d1cd7c1b76409345c811165ad5af2dd2cf5ea122917fe0f4be7544e6a582936c5b8a5aa64b50c22f5d99 - languageName: node - linkType: hard - -"@types/semver@npm:^7.5.0": +"@types/semver@npm:^7.3.4, @types/semver@npm:^7.5.0": version: 7.5.6 resolution: "@types/semver@npm:7.5.6" checksum: e77282b17f74354e17e771c0035cccb54b94cc53d0433fa7e9ba9d23fd5d7edcd14b6c8b7327d58bbd89e83b1c5eda71dfe408e06b929007e2b89586e9b63459 @@ -5391,16 +5362,7 @@ __metadata: languageName: node linkType: hard -"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2": - version: 8.10.0 - resolution: "acorn@npm:8.10.0" - bin: - acorn: bin/acorn - checksum: 522310c20fdc3c271caed3caf0f06c51d61cb42267279566edd1d58e83dbc12eebdafaab666a0f0be1b7ad04af9c6bc2a6f478690a9e6391c3c8b165ada917dd - languageName: node - linkType: hard - -"acorn@npm:^8.9.0": +"acorn@npm:^8.0.4, acorn@npm:^8.1.0, acorn@npm:^8.7.1, acorn@npm:^8.8.1, acorn@npm:^8.8.2, acorn@npm:^8.9.0": version: 8.11.2 resolution: "acorn@npm:8.11.2" bin: @@ -5636,7 +5598,7 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:5.1.3": +"aria-query@npm:5.1.3, aria-query@npm:^5.0.0": version: 5.1.3 resolution: "aria-query@npm:5.1.3" dependencies: @@ -5645,13 +5607,6 @@ __metadata: languageName: node linkType: hard -"aria-query@npm:^5.0.0": - version: 5.0.2 - resolution: "aria-query@npm:5.0.2" - checksum: a458c688ea8ba9a011f1df3a0ebaf221a9ca537e4927182a92a14cf32bdfa0017c19c0676e4f5d3db0f6c67c0616ffbe35cfc66f000e4acbf39d44712fe82fae - languageName: node - linkType: hard - "array-buffer-byte-length@npm:^1.0.0": version: 1.0.0 resolution: "array-buffer-byte-length@npm:1.0.0" @@ -5933,13 +5888,6 @@ __metadata: languageName: node linkType: hard -"big-integer@npm:^1.6.44": - version: 1.6.52 - resolution: "big-integer@npm:1.6.52" - checksum: 4bc6ae152a96edc9f95020f5fc66b13d26a9ad9a021225a9f0213f7e3dc44269f423aa8c42e19d6ac4a63bb2b22140b95d10be8f9ca7a6d9aa1b22b330d1f514 - languageName: node - linkType: hard - "big.js@npm:^5.2.2": version: 5.2.2 resolution: "big.js@npm:5.2.2" @@ -6000,15 +5948,6 @@ __metadata: languageName: node linkType: hard -"bplist-parser@npm:^0.2.0": - version: 0.2.0 - resolution: "bplist-parser@npm:0.2.0" - dependencies: - big-integer: "npm:^1.6.44" - checksum: 15d31c1b0c7e0fb384e96349453879a33609d92d91b55a9ccee04b4be4b0645f1c823253d73326a1a23104521fbc45c2dd97fb05adf61863841b68cbb2ca7a3d - languageName: node - linkType: hard - "brace-expansion@npm:^1.1.7": version: 1.1.11 resolution: "brace-expansion@npm:1.1.11" @@ -6161,15 +6100,6 @@ __metadata: languageName: node linkType: hard -"bundle-name@npm:^3.0.0": - version: 3.0.0 - resolution: "bundle-name@npm:3.0.0" - dependencies: - run-applescript: "npm:^5.0.0" - checksum: edf2b1fbe6096ed32e7566947ace2ea937ee427391744d7510a2880c4b9a5b3543d3f6c551236a29e5c87d3195f8e2912516290e638c15bcbede7b37cc375615 - languageName: node - linkType: hard - "bytes@npm:3.0.0": version: 3.0.0 resolution: "bytes@npm:3.0.0" @@ -6258,17 +6188,7 @@ __metadata: languageName: node linkType: hard -"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2": - version: 1.0.2 - resolution: "call-bind@npm:1.0.2" - dependencies: - function-bind: "npm:^1.1.1" - get-intrinsic: "npm:^1.0.2" - checksum: ca787179c1cbe09e1697b56ad499fd05dc0ae6febe5081d728176ade699ea6b1589240cb1ff1fe11fcf9f61538c1af60ad37e8eb2ceb4ef21cd6085dfd3ccedd - languageName: node - linkType: hard - -"call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": +"call-bind@npm:^1.0.0, call-bind@npm:^1.0.2, call-bind@npm:^1.0.4, call-bind@npm:^1.0.5": version: 1.0.5 resolution: "call-bind@npm:1.0.5" dependencies: @@ -6734,14 +6654,7 @@ __metadata: languageName: node linkType: hard -"colorette@npm:^2.0.10, colorette@npm:^2.0.14": - version: 2.0.19 - resolution: "colorette@npm:2.0.19" - checksum: 6e2606435cd30e1cae8fc6601b024fdd809e20515c57ce1e588d0518403cff0c98abf807912ba543645a9188af36763b69b67e353d47397f24a1c961aba300bd - languageName: node - linkType: hard - -"colorette@npm:^2.0.20": +"colorette@npm:^2.0.10, colorette@npm:^2.0.14, colorette@npm:^2.0.20": version: 2.0.20 resolution: "colorette@npm:2.0.20" checksum: 0b8de48bfa5d10afc160b8eaa2b9938f34a892530b2f7d7897e0458d9535a066e3998b49da9d21161c78225b272df19ae3a64d6df28b4c9734c0e55bbd02406f @@ -7924,28 +7837,6 @@ __metadata: languageName: node linkType: hard -"default-browser-id@npm:^3.0.0": - version: 3.0.0 - resolution: "default-browser-id@npm:3.0.0" - dependencies: - bplist-parser: "npm:^0.2.0" - untildify: "npm:^4.0.0" - checksum: 279c7ad492542e5556336b6c254a4eaf31b2c63a5433265655ae6e47301197b6cfb15c595a6fdc6463b2ff8e1a1a1ed3cba56038a60e1527ba4ab1628c6b9941 - languageName: node - linkType: hard - -"default-browser@npm:^4.0.0": - version: 4.0.0 - resolution: "default-browser@npm:4.0.0" - dependencies: - bundle-name: "npm:^3.0.0" - default-browser-id: "npm:^3.0.0" - execa: "npm:^7.1.1" - titleize: "npm:^3.0.0" - checksum: 40c5af984799042b140300be5639c9742599bda76dc9eba5ac9ad5943c83dd36cebc4471eafcfddf8e0ec817166d5ba89d56f08e66a126c7c7908a179cead1a7 - languageName: node - linkType: hard - "default-gateway@npm:^6.0.3": version: 6.0.3 resolution: "default-gateway@npm:6.0.3" @@ -7973,24 +7864,7 @@ __metadata: languageName: node linkType: hard -"define-lazy-prop@npm:^3.0.0": - version: 3.0.0 - resolution: "define-lazy-prop@npm:3.0.0" - checksum: f28421cf9ee86eecaf5f3b8fe875f13d7009c2625e97645bfff7a2a49aca678270b86c39f9c32939e5ca7ab96b551377ed4139558c795e076774287ad3af1aa4 - languageName: node - linkType: hard - -"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4": - version: 1.1.4 - resolution: "define-properties@npm:1.1.4" - dependencies: - has-property-descriptors: "npm:^1.0.0" - object-keys: "npm:^1.1.1" - checksum: ce0aef3f9eb193562b5cfb79b2d2c86b6a109dfc9fdcb5f45d680631a1a908c06824ddcdb72b7573b54e26ace07f0a23420aaba0d5c627b34d2c1de8ef527e2b - languageName: node - linkType: hard - -"define-properties@npm:^1.2.0": +"define-properties@npm:^1.1.3, define-properties@npm:^1.1.4, define-properties@npm:^1.2.0": version: 1.2.1 resolution: "define-properties@npm:1.2.1" dependencies: @@ -8623,26 +8497,6 @@ __metadata: languageName: node linkType: hard -"eslint-plugin-prettier@npm:^5.0.1": - version: 5.1.0 - resolution: "eslint-plugin-prettier@npm:5.1.0" - dependencies: - prettier-linter-helpers: "npm:^1.0.0" - synckit: "npm:^0.8.5" - peerDependencies: - "@types/eslint": ">=8.0.0" - eslint: ">=8.0.0" - eslint-config-prettier: "*" - prettier: ">=3.0.0" - peerDependenciesMeta: - "@types/eslint": - optional: true - eslint-config-prettier: - optional: true - checksum: 6db5a9dade4157092e87eb876508c8b510ab9bb0e4592536933d84b351b99d7c30259bad8ba76057b5c739fa62005d26f3008745438dc785060dbaae741f7fa5 - languageName: node - linkType: hard - "eslint-scope@npm:5.1.1": version: 5.1.1 resolution: "eslint-scope@npm:5.1.1" @@ -8663,14 +8517,7 @@ __metadata: languageName: node linkType: hard -"eslint-visitor-keys@npm:^3.3.0": - version: 3.3.0 - resolution: "eslint-visitor-keys@npm:3.3.0" - checksum: 37a1a5912a0b1de0f6d26237d8903af8a3af402bbef6e4181aeda1ace12a67348a0356c677804cfc839f62e68c3845b3eb96bb8f334d30d5ce96348d482567ed - languageName: node - linkType: hard - -"eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": +"eslint-visitor-keys@npm:^3.3.0, eslint-visitor-keys@npm:^3.4.1, eslint-visitor-keys@npm:^3.4.3": version: 3.4.3 resolution: "eslint-visitor-keys@npm:3.4.3" checksum: 3f357c554a9ea794b094a09bd4187e5eacd1bc0d0653c3adeb87962c548e6a1ab8f982b86963ae1337f5d976004146536dcee5d0e2806665b193fbfbf1a9231b @@ -8854,23 +8701,6 @@ __metadata: languageName: node linkType: hard -"execa@npm:^7.1.1": - version: 7.2.0 - resolution: "execa@npm:7.2.0" - dependencies: - cross-spawn: "npm:^7.0.3" - get-stream: "npm:^6.0.1" - human-signals: "npm:^4.3.0" - is-stream: "npm:^3.0.0" - merge-stream: "npm:^2.0.0" - npm-run-path: "npm:^5.1.0" - onetime: "npm:^6.0.0" - signal-exit: "npm:^3.0.7" - strip-final-newline: "npm:^3.0.0" - checksum: 473feff60f9d4dbe799225948de48b5158c1723021d19c4b982afe37bcd111ae84e1b4c9dfe967fae5101b0894b1a62e4dd564a286dfa3e46d7b0cfdbf7fe62b - languageName: node - linkType: hard - "exif-parser@npm:^0.1.12": version: 0.1.12 resolution: "exif-parser@npm:0.1.12" @@ -8971,13 +8801,6 @@ __metadata: languageName: node linkType: hard -"fast-diff@npm:^1.1.2": - version: 1.2.0 - resolution: "fast-diff@npm:1.2.0" - checksum: f62419b3d770f201d51c3ee8c4443b752b3ba2d548a6639026b7e09a08203ed2699a8d1fe21efcb8c5186135002d5d2916c12a687cac63785626456a92915adc - languageName: node - linkType: hard - "fast-fifo@npm:^1.1.0": version: 1.3.2 resolution: "fast-fifo@npm:1.3.2" @@ -8986,19 +8809,6 @@ __metadata: linkType: hard "fast-glob@npm:^3.2.11, fast-glob@npm:^3.2.9": - version: 3.2.12 - resolution: "fast-glob@npm:3.2.12" - dependencies: - "@nodelib/fs.stat": "npm:^2.0.2" - "@nodelib/fs.walk": "npm:^1.2.3" - glob-parent: "npm:^5.1.2" - merge2: "npm:^1.3.0" - micromatch: "npm:^4.0.4" - checksum: 641e748664ae0fdc4dadd23c812fd7d6c80cd92d451571cb1f81fa87edb750e917f25abf74fc9503c97438b0b67ecf75b738bb8e50a83b16bd2a88b4d64e81fa - languageName: node - linkType: hard - -"fast-glob@npm:^3.3.0": version: 3.3.2 resolution: "fast-glob@npm:3.3.2" dependencies: @@ -9429,14 +9239,7 @@ __metadata: languageName: node linkType: hard -"function-bind@npm:^1.1.1": - version: 1.1.1 - resolution: "function-bind@npm:1.1.1" - checksum: d83f2968030678f0b8c3f2183d63dcd969344eb8b55b4eb826a94ccac6de8b87c95bebffda37a6386c74f152284eb02956ff2c496897f35d32bdc2628ac68ac5 - languageName: node - linkType: hard - -"function-bind@npm:^1.1.2": +"function-bind@npm:^1.1.1, function-bind@npm:^1.1.2": version: 1.1.2 resolution: "function-bind@npm:1.1.2" checksum: 185e20d20f10c8d661d59aac0f3b63b31132d492e1b11fcc2a93cb2c47257ebaee7407c38513efd2b35cafdf972d9beb2ea4593c1e0f3bf8f2744836928d7454 @@ -9506,18 +9309,7 @@ __metadata: languageName: node linkType: hard -"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.0, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3": - version: 1.1.3 - resolution: "get-intrinsic@npm:1.1.3" - dependencies: - function-bind: "npm:^1.1.1" - has: "npm:^1.0.3" - has-symbols: "npm:^1.0.3" - checksum: ab4d7d83d6d08036d197291927442d1c05d5329484f8bdcdf895f5d6ecf158ec99a8ccd9f548bcfe917382ea3b74a423bdf5bee03f5c166359045d2f8a24c7a5 - languageName: node - linkType: hard - -"get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": +"get-intrinsic@npm:^1.0.2, get-intrinsic@npm:^1.1.1, get-intrinsic@npm:^1.1.3, get-intrinsic@npm:^1.2.0, get-intrinsic@npm:^1.2.1, get-intrinsic@npm:^1.2.2": version: 1.2.2 resolution: "get-intrinsic@npm:1.2.2" dependencies: @@ -9543,7 +9335,7 @@ __metadata: languageName: node linkType: hard -"get-stream@npm:^6.0.0, get-stream@npm:^6.0.1": +"get-stream@npm:^6.0.0": version: 6.0.1 resolution: "get-stream@npm:6.0.1" checksum: 781266d29725f35c59f1d214aedc92b0ae855800a980800e2923b3fbc4e56b3cb6e462c42e09a1cf1a00c64e056a78fa407cbe06c7c92b7e5cd49b4b85c2a497 @@ -10151,13 +9943,6 @@ __metadata: languageName: node linkType: hard -"human-signals@npm:^4.3.0": - version: 4.3.1 - resolution: "human-signals@npm:4.3.1" - checksum: fa59894c358fe9f2b5549be2fb083661d5e1dff618d3ac70a49ca73495a72e873fbf6c0878561478e521e17d498292746ee391791db95ffe5747bfb5aef8765b - languageName: node - linkType: hard - "human-signals@npm:^5.0.0": version: 5.0.0 resolution: "human-signals@npm:5.0.0" @@ -10288,14 +10073,7 @@ __metadata: languageName: node linkType: hard -"ignore@npm:^5.2.0": - version: 5.2.0 - resolution: "ignore@npm:5.2.0" - checksum: 30283f05fb7d867ee0e08faebb3e69caba2c6c55092042cd061eac1b37a3e78db72bfcfbb08b3598999344fba3d93a9c693b5401da5faaecc0fb7c2dce87beb4 - languageName: node - linkType: hard - -"ignore@npm:^5.2.4": +"ignore@npm:^5.2.0, ignore@npm:^5.2.4": version: 5.3.0 resolution: "ignore@npm:5.3.0" checksum: 51594355cea4c6ad6b28b3b85eb81afa7b988a1871feefd7062baf136c95aa06760ee934fa9590e43d967bd377ce84a4cf6135fbeb6063e063f1182a0e9a3bcd @@ -10439,18 +10217,7 @@ __metadata: languageName: node linkType: hard -"internal-slot@npm:^1.0.3": - version: 1.0.3 - resolution: "internal-slot@npm:1.0.3" - dependencies: - get-intrinsic: "npm:^1.1.0" - has: "npm:^1.0.3" - side-channel: "npm:^1.0.4" - checksum: 1c6d22f7977b325e51387191a992a553bf7c380db548a32c09bbb4563a799d739d3ef629841234290a032dc555ca7e89178e8a35404dad77b55f2676be8a1ba2 - languageName: node - linkType: hard - -"internal-slot@npm:^1.0.4": +"internal-slot@npm:^1.0.3, internal-slot@npm:^1.0.4": version: 1.0.6 resolution: "internal-slot@npm:1.0.6" dependencies: @@ -10666,15 +10433,6 @@ __metadata: languageName: node linkType: hard -"is-docker@npm:^3.0.0": - version: 3.0.0 - resolution: "is-docker@npm:3.0.0" - bin: - is-docker: cli.js - checksum: b698118f04feb7eaf3338922bd79cba064ea54a1c3db6ec8c0c8d8ee7613e7e5854d802d3ef646812a8a3ace81182a085dfa0a71cc68b06f3fa794b9783b3c90 - languageName: node - linkType: hard - "is-extglob@npm:^2.1.0, is-extglob@npm:^2.1.1": version: 2.1.1 resolution: "is-extglob@npm:2.1.1" @@ -10737,17 +10495,6 @@ __metadata: languageName: node linkType: hard -"is-inside-container@npm:^1.0.0": - version: 1.0.0 - resolution: "is-inside-container@npm:1.0.0" - dependencies: - is-docker: "npm:^3.0.0" - bin: - is-inside-container: cli.js - checksum: c50b75a2ab66ab3e8b92b3bc534e1ea72ca25766832c0623ac22d134116a98bcf012197d1caabe1d1c4bd5f84363d4aa5c36bb4b585fbcaf57be172cd10a1a03 - languageName: node - linkType: hard - "is-lambda@npm:^1.0.1": version: 1.0.1 resolution: "is-lambda@npm:1.0.1" @@ -13112,18 +12859,6 @@ __metadata: languageName: node linkType: hard -"open@npm:^9.1.0": - version: 9.1.0 - resolution: "open@npm:9.1.0" - dependencies: - default-browser: "npm:^4.0.0" - define-lazy-prop: "npm:^3.0.0" - is-inside-container: "npm:^1.0.0" - is-wsl: "npm:^2.2.0" - checksum: b45bcc7a6795804a2f560f0ca9f5e5344114bc40754d10c28a811c0c8f7027356979192931a6a7df2ab9e5bab3058988c99ae55f4fb71db2ce9fc77c40f619aa - languageName: node - linkType: hard - "opener@npm:^1.5.2": version: 1.5.2 resolution: "opener@npm:1.5.2" @@ -14370,15 +14105,6 @@ __metadata: languageName: node linkType: hard -"prettier-linter-helpers@npm:^1.0.0": - version: 1.0.0 - resolution: "prettier-linter-helpers@npm:1.0.0" - dependencies: - fast-diff: "npm:^1.1.2" - checksum: 00ce8011cf6430158d27f9c92cfea0a7699405633f7f1d4a45f07e21bf78e99895911cbcdc3853db3a824201a7c745bd49bfea8abd5fb9883e765a90f74f8392 - languageName: node - linkType: hard - "prettier@npm:^3.1.0": version: 3.1.0 resolution: "prettier@npm:3.1.0" @@ -14900,18 +14626,7 @@ __metadata: languageName: node linkType: hard -"regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3": - version: 1.4.3 - resolution: "regexp.prototype.flags@npm:1.4.3" - dependencies: - call-bind: "npm:^1.0.2" - define-properties: "npm:^1.1.3" - functions-have-names: "npm:^1.2.2" - checksum: 3cde7cd22f0cf9d04db0b77c825b14824c6e7d2ec77e17e8dba707ad1b3c70bb3f2ac5b4cad3c0932045ba61cb2fd1b8ef84a49140e952018bdae065cc001670 - languageName: node - linkType: hard - -"regexp.prototype.flags@npm:^1.5.1": +"regexp.prototype.flags@npm:^1.4.1, regexp.prototype.flags@npm:^1.4.3, regexp.prototype.flags@npm:^1.5.1": version: 1.5.1 resolution: "regexp.prototype.flags@npm:1.5.1" dependencies: @@ -15249,15 +14964,6 @@ __metadata: languageName: node linkType: hard -"run-applescript@npm:^5.0.0": - version: 5.0.0 - resolution: "run-applescript@npm:5.0.0" - dependencies: - execa: "npm:^5.0.0" - checksum: d00c2dbfa5b2d774de7451194b8b125f40f65fc183de7d9dcae97f57f59433586d3c39b9001e111c38bfa24c3436c99df1bb4066a2a0c90d39a8c4cd6889af77 - languageName: node - linkType: hard - "run-async@npm:^2.4.0": version: 2.4.1 resolution: "run-async@npm:2.4.1" @@ -16303,16 +16009,6 @@ __metadata: languageName: node linkType: hard -"synckit@npm:^0.8.5": - version: 0.8.6 - resolution: "synckit@npm:0.8.6" - dependencies: - "@pkgr/utils": "npm:^2.4.2" - tslib: "npm:^2.6.2" - checksum: 565c659b5c935905e3774f8a53b013aeb1db03b69cb26cfea742021a274fba792e6ec22f1f918bfb6a7fe16dc9ab6e32a94b4289a8d5d9039b695cd9d524953d - languageName: node - linkType: hard - "systemjs-webpack-interop@npm:^2.3.7": version: 2.3.7 resolution: "systemjs-webpack-interop@npm:2.3.7" @@ -16510,13 +16206,6 @@ __metadata: languageName: node linkType: hard -"titleize@npm:^3.0.0": - version: 3.0.0 - resolution: "titleize@npm:3.0.0" - checksum: 71fbbeabbfb36ccd840559f67f21e356e1d03da2915b32d2ae1a60ddcc13a124be2739f696d2feb884983441d159a18649e8d956648d591bdad35c430a6b6d28 - languageName: node - linkType: hard - "tmp@npm:^0.0.33": version: 0.0.33 resolution: "tmp@npm:0.0.33" @@ -16671,7 +16360,7 @@ __metadata: languageName: node linkType: hard -"tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.0, tslib@npm:^2.6.2": +"tslib@npm:^2.0.3, tslib@npm:^2.3.0, tslib@npm:^2.4.0, tslib@npm:^2.6.2": version: 2.6.2 resolution: "tslib@npm:2.6.2" checksum: bd26c22d36736513980091a1e356378e8b662ded04204453d353a7f34a4c21ed0afc59b5f90719d4ba756e581a162ecbf93118dc9c6be5acf70aa309188166ca @@ -17096,13 +16785,6 @@ __metadata: languageName: node linkType: hard -"untildify@npm:^4.0.0": - version: 4.0.0 - resolution: "untildify@npm:4.0.0" - checksum: 39ced9c418a74f73f0a56e1ba4634b4d959422dff61f4c72a8e39f60b99380c1b45ed776fbaa0a4101b157e4310d873ad7d114e8534ca02609b4916bb4187fb9 - languageName: node - linkType: hard - "upath@npm:^1.2.0": version: 1.2.0 resolution: "upath@npm:1.2.0" From 0207d4d18a2cdb7dc335f8b2c4d4ad51fb6da015 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Mon, 25 Dec 2023 02:49:36 -0500 Subject: [PATCH 10/37] (feat) Provide function for obtaining default config tree in test code (#863) --- packages/framework/esm-framework/docs/API.md | 30 +++++++++++++++++ packages/framework/esm-framework/mock.tsx | 32 +++++++------------ packages/framework/esm-utils/src/index.ts | 1 + .../framework/esm-utils/src/test-helpers.ts | 31 ++++++++++++++++++ 4 files changed, 73 insertions(+), 21 deletions(-) create mode 100644 packages/framework/esm-utils/src/test-helpers.ts diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 6ce39c045..e03de730e 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -198,6 +198,7 @@ - [age](API.md#age) - [canAccessStorage](API.md#canaccessstorage) - [daysIntoYear](API.md#daysintoyear) +- [getDefaultsFromConfigSchema](API.md#getdefaultsfromconfigschema) - [isSameDay](API.md#issameday) - [isVersionSatisfied](API.md#isversionsatisfied) - [retry](API.md#retry) @@ -4841,6 +4842,35 @@ The number of days. ___ +### getDefaultsFromConfigSchema + +▸ **getDefaultsFromConfigSchema**(`schema`): `Object` + +Given a config schema, this returns an object like is returned by `useConfig` +with all default values. + +This should be used in tests and not in production code. + +If all you need is the default values in your tests, these are returned by +default from the `useConfig`/`getConfig` mock. This function is useful if you +need to override some of the default values. + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `schema` | `any` | + +#### Returns + +`Object` + +#### Defined in + +[packages/framework/esm-utils/src/test-helpers.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-utils/src/test-helpers.ts#L13) + +___ + ### isSameDay ▸ **isSameDay**(`firstDate`, `secondDate`): `boolean` diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 22a0b1aca..999533fa1 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -4,7 +4,15 @@ import { createStore, type StoreApi } from 'zustand'; import { NEVER, of } from 'rxjs'; import { interpolateUrl } from '@openmrs/esm-config'; import { type SessionStore } from '@openmrs/esm-api'; -export { parseDate, formatDate, formatDatetime, formatTime, age } from '@openmrs/esm-utils'; +import { getDefaultsFromConfigSchema } from '@openmrs/esm-utils'; +export { + getDefaultsFromConfigSchema, + parseDate, + formatDate, + formatDatetime, + formatTime, + age, +} from '@openmrs/esm-utils'; export { interpolateString, interpolateUrl, validators, validator } from '@openmrs/esm-config'; window.i18next = { ...window.i18next, language: 'en' }; @@ -135,28 +143,10 @@ export enum Type { } let configSchema = {}; -function getDefaults(schema) { - let tmp = {}; - for (let k of Object.keys(schema)) { - if (schema[k].hasOwnProperty('_default')) { - tmp[k] = schema[k]._default; - } else if (k.startsWith('_')) { - continue; - } else if (isOrdinaryObject(schema[k])) { - tmp[k] = getDefaults(schema[k]); - } else { - tmp[k] = schema[k]; - } - } - return tmp; -} -function isOrdinaryObject(x) { - return !!x && x.constructor === Object; -} -export const getConfig = jest.fn().mockImplementation(() => Promise.resolve(getDefaults(configSchema))); +export const getConfig = jest.fn().mockImplementation(() => Promise.resolve(getDefaultsFromConfigSchema(configSchema))); -export const useConfig = jest.fn().mockImplementation(() => getDefaults(configSchema)); +export const useConfig = jest.fn().mockImplementation(() => getDefaultsFromConfigSchema(configSchema)); export function defineConfigSchema(moduleName, schema) { configSchema = schema; diff --git a/packages/framework/esm-utils/src/index.ts b/packages/framework/esm-utils/src/index.ts index 804499d25..68b47c9f4 100644 --- a/packages/framework/esm-utils/src/index.ts +++ b/packages/framework/esm-utils/src/index.ts @@ -2,6 +2,7 @@ export * from './age-helpers'; export * from './omrs-dates'; export * from './shallowEqual'; export * from './storage'; +export * from './test-helpers'; export * from './translate'; export * from './version'; export * from './retry'; diff --git a/packages/framework/esm-utils/src/test-helpers.ts b/packages/framework/esm-utils/src/test-helpers.ts new file mode 100644 index 000000000..c9cd7596a --- /dev/null +++ b/packages/framework/esm-utils/src/test-helpers.ts @@ -0,0 +1,31 @@ +/** @module @category Utility */ + +/** + * Given a config schema, this returns an object like is returned by `useConfig` + * with all default values. + * + * This should be used in tests and not in production code. + * + * If all you need is the default values in your tests, these are returned by + * default from the `useConfig`/`getConfig` mock. This function is useful if you + * need to override some of the default values. + */ +export function getDefaultsFromConfigSchema(schema) { + let tmp = {}; + for (let k of Object.keys(schema)) { + if (schema[k].hasOwnProperty('_default')) { + tmp[k] = schema[k]._default; + } else if (k.startsWith('_')) { + continue; + } else if (isOrdinaryObject(schema[k])) { + tmp[k] = getDefaultsFromConfigSchema(schema[k]); + } else { + tmp[k] = schema[k]; + } + } + return tmp; +} + +function isOrdinaryObject(x) { + return !!x && x.constructor === Object; +} From f52c335ca147fe599180682ce14bb049625bb85a Mon Sep 17 00:00:00 2001 From: jnsereko <58003327+jnsereko@users.noreply.github.com> Date: Thu, 28 Dec 2023 13:06:02 +0300 Subject: [PATCH 11/37] feat: O3-310: Add an application-writable config.json file in frontends/ (#629) Co-authored-by: Brandon Istenes --- .../openmrs-backend-dependencies.ts | 19 ++++++++ .../configuration/configuration.component.tsx | 45 ++++++++++++++++++- .../configuration/configuration.resource.tsx | 11 +++++ .../src/popup/popup.styles.scss | 2 +- .../translations/am.json | 4 ++ .../translations/ar.json | 4 ++ .../translations/en.json | 4 ++ .../translations/es.json | 4 ++ .../translations/fr.json | 4 ++ .../translations/he.json | 4 ++ .../translations/km.json | 4 ++ 11 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 packages/apps/esm-implementer-tools-app/src/configuration/configuration.resource.tsx diff --git a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/openmrs-backend-dependencies.ts b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/openmrs-backend-dependencies.ts index f6c9e8244..c8677ec5b 100644 --- a/packages/apps/esm-implementer-tools-app/src/backend-dependencies/openmrs-backend-dependencies.ts +++ b/packages/apps/esm-implementer-tools-app/src/backend-dependencies/openmrs-backend-dependencies.ts @@ -1,5 +1,6 @@ import { isVersionSatisfied, openmrsFetch } from '@openmrs/esm-framework'; import difference from 'lodash-es/difference'; +import { useMemo, useState } from 'react'; export type ResolvedBackendModuleType = 'missing' | 'version-mismatch' | 'okay'; @@ -155,3 +156,21 @@ export async function checkModules(): Promise> export function hasInvalidDependencies(frontendModules: Array) { return frontendModules.some((m) => m.dependencies.some((n) => n.type !== 'okay')); } + +export function useBackendDependencyCheck(moduleName: string) { + const [backendDependencies, setBackendDependencies] = useState>([]); + + useMemo(async () => { + const dependencies = await initInstalledBackendModules(); + setBackendDependencies(dependencies); + }, []); + + const isPresent = useMemo(() => { + if (backendDependencies) { + return backendDependencies.some((module) => module.uuid === moduleName); + } + return false; + }, [backendDependencies, moduleName]); + + return isPresent; +} diff --git a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx index 1acccb9b7..2a9a97b55 100644 --- a/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/configuration/configuration.component.tsx @@ -1,13 +1,16 @@ import React, { useMemo, useState } from 'react'; import { Button, Column, FlexGrid, Row, TextInput, Toggle } from '@carbon/react'; import { useTranslation } from 'react-i18next'; -import { ChevronDown, ChevronUp, Download, TrashCan } from '@carbon/react/icons'; +import { ChevronDown, ChevronUp, Download, TrashCan, Upload } from '@carbon/react/icons'; import cloneDeep from 'lodash-es/cloneDeep'; import isEmpty from 'lodash-es/isEmpty'; import type { Config } from '@openmrs/esm-framework/src/internal'; import { getExtensionInternalStore, implementerToolsConfigStore, + navigate, + showNotification, + showToast, temporaryConfigStore, useStore, useStoreWithActions, @@ -17,6 +20,8 @@ import { Description } from './interactive-editor/description.component'; import type { ImplementerToolsStore } from '../store'; import { implementerToolsStore } from '../store'; import styles from './configuration.styles.scss'; +import { saveConfig } from './configuration.resource'; +import { useBackendDependencyCheck } from '../backend-dependencies/openmrs-backend-dependencies'; const JsonEditor = React.lazy(() => import('./json-editor/json-editor.component')); @@ -62,6 +67,7 @@ export interface ConfigurationProps {} export const Configuration: React.FC = () => { const { t } = useTranslation(); + const isSpaModulePresent = useBackendDependencyCheck('spa'); const { isUIEditorEnabled, toggleIsUIEditorEnabled, @@ -158,6 +164,43 @@ export const Configuration: React.FC = () => { > {t('clearConfig', 'Clear Local Config')} + {isSpaModulePresent ? ( + + ) : null} - {isSpaModulePresent ? ( - - ) : null} ); } From 85301d806de251c7d5eec69d8e85f36bda688a49 Mon Sep 17 00:00:00 2001 From: Ian <52504170+ibacher@users.noreply.github.com> Date: Sat, 30 Dec 2023 08:52:04 -0500 Subject: [PATCH 15/37] (feat) Dynamically reload routes.json files for packages from sources (#824) --- packages/tooling/openmrs/package.json | 1 + packages/tooling/openmrs/src/cli.ts | 4 +- .../tooling/openmrs/src/commands/develop.ts | 44 +++++++++++++++---- .../tooling/openmrs/src/utils/debugger.ts | 12 ++--- .../tooling/openmrs/src/utils/dependencies.ts | 4 +- .../tooling/openmrs/src/utils/importmap.ts | 44 ++++++++++++++----- yarn.lock | 8 ++++ 7 files changed, 88 insertions(+), 29 deletions(-) diff --git a/packages/tooling/openmrs/package.json b/packages/tooling/openmrs/package.json index 6707c7f18..7edb835d7 100644 --- a/packages/tooling/openmrs/package.json +++ b/packages/tooling/openmrs/package.json @@ -45,6 +45,7 @@ "html-webpack-plugin": "^5.5.0", "inquirer": "^7.3.3", "mini-css-extract-plugin": "^2.4.5", + "node-watch": "^0.7.4", "npm-registry-fetch": "^14.0.3", "pacote": "^15.0.0", "postcss": "^8.4.6", diff --git a/packages/tooling/openmrs/src/cli.ts b/packages/tooling/openmrs/src/cli.ts index a7bcc480e..fc502a98f 100644 --- a/packages/tooling/openmrs/src/cli.ts +++ b/packages/tooling/openmrs/src/cli.ts @@ -43,7 +43,7 @@ yargs.command( .describe('add-cookie', 'Additional cookies to provide when proxying.') .boolean('support-offline') .describe('support-offline', 'Determines if a service worker should be installed for offline support.') - .default('support-offline', true) + .default('support-offline', false) .string('spa-path') .default('spa-path', '/openmrs/spa/') .describe('spa-path', 'The path of the application on the target server.') @@ -178,7 +178,7 @@ yargs.command( type: 'boolean', }) .option('support-offline', { - default: true, + default: false, describe: 'Determines if a service worker should be installed for offline support.', type: 'boolean', }) diff --git a/packages/tooling/openmrs/src/commands/develop.ts b/packages/tooling/openmrs/src/commands/develop.ts index ca2b92d7f..fe9542d20 100644 --- a/packages/tooling/openmrs/src/commands/develop.ts +++ b/packages/tooling/openmrs/src/commands/develop.ts @@ -1,9 +1,9 @@ import express from 'express'; import { createProxyMiddleware } from 'http-proxy-middleware'; -import { resolve } from 'path'; -import { readFileSync } from 'fs'; -import type { ImportmapDeclaration } from '../utils'; -import { logInfo, logWarn, removeTrailingSlash } from '../utils'; +import { resolve } from 'node:path'; +import { readFileSync } from 'node:fs'; +import { readFile } from 'node:fs/promises'; +import { type ImportmapDeclaration, type RoutesDeclaration, logInfo, logWarn, removeTrailingSlash } from '../utils'; /* eslint-disable no-console */ @@ -13,7 +13,8 @@ export interface DevelopArgs { backend: string; open: boolean; importmap: ImportmapDeclaration; - routes: Record; + routes: RoutesDeclaration; + watchedRoutesPaths: Record; spaPath: string; apiUrl: string; configUrls: Array; @@ -21,8 +22,9 @@ export interface DevelopArgs { supportOffline: boolean; } -export function runDevelop(args: DevelopArgs) { - const { backend, host, port, open, importmap, configUrls, addCookie, supportOffline } = args; +export async function runDevelop(args: DevelopArgs) { + const { backend, host, port, open, importmap, routes, watchedRoutesPaths, configUrls, addCookie, supportOffline } = + args; const apiUrl = removeTrailingSlash(args.apiUrl); const spaPath = removeTrailingSlash(args.spaPath); const app = express(); @@ -76,8 +78,32 @@ export function runDevelop(args: DevelopArgs) { }); } - if (args.routes && Object.keys(args.routes).length > 0) { - const stringifiedRoutes = JSON.stringify(args.routes); + if (routes.type === 'inline') { + let stringifiedRoutes = routes.value; + if (watchedRoutesPaths && !!Object.keys(watchedRoutesPaths).length) { + // watchedRoutesPath is keyed from package to path, but here we need to go from + // path to package. + const watchedRoutesByPath = Object.fromEntries(Object.entries(watchedRoutesPaths).map(([k, v]) => [v, k])); + + logInfo(`Watching routes.json for ${Object.keys(watchedRoutesPaths).join(', ')}`); + // setup watchers for all the discovered routes.json files which update the in-memory map + (await import('node-watch')).default(Object.keys(watchedRoutesByPath), { delay: 0 }, async (event, name) => { + if (event === 'update') { + const updatedApp = watchedRoutesByPath[name]; + if (updatedApp) { + const jsonRoutes = JSON.parse(stringifiedRoutes); + const version = jsonRoutes[updatedApp]?.version; + jsonRoutes[updatedApp] = { + ...JSON.parse(await readFile(name, 'utf8')), + version, + }; + stringifiedRoutes = JSON.stringify(jsonRoutes); + logInfo(`Updated routes for ${updatedApp}`); + } + } + }); + } + app.get(`${spaPath}/routes.registry.json`, (_, res) => { res.contentType('application/json').send(stringifiedRoutes); }); diff --git a/packages/tooling/openmrs/src/utils/debugger.ts b/packages/tooling/openmrs/src/utils/debugger.ts index ebd3029b0..9c32dbd96 100644 --- a/packages/tooling/openmrs/src/utils/debugger.ts +++ b/packages/tooling/openmrs/src/utils/debugger.ts @@ -1,5 +1,6 @@ -import { dirname } from 'path'; -import { logInfo, logWarn } from './logger'; +import { dirname } from 'node:path'; +import { logInfo } from './logger'; +import type { Configuration } from 'webpack'; function getWebpackEnv() { return { @@ -11,7 +12,7 @@ function getWebpackEnv() { } function loadConfig(configPath: string) { - const content = require(configPath); + const content: Configuration | ((env: unknown) => Configuration) = require(configPath); if (typeof content === 'function') { return content(getWebpackEnv()); } @@ -20,7 +21,8 @@ function loadConfig(configPath: string) { function debug(configPath: string, port: number) { const Webpack = require('webpack'); - const WebpackDevServer = require('webpack-dev-server'); + // eslint-disable-next-line @typescript-eslint/consistent-type-imports + const WebpackDevServer: typeof import('webpack-dev-server') = require('webpack-dev-server'); const config = loadConfig(configPath); const compiler = Webpack(config); @@ -37,4 +39,4 @@ function debug(configPath: string, port: number) { }); } -process.on('message', ({ source, port }) => debug(source, port)); +process.on('message', ({ source, port }: { source: string; port: number }) => debug(source, port)); diff --git a/packages/tooling/openmrs/src/utils/dependencies.ts b/packages/tooling/openmrs/src/utils/dependencies.ts index f20180015..3445dfb5d 100644 --- a/packages/tooling/openmrs/src/utils/dependencies.ts +++ b/packages/tooling/openmrs/src/utils/dependencies.ts @@ -1,5 +1,5 @@ -import { basename, dirname, resolve } from 'path'; -import { existsSync, readFileSync, statSync } from 'fs'; +import { basename, dirname, resolve } from 'node:path'; +import { existsSync, readFileSync, statSync } from 'node:fs'; import { inc } from 'semver'; export function getSharedDependencies() { diff --git a/packages/tooling/openmrs/src/utils/importmap.ts b/packages/tooling/openmrs/src/utils/importmap.ts index 38c9d83cd..d9448b156 100644 --- a/packages/tooling/openmrs/src/utils/importmap.ts +++ b/packages/tooling/openmrs/src/utils/importmap.ts @@ -30,7 +30,7 @@ async function readImportmap(path: string, backend?: string, spaPath?: string) { async function readRoutes(path: string, backend?: string, spaPath?: string) { if (path.startsWith('http://') || path.startsWith('https://')) { - return fetchRemoteImportmap(path); + return fetchRemoteRoutes(path); } else if (path === 'routes.registry.json') { if (backend && spaPath) { try { @@ -91,6 +91,12 @@ export interface ImportmapAndRoutes { routes: RoutesDeclaration; } +export interface ImportmapAndRoutesWithWatches extends ImportmapAndRoutes { + importMap: ImportmapDeclaration; + routes: RoutesDeclaration; + watchedRoutesPaths: Record; +} + export function checkImportmapJson(value: string) { try { const content = JSON.parse(value); @@ -162,11 +168,13 @@ export async function runProject( ): Promise<{ importMap: Record; routes: Record; + watchedRoutesPaths: Record; }> { const baseDir = process.cwd(); const sourceDirectories = await matchAny(baseDir, sourceDirectoryPatterns); const importMap = {}; const routes = {}; + const watchedRoutesPaths = {}; logInfo('Loading dynamic import map and routes ...'); @@ -174,6 +182,8 @@ export async function runProject( const sourceDirectory = resolve(baseDir, sourceDirectories[i]); const projectFile = resolve(sourceDirectory, 'package.json'); const configPath = resolve(sourceDirectory, 'webpack.config.js'); + const routesFile = resolve(sourceDirectory, 'src', 'routes.json'); + const port = basePort + i + 1; logInfo(`Looking in directory "${sourceDirectory}" ...`); @@ -186,6 +196,10 @@ export async function runProject( const project = require(projectFile); const startup = project['openmrs:develop']; + if (existsSync(routesFile)) { + watchedRoutesPaths[project.name] = routesFile; + } + if (typeof startup === 'object') { // detected specialized startup command const cp = exec(startup.command, { @@ -208,7 +222,7 @@ export async function runProject( logInfo(`Assembled dynamic import map and routes for packages (${Object.keys(importMap).join(', ')}).`); - return { importMap, routes }; + return { importMap, routes, watchedRoutesPaths }; } /** @@ -220,12 +234,22 @@ export async function runProject( */ export async function mergeImportmapAndRoutes( importAndRoutes: ImportmapAndRoutes, - additionalImportsAndRoutes: { importMap: Record; routes: Record } | false, + additionalImportsAndRoutes: + | { + importMap: Record; + routes: Record; + watchedRoutesPaths: Record; + } + | false, backend?: string, spaPath?: string, -): Promise { +): Promise { const { importMap: importDecl, routes: routesDecl } = importAndRoutes; - const { importMap: additionalImports, routes: additionalRoutes } = additionalImportsAndRoutes || {}; + const { + importMap: additionalImports, + routes: additionalRoutes, + watchedRoutesPaths = {}, + } = additionalImportsAndRoutes || {}; if (additionalImports && Object.keys(additionalImports).length > 0) { if (importDecl.type === 'url') { @@ -257,7 +281,7 @@ export async function mergeImportmapAndRoutes( }); } - return { importMap: importDecl, routes: routesDecl }; + return { importMap: importDecl, routes: routesDecl, watchedRoutesPaths }; } export async function getImportmapAndRoutes( @@ -350,12 +374,12 @@ export async function getRoutes(routesPath: string): Promise * `backend` changed to import from `http://${host}:${port}`. */ export function proxyImportmapAndRoutes( - importmapAndRoutes: ImportmapAndRoutes, + importmapAndRoutes: ImportmapAndRoutesWithWatches, backend: string, host: string, port: number, ) { - const { importMap: importMapDecl, routes: routesDecl } = importmapAndRoutes; + const { importMap: importMapDecl, routes: routesDecl, watchedRoutesPaths } = importmapAndRoutes; if (importMapDecl.type != 'inline') { throw new Error( 'proxyImportmapAndRoutes called on non-inline import map. This is a programming error. Value: ' + @@ -378,7 +402,5 @@ export function proxyImportmapAndRoutes( }); importMapDecl.value = JSON.stringify(importmap); - const routes: Record = JSON.parse(routesDecl.value); - - return { importmap: importMapDecl, routes }; + return { importmap: importMapDecl, routes: routesDecl, watchedRoutesPaths }; } diff --git a/yarn.lock b/yarn.lock index 760739278..98fc379ad 100644 --- a/yarn.lock +++ b/yarn.lock @@ -12487,6 +12487,13 @@ __metadata: languageName: node linkType: hard +"node-watch@npm:^0.7.4": + version: 0.7.4 + resolution: "node-watch@npm:0.7.4" + checksum: ea752dd5cd0aa1344ced1002409c8a81829cc5406fd949f34e8886786f2015651d2da9c3d3d4f164d23b9e84c7062ff97051746fe77db18955ffb23dc3dc0b76 + languageName: node + linkType: hard + "nopt@npm:^6.0.0": version: 6.0.0 resolution: "nopt@npm:6.0.0" @@ -12896,6 +12903,7 @@ __metadata: html-webpack-plugin: "npm:^5.5.0" inquirer: "npm:^7.3.3" mini-css-extract-plugin: "npm:^2.4.5" + node-watch: "npm:^0.7.4" npm-registry-fetch: "npm:^14.0.3" pacote: "npm:^15.0.0" postcss: "npm:^8.4.6" From bb1bf9b078b315e71a72f3acffbeb3df137a1181 Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Tue, 2 Jan 2024 21:40:12 +0300 Subject: [PATCH 16/37] (chore) Update GitHub Actions (#869) --- .github/workflows/ci.yml | 26 +++++++++++++------------- .github/workflows/e2e.yml | 6 +++--- 2 files changed, 16 insertions(+), 16 deletions(-) diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 9a59e7c06..b8a233f4c 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -22,9 +22,9 @@ jobs: actions: read steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: registry-url: "https://registry.npmjs.org" node-version: "18" @@ -55,15 +55,15 @@ jobs: pre_release: runs-on: ubuntu-latest needs: build - - if: ${{ (github.event.head_commit == null || - !startsWith(github.event.head_commit.message, '(chore) Release v')) && + + if: ${{ (github.event.head_commit == null || + !startsWith(github.event.head_commit.message, '(chore) Release v')) && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: registry-url: "https://registry.npmjs.org" node-version: "18" @@ -91,7 +91,7 @@ jobs: - name: Build run: yarn turbo run build --color --concurrency=5 - + - run: git config user.email "info@openmrs.org" && git config user.name "OpenMRS CI" - run: git add . && git commit -m "Prerelease version" --no-verify @@ -101,7 +101,7 @@ jobs: NODE_AUTH_TOKEN: ${{ secrets.NPM_AUTH_TOKEN }} - name: Upload Artifacts - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 with: name: packages path: | @@ -114,9 +114,9 @@ jobs: if: ${{ github.event_name == 'release' }} steps: - - uses: actions/checkout@v3 + - uses: actions/checkout@v4 - name: Setup Node.js - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: registry-url: "https://registry.npmjs.org" node-version: "18" @@ -145,8 +145,8 @@ jobs: needs: pre_release - if: ${{ (github.event.head_commit == null || - !startsWith(github.event.head_commit.message, '(release)')) && + if: ${{ (github.event.head_commit == null || + !startsWith(github.event.head_commit.message, '(release)')) && (github.event_name == 'push' || github.event_name == 'workflow_dispatch') }} steps: diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index 736e1717f..d40ece898 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -14,13 +14,13 @@ jobs: timeout-minutes: 15 steps: - name: Checkout repo - uses: actions/checkout@v3 + uses: actions/checkout@v4 - name: Copy test environment variables run: cp example.env .env - name: Setup node - uses: actions/setup-node@v3 + uses: actions/setup-node@v4 with: node-version: 18 @@ -54,7 +54,7 @@ jobs: run: docker stop $(docker ps -a -q) - name: Upload report - uses: actions/upload-artifact@v3 + uses: actions/upload-artifact@v4 if: always() with: name: playwright-report From 0d9f4b940bfeddde6928ddcf9f4d8e933cfc260e Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 2 Jan 2024 19:40:40 +0000 Subject: [PATCH 17/37] (feat) O3-2677: Improve the user menu (#868) --- .../esm-implementer-tools-app/package.json | 2 +- packages/apps/esm-login-app/package.json | 2 +- ...tsx => change-location-link.extension.tsx} | 27 ++++--- .../change-location-link.scss | 39 +--------- .../change-location-link.test.tsx | 25 +++--- packages/apps/esm-login-app/src/index.ts | 4 +- ...out.component.tsx => logout.extension.tsx} | 15 ++-- .../apps/esm-login-app/src/logout/logout.scss | 9 ++- packages/apps/esm-login-app/src/routes.json | 2 +- .../apps/esm-offline-tools-app/package.json | 2 +- .../apps/esm-offline-tools-app/src/index.ts | 2 +- ...offline-actions-mode-button.extension.tsx} | 9 ++- .../offline-actions-mode-button.scss | 25 ++---- .../esm-primary-navigation-app/jest.config.js | 4 +- .../esm-primary-navigation-app/package.json | 2 +- .../change-language-link.extension.tsx | 32 ++++++++ .../change-language/change-language-link.scss | 13 ++++ .../change-language-modal.scss | 16 ++++ .../change-language/change-language.modal.tsx | 76 +++++++++++++++++++ .../change-language.resource.tsx} | 0 .../change-language/change-language.test.tsx | 42 ++++++++++ .../choose-locale/change-locale.component.tsx | 73 ------------------ .../choose-locale/change-locale.scss | 42 ---------- .../choose-locale/change-locale.test.tsx | 34 --------- .../user-menu-panel.component.tsx | 40 ++++------ .../navbar-header-panels/user-menu-panel.scss | 44 +++++++++++ .../components/navbar/navbar.component.tsx | 14 +--- .../user-panel-switcher.component.tsx | 23 +++--- .../user-panel-switcher.scss | 59 -------------- .../user-panel-switcher.test.tsx | 11 ++- .../esm-primary-navigation-app/src/index.ts | 9 ++- .../esm-primary-navigation-app/src/offline.ts | 2 +- .../esm-primary-navigation-app/src/root.scss | 4 + .../src/routes.json | 10 ++- .../translations/am.json | 7 +- .../translations/ar.json | 7 +- .../translations/en.json | 7 +- .../translations/es.json | 7 +- .../translations/fr.json | 7 +- .../translations/he.json | 7 +- .../translations/km.json | 7 +- 41 files changed, 372 insertions(+), 390 deletions(-) rename packages/apps/esm-login-app/src/change-location-link/{change-location-link.component.tsx => change-location-link.extension.tsx} (53%) rename packages/apps/esm-login-app/src/logout/{logout.component.tsx => logout.extension.tsx} (55%) rename packages/apps/esm-offline-tools-app/src/offline-actions/{offline-actions-mode-button.component.tsx => offline-actions-mode-button.extension.tsx} (82%) create mode 100644 packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.extension.tsx create mode 100644 packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.scss create mode 100644 packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-modal.scss create mode 100644 packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.modal.tsx rename packages/apps/esm-primary-navigation-app/src/components/{choose-locale/change-locale.resource.tsx => change-language/change-language.resource.tsx} (100%) create mode 100644 packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.test.tsx delete mode 100644 packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx delete mode 100644 packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.scss delete mode 100644 packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx create mode 100644 packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss delete mode 100644 packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.scss diff --git a/packages/apps/esm-implementer-tools-app/package.json b/packages/apps/esm-implementer-tools-app/package.json index 76d4f8188..f2f4712e0 100644 --- a/packages/apps/esm-implementer-tools-app/package.json +++ b/packages/apps/esm-implementer-tools-app/package.json @@ -17,7 +17,7 @@ "analyze": "webpack --mode=production --env analyze=true", "typescript": "tsc", "lint": "eslint src --ext ts,tsx", - "extract-translations": "i18next 'src/**/*.component.tsx' --config='../../../tools/i18next-parser.config.js'" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.modal.tsx' --config='../../../tools/i18next-parser.config.js'" }, "keywords": [ "openmrs", diff --git a/packages/apps/esm-login-app/package.json b/packages/apps/esm-login-app/package.json index 960e0d554..fae75fe9f 100644 --- a/packages/apps/esm-login-app/package.json +++ b/packages/apps/esm-login-app/package.json @@ -17,7 +17,7 @@ "analyze": "webpack --mode=production --env analyze=true", "typescript": "tsc", "lint": "eslint src --ext ts,tsx", - "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.resource.ts' --config='../../../tools/i18next-parser.config.js'" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.modal.tsx' 'src/**/*.resource.ts' --config='../../../tools/i18next-parser.config.js'" }, "keywords": [ "openmrs", diff --git a/packages/apps/esm-login-app/src/change-location-link/change-location-link.component.tsx b/packages/apps/esm-login-app/src/change-location-link/change-location-link.extension.tsx similarity index 53% rename from packages/apps/esm-login-app/src/change-location-link/change-location-link.component.tsx rename to packages/apps/esm-login-app/src/change-location-link/change-location-link.extension.tsx index a41291146..e38380b60 100644 --- a/packages/apps/esm-login-app/src/change-location-link/change-location-link.component.tsx +++ b/packages/apps/esm-login-app/src/change-location-link/change-location-link.extension.tsx @@ -1,17 +1,16 @@ import React from 'react'; import { useTranslation } from 'react-i18next'; -import { navigate } from '@openmrs/esm-framework'; +import { navigate, useSession } from '@openmrs/esm-framework'; import { Button } from '@carbon/react'; import { Location } from '@carbon/react/icons'; import styles from './change-location-link.scss'; +import { SwitcherItem } from '@carbon/react'; -interface ChangeLocationLinkProps { - referer?: string; - currentLocation: string; -} - -const ChangeLocationLink: React.FC = ({ referer, currentLocation }) => { +const ChangeLocationLink: React.FC = () => { const { t } = useTranslation(); + const session = useSession(); + const currentLocation = session?.sessionLocation?.display; + const referer = window.location.pathname; const changeLocation = () => { // update=true is passed as a query param for updating the location preference, @@ -22,15 +21,15 @@ const ChangeLocationLink: React.FC = ({ referer, curren }; return ( -
- +
- {currentLocation} - + +

{currentLocation}

-
+ + ); }; diff --git a/packages/apps/esm-login-app/src/change-location-link/change-location-link.scss b/packages/apps/esm-login-app/src/change-location-link/change-location-link.scss index 035f888e5..565871148 100644 --- a/packages/apps/esm-login-app/src/change-location-link/change-location-link.scss +++ b/packages/apps/esm-login-app/src/change-location-link/change-location-link.scss @@ -1,46 +1,13 @@ @import '~@openmrs/esm-styleguide/src/vars'; @import '../root.scss'; -.changeLocationLinkContainer { +.panelItemContainer a { display: flex; - flex-direction: row; - width: 16rem; - justify-content: flex-start; - color: $field-01; align-items: center; - @extend .bodyLong01; - height: 3rem; - cursor: pointer; -} - -.changeLocationLinkContainer svg { - margin: 0rem 0.75rem; - fill: $field-01; + justify-content: space-between; } -.changeLocationLinkContainer div { - width: 100%; +.panelItemContainer div { display: flex; - justify-content: space-between; align-items: center; } - -.changeLocationLinkContainer button, -.changeLocationLinkContainer button:hover { - color: $inverse-link; -} - -.changeLocationLinkContainer button :hover { - @include brand-03(background-color); - color: $inverse-link; -} - -.changeLocationLink { - color: $field-01; - width: fit-content; -} - -.changeLocationLink :hover { - color: $field-01; - @include brand-01(background-color); -} diff --git a/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx b/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx index 37cc9d7a7..09b866e16 100644 --- a/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx +++ b/packages/apps/esm-login-app/src/change-location-link/change-location-link.test.tsx @@ -1,24 +1,23 @@ import React from 'react'; -import ChangeLocationLink from './change-location-link.component'; +import ChangeLocationLink from './change-location-link.extension'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { navigate } from '@openmrs/esm-framework'; +import { navigate, useSession } from '@openmrs/esm-framework'; const navigateMock = navigate as jest.Mock; +const useSessionMock = useSession as jest.Mock; -describe('', () => { - const mockChangeLocationProps = { - referer: '/openmrs/spa/home', - currentLocation: 'Unknown Location', - }; +delete window.location; +window.location = new URL('https://dev3.openmrs.org/openmrs/spa/home') as any as Location; +describe('', () => { beforeEach(() => { - render( - , - ); + useSessionMock.mockReturnValue({ + sessionLocation: { + display: 'Waffle House', + }, + }); + render(); }); it('should display the `Change location` link', async () => { diff --git a/packages/apps/esm-login-app/src/index.ts b/packages/apps/esm-login-app/src/index.ts index 89af91670..711c58d03 100644 --- a/packages/apps/esm-login-app/src/index.ts +++ b/packages/apps/esm-login-app/src/index.ts @@ -2,8 +2,8 @@ import { defineConfigSchema, getSyncLifecycle } from '@openmrs/esm-framework'; import { configSchema } from './config-schema'; import rootComponent from './root.component'; import locationPickerComponent from './location-picker/location-picker.component'; -import changeLocationLinkComponent from './change-location-link/change-location-link.component'; -import logoutButtonComponent from './logout/logout.component'; +import changeLocationLinkComponent from './change-location-link/change-location-link.extension'; +import logoutButtonComponent from './logout/logout.extension'; const moduleName = '@openmrs/esm-login-app'; diff --git a/packages/apps/esm-login-app/src/logout/logout.component.tsx b/packages/apps/esm-login-app/src/logout/logout.extension.tsx similarity index 55% rename from packages/apps/esm-login-app/src/logout/logout.component.tsx rename to packages/apps/esm-login-app/src/logout/logout.extension.tsx index 12f9f083f..6c345775b 100644 --- a/packages/apps/esm-login-app/src/logout/logout.component.tsx +++ b/packages/apps/esm-login-app/src/logout/logout.extension.tsx @@ -1,6 +1,6 @@ import React, { useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { Button, Switcher, SwitcherDivider } from '@carbon/react'; +import { Button, SwitcherItem } from '@carbon/react'; import { navigate } from '@openmrs/esm-framework'; import styles from './logout.scss'; @@ -13,14 +13,11 @@ const Logout: React.FC = () => { }, []); return ( - <> - - - - - + + + ); }; diff --git a/packages/apps/esm-login-app/src/logout/logout.scss b/packages/apps/esm-login-app/src/logout/logout.scss index 5921c9a24..39deb43cb 100644 --- a/packages/apps/esm-login-app/src/logout/logout.scss +++ b/packages/apps/esm-login-app/src/logout/logout.scss @@ -1,11 +1,12 @@ @import '../root.scss'; -.logout { - padding-right: 0rem; - @extend .productiveHeading01; +/* Repeat selector for specificity */ +button.logout.logout { + color: $field-01; + font-size: 1rem; width: 16rem; &:hover { - @include brand-01(background-color); + background-color: inherit; } } diff --git a/packages/apps/esm-login-app/src/routes.json b/packages/apps/esm-login-app/src/routes.json index afbffe724..adc91ef0f 100644 --- a/packages/apps/esm-login-app/src/routes.json +++ b/packages/apps/esm-login-app/src/routes.json @@ -27,7 +27,7 @@ }, { "name": "logout-button", - "slot": "user-panel-actions-slot", + "slot": "user-panel-bottom-slot", "component": "logoutButton", "online": true, "offline": true diff --git a/packages/apps/esm-offline-tools-app/package.json b/packages/apps/esm-offline-tools-app/package.json index 2bf76b0d4..23381c655 100644 --- a/packages/apps/esm-offline-tools-app/package.json +++ b/packages/apps/esm-offline-tools-app/package.json @@ -17,7 +17,7 @@ "analyze": "webpack --mode=production --env analyze=true", "typescript": "tsc", "lint": "eslint src --ext ts,tsx", - "extract-translations": "i18next 'src/**/*.component.tsx' --config='../../../tools/i18next-parser.config.js'" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.modal.tsx' --config='../../../tools/i18next-parser.config.js'" }, "keywords": [ "openmrs", diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index 301273677..983933555 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -14,7 +14,7 @@ import offlineToolsActionsComponent from './offline-actions/offline-actions.comp import offlineToolsPatientsComponent from './offline-patients/offline-patients.component'; import offlineToolsPageActionsComponent from './offline-actions/offline-actions-page.component'; import offlineToolsPatientChartComponent from './offline-actions/offline-actions-patient-chart-widget.component'; -import offlineToolsOptInButtonComponent from './offline-actions/offline-actions-mode-button.component'; +import offlineToolsOptInButtonComponent from './offline-actions/offline-actions-mode-button.extension'; import OfflineToolsNavLink from './nav/offline-tools-nav-link.component'; export const importTranslation = require.context('../translations', false, /.json$/, 'lazy'); diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx similarity index 82% rename from packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx rename to packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx index 14018ac5a..140e779dc 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.component.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx @@ -4,6 +4,7 @@ import { Toggle } from '@carbon/react'; import { Network_3 } from '@carbon/react/icons'; import { getCurrentOfflineMode, setCurrentOfflineMode } from '@openmrs/esm-framework/src/internal'; import styles from './offline-actions-mode-button.scss'; +import { SwitcherItem } from '@carbon/react'; function doNotCloseMenu(ev: React.SyntheticEvent) { ev.stopPropagation(); @@ -21,15 +22,15 @@ const OfflineActionsModeButton: React.FC = () => { }, []); return ( -
+
- +

{t('offlineReady', 'Offline Ready')} - +

-
+ ); }; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss index 94ba72837..6d77bb0a8 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss @@ -1,38 +1,27 @@ @import '~@openmrs/esm-styleguide/src/vars'; @import '../root.scss'; -.offlineModeButtonContainer { +.panelItemContainer a { display: flex; - flex-direction: row; - width: 16rem; justify-content: space-between; - color: $field-01; align-items: center; - @extend .bodyLong01; - height: 3rem; - cursor: pointer; :global(.cds--toggle-input__label .cds--toggle__switch) { margin-top: 0 !important; } :global(.cds--toggle) { + /* setting the width prevents the toggle from changing size when the text changes */ + width: 76px; margin: 0 1rem; } :global(.cds--toggle__text) { color: $ui-02; } +} - svg { - margin: 0rem 0.75rem; - fill: $field-01; - } - - & > div { - display: flex; - flex-direction: row; - width: fit-content; - align-items: center; - } +.panelItemContainer div { + display: flex; + align-items: center; } diff --git a/packages/apps/esm-primary-navigation-app/jest.config.js b/packages/apps/esm-primary-navigation-app/jest.config.js index f2b05f2ba..ef2c0b2ad 100644 --- a/packages/apps/esm-primary-navigation-app/jest.config.js +++ b/packages/apps/esm-primary-navigation-app/jest.config.js @@ -1,11 +1,11 @@ module.exports = { transform: { - '^.+\\.tsx?$': ['@swc/jest'], + '\\.(m?j|t)sx?$': ['@swc/jest'], }, transformIgnorePatterns: [], moduleNameMapper: { 'lodash-es': 'lodash', - '@openmrs/esm-framework': '/__mocks__/openmrs-esm-framework.mock.tsx', + '@openmrs/esm-framework': '@openmrs/esm-framework/mock.tsx', '\\.(s?css)$': 'identity-obj-proxy', 'react-i18next': '/__mocks__/react-i18next.mock.js', }, diff --git a/packages/apps/esm-primary-navigation-app/package.json b/packages/apps/esm-primary-navigation-app/package.json index 24b9cf840..6c0a4f191 100644 --- a/packages/apps/esm-primary-navigation-app/package.json +++ b/packages/apps/esm-primary-navigation-app/package.json @@ -17,7 +17,7 @@ "analyze": "webpack --mode=production --env analyze=true", "typescript": "tsc", "lint": "eslint src --ext ts,tsx", - "extract-translations": "i18next 'src/**/*.component.tsx' --config='../../../tools/i18next-parser.config.js'" + "extract-translations": "i18next 'src/**/*.component.tsx' 'src/**/*.extension.tsx' 'src/**/*.modal.tsx' --config='../../../tools/i18next-parser.config.js'" }, "keywords": [ "openmrs", diff --git a/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.extension.tsx b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.extension.tsx new file mode 100644 index 000000000..10b61f349 --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.extension.tsx @@ -0,0 +1,32 @@ +import React, { useCallback } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, SwitcherItem } from '@carbon/react'; +import { Language } from '@carbon/react/icons'; +import { showModal, useSession } from '@openmrs/esm-framework'; +import styles from './change-language-link.scss'; + +/** The user menu item that shows the current language and has a button to change the language */ +export function ChangeLanguageLink() { + const { t } = useTranslation(); + const session = useSession(); + + const launchChangeModal = useCallback(() => { + showModal('change-language-modal'); + }, []); + + const languageNames = new Intl.DisplayNames([session?.locale], { type: 'language' }); + + return ( + +
+ +

{languageNames.of(session?.locale)}

+
+ +
+ ); +} + +export default ChangeLanguageLink; diff --git a/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.scss b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.scss new file mode 100644 index 000000000..b167b32c4 --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-link.scss @@ -0,0 +1,13 @@ +@import '~@openmrs/esm-styleguide/src/vars'; +@import '../../root.scss'; + +.panelItemContainer a { + display: flex; + align-items: center; + justify-content: space-between; +} + +.panelItemContainer div { + display: flex; + align-items: center; +} diff --git a/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-modal.scss b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-modal.scss new file mode 100644 index 000000000..fd1389489 --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language-modal.scss @@ -0,0 +1,16 @@ +@use '@carbon/styles/scss/spacing'; +@import '../../root.scss'; + +.languageOptionsContainer { + display: flex; + flex-direction: column; + margin-left: 2em; + max-height: 28rem; +} + +.languageRadioButton { + display: flex; + height: spacing.$spacing-09; + align-items: center; + @extend .bodyShort01; +} diff --git a/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.modal.tsx b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.modal.tsx new file mode 100644 index 000000000..4ac4445eb --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.modal.tsx @@ -0,0 +1,76 @@ +import React, { useCallback, useMemo, useState } from 'react'; +import { useTranslation } from 'react-i18next'; +import { Button, ModalBody, ModalFooter, ModalHeader, RadioButton, RadioButtonGroup } from '@carbon/react'; +import { useConnectivity, useSession } from '@openmrs/esm-framework'; +import { postUserPropertiesOffline, postUserPropertiesOnline } from './change-language.resource'; +import styles from './change-language-modal.scss'; + +interface ChangeLanguageModalProps { + close(): void; +} + +export default function ChangeLanguageModal({ close }: ChangeLanguageModalProps) { + const { t } = useTranslation(); + const session = useSession(); + const user = session?.user; + const allowedLocales = session?.allowedLocales ?? []; + const [selectedLocale, setSelectedLocale] = useState(session?.locale); + const isOnline = useConnectivity(); + + const onSubmit = useCallback(() => { + const postUserProperties = isOnline ? postUserPropertiesOnline : postUserPropertiesOffline; + if (selectedLocale !== session?.locale) { + const ac = new AbortController(); + postUserProperties( + user.uuid, + { + ...(user.userProperties ?? {}), + defaultLocale: selectedLocale, + }, + ac, + ); + } + }, [isOnline, user.userProperties, user.uuid, selectedLocale]); + + const languageNames = useMemo( + () => Object.fromEntries(allowedLocales.map((l) => [l, new Intl.DisplayNames([l], { type: 'language' }).of(l)])), + [allowedLocales], + ); + + return ( + <> + + +
+ { + setSelectedLocale(l.toString()); + }} + > + {allowedLocales.map((l, i) => ( + + ))} + +
+
+ + + + + + ); +} diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.resource.tsx b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.resource.tsx similarity index 100% rename from packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.resource.tsx rename to packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.resource.tsx diff --git a/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.test.tsx b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.test.tsx new file mode 100644 index 000000000..bb8215498 --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/change-language/change-language.test.tsx @@ -0,0 +1,42 @@ +import React from 'react'; +import { render, screen } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; +import ChangeLanguageModal from './change-language.modal'; +import { useSession } from '@openmrs/esm-framework'; + +const mockUser: any = { + uuid: 'uuid', + userProperties: { + defaultLocale: 'fr', + }, +}; + +const mockUseSession = useSession as jest.Mock; +mockUseSession.mockReturnValue({ + authenticated: true, + user: mockUser, + allowedLocales: ['en', 'fr', 'it', 'pt'], + locale: 'fr', +}); + +const mockPostUserPropertiesOnline = jest.fn((...args) => Promise.resolve()); +jest.mock('./change-language.resource', () => ({ + postUserPropertiesOnline: (...args) => mockPostUserPropertiesOnline(...args), + postUserPropertiesOffline: jest.fn(), +})); + +describe(`Change Language Modal`, () => { + it('should change user locale', async () => { + const user = userEvent.setup(); + + render(); + expect(screen.getByRole('radio', { name: /français/ })).toBeChecked(); + await user.click(screen.getByRole('radio', { name: /english/i })); + await user.click(screen.getByRole('button', { name: /apply/i })); + expect(mockPostUserPropertiesOnline).toHaveBeenCalledWith( + mockUser.uuid, + { defaultLocale: 'en' }, + expect.anything(), + ); + }); +}); diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx deleted file mode 100644 index df8d5e168..000000000 --- a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.component.tsx +++ /dev/null @@ -1,73 +0,0 @@ -import React, { useCallback, useEffect, useMemo, useState } from 'react'; -import classNames from 'classnames'; -import { useTranslation } from 'react-i18next'; -import { Select, SelectItem } from '@carbon/react'; -import type { LoggedInUser } from '@openmrs/esm-framework'; -import { ExtensionSlot, useConnectivity } from '@openmrs/esm-framework'; -import type { PostUserProperties } from './change-locale.resource'; -import { postUserPropertiesOnline, postUserPropertiesOffline } from './change-locale.resource'; -import styles from './change-locale.scss'; - -export interface ChangeLocaleProps { - allowedLocales: Array; - user: LoggedInUser; - locale: string; - postUserProperties: PostUserProperties; -} - -const ChangeLocaleWrapper: React.FC> = (props) => { - const isOnline = useConnectivity(); - const postUserProperties = useMemo( - () => (isOnline ? postUserPropertiesOnline : postUserPropertiesOffline), - [isOnline], - ); - - return ; -}; - -// exported for tests -export const ChangeLocale: React.FC = ({ allowedLocales, locale, user, postUserProperties }) => { - const { t } = useTranslation(); - const [selectedLocale, setSelectedLocale] = useState(locale); - const options = allowedLocales?.map((locale) => ); - - const onChange = useCallback( - (event: React.ChangeEvent) => { - const newLocale = event.target.value; - if (newLocale !== selectedLocale) { - const ac = new AbortController(); - postUserProperties( - user.uuid, - { - ...(user.userProperties ?? {}), - defaultLocale: newLocale, - }, - ac, - ); - setSelectedLocale(newLocale); - } - }, - [postUserProperties, user.userProperties, user.uuid, selectedLocale], - ); - - const onClick = useCallback((event: React.SyntheticEvent) => event.stopPropagation(), []); - - return ( -
- - -
- ); -}; - -export default ChangeLocaleWrapper; diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.scss b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.scss deleted file mode 100644 index 9d7be5480..000000000 --- a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.scss +++ /dev/null @@ -1,42 +0,0 @@ -@import '../../root.scss'; - -.switcherContainer { - display: flex; - flex-direction: column; - padding: 0.5rem; - - label { - color: $labeldropdown; - } - - ul button { - @extend .productiveHeading01; - width: 100%; - background-color: var(--brand-02); - } - - ul div { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - @extend .bodyLong01; - } - - ul div button { - color: $inverse-link; - margin-left: 0.5rem; - width: 5rem; - } - - ul div button:hover { - @include brand-01(background-color); - color: $inverse-link; - } - - hr { - background-color: $ui-background; - width: 18rem; - margin: 0.5rem 0rem; - } -} diff --git a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx b/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx deleted file mode 100644 index effd7253b..000000000 --- a/packages/apps/esm-primary-navigation-app/src/components/choose-locale/change-locale.test.tsx +++ /dev/null @@ -1,34 +0,0 @@ -import React from 'react'; -import { render, screen } from '@testing-library/react'; -import userEvent from '@testing-library/user-event'; -import { ChangeLocale } from './change-locale.component'; -import type { PostUserProperties } from './change-locale.resource'; - -const allowedLocales = ['en', 'fr', 'it', 'pt']; -const user: any = { - uuid: 'uuid', - userProperties: { - defaultLocale: 'fr', - }, -}; - -describe(``, () => { - let postUserPropertiesMock: PostUserProperties = jest.fn(() => Promise.resolve()); - - it('should change user locale', async () => { - const userSetup = userEvent.setup(); - postUserPropertiesMock = jest.fn(() => Promise.resolve()); - - render( - , - ); - expect(screen.getByLabelText(/Select locale/)).toHaveValue('fr'); - await userSetup.selectOptions(screen.getByLabelText(/Select locale/i), 'en'); - expect(postUserPropertiesMock).toHaveBeenCalledWith(user.uuid, { defaultLocale: 'en' }, expect.anything()); - }); -}); diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx index b7909a734..07f1f3cbb 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx @@ -1,27 +1,19 @@ import React from 'react'; -import type { LoggedInUser, Session } from '@openmrs/esm-framework'; -import { ExtensionSlot, useOnClickOutside } from '@openmrs/esm-framework'; import type { HeaderPanelProps } from '@carbon/react'; -import { HeaderPanel } from '@carbon/react'; -import styles from '../../root.scss'; +import { HeaderPanel, Switcher, SwitcherDivider } from '@carbon/react'; +import { ExtensionSlot, useOnClickOutside } from '@openmrs/esm-framework'; +import styles from './user-menu-panel.scss'; interface UserMenuPanelProps extends HeaderPanelProps { expanded: boolean; - user: LoggedInUser | false | null; - allowedLocales: any; - onLogout(): void; - session: Session; hidePanel: () => void; } -const UserMenuPanel: React.FC = ({ - expanded, - user, - allowedLocales, - onLogout, - session, - hidePanel, -}) => { +/** + * Extensions attaching to `user-panel-slot` or `user-panel-bottom-slot` should in + * general be wrapped in the `SwitcherItem` Carbon component. + */ +const UserMenuPanel: React.FC = ({ expanded, hidePanel }) => { const userMenuRef = useOnClickOutside(hidePanel, expanded); return ( @@ -32,17 +24,11 @@ const UserMenuPanel: React.FC = ({ aria-label="Location" aria-labelledby="Location Icon" > - + + + + +
); }; diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss new file mode 100644 index 000000000..77a7e0247 --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss @@ -0,0 +1,44 @@ +@import '~@openmrs/esm-styleguide/src/vars'; +@import '../../root.scss'; + +.userPanelSwitcher { + padding-top: 1rem; + align-items: start; +} + +.userPanelSwitcher :global(.cds--switcher__item) { + height: 3rem; +} + +.userPanelSwitcher :global(.cds--switcher__item:first-child) { + margin-top: 0; +} + +.userPanelSwitcher :global(.cds--switcher__item-link) { + display: flex; + align-items: center; + color: $field-01; + padding: 0; + height: 3rem; + @extend .bodyLong01; +} + +.userPanelSwitcher :global(.cds--switcher__item-link):hover:not(.cds--switcher__item-link--selected) { + color: $field-01; + @include brand-02(background-color); +} + +.userPanelSwitcher :global(.cds--switcher__item) svg { + margin: 0rem 0.75rem; + fill: $field-01; + flex-shrink: 0; +} + +.userPanelSwitcher :global(.cds--switcher__item) button { + color: $inverse-link; +} + +.userPanelSwitcher :global(.cds--switcher__item) button:hover { + @include brand-03(background-color); + color: $inverse-link; +} diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx index faaf974c4..a801f32d7 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx @@ -26,7 +26,6 @@ const Navbar: React.FC = () => { const config = useConfig(); const [user, setUser] = useState(session?.user ?? null); const [activeHeaderPanel, setActiveHeaderPanel] = useState(null); - const allowedLocales = session?.allowedLocales ?? null; const layout = useLayoutType(); const navMenuItems = useConnectedExtensions('patient-chart-dashboard-slot').map((e) => e.id); const openmrsSpaBase = window['getOpenmrsSpaBase'](); @@ -40,8 +39,6 @@ const Navbar: React.FC = () => { [], ); - const logout = useCallback(() => setUser(false), []); - const hidePanel = useCallback(() => { setActiveHeaderPanel(null); }, []); @@ -122,16 +119,7 @@ const Navbar: React.FC = () => { {!isDesktop(layout) && } {showAppMenu && } - {showUserMenu && ( - - )} + {showUserMenu && } ); diff --git a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx index 44eda95ce..4a85be8c0 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.component.tsx @@ -1,20 +1,17 @@ import React from 'react'; -import { Switcher } from '@carbon/react'; import { UserAvatarFilledAlt } from '@carbon/react/icons'; -import type { LoggedInUser } from '@openmrs/esm-framework'; -import styles from './user-panel-switcher.scss'; +import { SwitcherItem } from '@carbon/react'; +import { useSession } from '@openmrs/esm-framework'; -export interface UserPanelSwitcherItemProps { - user: LoggedInUser; -} - -const UserPanelSwitcher: React.FC = ({ user }) => ( -
- +const UserPanelSwitcher: React.FC = () => { + const session = useSession(); + const user = session?.user; + return ( +

{user.person.display}

-
-
-); + + ); +}; export default UserPanelSwitcher; diff --git a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.scss b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.scss deleted file mode 100644 index fd35a8bd9..000000000 --- a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.scss +++ /dev/null @@ -1,59 +0,0 @@ -@import '../../root.scss'; - -.switcherContainer { - display: flex; - flex-direction: column; -} - -.switcherContainer ul { - display: flex; - flex-direction: row; - width: 20rem; - justify-content: flex-start; - color: $field-01; - align-items: center; - @extend .productiveHeading01; - height: 3rem; - cursor: pointer; -} - -.switcherContainer ul > svg { - margin: 0rem 0.75rem; - fill: $field-01; -} - -.switcherContainer ul button { - @extend .productiveHeading01; - width: 100%; - background-color: var(--brand-02); -} - -.switcherContainer ul button:hover { - color: $field-01; - background-color: var(--brand-01); -} - -.switcherContainer ul div { - display: flex; - flex-direction: row; - align-items: center; - justify-content: flex-start; - @extend .bodyLong01; -} - -.switcherContainer ul div button { - color: $inverse-link; - margin-left: 0.5rem; - width: 5rem; -} - -.switcherContainer ul div button:hover { - background-color: var(--brand-01); - color: $inverse-link; -} - -.switcherContainer hr { - background-color: $ui-background; - width: 16rem; - margin: 0.5rem 0rem; -} diff --git a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.test.tsx b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.test.tsx index 940e04e06..4bcd0046a 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.test.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/user-panel-switcher-item/user-panel-switcher.test.tsx @@ -1,14 +1,21 @@ import React from 'react'; -import UserPanelSwitcher from './user-panel-switcher.component'; import { screen, render } from '@testing-library/react'; +import { useSession } from '@openmrs/esm-framework'; +import UserPanelSwitcher from './user-panel-switcher.component'; import { mockLoggedInUser } from '../../../__mocks__/mock-user'; +const mockUseSession = useSession as jest.Mock; + describe('', () => { beforeEach(() => { - render(); + mockUseSession.mockReturnValue({ + authenticated: true, + user: mockLoggedInUser, + }); }); it('should display user name', async () => { + render(); expect(await screen.findByText(/Dr Healther Morgan/i)).toBeInTheDocument(); }); }); diff --git a/packages/apps/esm-primary-navigation-app/src/index.ts b/packages/apps/esm-primary-navigation-app/src/index.ts index ce4c3ad5e..882887c85 100644 --- a/packages/apps/esm-primary-navigation-app/src/index.ts +++ b/packages/apps/esm-primary-navigation-app/src/index.ts @@ -12,7 +12,7 @@ import { moduleName, userPropertyChange } from './constants'; import { syncUserLanguagePreference } from './offline'; import primaryNavRootComponent from './root.component'; import userPanelComponent from './components/user-panel-switcher-item/user-panel-switcher.component'; -import localeChangerComponent from './components/choose-locale/change-locale.component'; +import changeLanguageLinkComponent from './components/change-language/change-language-link.extension'; import offlineBannerComponent from './components/offline-banner/offline-banner.component'; import genericLinkComponent, { genericLinkConfigSchema } from './components/generic-link/generic-link.component'; @@ -40,7 +40,7 @@ export const redirect: Application = async () => ({ export const userPanel = getSyncLifecycle(userPanelComponent, options); -export const localeChanger = getSyncLifecycle(localeChangerComponent, options); +export const changeLanguageLink = getSyncLifecycle(changeLanguageLinkComponent, options); export const offlineBanner = getSyncLifecycle(offlineBannerComponent, options); @@ -48,3 +48,8 @@ export const linkComponent = getSyncLifecycle(genericLinkComponent, { featureName: 'Link', moduleName, }); + +export const changeLanguageModal = getAsyncLifecycle( + () => import('./components/change-language/change-language.modal'), + options, +); diff --git a/packages/apps/esm-primary-navigation-app/src/offline.ts b/packages/apps/esm-primary-navigation-app/src/offline.ts index 1c8b15ee3..b9169938f 100644 --- a/packages/apps/esm-primary-navigation-app/src/offline.ts +++ b/packages/apps/esm-primary-navigation-app/src/offline.ts @@ -1,6 +1,6 @@ import type { SyncProcessOptions } from '@openmrs/esm-framework/src/internal'; import { refetchCurrentUser, getLoggedInUser } from '@openmrs/esm-framework/src/internal'; -import { postUserPropertiesOnline } from './components/choose-locale/change-locale.resource'; +import { postUserPropertiesOnline } from './components/change-language/change-language.resource'; export async function syncUserLanguagePreference(_: any, options: SyncProcessOptions) { if (options.index === 0) { diff --git a/packages/apps/esm-primary-navigation-app/src/root.scss b/packages/apps/esm-primary-navigation-app/src/root.scss index 8e2da66b7..c07cc9387 100644 --- a/packages/apps/esm-primary-navigation-app/src/root.scss +++ b/packages/apps/esm-primary-navigation-app/src/root.scss @@ -13,6 +13,10 @@ @include type.type-style('body-01'); } +.bodyShort01 { + @include type.type-style('body-compact-01'); +} + .headerPanel { height: max-content; } diff --git a/packages/apps/esm-primary-navigation-app/src/routes.json b/packages/apps/esm-primary-navigation-app/src/routes.json index 087767b29..959147387 100644 --- a/packages/apps/esm-primary-navigation-app/src/routes.json +++ b/packages/apps/esm-primary-navigation-app/src/routes.json @@ -29,13 +29,19 @@ "order": 0 }, { - "name": "change-locale", + "name": "change-language", "slot": "user-panel-slot", - "component": "localeChanger", + "component": "changeLanguageLink", "online": true, "offline": true, "order": 1 }, + { + "name": "change-language-modal", + "component": "changeLanguageModal", + "online": true, + "offline": true + }, { "name": "offline-banner", "slot": "user-panel-slot", diff --git a/packages/apps/esm-primary-navigation-app/translations/am.json b/packages/apps/esm-primary-navigation-app/translations/am.json index 87a97c616..0073c9a15 100644 --- a/packages/apps/esm-primary-navigation-app/translations/am.json +++ b/packages/apps/esm-primary-navigation-app/translations/am.json @@ -1,4 +1,7 @@ { - "notifications": "Notifications", - "selectLocale": "Select locale" + "apply": "Apply", + "cancel": "Cancel", + "change": "Change", + "changeLanguage": "Change Language", + "notifications": "Notifications" } diff --git a/packages/apps/esm-primary-navigation-app/translations/ar.json b/packages/apps/esm-primary-navigation-app/translations/ar.json index a83e3cc18..61fabdb40 100644 --- a/packages/apps/esm-primary-navigation-app/translations/ar.json +++ b/packages/apps/esm-primary-navigation-app/translations/ar.json @@ -1,4 +1,7 @@ { - "notifications": "الإشعارات", - "selectLocale": "اختر اللغة" + "apply": "Apply", + "cancel": "Cancel", + "change": "تغيير", + "changeLanguage": "Change Language", + "notifications": "الإشعارات" } diff --git a/packages/apps/esm-primary-navigation-app/translations/en.json b/packages/apps/esm-primary-navigation-app/translations/en.json index 87a97c616..0073c9a15 100644 --- a/packages/apps/esm-primary-navigation-app/translations/en.json +++ b/packages/apps/esm-primary-navigation-app/translations/en.json @@ -1,4 +1,7 @@ { - "notifications": "Notifications", - "selectLocale": "Select locale" + "apply": "Apply", + "cancel": "Cancel", + "change": "Change", + "changeLanguage": "Change Language", + "notifications": "Notifications" } diff --git a/packages/apps/esm-primary-navigation-app/translations/es.json b/packages/apps/esm-primary-navigation-app/translations/es.json index 19c44404c..2173b6c2f 100644 --- a/packages/apps/esm-primary-navigation-app/translations/es.json +++ b/packages/apps/esm-primary-navigation-app/translations/es.json @@ -1,4 +1,7 @@ { - "notifications": "Notificaciones", - "selectLocale": "Seleccionar la localización" + "apply": "Aplicar", + "cancel": "Cancelar", + "change": "Cambiar", + "changeLanguage": "Cambiar idioma", + "notifications": "Notificaciones" } diff --git a/packages/apps/esm-primary-navigation-app/translations/fr.json b/packages/apps/esm-primary-navigation-app/translations/fr.json index 1b087590e..273b7fc0d 100644 --- a/packages/apps/esm-primary-navigation-app/translations/fr.json +++ b/packages/apps/esm-primary-navigation-app/translations/fr.json @@ -1,4 +1,7 @@ { - "notifications": "Notifications", - "selectLocale": "Sélectionner les paramètres régionaux" + "apply": "Appliquer", + "cancel": "Annuler", + "change": "Changer", + "changeLanguage": "Changer de langue", + "notifications": "Notifications" } diff --git a/packages/apps/esm-primary-navigation-app/translations/he.json b/packages/apps/esm-primary-navigation-app/translations/he.json index 3aef1656b..fa646a9f3 100644 --- a/packages/apps/esm-primary-navigation-app/translations/he.json +++ b/packages/apps/esm-primary-navigation-app/translations/he.json @@ -1,4 +1,7 @@ { - "notifications": "התראות", - "selectLocale": "בחירת שפה" + "apply": "אישור", + "cancel": "Cancel", + "change": "שינוי", + "changeLanguage": "Change Language", + "notifications": "התראות" } diff --git a/packages/apps/esm-primary-navigation-app/translations/km.json b/packages/apps/esm-primary-navigation-app/translations/km.json index d7e5b9e99..7dd4111ed 100644 --- a/packages/apps/esm-primary-navigation-app/translations/km.json +++ b/packages/apps/esm-primary-navigation-app/translations/km.json @@ -1,4 +1,7 @@ { - "notifications": "ការជូនដំណឹង", - "selectLocale": "ជ្រើសរើសភាសា" + "apply": "បញ្ជាក់", + "cancel": "Cancel", + "change": "ផ្លាស់ប្តូរ", + "changeLanguage": "Change Language", + "notifications": "ការជូនដំណឹង" } From 30f069ed4fe49a77fbdfe614a085c2aef4b4f464 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 2 Jan 2024 21:03:36 +0000 Subject: [PATCH 18/37] (feat) Allow ConfigurableLink to have a callback before navigating (#871) --- packages/framework/esm-framework/docs/API.md | 2 +- .../docs/interfaces/ConfigurableLinkProps.md | 22 +++++++++++-- packages/framework/esm-framework/mock.tsx | 8 +---- .../src/ConfigurableLink.test.tsx | 31 +++++++++++++++++-- .../esm-react-utils/src/ConfigurableLink.tsx | 10 ++++-- 5 files changed, 57 insertions(+), 16 deletions(-) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index e03de730e..09454248f 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -3174,7 +3174,7 @@ A React link component which calls [navigate](API.md#navigate) when clicked #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L29) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L32) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md index 93fefddb5..f42f38819 100644 --- a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md +++ b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md @@ -283,6 +283,10 @@ - [unselectable](ConfigurableLinkProps.md#unselectable) - [vocab](ConfigurableLinkProps.md#vocab) +### Navigation Methods + +- [onBeforeNavigate](ConfigurableLinkProps.md#onbeforenavigate) + ## Navigation Properties ### templateParams @@ -291,7 +295,7 @@ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L18) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L19) ___ @@ -301,7 +305,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L17) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L18) ___ @@ -4156,3 +4160,17 @@ AnchorHTMLAttributes.vocab #### Defined in node_modules/@types/react/index.d.ts:1882 + +## Navigation Methods + +### onBeforeNavigate + +▸ `Optional` **onBeforeNavigate**(): `void` + +#### Returns + +`void` + +#### Defined in + +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L20) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 999533fa1..8c7b51270 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -2,7 +2,6 @@ import React from 'react'; import type {} from '@openmrs/esm-globals'; import { createStore, type StoreApi } from 'zustand'; import { NEVER, of } from 'rxjs'; -import { interpolateUrl } from '@openmrs/esm-config'; import { type SessionStore } from '@openmrs/esm-api'; import { getDefaultsFromConfigSchema } from '@openmrs/esm-utils'; export { @@ -14,6 +13,7 @@ export { age, } from '@openmrs/esm-utils'; export { interpolateString, interpolateUrl, validators, validator } from '@openmrs/esm-config'; +export { ConfigurableLink } from '@openmrs/esm-react-utils'; window.i18next = { ...window.i18next, language: 'en' }; @@ -158,12 +158,6 @@ export function defineExtensionConfigSchema(extensionName, schema) { export const navigate = jest.fn(); -export const ConfigurableLink = jest - .fn() - .mockImplementation((config: { to: string; children: React.ReactNode }) => ( - {config.children} - )); - /* esm-dynamic-loading */ export const importDynamic = jest.fn(); diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx index 3f4e3f8cb..ab0472034 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx @@ -18,14 +18,14 @@ describe(`ConfigurableLink`, () => { const path = '${openmrsSpaBase}/home'; beforeEach(() => { mockNavigate.mockClear(); + }); + + it(`interpolates the link`, async () => { render( SPA Home , ); - }); - - it(`interpolates the link`, async () => { const link = screen.getByRole('link', { name: /spa home/i }); expect(link).toBeTruthy(); expect(link.closest('a')).toHaveClass('fancy-link'); @@ -33,6 +33,11 @@ describe(`ConfigurableLink`, () => { }); it(`calls navigate on normal click but not special clicks`, async () => { + render( + + SPA Home + , + ); const user = userEvent.setup(); const link = screen.getByRole('link', { name: /spa home/i }); @@ -43,6 +48,11 @@ describe(`ConfigurableLink`, () => { }); it(`calls navigate on enter`, async () => { + render( + + SPA Home + , + ); const user = userEvent.setup(); expect(navigate).not.toHaveBeenCalled(); @@ -50,4 +60,19 @@ describe(`ConfigurableLink`, () => { await user.type(link, '{enter}'); expect(navigate).toHaveBeenCalledWith({ to: path }); }); + + it('executes onBeforeNavigate callback if provided', async () => { + const onBeforeNavigate = jest.fn(); + render( + + SPA Home + , + ); + + const user = userEvent.setup(); + const link = screen.getByRole('link', { name: /spa home/i }); + await user.click(link); + expect(onBeforeNavigate).toHaveBeenCalled(); + expect(navigate).toHaveBeenCalledWith({ to: path }); + }); }); diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx index 0dbca708b..99cbf0ab6 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx @@ -3,9 +3,10 @@ import React, { type MouseEvent, type AnchorHTMLAttributes, type PropsWithChildr import type { TemplateParams } from '@openmrs/esm-config'; import { navigate, interpolateUrl } from '@openmrs/esm-config'; -function handleClick(event: MouseEvent, to: string, templateParams?: TemplateParams) { +function handleClick(event: MouseEvent, to: string, templateParams?: TemplateParams, onBeforeNavigate?: () => void) { if (!event.metaKey && !event.ctrlKey && !event.shiftKey && event.button == 0) { event.preventDefault(); + onBeforeNavigate?.(); navigate({ to, templateParams }); } } @@ -16,25 +17,28 @@ function handleClick(event: MouseEvent, to: string, templateParams?: TemplatePar export interface ConfigurableLinkProps extends AnchorHTMLAttributes { to: string; templateParams?: TemplateParams; + onBeforeNavigate?: () => void; } /** * A React link component which calls [[navigate]] when clicked * * @param to The target path or URL. Supports interpolation. See [[navigate]] - * @param urlParams: A dictionary of values to interpolate into the URL, in addition to the default keys `openmrsBase` and `openmrsSpaBase`. + * @param templateParams: A dictionary of values to interpolate into the URL, in addition to the default keys `openmrsBase` and `openmrsSpaBase`. + * @param onBeforeNavigate A callback to be called just before navigation occurs * @param children Inline elements within the link * @param otherProps Any other valid props for an tag except `href` and `onClick` */ export function ConfigurableLink({ to, templateParams, + onBeforeNavigate, children, ...otherProps }: PropsWithChildren) { return ( handleClick(event, to, templateParams)} + onClick={(event) => handleClick(event, to, templateParams, onBeforeNavigate)} href={interpolateUrl(to, templateParams)} {...otherProps} > From 0e5d3c26dd13c171802a8659ddf4bbe9a2b97691 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 5 Jan 2024 12:36:02 +0100 Subject: [PATCH 19/37] (fix) Make navbar not re-render like crazy (#874) --- .../apps/esm-login-app/src/logout/logout.scss | 5 ++--- .../navbar-header-panels/user-menu-panel.scss | 4 ++++ .../components/navbar/navbar.component.tsx | 19 ++++++++++--------- .../user-panel-switcher.component.tsx | 3 +-- 4 files changed, 17 insertions(+), 14 deletions(-) diff --git a/packages/apps/esm-login-app/src/logout/logout.scss b/packages/apps/esm-login-app/src/logout/logout.scss index 39deb43cb..be0b1fabe 100644 --- a/packages/apps/esm-login-app/src/logout/logout.scss +++ b/packages/apps/esm-login-app/src/logout/logout.scss @@ -1,8 +1,7 @@ @import '../root.scss'; -/* Repeat selector for specificity */ -button.logout.logout { - color: $field-01; +button.logout { + color: $field-01 !important; font-size: 1rem; width: 16rem; diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss index 77a7e0247..d1f456137 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss @@ -1,6 +1,10 @@ @import '~@openmrs/esm-styleguide/src/vars'; @import '../../root.scss'; +.headerPanel { + transition: none; +} + .userPanelSwitcher { padding-top: 1rem; align-items: start; diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx index a801f32d7..d73d5e8f2 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx @@ -1,9 +1,8 @@ -import React, { memo, useCallback, useMemo, useState } from 'react'; +import React, { useCallback, useMemo, useState } from 'react'; import { Navigate } from 'react-router-dom'; import classNames from 'classnames'; import { HeaderContainer, Header, HeaderMenuButton, HeaderGlobalBar, HeaderGlobalAction } from '@carbon/react'; import { Close, Switcher, UserAvatarFilledAlt } from '@carbon/react/icons'; -import type { LoggedInUser } from '@openmrs/esm-framework'; import { useLayoutType, ExtensionSlot, @@ -21,14 +20,11 @@ import UserMenuPanel from '../navbar-header-panels/user-menu-panel.component'; import SideMenuPanel from '../navbar-header-panels/side-menu-panel.component'; import styles from './navbar.scss'; -const Navbar: React.FC = () => { - const session = useSession(); +const HeaderItems: React.FC = () => { const config = useConfig(); - const [user, setUser] = useState(session?.user ?? null); const [activeHeaderPanel, setActiveHeaderPanel] = useState(null); const layout = useLayoutType(); const navMenuItems = useConnectedExtensions('patient-chart-dashboard-slot').map((e) => e.id); - const openmrsSpaBase = window['getOpenmrsSpaBase'](); const appMenuItems = useConnectedExtensions('app-menu-slot'); const userMenuItems = useConnectedExtensions('user-panel-slot'); const isActivePanel = useCallback((panelName: string) => activeHeaderPanel === panelName, [activeHeaderPanel]); @@ -46,7 +42,7 @@ const Navbar: React.FC = () => { const showHamburger = useMemo(() => !isDesktop(layout) && navMenuItems.length > 0, [navMenuItems.length, layout]); const showAppMenu = useMemo(() => appMenuItems.length > 0, [appMenuItems.length]); const showUserMenu = useMemo(() => userMenuItems.length > 0, [userMenuItems.length]); - const HeaderItems = () => ( + return ( <>
@@ -123,10 +119,15 @@ const Navbar: React.FC = () => {
); +}; + +const Navbar: React.FC = () => { + const session = useSession(); + const openmrsSpaBase = window['getOpenmrsSpaBase'](); - if (user && session) { + if (session?.user?.person) { return session.sessionLocation ? ( - + ) : ( { const session = useSession(); - const user = session?.user; return ( -

{user.person.display}

+

{session?.user?.person?.display}

); }; From 2277e234714ac7448d29b40729ff0a7e9100243e Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 5 Jan 2024 12:37:00 +0100 Subject: [PATCH 20/37] (fix) Ensure extension slots receive correct list of extensions on first render (#875) --- .../esm-extensions/src/extensions.ts | 8 +++++-- .../src/useAssignedExtensions.ts | 21 ++++++------------- 2 files changed, 12 insertions(+), 17 deletions(-) diff --git a/packages/framework/esm-extensions/src/extensions.ts b/packages/framework/esm-extensions/src/extensions.ts index e0b114b73..cfd9fcc2f 100644 --- a/packages/framework/esm-extensions/src/extensions.ts +++ b/packages/framework/esm-extensions/src/extensions.ts @@ -169,7 +169,9 @@ export function attach(slotName: string, extensionId: string) { }); } -/** Avoid using this. Extension attachments should be considered declarative. */ +/** + * @deprecated Avoid using this. Extension attachments should be considered declarative. + */ export function detach(extensionSlotName: string, extensionId: string) { updateInternalExtensionStore((state) => { const existingSlot = state.slots[extensionSlotName]; @@ -191,7 +193,9 @@ export function detach(extensionSlotName: string, extensionId: string) { }); } -/** Avoid using this. Extension attachments should be considered declarative. */ +/** + * @deprecated Avoid using this. Extension attachments should be considered declarative. + */ export function detachAll(extensionSlotName: string) { updateInternalExtensionStore((state) => { const existingSlot = state.slots[extensionSlotName]; diff --git a/packages/framework/esm-react-utils/src/useAssignedExtensions.ts b/packages/framework/esm-react-utils/src/useAssignedExtensions.ts index 09737f1e8..1918e859f 100644 --- a/packages/framework/esm-react-utils/src/useAssignedExtensions.ts +++ b/packages/framework/esm-react-utils/src/useAssignedExtensions.ts @@ -1,8 +1,6 @@ /** @module @category Extension */ -import { useEffect, useState } from 'react'; -import type { AssignedExtension, ExtensionStore } from '@openmrs/esm-extensions'; -import { getExtensionStore } from '@openmrs/esm-extensions'; -import isEqual from 'lodash-es/isEqual'; +import { useMemo } from 'react'; +import { useExtensionStore } from './useExtensionStore'; /** * Gets the assigned extensions for a given extension slot name. @@ -10,18 +8,11 @@ import isEqual from 'lodash-es/isEqual'; * @param slotName The name of the slot to get the assigned extensions for. */ export function useAssignedExtensions(slotName: string) { - const [extensions, setExtensions] = useState>([]); + const { slots } = useExtensionStore(); - useEffect(() => { - function update(state: ExtensionStore) { - const newExtensions = state.slots[slotName]?.assignedExtensions ?? []; - if (!isEqual(newExtensions, extensions)) { - setExtensions(newExtensions); - } - } - update(getExtensionStore().getState()); - return getExtensionStore().subscribe(update); - }, [slotName, extensions]); + const extensions = useMemo(() => { + return slots[slotName]?.assignedExtensions ?? []; + }, [slots, slotName]); return extensions; } From 4cd51e800bd41a13c2a22f240663a798bf261c4b Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 5 Jan 2024 19:09:37 +0300 Subject: [PATCH 21/37] (fix) Amend ContentSwitcher style overrides (#872) --- .../esm-styleguide/src/_overrides.scss | 173 +++++++++++++++--- 1 file changed, 150 insertions(+), 23 deletions(-) diff --git a/packages/framework/esm-styleguide/src/_overrides.scss b/packages/framework/esm-styleguide/src/_overrides.scss index 9526d3b0e..36bb6d1c0 100644 --- a/packages/framework/esm-styleguide/src/_overrides.scss +++ b/packages/framework/esm-styleguide/src/_overrides.scss @@ -56,6 +56,26 @@ /* Content Switcher */ .cds--content-switcher { @include layout.use('size', $default: 'sm'); + + & > :first-child { + border-bottom-left-radius: 0.25rem; + border-right: unset !important; + border-top-left-radius: 0.25rem; + + [aria-selected='false'] { + border-left: 0.0625rem solid colors.$blue-30 !important; + } + } + + & > :last-child { + border-bottom-right-radius: 0.25rem; + border-left: unset !important; + border-top-right-radius: 0.25rem; + + [aria-selected='false'] { + border-right: 0.0625rem solid colors.$blue-30 !important; + } + } } .cds--content-switcher-btn { @@ -68,16 +88,12 @@ background-color: transparent !important; } - &:first-child { - border-bottom-left-radius: 0.25rem; - border-left: 0.0625rem solid colors.$blue-30 !important; - border-top-left-radius: 0.25rem; - } + &.cds--btn--primary { + background-color: unset; - &:last-child { - border-bottom-right-radius: 0.25rem; - border-right: 0.0625rem solid colors.$blue-30 !important; - border-top-right-radius: 0.25rem; + &:hover { + background-color: colors.$gray-10-hover; + } } &::before { @@ -88,8 +104,12 @@ &.cds--content-switcher--selected { border: 1px solid colors.$blue-60 !important; - background-color: colors.$blue-10; - color: colors.$blue-60; + background-color: colors.$blue-10 !important; + color: colors.$blue-60 !important; + + svg { + fill: colors.$blue-60 !important; + } &::after { background-color: colors.$blue-10; @@ -105,6 +125,22 @@ } } +.cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:first-child .cds--content-switcher-btn { + border-left: unset; +} + +.cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:last-child .cds--content-switcher-btn { + border-right: unset; +} + +.cds--content-switcher:not(.cds--content-switcher--icon-only) .cds--content-switcher-btn:first-child { + border-left: 0.0625rem solid colors.$blue-30; +} + +.cds--content-switcher:not(.cds--content-switcher--icon-only) .cds--content-switcher-btn:last-child { + border-right: 0.0625rem solid colors.$blue-30; +} + /* Tabs */ .cds--tabs--scrollable .cds--tabs--scrollable__nav-item--selected .cds--tabs--scrollable__nav-link, .cds--tabs--scrollable .cds--tabs--scrollable__nav-item--selected .cds--tabs--scrollable__nav-link:active, @@ -320,7 +356,6 @@ html[dir='rtl'] { } .cds--btn--secondary { - padding: calc(0.375rem - 3px) 12px calc(0.375rem - 3px) 60px; svg { left: spacing.$spacing-05; right: unset; @@ -371,22 +406,114 @@ html[dir='rtl'] { } .cds--content-switcher { + @include layout.use('size', $default: 'sm'); + + & > :first-child { + border-bottom-right-radius: 0.25rem !important; + border-left: unset !important; + border-right: unset !important; + border-top-right-radius: 0.25rem !important; + + [aria-selected='false'] { + border-right: 0.0625rem solid colors.$blue-30; + border-left: unset !important; + } + } + & > :last-child { - border-bottom-left-radius: 0.25rem; - border-top-left-radius: 0.25rem; - border-bottom-right-radius: unset; - border-top-right-radius: unset; - border-left: 0.0625rem solid #a6c8ff; + border-bottom-left-radius: 0.25rem !important; + border-left: unset; + border-right: unset; + border-top-left-radius: 0.25rem !important; + + [aria-selected='false'] { + border-left: 0.0625rem solid colors.$blue-30; + border-right: unset !important; + } } - & > :first-child { - border-right: 0.0625rem solid #a6c8ff; - border-bottom-right-radius: 0.25rem; - border-top-right-radius: 0.25rem; - border-bottom-left-radius: unset; - border-top-left-radius: unset; + + .cds--btn--icon-only { + display: flex; + align-items: center; + } + } + + .cds--content-switcher-btn { + &::after { + background-color: transparent !important; + } + + &.cds--btn--primary { + background-color: unset; + + &:hover { + background-color: colors.$gray-10-hover; + } + } + + &::before { + background-color: colors.$blue-30; + height: 100%; + z-index: 0; + } + + &.cds--content-switcher--selected { + border: 1px solid colors.$blue-60 !important; + background-color: colors.$blue-10 !important; + color: colors.$blue-60 !important; + + svg { + fill: colors.$blue-60 !important; + } + + &::after { + background-color: colors.$blue-10; + } + + &::before { + background-color: transparent; + } + + &:disabled { + border: 0 !important; + } } } + .cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:first-child .cds--content-switcher-btn { + border-bottom-right-radius: 0.25rem !important; + border-top-right-radius: 0.25rem !important; + border-top-left-radius: unset !important; + border-bottom-left-radius: unset !important; + } + + .cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:last-child .cds--content-switcher-btn { + border-bottom-left-radius: 0.25rem !important; + border-top-left-radius: 0.25rem !important; + border-top-right-radius: unset !important; + border-bottom-right-radius: unset !important; + } + + .cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:first-child .cds--content-switcher-btn { + border-left: unset; + } + + .cds--content-switcher--icon-only .cds--content-switcher-popover__wrapper:last-child .cds--content-switcher-btn { + border-right: unset; + } + + .cds--content-switcher:not(.cds--content-switcher--icon-only) .cds--content-switcher-btn:first-child { + border-right: 0.0625rem solid colors.$blue-30; + border-bottom-left-radius: unset !important; + border-top-left-radius: unset !important; + } + + .cds--content-switcher:not(.cds--content-switcher--icon-only) .cds--content-switcher-btn:last-child { + border-left: 0.0625rem solid colors.$blue-30; + border-bottom-right-radius: unset !important; + border-top-right-radius: unset !important; + } + .cds--date-picker-input__wrapper { svg { left: spacing.$spacing-05; From ad1c75472c14c7de95f64027cf0175a1fef497cc Mon Sep 17 00:00:00 2001 From: Dennis Kigen Date: Fri, 5 Jan 2024 22:29:31 +0300 Subject: [PATCH 22/37] (fix) Full-width switcher items in user menu panel (#876) --- .../navbar-header-panels/user-menu-panel.component.tsx | 7 +++---- .../components/navbar-header-panels/user-menu-panel.scss | 4 ++++ 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx index 07f1f3cbb..8226eacbe 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.component.tsx @@ -1,5 +1,4 @@ import React from 'react'; -import type { HeaderPanelProps } from '@carbon/react'; import { HeaderPanel, Switcher, SwitcherDivider } from '@carbon/react'; import { ExtensionSlot, useOnClickOutside } from '@openmrs/esm-framework'; import styles from './user-menu-panel.scss'; @@ -18,16 +17,16 @@ const UserMenuPanel: React.FC = ({ expanded, hidePanel }) => return ( - + - + ); diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss index d1f456137..acb54b383 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar-header-panels/user-menu-panel.scss @@ -5,6 +5,10 @@ transition: none; } +.fullWidth { + width: 100%; +} + .userPanelSwitcher { padding-top: 1rem; align-items: start; From 966e697c1ec2918843f7d359237a044092b7a55b Mon Sep 17 00:00:00 2001 From: kyampeire Hadijah <30952856+hadijahkyampeire@users.noreply.github.com> Date: Mon, 8 Jan 2024 17:57:23 +0300 Subject: [PATCH 23/37] (feat) O3-2546: Add the ability to use actions in the existing toast (#822) * implement the actionable toast * Update the documentation * some refactors * update docs * leverage the existing toast to allow actions * update docs * cleanup * override the green color for tertiary buttons to fix the notification action btns * fix lint changes * update docs again * tweak the auto closing logic --------- Co-authored-by: Ian <52504170+ibacher@users.noreply.github.com> --- .../src/implementer-tools.component.tsx | 6 +-- packages/framework/esm-framework/docs/API.md | 10 ++-- .../docs/interfaces/ShowSnackbarEvent.md | 16 +++---- .../docs/interfaces/ShowToastEvent.md | 29 ++++++++++++ .../docs/interfaces/ToastDescriptor.md | 37 +++++++++++++-- .../docs/interfaces/ToastNotificationMeta.md | 47 +++++++++++++++++-- packages/framework/esm-globals/src/events.ts | 10 ++-- .../esm-styleguide/src/_overrides.scss | 7 +++ .../src/snackbars/_snackbars.scss | 1 - .../esm-styleguide/src/toasts/_toasts.scss | 4 ++ .../src/toasts/active-toasts.component.tsx | 7 ++- .../src/toasts/toast.component.tsx | 31 ++++++++---- 12 files changed, 166 insertions(+), 39 deletions(-) diff --git a/packages/apps/esm-implementer-tools-app/src/implementer-tools.component.tsx b/packages/apps/esm-implementer-tools-app/src/implementer-tools.component.tsx index 447326d74..7c76e24e8 100644 --- a/packages/apps/esm-implementer-tools-app/src/implementer-tools.component.tsx +++ b/packages/apps/esm-implementer-tools-app/src/implementer-tools.component.tsx @@ -1,5 +1,5 @@ import React, { useState, useEffect } from 'react'; -import { showActionableNotification, UserHasAccess, useStore } from '@openmrs/esm-framework'; +import { showToast, UserHasAccess, useStore } from '@openmrs/esm-framework'; import { implementerToolsStore, showModuleDiagnostics, togglePopup } from './store'; import { useBackendDependencies } from './backend-dependencies/useBackendDependencies'; @@ -24,10 +24,10 @@ function PopupHandler() { useEffect(() => { // only show notification max. 1 time if (shouldShowNotification) { - showActionableNotification({ + showToast({ critical: false, kind: 'error', - subtitle: t( + description: t( 'checkImplementerToolsMessage', 'Check the Backend Modules tab in the Implementer Tools for more details', ), diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 09454248f..7ac0b16fc 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -688,7 +688,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:26](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L26) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:28](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L28) ___ @@ -4564,7 +4564,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:102](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L102) +[packages/framework/esm-globals/src/events.ts:104](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L104) ___ @@ -4590,7 +4590,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:95](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L95) +[packages/framework/esm-globals/src/events.ts:97](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L97) ___ @@ -4616,7 +4616,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:116](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L116) +[packages/framework/esm-globals/src/events.ts:118](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L118) ___ @@ -4642,7 +4642,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:109](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L109) +[packages/framework/esm-globals/src/events.ts:111](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L111) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/ShowSnackbarEvent.md b/packages/framework/esm-framework/docs/interfaces/ShowSnackbarEvent.md index e2a3ef832..177b43bc2 100644 --- a/packages/framework/esm-framework/docs/interfaces/ShowSnackbarEvent.md +++ b/packages/framework/esm-framework/docs/interfaces/ShowSnackbarEvent.md @@ -26,7 +26,7 @@ #### Defined in -[packages/framework/esm-globals/src/events.ts:70](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L70) +[packages/framework/esm-globals/src/events.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L72) ___ @@ -36,7 +36,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L73) +[packages/framework/esm-globals/src/events.ts:75](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L75) ___ @@ -46,7 +46,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:68](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L68) +[packages/framework/esm-globals/src/events.ts:70](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L70) ___ @@ -56,7 +56,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:72](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L72) +[packages/framework/esm-globals/src/events.ts:74](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L74) ___ @@ -66,7 +66,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:67](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L67) +[packages/framework/esm-globals/src/events.ts:69](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L69) ___ @@ -76,7 +76,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:74](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L74) +[packages/framework/esm-globals/src/events.ts:76](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L76) ___ @@ -86,7 +86,7 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:69](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L69) +[packages/framework/esm-globals/src/events.ts:71](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L71) ## Methods @@ -100,4 +100,4 @@ ___ #### Defined in -[packages/framework/esm-globals/src/events.ts:71](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L71) +[packages/framework/esm-globals/src/events.ts:73](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L73) diff --git a/packages/framework/esm-framework/docs/interfaces/ShowToastEvent.md b/packages/framework/esm-framework/docs/interfaces/ShowToastEvent.md index 23c2b5604..25956470b 100644 --- a/packages/framework/esm-framework/docs/interfaces/ShowToastEvent.md +++ b/packages/framework/esm-framework/docs/interfaces/ShowToastEvent.md @@ -6,13 +6,28 @@ ### Properties +- [actionButtonLabel](ShowToastEvent.md#actionbuttonlabel) - [description](ShowToastEvent.md#description) - [kind](ShowToastEvent.md#kind) - [millis](ShowToastEvent.md#millis) - [title](ShowToastEvent.md#title) +### Methods + +- [onActionButtonClick](ShowToastEvent.md#onactionbuttonclick) + ## Properties +### actionButtonLabel + +• `Optional` **actionButtonLabel**: `any` + +#### Defined in + +[packages/framework/esm-globals/src/events.ts:63](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L63) + +___ + ### description • **description**: `any` @@ -50,3 +65,17 @@ ___ #### Defined in [packages/framework/esm-globals/src/events.ts:61](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L61) + +## Methods + +### onActionButtonClick + +▸ `Optional` **onActionButtonClick**(): `void` + +#### Returns + +`void` + +#### Defined in + +[packages/framework/esm-globals/src/events.ts:64](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-globals/src/events.ts#L64) diff --git a/packages/framework/esm-framework/docs/interfaces/ToastDescriptor.md b/packages/framework/esm-framework/docs/interfaces/ToastDescriptor.md index 5bd800d22..a28d49913 100644 --- a/packages/framework/esm-framework/docs/interfaces/ToastDescriptor.md +++ b/packages/framework/esm-framework/docs/interfaces/ToastDescriptor.md @@ -12,21 +12,36 @@ ### UI Properties +- [actionButtonLabel](ToastDescriptor.md#actionbuttonlabel) - [critical](ToastDescriptor.md#critical) - [description](ToastDescriptor.md#description) - [kind](ToastDescriptor.md#kind) - [millis](ToastDescriptor.md#millis) - [title](ToastDescriptor.md#title) +### UI Methods + +- [onActionButtonClick](ToastDescriptor.md#onactionbuttonclick) + ## UI Properties +### actionButtonLabel + +• `Optional` **actionButtonLabel**: `string` + +#### Defined in + +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L17) + +___ + ### critical • `Optional` **critical**: `boolean` #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L17) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L19) ___ @@ -46,7 +61,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L16) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L18) ___ @@ -56,7 +71,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L19) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L21) ___ @@ -66,4 +81,18 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L18) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L20) + +## UI Methods + +### onActionButtonClick + +▸ `Optional` **onActionButtonClick**(): `void` + +#### Returns + +`void` + +#### Defined in + +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L16) diff --git a/packages/framework/esm-framework/docs/interfaces/ToastNotificationMeta.md b/packages/framework/esm-framework/docs/interfaces/ToastNotificationMeta.md index 0a2b3f303..58257952d 100644 --- a/packages/framework/esm-framework/docs/interfaces/ToastNotificationMeta.md +++ b/packages/framework/esm-framework/docs/interfaces/ToastNotificationMeta.md @@ -12,6 +12,7 @@ ### UI Properties +- [actionButtonLabel](ToastNotificationMeta.md#actionbuttonlabel) - [critical](ToastNotificationMeta.md#critical) - [description](ToastNotificationMeta.md#description) - [id](ToastNotificationMeta.md#id) @@ -19,8 +20,26 @@ - [millis](ToastNotificationMeta.md#millis) - [title](ToastNotificationMeta.md#title) +### UI Methods + +- [onActionButtonClick](ToastNotificationMeta.md#onactionbuttonclick) + ## UI Properties +### actionButtonLabel + +• `Optional` **actionButtonLabel**: `string` + +#### Inherited from + +[ToastDescriptor](ToastDescriptor.md).[actionButtonLabel](ToastDescriptor.md#actionbuttonlabel) + +#### Defined in + +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L17) + +___ + ### critical • `Optional` **critical**: `boolean` @@ -31,7 +50,7 @@ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L17) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L19) ___ @@ -55,7 +74,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:23](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L23) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L25) ___ @@ -69,7 +88,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L16) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L18) ___ @@ -83,7 +102,7 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L19) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:21](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L21) ___ @@ -97,4 +116,22 @@ ___ #### Defined in -[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L18) +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L20) + +## UI Methods + +### onActionButtonClick + +▸ `Optional` **onActionButtonClick**(): `void` + +#### Returns + +`void` + +#### Inherited from + +[ToastDescriptor](ToastDescriptor.md).[onActionButtonClick](ToastDescriptor.md#onactionbuttonclick) + +#### Defined in + +[packages/framework/esm-styleguide/src/toasts/toast.component.tsx:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-styleguide/src/toasts/toast.component.tsx#L16) diff --git a/packages/framework/esm-globals/src/events.ts b/packages/framework/esm-globals/src/events.ts index a48645721..d2504e682 100644 --- a/packages/framework/esm-globals/src/events.ts +++ b/packages/framework/esm-globals/src/events.ts @@ -60,6 +60,8 @@ export interface ShowToastEvent { kind?: 'error' | 'info' | 'info-square' | 'success' | 'warning' | 'warning-alt'; title?: string; millis?: number; + actionButtonLabel?: string | any; + onActionButtonClick?: () => void; } /** @category UI */ @@ -77,7 +79,7 @@ export interface ShowSnackbarEvent { const notificationShownName = 'openmrs:notification-shown'; const actionableNotificationShownName = 'openmrs:actionable-notification-shown'; const toastShownName = 'openmrs:toast-shown'; -const SnackbarShownName = 'openmrs:snack-bar-shown'; +const snackbarShownName = 'openmrs:snack-bar-shown'; export function dispatchNotificationShown(data: ShowNotificationEvent) { window.dispatchEvent(new CustomEvent(notificationShownName, { detail: data })); @@ -88,7 +90,7 @@ export function dispatchActionableNotificationShown(data: ShowActionableNotifica } export function dispatchSnackbarShown(data: ShowSnackbarEvent) { - window.dispatchEvent(new CustomEvent(SnackbarShownName, { detail: data })); + window.dispatchEvent(new CustomEvent(snackbarShownName, { detail: data })); } /** @category UI */ @@ -115,6 +117,6 @@ export function subscribeToastShown(cb: (data: ShowToastEvent) => void) { /** @category UI */ export function subscribeSnackbarShown(cb: (data: ShowSnackbarEvent) => void) { const handler = (ev: CustomEvent) => cb(ev.detail); - window.addEventListener(SnackbarShownName, handler); - return () => window.removeEventListener(SnackbarShownName, handler); + window.addEventListener(snackbarShownName, handler); + return () => window.removeEventListener(snackbarShownName, handler); } diff --git a/packages/framework/esm-styleguide/src/_overrides.scss b/packages/framework/esm-styleguide/src/_overrides.scss index 36bb6d1c0..d2bf52ad4 100644 --- a/packages/framework/esm-styleguide/src/_overrides.scss +++ b/packages/framework/esm-styleguide/src/_overrides.scss @@ -621,3 +621,10 @@ html[dir='rtl'] { } } } + +// This is to override the green border and background color which we apply to tertiary buttons. Since this in the Notification carbon uses blue. +.cds--actionable-notification__action-button.cds--btn--tertiary { + background-color: transparent; + border: 1px solid #0f62fe; + color: #0f62fe; +} diff --git a/packages/framework/esm-styleguide/src/snackbars/_snackbars.scss b/packages/framework/esm-styleguide/src/snackbars/_snackbars.scss index c8c3c6762..ad186dbf1 100644 --- a/packages/framework/esm-styleguide/src/snackbars/_snackbars.scss +++ b/packages/framework/esm-styleguide/src/snackbars/_snackbars.scss @@ -4,7 +4,6 @@ z-index: 1000; position: fixed; width: 20rem; - display: flex; bottom: 1rem; left: 1rem; gap: 0.5rem; diff --git a/packages/framework/esm-styleguide/src/toasts/_toasts.scss b/packages/framework/esm-styleguide/src/toasts/_toasts.scss index 7583445fe..d4eaa10f2 100644 --- a/packages/framework/esm-styleguide/src/toasts/_toasts.scss +++ b/packages/framework/esm-styleguide/src/toasts/_toasts.scss @@ -1,8 +1,12 @@ .omrs-toasts-container { + display: flex; + flex-direction: column; z-index: 100000; position: fixed; + width: 20rem; top: 4rem; right: 1rem; + gap: 0.5rem; } .omrs-toast-mounting, diff --git a/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx b/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx index 0484ee689..18cac7558 100644 --- a/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx +++ b/packages/framework/esm-styleguide/src/toasts/active-toasts.component.tsx @@ -18,7 +18,12 @@ const ActiveToasts: React.FC = ({ subject }) => { const subscription = subject.subscribe((toast) => setToasts((toasts) => [ ...toasts.filter( - (t) => t.description !== toast.description || t.kind !== toast.kind || t.title !== toast.title, + (t) => + t.description !== toast.description || + t.kind !== toast.kind || + t.title !== toast.title || + t.actionButtonLabel !== toast.actionButtonLabel || + t.onActionButtonClick !== toast.onActionButtonClick, ), toast, ]), diff --git a/packages/framework/esm-styleguide/src/toasts/toast.component.tsx b/packages/framework/esm-styleguide/src/toasts/toast.component.tsx index f26f1ffcc..263a75023 100644 --- a/packages/framework/esm-styleguide/src/toasts/toast.component.tsx +++ b/packages/framework/esm-styleguide/src/toasts/toast.component.tsx @@ -1,6 +1,6 @@ /** @module @category UI */ -import React, { useEffect, useState } from 'react'; -import { ToastNotification } from '@carbon/react'; +import React, { useEffect, useCallback, useState } from 'react'; +import { ActionableNotification } from '@carbon/react'; const defaultOptions = { millis: 5000, @@ -13,6 +13,8 @@ export interface ToastProps { export interface ToastDescriptor { description: React.ReactNode; + onActionButtonClick?: () => void; + actionButtonLabel?: string; kind?: ToastType; critical?: boolean; title?: string; @@ -26,25 +28,38 @@ export interface ToastNotificationMeta extends ToastDescriptor { export type ToastType = 'error' | 'info' | 'info-square' | 'success' | 'warning' | 'warning-alt'; export const Toast: React.FC = ({ toast, closeToast }) => { - const { description, kind, critical, title, millis = defaultOptions.millis } = toast; - + const { + description, + kind, + critical, + title, + actionButtonLabel, + onActionButtonClick = () => {}, + millis = defaultOptions.millis, + } = toast; const [waitingForTime, setWaitingForTime] = useState(true); + const handleActionClick = useCallback(() => { + onActionButtonClick(); + closeToast(); + }, [closeToast, onActionButtonClick]); useEffect(() => { - if (waitingForTime) { + if (!actionButtonLabel && waitingForTime) { const timeoutId = setTimeout(closeToast, millis); return () => clearTimeout(timeoutId); } - }, [waitingForTime]); + }, [closeToast, waitingForTime, millis, actionButtonLabel]); return (
setWaitingForTime(false)} onMouseLeave={() => setWaitingForTime(true)}> -
); From 43a20b2cc5673071ed9c816c20a93682cb9e977e Mon Sep 17 00:00:00 2001 From: elimm Date: Tue, 9 Jan 2024 19:35:55 +0200 Subject: [PATCH 24/37] (fix) O3-2694: fixed form display when RTL language is selected (#873) Co-authored-by: Andrey J --- .../esm-styleguide/src/_overrides.scss | 33 ++++++++++++++++--- 1 file changed, 28 insertions(+), 5 deletions(-) diff --git a/packages/framework/esm-styleguide/src/_overrides.scss b/packages/framework/esm-styleguide/src/_overrides.scss index d2bf52ad4..bc417cb3f 100644 --- a/packages/framework/esm-styleguide/src/_overrides.scss +++ b/packages/framework/esm-styleguide/src/_overrides.scss @@ -342,6 +342,10 @@ html[dir='rtl'] { } } + .cds--header__name { + padding-inline: 1rem 2rem; + } + .cds--header-panel--expanded { right: calc(100vw - var(--omrs-sidenav-width)); } @@ -610,15 +614,34 @@ html[dir='rtl'] { } } } - .tab-content { - margin-left: unset; - margin-right: 10rem; + .tab-content { .pane { - padding-left: unset; - padding-right: 1rem; + padding-inline: 0; + + & > h4 { + padding-left: unset; + padding-inline-start: 1rem; + } } } + + .cds--accordion__title { + text-align: start; + } + + .cds--accordion__content { + padding-inline: 1rem; + + .cds--text-input, + .cds--text-area { + box-sizing: border-box; + } + } + + .question-area { + min-width: unset; + } } } From 18368f5b330409ca287d4c41a01ff778578fdfbc Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Thu, 11 Jan 2024 16:16:09 +0300 Subject: [PATCH 25/37] (feat) Create a global app history utility (#877) --- .eslintrc | 3 +- README.md | 2 +- .../redirect-logout.component.tsx | 2 + .../redirect-logout/redirect-logout.test.tsx | 11 --- .../__mocks__/openmrs-esm-config.mock.ts | 2 - .../__mocks__/openmrs-esm-navigation.mock.ts | 5 + packages/framework/esm-api/jest.config.js | 3 +- packages/framework/esm-api/package.json | 2 + .../esm-api/src/openmrs-fetch.test.ts | 3 +- .../framework/esm-api/src/openmrs-fetch.ts | 5 +- .../current-patient.test.ts | 19 ++-- packages/framework/esm-breadcrumbs/README.md | 1 - .../framework/esm-breadcrumbs/src/index.ts | 3 - packages/framework/esm-config/src/index.ts | 2 - packages/framework/esm-config/src/public.ts | 2 - packages/framework/esm-framework/docs/API.md | 90 +++++++++++++----- .../docs/classes/OpenmrsFetchError.md | 6 +- .../docs/interfaces/BreadcrumbRegistration.md | 4 +- .../docs/interfaces/BreadcrumbSettings.md | 8 +- .../docs/interfaces/FetchConfig.md | 4 +- .../docs/interfaces/NavigateOptions.md | 4 +- packages/framework/esm-framework/mock.tsx | 92 +++++++++++-------- packages/framework/esm-framework/package.json | 2 +- packages/framework/esm-framework/src/index.ts | 2 +- .../framework/esm-framework/src/internal.ts | 2 +- packages/framework/esm-navigation/README.md | 1 + .../jest.config.js | 7 +- .../package.json | 6 +- .../src/breadcrumbs}/db.ts | 2 +- .../src/breadcrumbs}/filter.ts | 2 +- .../src/history/history.test.ts | 76 +++++++++++++++ .../esm-navigation/src/history/history.ts | 68 ++++++++++++++ .../framework/esm-navigation/src/index.ts | 6 ++ .../src/navigation/interpolate-string.test.ts | 0 .../src/navigation/interpolate-string.ts | 0 .../src/navigation/navigate.test.ts | 8 +- .../src/navigation/navigate.ts | 7 +- .../framework/esm-navigation/src/public.ts | 6 ++ .../esm-navigation/src/setup-tests.js | 3 + .../src/types.ts | 0 .../tsconfig.json | 0 .../webpack.config.js | 2 +- .../framework/esm-react-utils/package.json | 2 + .../src/ConfigurableLink.test.tsx | 7 +- .../esm-react-utils/src/ConfigurableLink.tsx | 4 +- .../esm-react-utils/src/extensions.test.tsx | 2 +- .../esm-react-utils/src/setup-tests.js | 6 ++ packages/shell/esm-app-shell/src/run.ts | 2 + yarn.lock | 28 +++--- 49 files changed, 376 insertions(+), 148 deletions(-) create mode 100644 packages/framework/esm-api/__mocks__/openmrs-esm-navigation.mock.ts delete mode 100644 packages/framework/esm-breadcrumbs/README.md delete mode 100644 packages/framework/esm-breadcrumbs/src/index.ts create mode 100644 packages/framework/esm-navigation/README.md rename packages/framework/{esm-breadcrumbs => esm-navigation}/jest.config.js (79%) rename packages/framework/{esm-breadcrumbs => esm-navigation}/package.json (87%) rename packages/framework/{esm-breadcrumbs/src => esm-navigation/src/breadcrumbs}/db.ts (98%) rename packages/framework/{esm-breadcrumbs/src => esm-navigation/src/breadcrumbs}/filter.ts (96%) create mode 100644 packages/framework/esm-navigation/src/history/history.test.ts create mode 100644 packages/framework/esm-navigation/src/history/history.ts create mode 100644 packages/framework/esm-navigation/src/index.ts rename packages/framework/{esm-config => esm-navigation}/src/navigation/interpolate-string.test.ts (100%) rename packages/framework/{esm-config => esm-navigation}/src/navigation/interpolate-string.ts (100%) rename packages/framework/{esm-config => esm-navigation}/src/navigation/navigate.test.ts (85%) rename packages/framework/{esm-config => esm-navigation}/src/navigation/navigate.ts (85%) create mode 100644 packages/framework/esm-navigation/src/public.ts create mode 100644 packages/framework/esm-navigation/src/setup-tests.js rename packages/framework/{esm-breadcrumbs => esm-navigation}/src/types.ts (100%) rename packages/framework/{esm-breadcrumbs => esm-navigation}/tsconfig.json (100%) rename packages/framework/{esm-breadcrumbs => esm-navigation}/webpack.config.js (96%) diff --git a/.eslintrc b/.eslintrc index 6b26d3d70..8a1d314c8 100644 --- a/.eslintrc +++ b/.eslintrc @@ -1,6 +1,7 @@ { "env": { - "node": true + "node": true, + "browser": true }, "extends": ["eslint:recommended", "plugin:@typescript-eslint/recommended", "prettier"], "parser": "@typescript-eslint/parser", diff --git a/README.md b/README.md index c1c5a44c1..9fa69cd0a 100644 --- a/README.md +++ b/README.md @@ -26,12 +26,12 @@ This contains tooling and the app shell. The following common libraries have been developed. They may also be used independently of the app shell. - [@openmrs/esm-api](packages/framework/esm-api): helps make calls to the backend -- [@openmrs/esm-breadcrumbs](packages/framework/esm-breadcrumbs): management of UI breadcrumbs - [@openmrs/esm-config](packages/framework/esm-config): validation and storage of frontend configuration - [@openmrs/esm-error-handling](packages/framework/esm-error-handling): handling of errors - [@openmrs/esm-extensions](packages/framework/esm-extensions): implementation of a frontend component extension system - [@openmrs/esm-feature-flags](packages/framework/esm-feature-flags): hide features that are in progress - [@openmrs/esm-globals](packages/framework/esm-globals): useful global variables and types +- [@openmrs/esm-navigation](packages/framework/esm-navigation): navigation utilities, breadcrumbs, and history - [@openmrs/esm-offline](packages/framework/esm-offline): provides offline functionality - [@openmrs/esm-react-utils](packages/framework/esm-react-utils): utilities for React components - [@openmrs/esm-state](packages/framework/esm-state): brings in state management diff --git a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx index a9926e4f9..fd65dfa0b 100644 --- a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx +++ b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.component.tsx @@ -1,6 +1,7 @@ import type React from 'react'; import { useEffect } from 'react'; import { navigate, setUserLanguage, useConfig, useConnectivity, useSession } from '@openmrs/esm-framework'; +import { clearHistory } from '@openmrs/esm-framework/src/internal'; import { performLogout } from './logout.resource'; export interface RedirectLogoutProps {} @@ -11,6 +12,7 @@ const RedirectLogout: React.FC = () => { const isLoginEnabled = useConnectivity(); useEffect(() => { + clearHistory(); if (!session.authenticated || !isLoginEnabled) { navigate({ to: '${openmrsSpaBase}/login' }); } else { diff --git a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx index 60c90afac..0db083ad6 100644 --- a/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx +++ b/packages/apps/esm-login-app/src/redirect-logout/redirect-logout.test.tsx @@ -15,17 +15,6 @@ import { } from '@openmrs/esm-framework'; import { mutate } from 'swr'; -jest.mock('@openmrs/esm-framework', () => ({ - navigate: jest.fn(), - setUserLanguage: jest.fn(), - useConfig: jest.fn(), - useConnectivity: jest.fn(), - useSession: jest.fn(), - clearCurrentUser: jest.fn(), - openmrsFetch: jest.fn(), - refetchCurrentUser: jest.fn(), -})); - jest.mock('swr', () => ({ mutate: jest.fn(), })); diff --git a/packages/framework/esm-api/__mocks__/openmrs-esm-config.mock.ts b/packages/framework/esm-api/__mocks__/openmrs-esm-config.mock.ts index 7d813c7ed..dbab3f0f7 100644 --- a/packages/framework/esm-api/__mocks__/openmrs-esm-config.mock.ts +++ b/packages/framework/esm-api/__mocks__/openmrs-esm-config.mock.ts @@ -1,5 +1,3 @@ export const defineConfigSchema = jest.fn(); export const getConfig = jest.fn().mockResolvedValue({ redirectAuthFailure: { enabled: false } }); - -export const navigate = jest.fn(); diff --git a/packages/framework/esm-api/__mocks__/openmrs-esm-navigation.mock.ts b/packages/framework/esm-api/__mocks__/openmrs-esm-navigation.mock.ts new file mode 100644 index 000000000..1e5d62b1d --- /dev/null +++ b/packages/framework/esm-api/__mocks__/openmrs-esm-navigation.mock.ts @@ -0,0 +1,5 @@ +export { interpolateUrl, interpolateString } from '@openmrs/esm-navigation'; + +export const navigate = jest.fn(); + +export const clearHistory = jest.fn(); diff --git a/packages/framework/esm-api/jest.config.js b/packages/framework/esm-api/jest.config.js index 0a324b8b7..7d6f83ed0 100644 --- a/packages/framework/esm-api/jest.config.js +++ b/packages/framework/esm-api/jest.config.js @@ -4,8 +4,9 @@ module.exports = { }, moduleNameMapper: { 'lodash-es': 'lodash', - '@openmrs/esm-error-handling': '/__mocks__/openmrs-esm-error-handling.mock.ts', '@openmrs/esm-config': '/__mocks__/openmrs-esm-config.mock.ts', + '@openmrs/esm-error-handling': '/__mocks__/openmrs-esm-error-handling.mock.ts', + '@openmrs/esm-navigation': '/__mocks__/openmrs-esm-navigation.mock.ts', 'single-spa': '/__mocks__/single-spa.mock.ts', dexie: require.resolve('dexie'), }, diff --git a/packages/framework/esm-api/package.json b/packages/framework/esm-api/package.json index 1bb4fd29d..81e31768f 100644 --- a/packages/framework/esm-api/package.json +++ b/packages/framework/esm-api/package.json @@ -44,11 +44,13 @@ "peerDependencies": { "@openmrs/esm-config": "5.x", "@openmrs/esm-error-handling": "5.x", + "@openmrs/esm-navigation": "5.x", "@openmrs/esm-offline": "5.x" }, "devDependencies": { "@openmrs/esm-config": "workspace:*", "@openmrs/esm-error-handling": "workspace:*", + "@openmrs/esm-navigation": "workspace:*", "@openmrs/esm-state": "workspace:*", "rxjs": "^6.5.3", "webpack": "^5.88.0" diff --git a/packages/framework/esm-api/src/openmrs-fetch.test.ts b/packages/framework/esm-api/src/openmrs-fetch.test.ts index d8287dd15..55b3a7a07 100644 --- a/packages/framework/esm-api/src/openmrs-fetch.test.ts +++ b/packages/framework/esm-api/src/openmrs-fetch.test.ts @@ -1,7 +1,8 @@ import { openmrsFetch, openmrsObservableFetch } from './openmrs-fetch'; import { isObservable } from 'rxjs'; -import { getConfig as mockGetConfig, navigate as mockNavigate } from '@openmrs/esm-config'; +import { getConfig as mockGetConfig } from '@openmrs/esm-config'; +import { navigate as mockNavigate } from '@openmrs/esm-navigation'; describe('openmrsFetch', () => { beforeEach(() => { diff --git a/packages/framework/esm-api/src/openmrs-fetch.ts b/packages/framework/esm-api/src/openmrs-fetch.ts index 475810ae8..192f59ebc 100644 --- a/packages/framework/esm-api/src/openmrs-fetch.ts +++ b/packages/framework/esm-api/src/openmrs-fetch.ts @@ -1,8 +1,10 @@ /** @module @category API */ import { Observable } from 'rxjs'; import isPlainObject from 'lodash-es/isPlainObject'; -import { getConfig, navigate } from '@openmrs/esm-config'; +import { getConfig } from '@openmrs/esm-config'; +import { navigate } from '@openmrs/esm-navigation'; import type { FetchResponse } from './types'; +import { clearHistory } from '@openmrs/esm-navigation/src/index'; export const restBaseUrl = '/ws/rest/v1/'; @@ -190,6 +192,7 @@ export function openmrsFetch(path: string, fetchInit: FetchConfig = {}) (url === makeUrl(sessionEndpoint) && response.status === 403) || (redirectAuthFailure.enabled && redirectAuthFailure.errors.includes(response.status)) ) { + clearHistory(); navigate({ to: redirectAuthFailure.url }); /* We sometimes don't really want this promise to resolve since there's no response data, diff --git a/packages/framework/esm-api/src/shared-api-objects/current-patient.test.ts b/packages/framework/esm-api/src/shared-api-objects/current-patient.test.ts index 91e78fe47..8b9578923 100644 --- a/packages/framework/esm-api/src/shared-api-objects/current-patient.test.ts +++ b/packages/framework/esm-api/src/shared-api-objects/current-patient.test.ts @@ -1,51 +1,50 @@ import { fhirBaseUrl, openmrsFetch } from '../openmrs-fetch'; import { fetchCurrentPatient } from './current-patient'; +const mockOpenmrsFetch = openmrsFetch as jest.MockedFunction; + jest.mock('../openmrs-fetch', () => ({ openmrsFetch: jest.fn(), })); describe('current patient', () => { beforeEach(() => { - (openmrsFetch as jest.MockedFunction).mockReset(); + mockOpenmrsFetch.mockReset(); }); it('fetches the correct patient from a patient chart URL', () => { - (openmrsFetch as jest.MockedFunction).mockReturnValueOnce( + mockOpenmrsFetch.mockReturnValueOnce( Promise.resolve({ data: {}, }), ); return fetchCurrentPatient('12', undefined, false).then(() => { - expect(openmrsFetch as jest.MockedFunction).toHaveBeenCalledWith(`${fhirBaseUrl}/Patient/12`, undefined); + expect(mockOpenmrsFetch).toHaveBeenCalledWith(`${fhirBaseUrl}/Patient/12`, undefined); }); }); it('fetches the correct patient from the patient home URL', () => { - (openmrsFetch as jest.MockedFunction).mockReturnValueOnce( + mockOpenmrsFetch.mockReturnValueOnce( Promise.resolve({ data: {}, }), ); return fetchCurrentPatient('34', undefined, false).then(() => { - expect(openmrsFetch as jest.MockedFunction).toHaveBeenCalledWith(`${fhirBaseUrl}/Patient/34`, undefined); + expect(mockOpenmrsFetch).toHaveBeenCalledWith(`${fhirBaseUrl}/Patient/34`, undefined); }); }); it('can handle dashes and alphanumeric characters in the patient uuid', () => { - (openmrsFetch as jest.MockedFunction).mockReturnValueOnce( + mockOpenmrsFetch.mockReturnValueOnce( Promise.resolve({ data: {}, }), ); return fetchCurrentPatient('34-asdsd-234243h342', undefined, false).then(() => { - expect(openmrsFetch as jest.MockedFunction).toHaveBeenCalledWith( - `${fhirBaseUrl}/Patient/34-asdsd-234243h342`, - undefined, - ); + expect(mockOpenmrsFetch).toHaveBeenCalledWith(`${fhirBaseUrl}/Patient/34-asdsd-234243h342`, undefined); }); }); }); diff --git a/packages/framework/esm-breadcrumbs/README.md b/packages/framework/esm-breadcrumbs/README.md deleted file mode 100644 index 872fb3d12..000000000 --- a/packages/framework/esm-breadcrumbs/README.md +++ /dev/null @@ -1 +0,0 @@ -# openmrs-esm-breadcrumbs diff --git a/packages/framework/esm-breadcrumbs/src/index.ts b/packages/framework/esm-breadcrumbs/src/index.ts deleted file mode 100644 index 66b9b0001..000000000 --- a/packages/framework/esm-breadcrumbs/src/index.ts +++ /dev/null @@ -1,3 +0,0 @@ -export * from './db'; -export * from './filter'; -export * from './types'; diff --git a/packages/framework/esm-config/src/index.ts b/packages/framework/esm-config/src/index.ts index 98853db35..0af6bf048 100644 --- a/packages/framework/esm-config/src/index.ts +++ b/packages/framework/esm-config/src/index.ts @@ -1,7 +1,5 @@ export * from './module-config/module-config'; export * from './module-config/state'; -export * from './navigation/navigate'; -export * from './navigation/interpolate-string'; export * from './validators/validator'; export * from './validators/validators'; export * from './types'; diff --git a/packages/framework/esm-config/src/public.ts b/packages/framework/esm-config/src/public.ts index 33c851dd5..d9b71835d 100644 --- a/packages/framework/esm-config/src/public.ts +++ b/packages/framework/esm-config/src/public.ts @@ -1,6 +1,4 @@ export * from './types'; -export * from './navigation/interpolate-string'; -export * from './navigation/navigate'; export * from './validators/validator'; export * from './validators/validators'; export { defineConfigSchema, defineExtensionConfigSchema, provide, getConfig } from './module-config/module-config'; diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index 7ac0b16fc..e1f2799b6 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -123,6 +123,8 @@ ### Navigation Functions - [ConfigurableLink](API.md#configurablelink) +- [getHistory](API.md#gethistory) +- [goBackInHistory](API.md#gobackinhistory) - [interpolateString](API.md#interpolatestring) - [interpolateUrl](API.md#interpolateurl) - [navigate](API.md#navigate) @@ -339,7 +341,7 @@ ___ #### Defined in -[packages/framework/esm-config/src/navigation/navigate.ts:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/navigate.ts#L10) +[packages/framework/esm-navigation/src/navigation/navigate.ts:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/navigate.ts#L10) ___ @@ -769,7 +771,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L9) +[packages/framework/esm-api/src/openmrs-fetch.ts:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L11) ___ @@ -791,7 +793,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L7) +[packages/framework/esm-api/src/openmrs-fetch.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L9) ___ @@ -801,7 +803,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:11](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L11) +[packages/framework/esm-api/src/openmrs-fetch.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L13) ___ @@ -1274,7 +1276,7 @@ makeUrl('/foo/bar'); #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:23](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L23) +[packages/framework/esm-api/src/openmrs-fetch.ts:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L25) ___ @@ -1341,7 +1343,7 @@ free up memory and network resources and to prevent race conditions. #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:83](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L83) +[packages/framework/esm-api/src/openmrs-fetch.ts:85](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L85) ___ @@ -1392,7 +1394,7 @@ To cancel the network request, simply call `subscription.unsubscribe();` #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:262](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L262) +[packages/framework/esm-api/src/openmrs-fetch.ts:265](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L265) ___ @@ -1755,7 +1757,7 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/filter.ts:34](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/filter.ts#L34) +[packages/framework/esm-navigation/src/breadcrumbs/filter.ts:34](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/breadcrumbs/filter.ts#L34) ___ @@ -1769,7 +1771,7 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/db.ts:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/db.ts#L32) +[packages/framework/esm-navigation/src/breadcrumbs/db.ts:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/breadcrumbs/db.ts#L32) ___ @@ -1789,7 +1791,7 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/filter.ts:54](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/filter.ts#L54) +[packages/framework/esm-navigation/src/breadcrumbs/filter.ts:54](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/breadcrumbs/filter.ts#L54) ___ @@ -1809,7 +1811,7 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/db.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/db.ts#L18) +[packages/framework/esm-navigation/src/breadcrumbs/db.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/breadcrumbs/db.ts#L18) ___ @@ -1829,7 +1831,7 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/db.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/db.ts#L22) +[packages/framework/esm-navigation/src/breadcrumbs/db.ts:22](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/breadcrumbs/db.ts#L22) ___ @@ -2623,7 +2625,7 @@ ___ ▸ **detach**(`extensionSlotName`, `extensionId`): `void` -Avoid using this. Extension attachments should be considered declarative. +**`deprecated`** Avoid using this. Extension attachments should be considered declarative. #### Parameters @@ -2638,7 +2640,7 @@ Avoid using this. Extension attachments should be considered declarative. #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:173](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L173) +[packages/framework/esm-extensions/src/extensions.ts:175](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L175) ___ @@ -2646,7 +2648,7 @@ ___ ▸ **detachAll**(`extensionSlotName`): `void` -Avoid using this. Extension attachments should be considered declarative. +**`deprecated`** Avoid using this. Extension attachments should be considered declarative. #### Parameters @@ -2660,7 +2662,7 @@ Avoid using this. Extension attachments should be considered declarative. #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:195](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L195) +[packages/framework/esm-extensions/src/extensions.ts:199](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L199) ___ @@ -2684,7 +2686,7 @@ An array of extensions assigned to the named slot #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:329](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L329) +[packages/framework/esm-extensions/src/extensions.ts:333](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L333) ___ @@ -2711,7 +2713,7 @@ A list of extensions that should be rendered #### Defined in -[packages/framework/esm-extensions/src/extensions.ts:255](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L255) +[packages/framework/esm-extensions/src/extensions.ts:259](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-extensions/src/extensions.ts#L259) ___ @@ -2837,7 +2839,7 @@ Does not consider if offline or online. #### Defined in -[packages/framework/esm-react-utils/src/useAssignedExtensions.ts:12](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useAssignedExtensions.ts#L12) +[packages/framework/esm-react-utils/src/useAssignedExtensions.ts:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/useAssignedExtensions.ts#L10) ___ @@ -3178,6 +3180,45 @@ A React link component which calls [navigate](API.md#navigate) when clicked ___ +### getHistory + +▸ **getHistory**(): `string`[] + +Returns a list of URLs representing the history of the current window session. + +#### Returns + +`string`[] + +#### Defined in + +[packages/framework/esm-navigation/src/history/history.ts:39](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/history/history.ts#L39) + +___ + +### goBackInHistory + +▸ **goBackInHistory**(`toUrl:`): `void` + +Rolls back the history to the specified point and navigates to that URL. + +#### Parameters + +| Name | Type | Description | +| :------ | :------ | :------ | +| `toUrl:` | `Object` | The URL in the history to navigate to. History after that index will be deleted. If the URL is not found in the history, an error will be thrown. | +| `toUrl:.toUrl` | `string` | | + +#### Returns + +`void` + +#### Defined in + +[packages/framework/esm-navigation/src/history/history.ts:50](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/history/history.ts#L50) + +___ + ### interpolateString ▸ **interpolateString**(`template`, `params`): `string` @@ -3206,7 +3247,7 @@ interpolateString("test ok", { one: "1", two: "2" }) // will return "test ok" #### Defined in -[packages/framework/esm-config/src/navigation/interpolate-string.ts:60](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/interpolate-string.ts#L60) +[packages/framework/esm-navigation/src/navigation/interpolate-string.ts:60](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/interpolate-string.ts#L60) ___ @@ -3252,7 +3293,7 @@ navigate({ #### Defined in -[packages/framework/esm-config/src/navigation/interpolate-string.ts:36](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/interpolate-string.ts#L36) +[packages/framework/esm-navigation/src/navigation/interpolate-string.ts:36](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/interpolate-string.ts#L36) ___ @@ -3270,7 +3311,8 @@ const submitHandler = () => { navigate({ to: config.links.submitSuccess }); }; ``` -#### Example return values: + +#### Example behavior:: ```js @example navigate({ to: "/some/path" }); // => window.location.assign("/some/path") @@ -3279,6 +3321,8 @@ navigate({ to: "${openmrsBase}/some/path" }); // => window.location.assign("/ope navigate({ to: "/openmrs/spa/foo/page" }); // => navigateToUrl("/openmrs/spa/foo/page") navigate({ to: "${openmrsSpaBase}/bar/page" }); // => navigateToUrl("/openmrs/spa/bar/page") navigate({ to: "/${openmrsSpaBase}/baz/page" }) // => navigateToUrl("/openmrs/spa/baz/page") +navigate({ to: "https://o3.openmrs.org/${openmrsSpaBase}/qux/page" }); // => navigateToUrl("/openmrs/spa/qux/page") + if `window.location.origin` == "https://o3.openmrs.org", else will use window.location.assign ``` #### Parameters @@ -3293,7 +3337,7 @@ navigate({ to: "/${openmrsSpaBase}/baz/page" }) // => navigateToUrl("/openmrs/sp #### Defined in -[packages/framework/esm-config/src/navigation/navigate.ts:46](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/navigate.ts#L46) +[packages/framework/esm-navigation/src/navigation/navigate.ts:49](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/navigate.ts#L49) ___ diff --git a/packages/framework/esm-framework/docs/classes/OpenmrsFetchError.md b/packages/framework/esm-framework/docs/classes/OpenmrsFetchError.md index 46da08f72..b64ae5c78 100644 --- a/packages/framework/esm-framework/docs/classes/OpenmrsFetchError.md +++ b/packages/framework/esm-framework/docs/classes/OpenmrsFetchError.md @@ -53,7 +53,7 @@ Error.constructor #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:295](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L295) +[packages/framework/esm-api/src/openmrs-fetch.ts:298](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L298) ## API Properties @@ -63,7 +63,7 @@ Error.constructor #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:303](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L303) +[packages/framework/esm-api/src/openmrs-fetch.ts:306](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L306) ___ @@ -73,7 +73,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:304](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L304) +[packages/framework/esm-api/src/openmrs-fetch.ts:307](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L307) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/BreadcrumbRegistration.md b/packages/framework/esm-framework/docs/interfaces/BreadcrumbRegistration.md index 9781af1d9..2a34b3cdf 100644 --- a/packages/framework/esm-framework/docs/interfaces/BreadcrumbRegistration.md +++ b/packages/framework/esm-framework/docs/interfaces/BreadcrumbRegistration.md @@ -17,7 +17,7 @@ #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:33](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L33) +[packages/framework/esm-navigation/src/types.ts:33](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L33) ___ @@ -27,4 +27,4 @@ ___ #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:34](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L34) +[packages/framework/esm-navigation/src/types.ts:34](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L34) diff --git a/packages/framework/esm-framework/docs/interfaces/BreadcrumbSettings.md b/packages/framework/esm-framework/docs/interfaces/BreadcrumbSettings.md index bd0da1599..f757ba0e2 100644 --- a/packages/framework/esm-framework/docs/interfaces/BreadcrumbSettings.md +++ b/packages/framework/esm-framework/docs/interfaces/BreadcrumbSettings.md @@ -26,7 +26,7 @@ Can be omitted; the value of `path` is used as the default value. #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L16) +[packages/framework/esm-navigation/src/types.ts:16](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L16) ___ @@ -43,7 +43,7 @@ parent. #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L25) +[packages/framework/esm-navigation/src/types.ts:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L25) ___ @@ -55,7 +55,7 @@ Gets the path of breadcrumb for navigation purposes. #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L7) +[packages/framework/esm-navigation/src/types.ts:7](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L7) ___ @@ -67,4 +67,4 @@ The title of the breadcrumb. #### Defined in -[packages/framework/esm-breadcrumbs/src/types.ts:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-breadcrumbs/src/types.ts#L29) +[packages/framework/esm-navigation/src/types.ts:29](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/types.ts#L29) diff --git a/packages/framework/esm-framework/docs/interfaces/FetchConfig.md b/packages/framework/esm-framework/docs/interfaces/FetchConfig.md index 92912e8f6..7ebeef6dd 100644 --- a/packages/framework/esm-framework/docs/interfaces/FetchConfig.md +++ b/packages/framework/esm-framework/docs/interfaces/FetchConfig.md @@ -37,7 +37,7 @@ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:309](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L309) +[packages/framework/esm-api/src/openmrs-fetch.ts:312](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L312) ___ @@ -47,7 +47,7 @@ ___ #### Defined in -[packages/framework/esm-api/src/openmrs-fetch.ts:308](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L308) +[packages/framework/esm-api/src/openmrs-fetch.ts:311](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-api/src/openmrs-fetch.ts#L311) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/NavigateOptions.md b/packages/framework/esm-framework/docs/interfaces/NavigateOptions.md index 375d93aac..c12d20a37 100644 --- a/packages/framework/esm-framework/docs/interfaces/NavigateOptions.md +++ b/packages/framework/esm-framework/docs/interfaces/NavigateOptions.md @@ -17,7 +17,7 @@ #### Defined in -[packages/framework/esm-config/src/navigation/navigate.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/navigate.ts#L14) +[packages/framework/esm-navigation/src/navigation/navigate.ts:14](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/navigate.ts#L14) ___ @@ -27,4 +27,4 @@ ___ #### Defined in -[packages/framework/esm-config/src/navigation/navigate.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-config/src/navigation/navigate.ts#L13) +[packages/framework/esm-navigation/src/navigation/navigate.ts:13](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-navigation/src/navigation/navigate.ts#L13) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 8c7b51270..10b821c05 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -4,16 +4,7 @@ import { createStore, type StoreApi } from 'zustand'; import { NEVER, of } from 'rxjs'; import { type SessionStore } from '@openmrs/esm-api'; import { getDefaultsFromConfigSchema } from '@openmrs/esm-utils'; -export { - getDefaultsFromConfigSchema, - parseDate, - formatDate, - formatDatetime, - formatTime, - age, -} from '@openmrs/esm-utils'; -export { interpolateString, interpolateUrl, validators, validator } from '@openmrs/esm-config'; -export { ConfigurableLink } from '@openmrs/esm-react-utils'; +import { interpolateUrl, type TemplateParams } from '@openmrs/esm-navigation'; window.i18next = { ...window.i18next, language: 'en' }; @@ -31,48 +22,29 @@ export function setupPaths(config: any) { window.getOpenmrsSpaBase = () => `${window.spaBase}/`; } -/* esm-utils */ -export function isVersionSatisfied() { - return true; -} - -export function useConnectivity() { - return true; -} - /* esm-api */ export const setSessionLocation = jest.fn(() => Promise.resolve()); - export const openmrsFetch = jest.fn((url?: string) => new Promise(() => {})); - export const openmrsObservableFetch = jest.fn(() => of({ data: { entry: [] } })); - export function getCurrentUser() { return of({ authenticated: false }); } - export const mockSessionStore = createGlobalStore('mock-session-store', { loaded: false, session: null, }); - export const getSessionStore = jest.fn(() => mockSessionStore); - export const setCurrentVisit = jest.fn(); - export const newWorkspaceItem = jest.fn(); - export const fhirBaseUrl = '/ws/fhir2/R4'; - export const attachmentUrl = '/ws/rest/v1/attachment'; - export const getAttachmentByUuid = jest.fn(); - export const getAttachments = jest.fn(); - export const createAttachment = jest.fn(); - export const deleteAttachmentPermanently = jest.fn(); +export const clearCurrentUser = jest.fn(); +export const refetchCurrentUser = jest.fn(); +export const setUserLanguage = jest.fn(); /* esm-state */ interface StoreEntity { @@ -126,6 +98,8 @@ function instrumentedStore(name: string, store: StoreApi) { } /* esm-config */ +export { validators, validator } from '@openmrs/esm-config'; + export const configInternalStore = createGlobalStore('config-internal', {}); export const implementerToolsConfigStore = createGlobalStore('implementer-tools-config', {}); @@ -156,8 +130,6 @@ export function defineExtensionConfigSchema(extensionName, schema) { configSchema = schema; } -export const navigate = jest.fn(); - /* esm-dynamic-loading */ export const importDynamic = jest.fn(); @@ -168,11 +140,6 @@ export const reportError = jest.fn().mockImplementation((error) => { throw error; }); -/* esm-feature-flags */ -export const registerFeatureFlags = jest.fn(); -export const getFeatureFlag = jest.fn().mockReturnValue(true); -export const subscribeToFeatureFlag = jest.fn((name: string, callback) => callback(true)); - /* esm-extensions */ export const attach = jest.fn(); @@ -193,7 +160,39 @@ export const getExtensionInternalStore = () => extensions: {}, }); +/* esm-feature-flags */ +export const registerFeatureFlags = jest.fn(); +export const getFeatureFlag = jest.fn().mockReturnValue(true); +export const subscribeToFeatureFlag = jest.fn((name: string, callback) => callback(true)); + +/* esm-navigation */ +export { goBackInHistory, interpolateUrl, interpolateString } from '@openmrs/esm-navigation'; +export let history = ['https://o3.openmrs.org/home']; +export const navigate = jest.fn(({ to, templateParams }: { to: string; templateParams?: TemplateParams }) => { + let target = interpolateUrl(to, templateParams); + if (target.startsWith('/')) { + target = window.location.origin + target; + } + try { + // Don't mess with the real window.location + if (!(window.location instanceof Location)) { + (window.location as any).href = target; + } + } catch (e) { + // window.location is probably not mocked. Don't worry about it. + } + history.push(target); +}); +export const getHistory = jest.fn(() => history); +export const clearHistory = jest.fn(() => { + history = []; +}); + +/* esm-offline */ +export const useConnectivity = jest.fn().mockReturnValue(true); + /* esm-react-utils */ +export { ConfigurableLink } from '@openmrs/esm-react-utils'; export const ComponentContext = React.createContext(null); @@ -278,7 +277,6 @@ export function useOpenmrsSWR(key: string | Array) { export const useDebounce = jest.fn().mockImplementation((value) => value); /* esm-styleguide */ - export const showNotification = jest.fn(); export const showActionableNotification = jest.fn(); export const showToast = jest.fn(); @@ -290,3 +288,17 @@ export const setLeftNav = jest.fn(); export const unsetLeftNav = jest.fn(); export const OpenmrsDatePicker = jest.fn(); + +/* esm-utils */ +export { + getDefaultsFromConfigSchema, + parseDate, + formatDate, + formatDatetime, + formatTime, + age, +} from '@openmrs/esm-utils'; + +export function isVersionSatisfied() { + return true; +} diff --git a/packages/framework/esm-framework/package.json b/packages/framework/esm-framework/package.json index 607e0d46d..b0772ac86 100644 --- a/packages/framework/esm-framework/package.json +++ b/packages/framework/esm-framework/package.json @@ -38,13 +38,13 @@ }, "dependencies": { "@openmrs/esm-api": "workspace:*", - "@openmrs/esm-breadcrumbs": "workspace:*", "@openmrs/esm-config": "workspace:*", "@openmrs/esm-dynamic-loading": "workspace:*", "@openmrs/esm-error-handling": "workspace:*", "@openmrs/esm-extensions": "workspace:*", "@openmrs/esm-feature-flags": "workspace:*", "@openmrs/esm-globals": "workspace:*", + "@openmrs/esm-navigation": "workspace:*", "@openmrs/esm-offline": "workspace:*", "@openmrs/esm-react-utils": "workspace:*", "@openmrs/esm-routes": "workspace:*", diff --git a/packages/framework/esm-framework/src/index.ts b/packages/framework/esm-framework/src/index.ts index cec111898..c3165588f 100644 --- a/packages/framework/esm-framework/src/index.ts +++ b/packages/framework/esm-framework/src/index.ts @@ -1,11 +1,11 @@ export * from '@openmrs/esm-api/src/public'; -export * from '@openmrs/esm-breadcrumbs'; export * from '@openmrs/esm-config/src/public'; export * from '@openmrs/esm-dynamic-loading/src/public'; export * from '@openmrs/esm-error-handling'; export * from '@openmrs/esm-extensions/src/public'; export * from '@openmrs/esm-feature-flags/src/public'; export * from '@openmrs/esm-globals/src/public'; +export * from '@openmrs/esm-navigation/src/public'; export * from '@openmrs/esm-offline/src/public'; export * from '@openmrs/esm-react-utils/src/public'; export * from '@openmrs/esm-state/src/public'; diff --git a/packages/framework/esm-framework/src/internal.ts b/packages/framework/esm-framework/src/internal.ts index 3ffb4e4be..1ac46f78a 100644 --- a/packages/framework/esm-framework/src/internal.ts +++ b/packages/framework/esm-framework/src/internal.ts @@ -1,11 +1,11 @@ export * from '@openmrs/esm-api'; -export * from '@openmrs/esm-breadcrumbs'; export * from '@openmrs/esm-config'; export * from '@openmrs/esm-dynamic-loading'; export * from '@openmrs/esm-error-handling'; export * from '@openmrs/esm-extensions'; export * from '@openmrs/esm-feature-flags'; export * from '@openmrs/esm-globals'; +export * from '@openmrs/esm-navigation'; export * from '@openmrs/esm-offline'; export * from '@openmrs/esm-react-utils'; export * from '@openmrs/esm-routes'; diff --git a/packages/framework/esm-navigation/README.md b/packages/framework/esm-navigation/README.md new file mode 100644 index 000000000..bd59222ff --- /dev/null +++ b/packages/framework/esm-navigation/README.md @@ -0,0 +1 @@ +# openmrs-esm-navigation diff --git a/packages/framework/esm-breadcrumbs/jest.config.js b/packages/framework/esm-navigation/jest.config.js similarity index 79% rename from packages/framework/esm-breadcrumbs/jest.config.js rename to packages/framework/esm-navigation/jest.config.js index 7919641c5..7e7ff7bbb 100644 --- a/packages/framework/esm-breadcrumbs/jest.config.js +++ b/packages/framework/esm-navigation/jest.config.js @@ -1,10 +1,11 @@ module.exports = { - transform: { - '^.+\\.tsx?$': ['@swc/jest'], - }, moduleNameMapper: {}, + setupFiles: ['/src/setup-tests.js'], testEnvironment: 'jsdom', testEnvironmentOptions: { url: 'http://localhost/', }, + transform: { + '^.+\\.tsx?$': ['@swc/jest'], + }, }; diff --git a/packages/framework/esm-breadcrumbs/package.json b/packages/framework/esm-navigation/package.json similarity index 87% rename from packages/framework/esm-breadcrumbs/package.json rename to packages/framework/esm-navigation/package.json index 2df36d538..7f575d0ee 100644 --- a/packages/framework/esm-breadcrumbs/package.json +++ b/packages/framework/esm-navigation/package.json @@ -1,9 +1,9 @@ { - "name": "@openmrs/esm-breadcrumbs", + "name": "@openmrs/esm-navigation", "version": "5.3.2", "license": "MPL-2.0", - "description": "The javascript module for breadcrumb registration", - "browser": "dist/openmrs-esm-breadcrumbs.js", + "description": "OpenMRS library providing tools for breadcrumbs, navigation, and history.", + "browser": "dist/openmrs-esm-navigation.js", "main": "src/index.ts", "source": true, "scripts": { diff --git a/packages/framework/esm-breadcrumbs/src/db.ts b/packages/framework/esm-navigation/src/breadcrumbs/db.ts similarity index 98% rename from packages/framework/esm-breadcrumbs/src/db.ts rename to packages/framework/esm-navigation/src/breadcrumbs/db.ts index a5395d8e8..35de3f54e 100644 --- a/packages/framework/esm-breadcrumbs/src/db.ts +++ b/packages/framework/esm-navigation/src/breadcrumbs/db.ts @@ -1,7 +1,7 @@ /** @module @category Breadcrumb */ import { pathToRegexp } from 'path-to-regexp'; import { createGlobalStore } from '@openmrs/esm-state'; -import type { BreadcrumbSettings, BreadcrumbRegistration } from './types'; +import type { BreadcrumbSettings, BreadcrumbRegistration } from '../types'; const store = createGlobalStore>('breadcrumbs', []); diff --git a/packages/framework/esm-breadcrumbs/src/filter.ts b/packages/framework/esm-navigation/src/breadcrumbs/filter.ts similarity index 96% rename from packages/framework/esm-breadcrumbs/src/filter.ts rename to packages/framework/esm-navigation/src/breadcrumbs/filter.ts index 2118786f9..6ad17c17d 100644 --- a/packages/framework/esm-breadcrumbs/src/filter.ts +++ b/packages/framework/esm-navigation/src/breadcrumbs/filter.ts @@ -1,6 +1,6 @@ /** @module @category Breadcrumb */ import { getBreadcrumbs } from './db'; -import type { BreadcrumbRegistration } from './types'; +import type { BreadcrumbRegistration } from '../types'; function getExact(breadcrumbs: Array, path: string): BreadcrumbRegistration { const [bc] = breadcrumbs.filter((m) => m.matcher.test(path)); diff --git a/packages/framework/esm-navigation/src/history/history.test.ts b/packages/framework/esm-navigation/src/history/history.test.ts new file mode 100644 index 000000000..aba86fcf8 --- /dev/null +++ b/packages/framework/esm-navigation/src/history/history.test.ts @@ -0,0 +1,76 @@ +import { navigate } from '../navigation/navigate'; +import { clearHistory, getHistory, goBackInHistory, setupHistory } from './history'; + +jest.mock('../navigation/navigate'); +const mockNavigate = navigate as jest.Mock; + +describe('history', () => { + const originalWindowLocation = window.location; + const originalDocumentReferrer = Object.getOwnPropertyDescriptor( + Document.prototype, + 'referrer', + ) as PropertyDescriptor; + const mockReferrer = 'https://o3.openmrs.org/openmrs/spa/lalaland'; + let mockLocationAssign; + + beforeAll(() => { + delete (window as any).location; + delete (document as any).referrer; + (window as any).location = { + assign: jest.fn(), + href: 'https://o3.openmrs.org/openmrs/spa/chart', + origin: 'https://o3.openmrs.org', + }; + window.getOpenmrsSpaBase = () => 'https://o3.openmrs.org/openmrs/spa'; + Object.defineProperty(document, 'referrer', { + value: mockReferrer, + writable: true, + configurable: true, + }); + mockLocationAssign = window.location.assign as jest.Mock; + }); + + beforeEach(() => { + mockLocationAssign.mockClear(); + mockNavigate.mockClear(); + }); + + afterEach(() => { + clearHistory(); + }); + + afterAll(() => { + window.location = originalWindowLocation; + (document as any).referrer = originalDocumentReferrer; + Object.defineProperty(document, 'referrer', originalDocumentReferrer); + }); + + it('should be initialized with document.referrer if available', () => { + setupHistory(); + expect(getHistory()).toEqual([mockReferrer]); + }); + + it('should update history on routing events and go back correctly', () => { + setupHistory(); + window.location.href = 'https://o3.openmrs.org/openmrs/spa/labs'; + window.dispatchEvent(new CustomEvent('single-spa:routing-event')); + expect(getHistory()).toEqual([mockReferrer, 'https://o3.openmrs.org/openmrs/spa/labs']); + window.location.href = 'https://o3.openmrs.org/pharmacy'; + window.dispatchEvent(new CustomEvent('single-spa:routing-event')); + window.location.href = 'https://o3.openmrs.org/x-ray'; + window.dispatchEvent(new CustomEvent('single-spa:routing-event')); + expect(getHistory()).toEqual([ + mockReferrer, + 'https://o3.openmrs.org/openmrs/spa/labs', + 'https://o3.openmrs.org/pharmacy', + 'https://o3.openmrs.org/x-ray', + ]); + + mockNavigate.mockImplementation((params: { to: string }) => { + window.location.href = params.to; + window.dispatchEvent(new CustomEvent('single-spa:routing-event')); + }); + goBackInHistory({ toUrl: 'https://o3.openmrs.org/openmrs/spa/labs' }); + expect(getHistory()).toEqual([mockReferrer, 'https://o3.openmrs.org/openmrs/spa/labs']); + }); +}); diff --git a/packages/framework/esm-navigation/src/history/history.ts b/packages/framework/esm-navigation/src/history/history.ts new file mode 100644 index 000000000..f2e945f60 --- /dev/null +++ b/packages/framework/esm-navigation/src/history/history.ts @@ -0,0 +1,68 @@ +/** @module @category Navigation */ +import { navigate } from '../navigation/navigate'; + +const historyKey = 'openmrs:history'; + +function addToHistory(newLocation: string) { + let history = JSON.parse(sessionStorage.getItem(historyKey) ?? '[]') || []; + history.push(newLocation); + const maxSize = 50; + if (history.length > maxSize) { + history = history.slice(-maxSize); + } + sessionStorage.setItem(historyKey, JSON.stringify(history)); +} + +/** + * Initialize history from sessionStorage. If history is empty, add + * document.referrer if available. + * + * @internal + */ +export function setupHistory() { + let history = JSON.parse(sessionStorage.getItem(historyKey) ?? '[]'); + if (history.length === 0 && document.referrer) { + addToHistory(document.referrer); + } + + window.addEventListener('single-spa:routing-event', (evt) => { + const history = getHistory(); + if (history[history.length - 1] !== window.location.href) { + addToHistory(window.location.href); + } + }); +} + +/** + * Returns a list of URLs representing the history of the current window session. + */ +export function getHistory(): Array { + return JSON.parse(sessionStorage.getItem(historyKey) ?? '[]'); +} + +/** + * Rolls back the history to the specified point and navigates to that URL. + * + * @param toUrl: The URL in the history to navigate to. History after that index + * will be deleted. If the URL is not found in the history, an error will be + * thrown. + */ +export function goBackInHistory({ toUrl }: { toUrl: string }) { + const history = getHistory(); + const toIndex = history.lastIndexOf(toUrl); + if (toIndex != -1) { + const newHistory = history.slice(0, toIndex + 1); + navigate({ to: history[toIndex] }); + sessionStorage.setItem(historyKey, JSON.stringify(newHistory)); + } else { + throw new Error(`URL ${toUrl} not found in history; cannot go back to it.`); + } +} + +/** + * Clears the history from sessionStorage. This should be done when the user + * logs out. + */ +export function clearHistory() { + sessionStorage.removeItem(historyKey); +} diff --git a/packages/framework/esm-navigation/src/index.ts b/packages/framework/esm-navigation/src/index.ts new file mode 100644 index 000000000..c5fbb89cf --- /dev/null +++ b/packages/framework/esm-navigation/src/index.ts @@ -0,0 +1,6 @@ +export * from './breadcrumbs/db'; +export * from './breadcrumbs/filter'; +export * from './history/history'; +export * from './navigation/navigate'; +export * from './navigation/interpolate-string'; +export * from './types'; diff --git a/packages/framework/esm-config/src/navigation/interpolate-string.test.ts b/packages/framework/esm-navigation/src/navigation/interpolate-string.test.ts similarity index 100% rename from packages/framework/esm-config/src/navigation/interpolate-string.test.ts rename to packages/framework/esm-navigation/src/navigation/interpolate-string.test.ts diff --git a/packages/framework/esm-config/src/navigation/interpolate-string.ts b/packages/framework/esm-navigation/src/navigation/interpolate-string.ts similarity index 100% rename from packages/framework/esm-config/src/navigation/interpolate-string.ts rename to packages/framework/esm-navigation/src/navigation/interpolate-string.ts diff --git a/packages/framework/esm-config/src/navigation/navigate.test.ts b/packages/framework/esm-navigation/src/navigation/navigate.test.ts similarity index 85% rename from packages/framework/esm-config/src/navigation/navigate.test.ts rename to packages/framework/esm-navigation/src/navigation/navigate.test.ts index 41a41f692..9869cf0f8 100644 --- a/packages/framework/esm-config/src/navigation/navigate.test.ts +++ b/packages/framework/esm-navigation/src/navigation/navigate.test.ts @@ -11,7 +11,7 @@ describe('navigate', () => { beforeAll(() => { delete (window as any).location; //@ts-ignore - window.location = { assign: jest.fn() }; + window.location = { assign: jest.fn(), origin: 'https://o3.openmrs.org' }; mockLocationAssign = window.location.assign as jest.Mock; }); @@ -59,4 +59,10 @@ describe('navigate', () => { expect(navigateToUrl).toHaveBeenCalledWith('/openmrs/spa/baz/page'); expect(window.location.assign).not.toHaveBeenCalled(); }); + + it('uses single-spa navigateToUrl if the URL has the current origin', () => { + navigate({ to: `${window.location.origin}/openmrs/spa/qux/page` }); + expect(navigateToUrl).toHaveBeenCalledWith('/openmrs/spa/qux/page'); + expect(window.location.assign).not.toHaveBeenCalled(); + }); }); diff --git a/packages/framework/esm-config/src/navigation/navigate.ts b/packages/framework/esm-navigation/src/navigation/navigate.ts similarity index 85% rename from packages/framework/esm-config/src/navigation/navigate.ts rename to packages/framework/esm-navigation/src/navigation/navigate.ts index 935ebe275..4d19274b6 100644 --- a/packages/framework/esm-config/src/navigation/navigate.ts +++ b/packages/framework/esm-navigation/src/navigation/navigate.ts @@ -25,7 +25,8 @@ export interface NavigateOptions { * navigate({ to: config.links.submitSuccess }); * }; * ``` - * #### Example return values: + * + * #### Example behavior:: * ```js * @example * navigate({ to: "/some/path" }); // => window.location.assign("/some/path") @@ -34,6 +35,8 @@ export interface NavigateOptions { * navigate({ to: "/openmrs/spa/foo/page" }); // => navigateToUrl("/openmrs/spa/foo/page") * navigate({ to: "${openmrsSpaBase}/bar/page" }); // => navigateToUrl("/openmrs/spa/bar/page") * navigate({ to: "/${openmrsSpaBase}/baz/page" }) // => navigateToUrl("/openmrs/spa/baz/page") + * navigate({ to: "https://o3.openmrs.org/${openmrsSpaBase}/qux/page" }); // => navigateToUrl("/openmrs/spa/qux/page") + * if `window.location.origin` == "https://o3.openmrs.org", else will use window.location.assign * ``` * * @param to The target path or URL. Supports templating with 'openmrsBase', 'openmrsSpaBase', @@ -45,7 +48,7 @@ export interface NavigateOptions { */ export function navigate({ to, templateParams }: NavigateOptions): void { const openmrsSpaBase = trimTrailingSlash(window.getOpenmrsSpaBase()); - const target = interpolateUrl(to, templateParams); + const target = interpolateUrl(to, templateParams).replace(window.location.origin, ''); const isSpaPath = target.startsWith(openmrsSpaBase); if (isSpaPath) { diff --git a/packages/framework/esm-navigation/src/public.ts b/packages/framework/esm-navigation/src/public.ts new file mode 100644 index 000000000..b6a489bce --- /dev/null +++ b/packages/framework/esm-navigation/src/public.ts @@ -0,0 +1,6 @@ +export * from './breadcrumbs/db'; +export * from './breadcrumbs/filter'; +export { getHistory, goBackInHistory } from './history/history'; +export * from './navigation/interpolate-string'; +export * from './navigation/navigate'; +export * from './types'; diff --git a/packages/framework/esm-navigation/src/setup-tests.js b/packages/framework/esm-navigation/src/setup-tests.js new file mode 100644 index 000000000..dc037c8f3 --- /dev/null +++ b/packages/framework/esm-navigation/src/setup-tests.js @@ -0,0 +1,3 @@ +window.openmrsBase = '/openmrs'; +window.spaBase = '/spa'; +window.getOpenmrsSpaBase = () => '/openmrs/spa/'; diff --git a/packages/framework/esm-breadcrumbs/src/types.ts b/packages/framework/esm-navigation/src/types.ts similarity index 100% rename from packages/framework/esm-breadcrumbs/src/types.ts rename to packages/framework/esm-navigation/src/types.ts diff --git a/packages/framework/esm-breadcrumbs/tsconfig.json b/packages/framework/esm-navigation/tsconfig.json similarity index 100% rename from packages/framework/esm-breadcrumbs/tsconfig.json rename to packages/framework/esm-navigation/tsconfig.json diff --git a/packages/framework/esm-breadcrumbs/webpack.config.js b/packages/framework/esm-navigation/webpack.config.js similarity index 96% rename from packages/framework/esm-breadcrumbs/webpack.config.js rename to packages/framework/esm-navigation/webpack.config.js index 85a1013f7..0e67019bc 100644 --- a/packages/framework/esm-breadcrumbs/webpack.config.js +++ b/packages/framework/esm-navigation/webpack.config.js @@ -8,7 +8,7 @@ const { peerDependencies } = require('./package.json'); module.exports = (env) => ({ entry: [resolve(__dirname, 'src/index.ts')], output: { - filename: 'openmrs-esm-breadcrumbs.js', + filename: 'openmrs-esm-navigation.js', path: resolve(__dirname, 'dist'), library: { type: 'system' }, }, diff --git a/packages/framework/esm-react-utils/package.json b/packages/framework/esm-react-utils/package.json index c5761e9fe..d3fe5aa98 100644 --- a/packages/framework/esm-react-utils/package.json +++ b/packages/framework/esm-react-utils/package.json @@ -48,6 +48,7 @@ "@openmrs/esm-error-handling": "5.x", "@openmrs/esm-extensions": "5.x", "@openmrs/esm-globals": "5.x", + "@openmrs/esm-navigation": "5.x", "dayjs": "1.x", "i18next": "19.x", "react": "18.x", @@ -63,6 +64,7 @@ "@openmrs/esm-extensions": "workspace:*", "@openmrs/esm-feature-flags": "workspace:*", "@openmrs/esm-globals": "workspace:*", + "@openmrs/esm-navigation": "workspace:*", "dayjs": "^1.10.8", "i18next": "^21.10.0", "react": "^18.1.0", diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx index ab0472034..bb95c5909 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx @@ -2,18 +2,13 @@ import React from 'react'; import '@testing-library/jest-dom'; import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; -import { navigate, interpolateUrl } from '@openmrs/esm-config'; +import { navigate } from '@openmrs/esm-navigation'; import { ConfigurableLink } from './ConfigurableLink'; jest.mock('single-spa'); -jest.mock('@openmrs/esm-config'); const mockNavigate = navigate as jest.Mock; -const realInterpolate = jest.requireActual('@openmrs/esm-config').interpolateUrl; - -(interpolateUrl as jest.Mock).mockImplementation((...args) => realInterpolate(...args)); - describe(`ConfigurableLink`, () => { const path = '${openmrsSpaBase}/home'; beforeEach(() => { diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx index 99cbf0ab6..4a12ac6be 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx @@ -1,7 +1,7 @@ /** @module @category Navigation */ import React, { type MouseEvent, type AnchorHTMLAttributes, type PropsWithChildren } from 'react'; -import type { TemplateParams } from '@openmrs/esm-config'; -import { navigate, interpolateUrl } from '@openmrs/esm-config'; +import type { TemplateParams } from '@openmrs/esm-navigation'; +import { navigate, interpolateUrl } from '@openmrs/esm-navigation'; function handleClick(event: MouseEvent, to: string, templateParams?: TemplateParams, onBeforeNavigate?: () => void) { if (!event.metaKey && !event.ctrlKey && !event.shiftKey && event.button == 0) { diff --git a/packages/framework/esm-react-utils/src/extensions.test.tsx b/packages/framework/esm-react-utils/src/extensions.test.tsx index 024162900..b133082d0 100644 --- a/packages/framework/esm-react-utils/src/extensions.test.tsx +++ b/packages/framework/esm-react-utils/src/extensions.test.tsx @@ -18,7 +18,7 @@ import { import userEvent from '@testing-library/user-event'; import { registerFeatureFlag, setFeatureFlag } from '@openmrs/esm-feature-flags'; -// For some reason in the text context `isEqual` always returns true +// For some reason in the test context `isEqual` always returns true // when using the import substitution in jest.config.js. Here's a custom // mock. jest.mock('lodash-es/isEqual', () => (a, b) => JSON.stringify(a) == JSON.stringify(b)); diff --git a/packages/framework/esm-react-utils/src/setup-tests.js b/packages/framework/esm-react-utils/src/setup-tests.js index 436aecd89..7ed3ee803 100644 --- a/packages/framework/esm-react-utils/src/setup-tests.js +++ b/packages/framework/esm-react-utils/src/setup-tests.js @@ -1,5 +1,11 @@ +import { jest } from '@jest/globals' import '@testing-library/jest-dom'; global.window.openmrsBase = '/openmrs'; global.window.spaBase = '/spa'; global.window.getOpenmrsSpaBase = () => '/openmrs/spa/'; + +jest.mock('@openmrs/esm-navigation', () => ({ + ...jest.requireActual('@openmrs/esm-navigation'), + navigate: jest.fn(), +})); diff --git a/packages/shell/esm-app-shell/src/run.ts b/packages/shell/esm-app-shell/src/run.ts index 80c10d376..f9819bf8b 100644 --- a/packages/shell/esm-app-shell/src/run.ts +++ b/packages/shell/esm-app-shell/src/run.ts @@ -36,6 +36,7 @@ import { localStorageRoutesPrefix, isOpenmrsAppRoutes, isOpenmrsRoutes, + setupHistory, } from '@openmrs/esm-framework/src/internal'; import { finishRegisteringAllApps, registerApp, tryRegisterExtension } from './apps'; import { setupI18n } from './locale'; @@ -404,6 +405,7 @@ export function run(configUrls: Array, offline: boolean) { subscribeSnackbarShown(showSnackbar); subscribePrecacheStaticDependencies(precacheGlobalStaticDependencies); setupApiModule(); + setupHistory(); registerCoreExtensions(); return setupApps() diff --git a/yarn.lock b/yarn.lock index 98fc379ad..cc3df8e72 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2609,6 +2609,7 @@ __metadata: dependencies: "@openmrs/esm-config": "workspace:*" "@openmrs/esm-error-handling": "workspace:*" + "@openmrs/esm-navigation": "workspace:*" "@openmrs/esm-state": "workspace:*" "@types/fhir": "npm:0.0.31" lodash-es: "npm:^4.17.21" @@ -2617,6 +2618,7 @@ __metadata: peerDependencies: "@openmrs/esm-config": 5.x "@openmrs/esm-error-handling": 5.x + "@openmrs/esm-navigation": 5.x "@openmrs/esm-offline": 5.x languageName: unknown linkType: soft @@ -2656,17 +2658,6 @@ __metadata: languageName: unknown linkType: soft -"@openmrs/esm-breadcrumbs@workspace:*, @openmrs/esm-breadcrumbs@workspace:packages/framework/esm-breadcrumbs": - version: 0.0.0-use.local - resolution: "@openmrs/esm-breadcrumbs@workspace:packages/framework/esm-breadcrumbs" - dependencies: - "@openmrs/esm-state": "workspace:*" - path-to-regexp: "npm:6.1.0" - peerDependencies: - "@openmrs/esm-state": 5.x - languageName: unknown - linkType: soft - "@openmrs/esm-config@workspace:*, @openmrs/esm-config@workspace:packages/framework/esm-config": version: 0.0.0-use.local resolution: "@openmrs/esm-config@workspace:packages/framework/esm-config" @@ -2811,13 +2802,13 @@ __metadata: resolution: "@openmrs/esm-framework@workspace:packages/framework/esm-framework" dependencies: "@openmrs/esm-api": "workspace:*" - "@openmrs/esm-breadcrumbs": "workspace:*" "@openmrs/esm-config": "workspace:*" "@openmrs/esm-dynamic-loading": "workspace:*" "@openmrs/esm-error-handling": "workspace:*" "@openmrs/esm-extensions": "workspace:*" "@openmrs/esm-feature-flags": "workspace:*" "@openmrs/esm-globals": "workspace:*" + "@openmrs/esm-navigation": "workspace:*" "@openmrs/esm-offline": "workspace:*" "@openmrs/esm-react-utils": "workspace:*" "@openmrs/esm-routes": "workspace:*" @@ -2904,6 +2895,17 @@ __metadata: languageName: unknown linkType: soft +"@openmrs/esm-navigation@workspace:*, @openmrs/esm-navigation@workspace:packages/framework/esm-navigation": + version: 0.0.0-use.local + resolution: "@openmrs/esm-navigation@workspace:packages/framework/esm-navigation" + dependencies: + "@openmrs/esm-state": "workspace:*" + path-to-regexp: "npm:6.1.0" + peerDependencies: + "@openmrs/esm-state": 5.x + languageName: unknown + linkType: soft + "@openmrs/esm-offline-tools-app@workspace:packages/apps/esm-offline-tools-app": version: 0.0.0-use.local resolution: "@openmrs/esm-offline-tools-app@workspace:packages/apps/esm-offline-tools-app" @@ -2990,6 +2992,7 @@ __metadata: "@openmrs/esm-extensions": "workspace:*" "@openmrs/esm-feature-flags": "workspace:*" "@openmrs/esm-globals": "workspace:*" + "@openmrs/esm-navigation": "workspace:*" dayjs: "npm:^1.10.8" i18next: "npm:^21.10.0" lodash-es: "npm:^4.17.21" @@ -3006,6 +3009,7 @@ __metadata: "@openmrs/esm-error-handling": 5.x "@openmrs/esm-extensions": 5.x "@openmrs/esm-globals": 5.x + "@openmrs/esm-navigation": 5.x dayjs: 1.x i18next: 19.x react: 18.x From 6c083ad1dcbb98d8939895ba1c804d4b34e7b448 Mon Sep 17 00:00:00 2001 From: ThemboJonathan Date: Thu, 11 Jan 2024 16:50:52 +0300 Subject: [PATCH 26/37] (chore) Migrate to newer Transifex version (#878) --- .tx/config | 48 ++++++++++++++++++++++++++++-------------------- 1 file changed, 28 insertions(+), 20 deletions(-) diff --git a/.tx/config b/.tx/config index e478a0cf7..1da047081 100644 --- a/.tx/config +++ b/.tx/config @@ -1,27 +1,35 @@ [main] host = https://www.transifex.com +[o:openmrs:p:openmrs-esm-core:r:esm-implementer-tools-app] +file_filter = packages/apps/esm-implementer-tools-app/translations/.json +source_file = packages/apps/esm-implementer-tools-app/translations/en.json +source_lang = en +type = KEYVALUEJSON +replace_edited_strings = false +keep_translations = false -[openmrs-esm-core.esm-implementer-tools-app] -file_filter = packages/apps/esm-implementer-tools-app/translations/.json -source_file = packages/apps/esm-implementer-tools-app/translations/en.json -source_lang = en -type = KEYVALUEJSON +[o:openmrs:p:openmrs-esm-core:r:esm-login-app] +file_filter = packages/apps/esm-login-app/translations/.json +source_file = packages/apps/esm-login-app/translations/en.json +source_lang = en +type = KEYVALUEJSON +replace_edited_strings = false +keep_translations = false -[openmrs-esm-core.esm-login-app] -file_filter = packages/apps/esm-login-app/translations/.json -source_file = packages/apps/esm-login-app/translations/en.json -source_lang = en -type = KEYVALUEJSON +[o:openmrs:p:openmrs-esm-core:r:esm-offline-tools-app] +file_filter = packages/apps/esm-offline-tools-app/translations/.json +source_file = packages/apps/esm-offline-tools-app/translations/en.json +source_lang = en +type = KEYVALUEJSON +replace_edited_strings = false +keep_translations = false -[openmrs-esm-core.esm-offline-tools-app] -file_filter = packages/apps/esm-offline-tools-app/translations/.json -source_file = packages/apps/esm-offline-tools-app/translations/en.json -source_lang = en -type = KEYVALUEJSON +[o:openmrs:p:openmrs-esm-core:r:esm-primary-navigation-app] +file_filter = packages/apps/esm-primary-navigation-app/translations/.json +source_file = packages/apps/esm-primary-navigation-app/translations/en.json +source_lang = en +type = KEYVALUEJSON +replace_edited_strings = false +keep_translations = false -[openmrs-esm-core.esm-primary-navigation-app] -file_filter = packages/apps/esm-primary-navigation-app/translations/.json -source_file = packages/apps/esm-primary-navigation-app/translations/en.json -source_lang = en -type = KEYVALUEJSON From 6ff3e1cfca07185c93d22c1366fa8d5f99cefc33 Mon Sep 17 00:00:00 2001 From: Jose Francisco <94977371+icrc-jofrancisco@users.noreply.github.com> Date: Thu, 11 Jan 2024 19:12:53 +0000 Subject: [PATCH 27/37] (fix) Update offline tools to support i18next interpolation syntax (#881) --- packages/apps/esm-offline-tools-app/src/index.ts | 4 ++-- .../src/offline-actions/synchronizing-notification.tsx | 2 +- packages/apps/esm-offline-tools-app/translations/am.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/ar.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/en.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/es.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/fr.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/he.json | 7 ++++++- packages/apps/esm-offline-tools-app/translations/km.json | 7 ++++++- 9 files changed, 45 insertions(+), 10 deletions(-) diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index 983933555..60a0ca689 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -44,7 +44,7 @@ export const offlineToolsPatientsLink = getSyncLifecycle( () => OfflineToolsNavLink({ page: 'patients', - title: 'patients', + title: 'offlinePatients', }), options, ); @@ -53,7 +53,7 @@ export const offlineToolsActionsLink = getSyncLifecycle( () => OfflineToolsNavLink({ page: 'actions', - title: 'actions', + title: 'offlineActions', }), options, ); diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx index 5a179a0fd..3c831e249 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/synchronizing-notification.tsx @@ -47,7 +47,7 @@ function SynchronizingNotification({ mySynchronizationIndex }) {
{isCanceled ? t('offlineActionsSynchronizationNotificationCanceling', 'Canceling...') - : t('offlineActionsSynchronizationNotificationStatus', '{current} / {total} actions', { + : t('offlineActionsSynchronizationNotificationStatus', '{{current}} / {{total}} actions', { current: synchronization.totalCount - synchronization.pendingCount, total: synchronization.totalCount, })} diff --git a/packages/apps/esm-offline-tools-app/translations/am.json b/packages/apps/esm-offline-tools-app/translations/am.json index 91d1d6103..f74f103e2 100644 --- a/packages/apps/esm-offline-tools-app/translations/am.json +++ b/packages/apps/esm-offline-tools-app/translations/am.json @@ -53,5 +53,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "offlineActionsSynchronizationNotificationTitle": "Upload", + "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", + "offlineActionsSynchronizationNotificationCanceling": "Canceling...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} actions", + "offlineActionsSynchronizationNotificationCancelUpload": "Cancel upload" } diff --git a/packages/apps/esm-offline-tools-app/translations/ar.json b/packages/apps/esm-offline-tools-app/translations/ar.json index 84da5f58e..0a6174dd6 100644 --- a/packages/apps/esm-offline-tools-app/translations/ar.json +++ b/packages/apps/esm-offline-tools-app/translations/ar.json @@ -57,5 +57,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "خطأ غير معروف.", "offlinePatientSyncDetailsHeader": "تفاصيل المريض بدون اتصال", "offlineReady": "جاهز للعمل بدون اتصال", - "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال" + "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال", + "offlineActionsSynchronizationNotificationTitle": "تحميل", + "offlineActionsSynchronizationNotificationSynchronized": "انتهت مزامنة الإجراءات غير المتصلة.", + "offlineActionsSynchronizationNotificationCanceling": "إلغاء...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} إجراء", + "offlineActionsSynchronizationNotificationCancelUpload": "إلغاء التحميل" } diff --git a/packages/apps/esm-offline-tools-app/translations/en.json b/packages/apps/esm-offline-tools-app/translations/en.json index 304df0615..bc0e5f924 100644 --- a/packages/apps/esm-offline-tools-app/translations/en.json +++ b/packages/apps/esm-offline-tools-app/translations/en.json @@ -53,5 +53,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "offlineActionsSynchronizationNotificationTitle": "Upload", + "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", + "offlineActionsSynchronizationNotificationCanceling": "Canceling...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} actions", + "offlineActionsSynchronizationNotificationCancelUpload": "Cancel upload" } diff --git a/packages/apps/esm-offline-tools-app/translations/es.json b/packages/apps/esm-offline-tools-app/translations/es.json index 6cc1961b4..255b87085 100644 --- a/packages/apps/esm-offline-tools-app/translations/es.json +++ b/packages/apps/esm-offline-tools-app/translations/es.json @@ -54,5 +54,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", "offlineReady": "Listo offline", - "offlineToolsAppMenuLink": "Herramientas offline" + "offlineToolsAppMenuLink": "Herramientas offline", + "offlineActionsSynchronizationNotificationTitle": "Subir", + "offlineActionsSynchronizationNotificationSynchronized": "La sincronización de acciones sin conexión ha finalizado.", + "offlineActionsSynchronizationNotificationCanceling": "Cancelando...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} acciones", + "offlineActionsSynchronizationNotificationCancelUpload": "Cancelar subida" } diff --git a/packages/apps/esm-offline-tools-app/translations/fr.json b/packages/apps/esm-offline-tools-app/translations/fr.json index 6d3bad255..b0fd9277e 100644 --- a/packages/apps/esm-offline-tools-app/translations/fr.json +++ b/packages/apps/esm-offline-tools-app/translations/fr.json @@ -54,5 +54,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", "offlineReady": "Prêt pour être hors ligne", - "offlineToolsAppMenuLink": "Outils hors ligne" + "offlineToolsAppMenuLink": "Outils hors ligne", + "offlineActionsSynchronizationNotificationTitle": "Téléversement", + "offlineActionsSynchronizationNotificationSynchronized": "La synchronisation des actions hors ligne est terminée.", + "offlineActionsSynchronizationNotificationCanceling": "Annulation...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} actions", + "offlineActionsSynchronizationNotificationCancelUpload": "Annuler le téléversement" } diff --git a/packages/apps/esm-offline-tools-app/translations/he.json b/packages/apps/esm-offline-tools-app/translations/he.json index 1df128305..623ebc699 100644 --- a/packages/apps/esm-offline-tools-app/translations/he.json +++ b/packages/apps/esm-offline-tools-app/translations/he.json @@ -55,5 +55,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "שגיאה לא ידועה.", "offlinePatientSyncDetailsHeader": "פרטי מטופל לא מקוון", "offlineReady": "מצב לא מקוון מוכן", - "offlineToolsAppMenuLink": "כלי לא מקוונים" + "offlineToolsAppMenuLink": "כלי לא מקוונים", + "offlineActionsSynchronizationNotificationTitle": "העלאה", + "offlineActionsSynchronizationNotificationSynchronized": "הסנכרון של הפעולות במצב לא מקוון הושלם.", + "offlineActionsSynchronizationNotificationCanceling": "מבטל...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} פעולות", + "offlineActionsSynchronizationNotificationCancelUpload": "בטל העלאה" } diff --git a/packages/apps/esm-offline-tools-app/translations/km.json b/packages/apps/esm-offline-tools-app/translations/km.json index 4b2781b68..bec8343b5 100644 --- a/packages/apps/esm-offline-tools-app/translations/km.json +++ b/packages/apps/esm-offline-tools-app/translations/km.json @@ -52,5 +52,10 @@ "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", "offlineReady": "Offline Ready", - "offlineToolsAppMenuLink": "Offline tools" + "offlineToolsAppMenuLink": "Offline tools", + "offlineActionsSynchronizationNotificationTitle": "Upload", + "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", + "offlineActionsSynchronizationNotificationCanceling": "Canceling...", + "offlineActionsSynchronizationNotificationStatus": "{{current}} / {{total}} actions", + "offlineActionsSynchronizationNotificationCancelUpload": "Cancel upload" } From 84d6b056cce10e117c6baae1e973e1d730a0ad65 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 12 Jan 2024 01:21:07 +0300 Subject: [PATCH 28/37] (fix) Make ConfigurableLink warn when bad props are provided (#882) --- packages/framework/esm-framework/docs/API.md | 2 +- .../docs/interfaces/ConfigurableLinkProps.md | 14 ++++++++--- .../esm-react-utils/src/ConfigurableLink.tsx | 25 ++++++++++++++++--- 3 files changed, 32 insertions(+), 9 deletions(-) diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index e1f2799b6..a49ead0ca 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -3176,7 +3176,7 @@ A React link component which calls [navigate](API.md#navigate) when clicked #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L32) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:53](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L53) ___ diff --git a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md index f42f38819..96e64b2c0 100644 --- a/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md +++ b/packages/framework/esm-framework/docs/interfaces/ConfigurableLinkProps.md @@ -295,7 +295,7 @@ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:19](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L19) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:40](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L40) ___ @@ -305,7 +305,7 @@ ___ #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L18) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:39](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L39) ___ @@ -4165,7 +4165,13 @@ node_modules/@types/react/index.d.ts:1882 ### onBeforeNavigate -▸ `Optional` **onBeforeNavigate**(): `void` +▸ `Optional` **onBeforeNavigate**(`event`): `void` + +#### Parameters + +| Name | Type | +| :------ | :------ | +| `event` | `MouseEvent`<`Element`, `MouseEvent`\> | #### Returns @@ -4173,4 +4179,4 @@ node_modules/@types/react/index.d.ts:1882 #### Defined in -[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:20](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L20) +[packages/framework/esm-react-utils/src/ConfigurableLink.tsx:41](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/ConfigurableLink.tsx#L41) diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx index 4a12ac6be..319796d4a 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx @@ -1,12 +1,17 @@ /** @module @category Navigation */ -import React, { type MouseEvent, type AnchorHTMLAttributes, type PropsWithChildren } from 'react'; +import React, { type MouseEvent, type AnchorHTMLAttributes, type PropsWithChildren, useEffect } from 'react'; import type { TemplateParams } from '@openmrs/esm-navigation'; import { navigate, interpolateUrl } from '@openmrs/esm-navigation'; -function handleClick(event: MouseEvent, to: string, templateParams?: TemplateParams, onBeforeNavigate?: () => void) { +function handleClick( + event: MouseEvent, + to: string, + templateParams?: TemplateParams, + onBeforeNavigate?: (event: MouseEvent) => void, +) { if (!event.metaKey && !event.ctrlKey && !event.shiftKey && event.button == 0) { event.preventDefault(); - onBeforeNavigate?.(); + onBeforeNavigate?.(event); navigate({ to, templateParams }); } } @@ -17,7 +22,7 @@ function handleClick(event: MouseEvent, to: string, templateParams?: TemplatePar export interface ConfigurableLinkProps extends AnchorHTMLAttributes { to: string; templateParams?: TemplateParams; - onBeforeNavigate?: () => void; + onBeforeNavigate?: (event: MouseEvent) => void; } /** @@ -36,6 +41,18 @@ export function ConfigurableLink({ children, ...otherProps }: PropsWithChildren) { + useEffect(() => { + if (otherProps.href) { + console.warn( + `ConfigurableLink does not support the href prop. Use the 'to' prop instead. The provided href value is '${otherProps.href}'`, + ); + } + if (otherProps.onClick) { + console.warn( + `ConfigurableLink does not support the onClick prop. Use the 'onBeforeNavigate' prop instead. The 'to' prop of the offending link is ${to}`, + ); + } + }, []); return ( handleClick(event, to, templateParams, onBeforeNavigate)} From d0a86cec115e2f22f520bc972c608af041a14df4 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Fri, 12 Jan 2024 15:44:52 +0000 Subject: [PATCH 29/37] (fix) Improvement to history mock (#886) --- packages/framework/esm-framework/mock.tsx | 12 +++++++++++- .../framework/esm-framework/src/mock-test.test.ts | 8 ++++++++ .../esm-navigation/src/history/history.test.ts | 2 ++ 3 files changed, 21 insertions(+), 1 deletion(-) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 10b821c05..0147b523b 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -166,7 +166,7 @@ export const getFeatureFlag = jest.fn().mockReturnValue(true); export const subscribeToFeatureFlag = jest.fn((name: string, callback) => callback(true)); /* esm-navigation */ -export { goBackInHistory, interpolateUrl, interpolateString } from '@openmrs/esm-navigation'; +export { interpolateUrl, interpolateString } from '@openmrs/esm-navigation'; export let history = ['https://o3.openmrs.org/home']; export const navigate = jest.fn(({ to, templateParams }: { to: string; templateParams?: TemplateParams }) => { let target = interpolateUrl(to, templateParams); @@ -187,6 +187,16 @@ export const getHistory = jest.fn(() => history); export const clearHistory = jest.fn(() => { history = []; }); +export const goBackInHistory = jest.fn(({ toUrl }) => { + const toIndex = history.lastIndexOf(toUrl); + if (toIndex != -1) { + const newHistory = history.slice(0, toIndex + 1); + navigate({ to: history[toIndex] }); + history = newHistory; + } else { + throw new Error(`URL ${toUrl} not found in history; cannot go back to it.`); + } +}); /* esm-offline */ export const useConnectivity = jest.fn().mockReturnValue(true); diff --git a/packages/framework/esm-framework/src/mock-test.test.ts b/packages/framework/esm-framework/src/mock-test.test.ts index 7aa4eb78a..b9fcd2e63 100644 --- a/packages/framework/esm-framework/src/mock-test.test.ts +++ b/packages/framework/esm-framework/src/mock-test.test.ts @@ -14,4 +14,12 @@ describe('@openmrs/esm-framework/mock', () => { xit('should have the same exports as @openmrs/esm-framework', () => { expect(new Set(Object.keys(real))).toEqual(new Set(Object.keys(mock))); }); + + it('should have a working goBackInHistory function', () => { + mock.navigate({ to: '/test' }); + const history = mock.getHistory(); + mock.goBackInHistory({ toUrl: history[0] }); + expect(mock.getHistory()).toEqual([history[0]]); + expect(mock.navigate).toHaveBeenCalled(); + }); }); diff --git a/packages/framework/esm-navigation/src/history/history.test.ts b/packages/framework/esm-navigation/src/history/history.test.ts index aba86fcf8..4387305d2 100644 --- a/packages/framework/esm-navigation/src/history/history.test.ts +++ b/packages/framework/esm-navigation/src/history/history.test.ts @@ -72,5 +72,7 @@ describe('history', () => { }); goBackInHistory({ toUrl: 'https://o3.openmrs.org/openmrs/spa/labs' }); expect(getHistory()).toEqual([mockReferrer, 'https://o3.openmrs.org/openmrs/spa/labs']); + goBackInHistory({ toUrl: mockReferrer }); + expect(getHistory()).toEqual([mockReferrer]); }); }); From 5277fe1d321d18c6d73661db93401b37c0078d68 Mon Sep 17 00:00:00 2001 From: Ian <52504170+ibacher@users.noreply.github.com> Date: Fri, 12 Jan 2024 15:51:18 -0500 Subject: [PATCH 30/37] (chore) Upgrade to single-spa@6 (#883) --- packages/framework/esm-config/package.json | 2 +- .../framework/esm-extensions/package.json | 2 +- .../framework/esm-feature-flags/package.json | 2 +- packages/framework/esm-framework/docs/API.md | 30 ++++---- packages/framework/esm-framework/typedoc.json | 1 + packages/framework/esm-globals/package.json | 2 +- .../framework/esm-react-utils/package.json | 2 +- .../esm-react-utils/src/getLifecycle.ts | 7 +- .../src/openmrsComponentDecorator.tsx | 11 +-- packages/shell/esm-app-shell/package.json | 2 +- yarn.lock | 72 ++++++++++++------- 11 files changed, 80 insertions(+), 53 deletions(-) diff --git a/packages/framework/esm-config/package.json b/packages/framework/esm-config/package.json index 8d3ca69f5..b5cebfe96 100644 --- a/packages/framework/esm-config/package.json +++ b/packages/framework/esm-config/package.json @@ -49,6 +49,6 @@ "@openmrs/esm-globals": "workspace:*", "@openmrs/esm-state": "workspace:*", "@types/ramda": "^0.26.44", - "single-spa": "^5.9.2" + "single-spa": "^6.0.0" } } diff --git a/packages/framework/esm-extensions/package.json b/packages/framework/esm-extensions/package.json index 3a02ea15f..e97ca9eee 100644 --- a/packages/framework/esm-extensions/package.json +++ b/packages/framework/esm-extensions/package.json @@ -49,7 +49,7 @@ "@openmrs/esm-config": "workspace:*", "@openmrs/esm-feature-flags": "workspace:*", "@openmrs/esm-state": "workspace:*", - "single-spa": "^5.9.2" + "single-spa": "^6.0.0" }, "dependencies": { "lodash-es": "^4.17.21" diff --git a/packages/framework/esm-feature-flags/package.json b/packages/framework/esm-feature-flags/package.json index 155a52f2d..31d964dbc 100644 --- a/packages/framework/esm-feature-flags/package.json +++ b/packages/framework/esm-feature-flags/package.json @@ -48,6 +48,6 @@ "devDependencies": { "@openmrs/esm-globals": "workspace:*", "@openmrs/esm-state": "workspace:*", - "single-spa": "^5.9.2" + "single-spa": "^6.0.0" } } diff --git a/packages/framework/esm-framework/docs/API.md b/packages/framework/esm-framework/docs/API.md index a49ead0ca..af981dcfa 100644 --- a/packages/framework/esm-framework/docs/API.md +++ b/packages/framework/esm-framework/docs/API.md @@ -3030,7 +3030,7 @@ ___ ### getAsyncExtensionLifecycle -▸ **getAsyncExtensionLifecycle**<`T`\>(`lazy`, `options`): () => `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ **getAsyncExtensionLifecycle**<`T`\>(`lazy`, `options`): () => `Promise`<`any`\> **`deprecated`** Use getAsyncLifecycle instead. @@ -3051,21 +3051,21 @@ ___ `fn` -▸ (): `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ (): `Promise`<`any`\> ##### Returns -`Promise`<`ReactAppOrParcel`<`any`\>\> +`Promise`<`any`\> #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:31](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L31) +[packages/framework/esm-react-utils/src/getLifecycle.ts:32](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L32) ___ ### getAsyncLifecycle -▸ **getAsyncLifecycle**<`T`\>(`lazy`, `options`): () => `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ **getAsyncLifecycle**<`T`\>(`lazy`, `options`): () => `Promise`<`any`\> #### Type parameters @@ -3084,21 +3084,21 @@ ___ `fn` -▸ (): `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ (): `Promise`<`any`\> ##### Returns -`Promise`<`ReactAppOrParcel`<`any`\>\> +`Promise`<`any`\> #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:17](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L17) +[packages/framework/esm-react-utils/src/getLifecycle.ts:18](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L18) ___ ### getLifecycle -▸ **getLifecycle**<`T`\>(`Component`, `options`): `ReactAppOrParcel`<`any`\> +▸ **getLifecycle**<`T`\>(`Component`, `options`): `any` #### Type parameters @@ -3115,17 +3115,17 @@ ___ #### Returns -`ReactAppOrParcel`<`any`\> +`any` #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:9](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L9) +[packages/framework/esm-react-utils/src/getLifecycle.ts:10](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L10) ___ ### getSyncLifecycle -▸ **getSyncLifecycle**<`T`\>(`Component`, `options`): () => `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ **getSyncLifecycle**<`T`\>(`Component`, `options`): () => `Promise`<`any`\> #### Type parameters @@ -3144,15 +3144,15 @@ ___ `fn` -▸ (): `Promise`<`ReactAppOrParcel`<`any`\>\> +▸ (): `Promise`<`any`\> ##### Returns -`Promise`<`ReactAppOrParcel`<`any`\>\> +`Promise`<`any`\> #### Defined in -[packages/framework/esm-react-utils/src/getLifecycle.ts:24](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L24) +[packages/framework/esm-react-utils/src/getLifecycle.ts:25](https://github.com/openmrs/openmrs-esm-core/blob/main/packages/framework/esm-react-utils/src/getLifecycle.ts#L25) ___ diff --git a/packages/framework/esm-framework/typedoc.json b/packages/framework/esm-framework/typedoc.json index 6e796d5b9..e1baf2b42 100644 --- a/packages/framework/esm-framework/typedoc.json +++ b/packages/framework/esm-framework/typedoc.json @@ -1,4 +1,5 @@ { + "$schema": "https://typedoc.org/schema.json", "out": "docs", "readme": "none", "excludeInternal": true, diff --git a/packages/framework/esm-globals/package.json b/packages/framework/esm-globals/package.json index 795861c01..9901df407 100644 --- a/packages/framework/esm-globals/package.json +++ b/packages/framework/esm-globals/package.json @@ -37,6 +37,6 @@ "single-spa": "5.x" }, "devDependencies": { - "single-spa": "^5.9.2" + "single-spa": "^6.0.0" } } diff --git a/packages/framework/esm-react-utils/package.json b/packages/framework/esm-react-utils/package.json index d3fe5aa98..024893fee 100644 --- a/packages/framework/esm-react-utils/package.json +++ b/packages/framework/esm-react-utils/package.json @@ -40,7 +40,7 @@ }, "dependencies": { "lodash-es": "^4.17.21", - "single-spa-react": "~5.0.0" + "single-spa-react": "^6.0.0" }, "peerDependencies": { "@openmrs/esm-api": "5.x", diff --git a/packages/framework/esm-react-utils/src/getLifecycle.ts b/packages/framework/esm-react-utils/src/getLifecycle.ts index 751d15ee5..31fd83207 100644 --- a/packages/framework/esm-react-utils/src/getLifecycle.ts +++ b/packages/framework/esm-react-utils/src/getLifecycle.ts @@ -2,15 +2,16 @@ import type { ComponentType } from 'react'; import React from 'react'; import ReactDOMClient from 'react-dom/client'; -import singleSpaReact from 'single-spa-react'; +import type { AppProps } from 'single-spa'; +import singleSpaReact, { type ReactAppOrParcel } from 'single-spa-react'; import type { ComponentDecoratorOptions } from './openmrsComponentDecorator'; import { openmrsComponentDecorator } from './openmrsComponentDecorator'; export function getLifecycle(Component: ComponentType, options: ComponentDecoratorOptions) { - return singleSpaReact({ + return singleSpaReact({ React, ReactDOMClient, - rootComponent: openmrsComponentDecorator(options)(Component), + rootComponent: openmrsComponentDecorator(options)(Component) as ComponentType, }); } diff --git a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx index a5f0e184b..f533a4eba 100644 --- a/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx +++ b/packages/framework/esm-react-utils/src/openmrsComponentDecorator.tsx @@ -27,7 +27,7 @@ export interface OpenmrsReactComponentState { config: ComponentConfig; } -export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) { +export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) { if ( typeof userOpts !== 'object' || typeof userOpts.featureName !== 'string' || @@ -38,11 +38,14 @@ export function openmrsComponentDecorator(userOpts: ComponentDecoratorOptions) { const opts = Object.assign({}, defaultOpts, userOpts); - return function decorateComponent(Comp: ComponentType): ComponentType { - return class OpenmrsReactComponent extends React.Component { + return function decorateComponent(Comp: ComponentType): ComponentType { + return class OpenmrsReactComponent extends React.Component< + OpenmrsReactComponentProps & T, + OpenmrsReactComponentState + > { static displayName = `OpenmrsReactComponent(${opts.featureName})`; - constructor(props: OpenmrsReactComponentProps) { + constructor(props: OpenmrsReactComponentProps & T) { super(props); this.state = { caughtError: null, diff --git a/packages/shell/esm-app-shell/package.json b/packages/shell/esm-app-shell/package.json index b79e4f105..29d642d32 100644 --- a/packages/shell/esm-app-shell/package.json +++ b/packages/shell/esm-app-shell/package.json @@ -49,7 +49,7 @@ "react-router-dom": "^6.3.0", "rxjs": "^6.5.3", "semver": "^7.3.4", - "single-spa": "^5.9.2", + "single-spa": "^6.0.0", "swc-loader": "^0.2.3", "swr": "^2.2.2", "systemjs": "^6.8.3", diff --git a/yarn.lock b/yarn.lock index cc3df8e72..bbc369c0b 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2644,7 +2644,7 @@ __metadata: react-router-dom: "npm:^6.3.0" rxjs: "npm:^6.5.3" semver: "npm:^7.3.4" - single-spa: "npm:^5.9.2" + single-spa: "npm:^6.0.0" swc-loader: "npm:^0.2.3" swr: "npm:^2.2.2" systemjs: "npm:^6.8.3" @@ -2666,7 +2666,7 @@ __metadata: "@openmrs/esm-state": "workspace:*" "@types/ramda": "npm:^0.26.44" ramda: "npm:^0.26.1" - single-spa: "npm:^5.9.2" + single-spa: "npm:^6.0.0" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x @@ -2772,7 +2772,7 @@ __metadata: "@openmrs/esm-feature-flags": "workspace:*" "@openmrs/esm-state": "workspace:*" lodash-es: "npm:^4.17.21" - single-spa: "npm:^5.9.2" + single-spa: "npm:^6.0.0" peerDependencies: "@openmrs/esm-api": 5.x "@openmrs/esm-config": 5.x @@ -2789,7 +2789,7 @@ __metadata: "@openmrs/esm-globals": "workspace:*" "@openmrs/esm-state": "workspace:*" ramda: "npm:^0.26.1" - single-spa: "npm:^5.9.2" + single-spa: "npm:^6.0.0" peerDependencies: "@openmrs/esm-globals": 5.x "@openmrs/esm-state": 5.x @@ -2836,7 +2836,7 @@ __metadata: version: 0.0.0-use.local resolution: "@openmrs/esm-globals@workspace:packages/framework/esm-globals" dependencies: - single-spa: "npm:^5.9.2" + single-spa: "npm:^6.0.0" peerDependencies: single-spa: 5.x languageName: unknown @@ -3000,7 +3000,7 @@ __metadata: react-dom: "npm:^18.1.0" react-i18next: "npm:^11.18.6" rxjs: "npm:^6.5.3" - single-spa-react: "npm:~5.0.0" + single-spa-react: "npm:^6.0.0" swr: "npm:^2.2.2" webpack: "npm:^5.88.0" peerDependencies: @@ -6272,9 +6272,9 @@ __metadata: linkType: hard "caniuse-lite@npm:^1.0.0, caniuse-lite@npm:^1.0.30001109, caniuse-lite@npm:^1.0.30001400, caniuse-lite@npm:^1.0.30001407": - version: 1.0.30001488 - resolution: "caniuse-lite@npm:1.0.30001488" - checksum: f6c570c58052387d7a01c48a189d8ba8717921103ccbe0ac3490baf87b7cb82245ebdbf23f33a5657fb30dca5e13bab8735567721afc22b12dcd492ff3372193 + version: 1.0.30001576 + resolution: "caniuse-lite@npm:1.0.30001576" + checksum: 51632942733593f310e581bd91c9558b8d75fbf67160a39f8036d2976cd7df9183e96d4c9d9e6f18e0205950b940d9c761bcfb7810962d7899f8a1179fde6e3f languageName: node linkType: hard @@ -9440,7 +9440,7 @@ __metadata: languageName: node linkType: hard -"glob@npm:^8.0.1, glob@npm:^8.0.3": +"glob@npm:^8.0.1": version: 8.0.3 resolution: "glob@npm:8.0.3" dependencies: @@ -9453,6 +9453,19 @@ __metadata: languageName: node linkType: hard +"glob@npm:^8.0.3": + version: 8.1.0 + resolution: "glob@npm:8.1.0" + dependencies: + fs.realpath: "npm:^1.0.0" + inflight: "npm:^1.0.4" + inherits: "npm:2" + minimatch: "npm:^5.0.1" + once: "npm:^1.3.0" + checksum: 9aab1c75eb087c35dbc41d1f742e51d0507aa2b14c910d96fb8287107a10a22f4bbdce26fc0a3da4c69a20f7b26d62f1640b346a4f6e6becfff47f335bb1dc5e + languageName: node + linkType: hard + "global@npm:~4.4.0": version: 4.4.0 resolution: "global@npm:4.4.0" @@ -11989,11 +12002,11 @@ __metadata: linkType: hard "marked@npm:^4.0.16": - version: 4.1.1 - resolution: "marked@npm:4.1.1" + version: 4.3.0 + resolution: "marked@npm:4.3.0" bin: marked: bin/marked.js - checksum: 7cf479000a1ee3e51be81a542d5a6fd639394484f29942bb7bd25d045b5475c3a861106790a8e91c7ab1c071db66d20ea02174c5982ff1262026c54e98270637 + checksum: c830bb4cb3705b754ca342b656e8a582d7428706b2678c898b856f6030c134ce2d1e19136efa3e6a1841f7330efbd24963d6bdeddc57d2938e906250f99895d0 languageName: node linkType: hard @@ -12166,7 +12179,7 @@ __metadata: languageName: node linkType: hard -"minimatch@npm:^5.0.1, minimatch@npm:^5.1.0": +"minimatch@npm:^5.0.1": version: 5.1.0 resolution: "minimatch@npm:5.1.0" dependencies: @@ -12175,6 +12188,15 @@ __metadata: languageName: node linkType: hard +"minimatch@npm:^5.1.0": + version: 5.1.6 + resolution: "minimatch@npm:5.1.6" + dependencies: + brace-expansion: "npm:^2.0.1" + checksum: 126b36485b821daf96d33b5c821dac600cc1ab36c87e7a532594f9b1652b1fa89a1eebcaad4dff17c764dce1a7ac1531327f190fed5f97d8f6e5f889c116c429 + languageName: node + linkType: hard + "minimist@npm:^1.2.5, minimist@npm:^1.2.6": version: 1.2.6 resolution: "minimist@npm:1.2.6" @@ -15371,9 +15393,9 @@ __metadata: languageName: node linkType: hard -"single-spa-react@npm:~5.0.0": - version: 5.0.2 - resolution: "single-spa-react@npm:5.0.2" +"single-spa-react@npm:^6.0.0": + version: 6.0.1 + resolution: "single-spa-react@npm:6.0.1" dependencies: browserslist-config-single-spa: "npm:^1.0.1" peerDependencies: @@ -15385,14 +15407,14 @@ __metadata: optional: true "@types/react-dom": optional: true - checksum: 142f04ffde1cbede0c3b81abe0439b1a87d0a031efa6a4f8c4ae61ffbefe0e9368e32944a63b96e7cd83d2b09ac102278d256fbf4272cf01ad438fdef2295c50 + checksum: 5c75581a0925f031248c184f09dd90200e7518a78642f050ddcc52ff1c59bfb84752a15dd4642511b5388061bf2c594872faeac3469e1f80e2d2c48f013ded8f languageName: node linkType: hard -"single-spa@npm:^5.9.2": - version: 5.9.4 - resolution: "single-spa@npm:5.9.4" - checksum: 7b89384063885d3f25bce45996e29928fce9e36ad39bf1189d59b601796bbfe086b40e82d1843a38507c0d9f91f3710a7ddd1f81bf23ec4f24649b2e1ec4f98b +"single-spa@npm:^6.0.0": + version: 6.0.0 + resolution: "single-spa@npm:6.0.0" + checksum: e61f6b83f5b200fc093fce41ed2704b631c53d3214fef77342571ee9aadf903131c9aedec80568424ba23fa794b97bc74cbdb8ac741b19ad44a1c2cb1628a462 languageName: node linkType: hard @@ -17053,9 +17075,9 @@ __metadata: linkType: hard "vscode-oniguruma@npm:^1.6.1": - version: 1.6.2 - resolution: "vscode-oniguruma@npm:1.6.2" - checksum: 2b9404ffe6e4ff4079844a3dc1cc6be459d74e475007355cfc09af8bdee09a8c8ac26787d372e08b6c2563f68b31f9b4ec1eb9ae0cc6991bdea2bfd3d38ade45 + version: 1.7.0 + resolution: "vscode-oniguruma@npm:1.7.0" + checksum: 7da9d21459f9788544b258a5fd1b9752df6edd8b406a19eea0209c6bf76507d5717277016799301c4da0d536095f9ca8c06afd1ab8f4001189090c804ca4814e languageName: node linkType: hard From 789fc5ea71ae7e9246716039486f5535570e47d5 Mon Sep 17 00:00:00 2001 From: Ian <52504170+ibacher@users.noreply.github.com> Date: Fri, 12 Jan 2024 16:16:15 -0500 Subject: [PATCH 31/37] (chore) Add GitHub Actions flows to automate Transifex (#887) --- .github/workflows/tx-pull.yml | 31 +++++++++++++++++++++++++++++++ .github/workflows/tx-push.yml | 21 +++++++++++++++++++++ 2 files changed, 52 insertions(+) create mode 100644 .github/workflows/tx-pull.yml create mode 100644 .github/workflows/tx-push.yml diff --git a/.github/workflows/tx-pull.yml b/.github/workflows/tx-pull.yml new file mode 100644 index 000000000..03ceb530e --- /dev/null +++ b/.github/workflows/tx-pull.yml @@ -0,0 +1,31 @@ +on: + workflow_dispatch: + schedule: + # every day at 8 PM UTC + - cron: "0 20 * * *" + +name: "Scheduled Transifex Update" + +jobs: + pull-translations-from-transifex: + name: pull-translations-from-transifex + + runs-on: ubuntu-latest + permissions: + actions: write + steps: + - uses: actions/checkout@v4 + - name: Push source file using transifex client + uses: transifex/cli-action@v2 + args: pull + with: + token: ${{ secrets.TRANSIFEX_TOKEN }} + - name: Create PR if necessary + uses: peter-evans/create-pull-request@v5 + with: + commit-message: "(chore) Update translations from Transifex" + title: "(chore) Update translations from Transifex" + body: "Automated updates of translations pulled from Transifex" + branch: "chore/update-transifex" + author: "OpenMRS Bot " + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/tx-push.yml b/.github/workflows/tx-push.yml new file mode 100644 index 000000000..1bd1637bc --- /dev/null +++ b/.github/workflows/tx-push.yml @@ -0,0 +1,21 @@ +on: + workflow_dispatch: + push: + branches: [main] + +name: "Update Transifex on Push" + +jobs: + push-translations-to-transifex: + name: push-translations-to-transifex + + runs-on: ubuntu-latest + permissions: + actions: read + + steps: + - uses: actions/checkout@v4 + - name: Push source file using transifex client + uses: transifex/cli-action@v2 + with: + token: ${{ secrets.TRANSIFEX_TOKEN }} From 6f89ecc7e88b7a10adde0bc649929e0818d1981f Mon Sep 17 00:00:00 2001 From: Usama Idriss Kakumba <53287480+usamaidrsk@users.noreply.github.com> Date: Sat, 13 Jan 2024 00:48:46 +0300 Subject: [PATCH 32/37] (fix) O3-2734: Fix user menu tooltip and toast notification description (#880) * fix: fix user arial label and user menu name * fix: fix tests * fix: fix translations * refactor: add user menu tooltip translation * Update E2E test --------- Co-authored-by: Dennis Kigen --- e2e/specs/login.spec.ts | 2 +- .../src/location-picker/location-picker.resource.ts | 2 +- .../src/location-picker/location-picker.test.tsx | 2 +- packages/apps/esm-login-app/translations/am.json | 2 +- packages/apps/esm-login-app/translations/ar.json | 2 +- packages/apps/esm-login-app/translations/en.json | 2 +- packages/apps/esm-login-app/translations/es.json | 2 +- packages/apps/esm-login-app/translations/fr.json | 2 +- packages/apps/esm-login-app/translations/he.json | 2 +- .../src/components/navbar/navbar.component.tsx | 6 ++++-- .../esm-primary-navigation-app/src/root.component.test.tsx | 4 ++-- .../apps/esm-primary-navigation-app/translations/am.json | 3 ++- .../apps/esm-primary-navigation-app/translations/ar.json | 3 ++- .../apps/esm-primary-navigation-app/translations/en.json | 3 ++- .../apps/esm-primary-navigation-app/translations/es.json | 3 ++- .../apps/esm-primary-navigation-app/translations/fr.json | 3 ++- .../apps/esm-primary-navigation-app/translations/he.json | 3 ++- .../apps/esm-primary-navigation-app/translations/km.json | 3 ++- 18 files changed, 29 insertions(+), 20 deletions(-) diff --git a/e2e/specs/login.spec.ts b/e2e/specs/login.spec.ts index 3635e6aa2..da357cfe8 100644 --- a/e2e/specs/login.spec.ts +++ b/e2e/specs/login.spec.ts @@ -33,7 +33,7 @@ test('Login as Admin user', async ({ page }) => { }); await test.step('And I should be able to see various elements on the page', async () => { - await page.getByRole('button', { name: 'Users' }).click(); + await page.getByRole('button', { name: /user/i }).click(); await expect(page.getByText(/super user/i)).toBeVisible(); await expect(page.getByText(/outpatient clinic/i)).toBeVisible(); await expect(page.getByRole('button', { name: /logout/i })).toBeVisible(); diff --git a/packages/apps/esm-login-app/src/location-picker/location-picker.resource.ts b/packages/apps/esm-login-app/src/location-picker/location-picker.resource.ts index 65ae00a38..85c840b4a 100644 --- a/packages/apps/esm-login-app/src/location-picker/location-picker.resource.ts +++ b/packages/apps/esm-login-app/src/location-picker/location-picker.resource.ts @@ -59,7 +59,7 @@ export function useDefaultLocation(isUpdateFlow: boolean) { ? t('locationPreferenceAdded', 'Selected location will be used for your next logins') : t('locationPreferenceUpdated', 'Login location preference updated'), description: !isUpdateFlow - ? t('selectedLocationPreferenceSetMessage', 'You can change your preference from the user dashboard') + ? t('selectedLocationPreferenceSetMessage', 'You can change your preference from the user menu') : t('locationPreferenceAdded', 'Selected location will be used for your next logins'), kind: 'success', }); diff --git a/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx b/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx index 19c39dc37..749dee254 100644 --- a/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx +++ b/packages/apps/esm-login-app/src/location-picker/location-picker.test.tsx @@ -116,7 +116,7 @@ describe('LocationPicker', () => { expect(showToast).toHaveBeenCalledWith({ kind: 'success', title: 'Selected location will be used for your next logins', - description: 'You can change your preference from the user dashboard', + description: 'You can change your preference from the user menu', }), ); }); diff --git a/packages/apps/esm-login-app/translations/am.json b/packages/apps/esm-login-app/translations/am.json index b75aa0e3d..bd1d55fac 100644 --- a/packages/apps/esm-login-app/translations/am.json +++ b/packages/apps/esm-login-app/translations/am.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "Search for a location", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.", "submitting": "Submitting", "username": "Username", diff --git a/packages/apps/esm-login-app/translations/ar.json b/packages/apps/esm-login-app/translations/ar.json index 19aa8ae6d..b88ef0df1 100644 --- a/packages/apps/esm-login-app/translations/ar.json +++ b/packages/apps/esm-login-app/translations/ar.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "ابحث عن موقع", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "اختر موقعك من القائمة أدناه. استخدم شريط البحث للعثور على موقعك.", "submitting": "جار الإرسال", "username": "اسم المستخدم", diff --git a/packages/apps/esm-login-app/translations/en.json b/packages/apps/esm-login-app/translations/en.json index f84b13e58..0fa9d11b7 100644 --- a/packages/apps/esm-login-app/translations/en.json +++ b/packages/apps/esm-login-app/translations/en.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "Search for a location", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "Select your location from the list below. Use the search bar to find your location.", "submitting": "Submitting", "username": "Username", diff --git a/packages/apps/esm-login-app/translations/es.json b/packages/apps/esm-login-app/translations/es.json index 2c20b108f..0f99631e8 100644 --- a/packages/apps/esm-login-app/translations/es.json +++ b/packages/apps/esm-login-app/translations/es.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "Buscar una ubicación", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "Selecciona tu ubicación de la lista de abajo. Utiliza la barra de búsqueda para encontrar tu ubicación.", "submitting": "Enviando", "username": "Nombre de usuario", diff --git a/packages/apps/esm-login-app/translations/fr.json b/packages/apps/esm-login-app/translations/fr.json index acc67b91a..a8b10c4b8 100644 --- a/packages/apps/esm-login-app/translations/fr.json +++ b/packages/apps/esm-login-app/translations/fr.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "Rechercher un emplacement", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "Sélectionnez votre emplacement dans la liste ci-dessous. Utilisez la barre de recherche pour rechercher votre emplacement.", "submitting": "Submitting", "username": "Nom d'utilisateur", diff --git a/packages/apps/esm-login-app/translations/he.json b/packages/apps/esm-login-app/translations/he.json index e62012c83..2cacf673e 100644 --- a/packages/apps/esm-login-app/translations/he.json +++ b/packages/apps/esm-login-app/translations/he.json @@ -19,7 +19,7 @@ "rememberLocationForFutureLogins": "Remember my location for future logins", "removedLoginLocationPreference": "The login location preference has been removed.", "searchForLocation": "חיפוש מיקום", - "selectedLocationPreferenceSetMessage": "You can change your preference from the user dashboard", + "selectedLocationPreferenceSetMessage": "You can change your preference from the user menu", "selectYourLocation": "בחר את המיקום שלך מהרשימה למטה. השתמש בשורת החיפוש לחיפוש המיקום שלך.", "submitting": "Submitting", "username": "שם משתמש", diff --git a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx index d73d5e8f2..72f5b2f5e 100644 --- a/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx +++ b/packages/apps/esm-primary-navigation-app/src/components/navbar/navbar.component.tsx @@ -19,8 +19,10 @@ import OfflineBanner from '../offline-banner/offline-banner.component'; import UserMenuPanel from '../navbar-header-panels/user-menu-panel.component'; import SideMenuPanel from '../navbar-header-panels/side-menu-panel.component'; import styles from './navbar.scss'; +import { useTranslation } from 'react-i18next'; const HeaderItems: React.FC = () => { + const { t } = useTranslation(); const config = useConfig(); const [activeHeaderPanel, setActiveHeaderPanel] = useState(null); const layout = useLayoutType(); @@ -75,14 +77,14 @@ const HeaderItems: React.FC = () => { /> {showUserMenu && ( { togglePanel('userMenu'); diff --git a/packages/apps/esm-primary-navigation-app/src/root.component.test.tsx b/packages/apps/esm-primary-navigation-app/src/root.component.test.tsx index edcbdfeae..c6d332ae4 100644 --- a/packages/apps/esm-primary-navigation-app/src/root.component.test.tsx +++ b/packages/apps/esm-primary-navigation-app/src/root.component.test.tsx @@ -51,7 +51,7 @@ describe('Root', () => { it('should display navbar with title', async () => { render(); - expect(screen.getByRole('button', { name: /users/i })).toBeInTheDocument(); + expect(screen.getByRole('button', { name: /user/i })).toBeInTheDocument(); expect(screen.getByRole('banner', { name: /openmrs/i })).toBeInTheDocument(); expect(screen.getByText(/mock emr/i)).toBeInTheDocument(); }); @@ -61,7 +61,7 @@ describe('Root', () => { render(); - const userButton = screen.getByRole('button', { name: /users/i }); + const userButton = screen.getByRole('button', { name: /user/i }); await user.click(userButton); expect(screen.getByLabelText(/location/i)).toBeInTheDocument(); }); diff --git a/packages/apps/esm-primary-navigation-app/translations/am.json b/packages/apps/esm-primary-navigation-app/translations/am.json index 0073c9a15..e67b75a3d 100644 --- a/packages/apps/esm-primary-navigation-app/translations/am.json +++ b/packages/apps/esm-primary-navigation-app/translations/am.json @@ -3,5 +3,6 @@ "cancel": "Cancel", "change": "Change", "changeLanguage": "Change Language", - "notifications": "Notifications" + "notifications": "Notifications", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/ar.json b/packages/apps/esm-primary-navigation-app/translations/ar.json index 61fabdb40..298a22e40 100644 --- a/packages/apps/esm-primary-navigation-app/translations/ar.json +++ b/packages/apps/esm-primary-navigation-app/translations/ar.json @@ -3,5 +3,6 @@ "cancel": "Cancel", "change": "تغيير", "changeLanguage": "Change Language", - "notifications": "الإشعارات" + "notifications": "الإشعارات", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/en.json b/packages/apps/esm-primary-navigation-app/translations/en.json index 0073c9a15..e67b75a3d 100644 --- a/packages/apps/esm-primary-navigation-app/translations/en.json +++ b/packages/apps/esm-primary-navigation-app/translations/en.json @@ -3,5 +3,6 @@ "cancel": "Cancel", "change": "Change", "changeLanguage": "Change Language", - "notifications": "Notifications" + "notifications": "Notifications", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/es.json b/packages/apps/esm-primary-navigation-app/translations/es.json index 2173b6c2f..fdbbb59b1 100644 --- a/packages/apps/esm-primary-navigation-app/translations/es.json +++ b/packages/apps/esm-primary-navigation-app/translations/es.json @@ -3,5 +3,6 @@ "cancel": "Cancelar", "change": "Cambiar", "changeLanguage": "Cambiar idioma", - "notifications": "Notificaciones" + "notifications": "Notificaciones", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/fr.json b/packages/apps/esm-primary-navigation-app/translations/fr.json index 273b7fc0d..9fb909690 100644 --- a/packages/apps/esm-primary-navigation-app/translations/fr.json +++ b/packages/apps/esm-primary-navigation-app/translations/fr.json @@ -3,5 +3,6 @@ "cancel": "Annuler", "change": "Changer", "changeLanguage": "Changer de langue", - "notifications": "Notifications" + "notifications": "Notifications", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/he.json b/packages/apps/esm-primary-navigation-app/translations/he.json index fa646a9f3..161041c61 100644 --- a/packages/apps/esm-primary-navigation-app/translations/he.json +++ b/packages/apps/esm-primary-navigation-app/translations/he.json @@ -3,5 +3,6 @@ "cancel": "Cancel", "change": "שינוי", "changeLanguage": "Change Language", - "notifications": "התראות" + "notifications": "התראות", + "userMenuTooltip": "User" } diff --git a/packages/apps/esm-primary-navigation-app/translations/km.json b/packages/apps/esm-primary-navigation-app/translations/km.json index 7dd4111ed..7d63231ab 100644 --- a/packages/apps/esm-primary-navigation-app/translations/km.json +++ b/packages/apps/esm-primary-navigation-app/translations/km.json @@ -3,5 +3,6 @@ "cancel": "Cancel", "change": "ផ្លាស់ប្តូរ", "changeLanguage": "Change Language", - "notifications": "ការជូនដំណឹង" + "notifications": "ការជូនដំណឹង", + "userMenuTooltip": "User" } From 2de4812f639d4399a20f85697a463ce1e8ab1b99 Mon Sep 17 00:00:00 2001 From: Ian <52504170+ibacher@users.noreply.github.com> Date: Sat, 13 Jan 2024 19:48:25 -0500 Subject: [PATCH 33/37] Fix args --- .github/workflows/tx-pull.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/tx-pull.yml b/.github/workflows/tx-pull.yml index 03ceb530e..1ccc0d4c8 100644 --- a/.github/workflows/tx-pull.yml +++ b/.github/workflows/tx-pull.yml @@ -17,9 +17,9 @@ jobs: - uses: actions/checkout@v4 - name: Push source file using transifex client uses: transifex/cli-action@v2 - args: pull with: token: ${{ secrets.TRANSIFEX_TOKEN }} + args: pull - name: Create PR if necessary uses: peter-evans/create-pull-request@v5 with: From 5e5e5f4b56e6d0c016379f88496495e123c94004 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 16 Jan 2024 13:05:45 +0000 Subject: [PATCH 34/37] Make ConfigurableLink call onBeforeNavigate for alternative clicks (#884) --- .../src/ConfigurableLink.test.tsx | 16 +++++++++++++++- .../esm-react-utils/src/ConfigurableLink.tsx | 18 +++++++++++++++++- 2 files changed, 32 insertions(+), 2 deletions(-) diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx index bb95c5909..b323174d1 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.test.tsx @@ -56,7 +56,7 @@ describe(`ConfigurableLink`, () => { expect(navigate).toHaveBeenCalledWith({ to: path }); }); - it('executes onBeforeNavigate callback if provided', async () => { + it('executes onBeforeNavigate callback on any click that would open the page (including ctrl-click etc)', async () => { const onBeforeNavigate = jest.fn(); render( @@ -69,5 +69,19 @@ describe(`ConfigurableLink`, () => { await user.click(link); expect(onBeforeNavigate).toHaveBeenCalled(); expect(navigate).toHaveBeenCalledWith({ to: path }); + onBeforeNavigate.mockClear(); + await user.pointer({ target: link, keys: '[MouseRight]' }); + expect(onBeforeNavigate).not.toHaveBeenCalled(); + // Note: This ought to work, but doesn't because of + // https://github.com/testing-library/user-event/issues/1083 + // `event.button` is getting set to 0 when it should be 1. + // await user.pointer({ target: link, keys: '[MouseMiddle]' }); + // expect(onBeforeNavigate).toHaveBeenCalled(); + // onBeforeNavigate.mockClear(); + await user.pointer({ target: link, keys: '[ControlLeft][MouseLeft][/ControlLeft]' }); + expect(onBeforeNavigate).toHaveBeenCalled(); + onBeforeNavigate.mockClear(); + await user.pointer({ target: link, keys: '[ShiftLeft][MouseLeft][/ShiftLeft]' }); + expect(onBeforeNavigate).toHaveBeenCalled(); }); }); diff --git a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx index 319796d4a..73c2b77be 100644 --- a/packages/framework/esm-react-utils/src/ConfigurableLink.tsx +++ b/packages/framework/esm-react-utils/src/ConfigurableLink.tsx @@ -9,11 +9,27 @@ function handleClick( templateParams?: TemplateParams, onBeforeNavigate?: (event: MouseEvent) => void, ) { - if (!event.metaKey && !event.ctrlKey && !event.shiftKey && event.button == 0) { + // Left click without modifiers (normal navigation) + if (event.button === 0 && !event.ctrlKey && !event.shiftKey && !event.altKey && !event.metaKey) { event.preventDefault(); onBeforeNavigate?.(event); navigate({ to, templateParams }); } + + // Left click with Ctrl key (or Cmd key on Mac) - Open in new tab + if (event.button === 0 && (event.ctrlKey || event.metaKey)) { + onBeforeNavigate?.(event); + } + + // Left click with Shift key - Open in new window + if (event.button === 0 && event.shiftKey) { + onBeforeNavigate?.(event); + } + + // Middle click - Open in new background tab + if (event.button === 1) { + onBeforeNavigate?.(event); + } } /** From 8bd35d7cbf11b3b2bd0c31d5c40eceaed7eae6f7 Mon Sep 17 00:00:00 2001 From: Brandon Istenes Date: Tue, 16 Jan 2024 13:09:46 +0000 Subject: [PATCH 35/37] (fix) Simplify history mock, add more mocks (#889) --- packages/framework/esm-framework/mock.tsx | 68 +++++++---------------- 1 file changed, 21 insertions(+), 47 deletions(-) diff --git a/packages/framework/esm-framework/mock.tsx b/packages/framework/esm-framework/mock.tsx index 0147b523b..db3c5b4d4 100644 --- a/packages/framework/esm-framework/mock.tsx +++ b/packages/framework/esm-framework/mock.tsx @@ -3,8 +3,7 @@ import type {} from '@openmrs/esm-globals'; import { createStore, type StoreApi } from 'zustand'; import { NEVER, of } from 'rxjs'; import { type SessionStore } from '@openmrs/esm-api'; -import { getDefaultsFromConfigSchema } from '@openmrs/esm-utils'; -import { interpolateUrl, type TemplateParams } from '@openmrs/esm-navigation'; +import * as utils from '@openmrs/esm-utils'; window.i18next = { ...window.i18next, language: 'en' }; @@ -118,9 +117,11 @@ export enum Type { let configSchema = {}; -export const getConfig = jest.fn().mockImplementation(() => Promise.resolve(getDefaultsFromConfigSchema(configSchema))); +export const getConfig = jest + .fn() + .mockImplementation(() => Promise.resolve(utils.getDefaultsFromConfigSchema(configSchema))); -export const useConfig = jest.fn().mockImplementation(() => getDefaultsFromConfigSchema(configSchema)); +export const useConfig = jest.fn().mockImplementation(() => utils.getDefaultsFromConfigSchema(configSchema)); export function defineConfigSchema(moduleName, schema) { configSchema = schema; @@ -167,42 +168,16 @@ export const subscribeToFeatureFlag = jest.fn((name: string, callback) => callba /* esm-navigation */ export { interpolateUrl, interpolateString } from '@openmrs/esm-navigation'; -export let history = ['https://o3.openmrs.org/home']; -export const navigate = jest.fn(({ to, templateParams }: { to: string; templateParams?: TemplateParams }) => { - let target = interpolateUrl(to, templateParams); - if (target.startsWith('/')) { - target = window.location.origin + target; - } - try { - // Don't mess with the real window.location - if (!(window.location instanceof Location)) { - (window.location as any).href = target; - } - } catch (e) { - // window.location is probably not mocked. Don't worry about it. - } - history.push(target); -}); -export const getHistory = jest.fn(() => history); -export const clearHistory = jest.fn(() => { - history = []; -}); -export const goBackInHistory = jest.fn(({ toUrl }) => { - const toIndex = history.lastIndexOf(toUrl); - if (toIndex != -1) { - const newHistory = history.slice(0, toIndex + 1); - navigate({ to: history[toIndex] }); - history = newHistory; - } else { - throw new Error(`URL ${toUrl} not found in history; cannot go back to it.`); - } -}); +export const navigate = jest.fn(); +export const getHistory = jest.fn(() => ['https://o3.openmrs.org/home']); +export const clearHistory = jest.fn(); +export const goBackInHistory = jest.fn(); /* esm-offline */ export const useConnectivity = jest.fn().mockReturnValue(true); /* esm-react-utils */ -export { ConfigurableLink } from '@openmrs/esm-react-utils'; +export { ConfigurableLink, isDesktop, useStore, useStoreWithActions, createUseStore } from '@openmrs/esm-react-utils'; export const ComponentContext = React.createContext(null); @@ -232,6 +207,8 @@ export const useSession = jest.fn(() => ({ export const useLayoutType = jest.fn(() => 'desktop'); +export const useAssignedExtensions = jest.fn(() => []); + export const useExtensionSlotMeta = jest.fn(() => ({})); export const useConnectedExtensions = jest.fn(() => []); @@ -246,8 +223,6 @@ export const useExtensionStore = getExtensionStore(); export const useFeatureFlag = jest.fn().mockReturnValue(true); -export { isDesktop, useStore, useStoreWithActions, createUseStore } from '@openmrs/esm-react-utils'; - export const usePagination = jest.fn().mockImplementation(() => ({ currentPage: 1, goTo: () => {}, @@ -286,6 +261,8 @@ export function useOpenmrsSWR(key: string | Array) { export const useDebounce = jest.fn().mockImplementation((value) => value); +export const useOnClickOutside = jest.fn(); + /* esm-styleguide */ export const showNotification = jest.fn(); export const showActionableNotification = jest.fn(); @@ -293,22 +270,19 @@ export const showToast = jest.fn(); export const showSnackbar = jest.fn(); export const showModal = jest.fn(); -export const LeftNavMenu = jest.fn(); +export const LeftNavMenu = jest.fn(() =>
Left Nav Menu
); export const setLeftNav = jest.fn(); export const unsetLeftNav = jest.fn(); -export const OpenmrsDatePicker = jest.fn(); +export const OpenmrsDatePicker = jest.fn(() =>
OpenMRS DatePicker
); /* esm-utils */ -export { - getDefaultsFromConfigSchema, - parseDate, - formatDate, - formatDatetime, - formatTime, - age, -} from '@openmrs/esm-utils'; +export { getDefaultsFromConfigSchema, parseDate, formatDate, formatDatetime, formatTime } from '@openmrs/esm-utils'; + +export const age = jest.fn((arg) => utils.age(arg)); export function isVersionSatisfied() { return true; } + +export const translateFrom = jest.fn((m, key, fallback) => fallback ?? key); From ece61c40cc77cee6384fe6276dac44dbc007b2e0 Mon Sep 17 00:00:00 2001 From: ThemboJonathan Date: Tue, 16 Jan 2024 16:25:38 +0300 Subject: [PATCH 36/37] (chore) Add chinese language files (#879) --- .../translations/zh.json | 22 ++++++++ .../apps/esm-login-app/translations/zh.json | 27 +++++++++ .../translations/zh.json | 55 +++++++++++++++++++ .../translations/zh.json | 4 ++ tools/i18next-parser.config.js | 2 +- 5 files changed, 109 insertions(+), 1 deletion(-) create mode 100644 packages/apps/esm-implementer-tools-app/translations/zh.json create mode 100644 packages/apps/esm-login-app/translations/zh.json create mode 100644 packages/apps/esm-offline-tools-app/translations/zh.json create mode 100644 packages/apps/esm-primary-navigation-app/translations/zh.json diff --git a/packages/apps/esm-implementer-tools-app/translations/zh.json b/packages/apps/esm-implementer-tools-app/translations/zh.json new file mode 100644 index 000000000..460a68f72 --- /dev/null +++ b/packages/apps/esm-implementer-tools-app/translations/zh.json @@ -0,0 +1,22 @@ +{ + "activeItemSourceText": "当前值来自", + "backendModules": "后端模块", + "clearConfig": "清除本地配置", + "configuration": "配置", + "devConfig": "Dev配置", + "downloadConfig": "下载配置", + "edit": "编辑", + "editValueButtonText": "编辑", + "frontendModules": "前端模块", + "installedVersion": "已安装版本", + "itemDescriptionSourceDefaultText": "当前值为默认值。", + "jsonEditor": "JSON编辑器", + "missing": "缺失", + "moduleName": "模块名称", + "requiredVersion": "所需版本", + "resetToDefaultValueButtonText": "恢复为默认值", + "uiEditor": "UI编辑器", + "unknownVersion": "未知", + "value": "值", + "view": "查看" +} diff --git a/packages/apps/esm-login-app/translations/zh.json b/packages/apps/esm-login-app/translations/zh.json new file mode 100644 index 000000000..56a4d3376 --- /dev/null +++ b/packages/apps/esm-login-app/translations/zh.json @@ -0,0 +1,27 @@ +{ + "back": "返回", + "change": "更改", + "confirm": "确认", + "contactAdmin": "联系管理员", + "continue": "继续", + "error": "错误", + "found": "已找到", + "invalidCredentials": "用户名或密码无效", + "loading": "加载中", + "locationNotFound": "对不起,未找到匹配的地点。", + "locations": "地点", + "login": "登录", + "Logout": "退出", + "match": "匹配", + "matches": "匹配", + "needHelp": "需要帮助?", + "of": "of", + "password": "密码", + "poweredBy": "Powered by", + "searchForLocation": "搜索一个地点", + "selectYourLocation": "选择您的地点。使用搜索栏搜索。", + "showing": "显示", + "username": "用户名", + "validValueRequired": "需要一个有效的值", + "welcome": "欢迎" +} diff --git a/packages/apps/esm-offline-tools-app/translations/zh.json b/packages/apps/esm-offline-tools-app/translations/zh.json new file mode 100644 index 000000000..ba870559e --- /dev/null +++ b/packages/apps/esm-offline-tools-app/translations/zh.json @@ -0,0 +1,55 @@ +{ + "home": "首页", + "homeHeader": "离线首页", + "homeOverviewCardOfflineActionsFailedToUpload": "上传失败", + "homeOverviewCardOfflineActionsHeader": "离线操作", + "homeOverviewCardOfflineActionsPendingUpload": "等待上传", + "homeOverviewCardPatientsDownloaded": "下载完成", + "homeOverviewCardPatientsHeader": "患者", + "homeOverviewCardPatientsNewlyRegistered": "新注册的", + "homeOverviewCardView": "查看", + "offlineActions": "离线操作", + "offlineActionsDeleteConfirmationModalCancel": "取消", + "offlineActionsDeleteConfirmationModalConfirm": "永久删除", + "offlineActionsDeleteConfirmationModalContent": "你确定要删除所有选择的离线操作吗?这将无法撤销!", + "offlineActionsDeleteConfirmationModalTitle": "删除离线操作", + "offlineActionsHeader": "离线操作", + "offlineActionsNoActionsEmptyStateContent": "所有离线操作已成功上传,并与在线患者记录合并。", + "offlineActionsNoActionsEmptyStateImageAlt": "没有待处理的图像", + "offlineActionsNoActionsEmptyStateTitle": "没有待上传的操作", + "offlineActionsTableAction": "操作", + "offlineActionsTableCreatedOn": "日期/时间", + "offlineActionsTableDeleteAction": "删除操作", + "offlineActionsTableDeleteActions_one": "删除 {count} 个操作", + "offlineActionsTableDeleteActions_other": "删除 {count} 个操作", + "offlineActionsTableError": "错误", + "offlineActionsTablePatient": "患者", + "offlineActionsUpdateOfflinePatients": "更新离线患者", + "offlinePatientsHeader": "离线患者", + "offlinePatientsTableDeleteConfirmationModalCancel": "取消", + "offlinePatientsTableDeleteConfirmationModalConfirm": "删除患者", + "offlinePatientsTableDeleteConfirmationModalContent": "您确定要从离线列表中删除所有选择的患者吗?他们的病历将不再在离线模式下可用,并且任何新注册的患者将被永久删除。", + "offlinePatientsTableDeleteConfirmationModalTitle": "删除离线患者", + "offlinePatientsTableHeaderAge": "年龄", + "offlinePatientsTableHeaderGender": "性别", + "offlinePatientsTableHeaderLastUpdated": "最后更新", + "offlinePatientsTableHeaderName": "名称", + "offlinePatientsTableLastUpdatedDownloading": "下载中...", + "offlinePatientsTableLastUpdatedError": "错误", + "offlinePatientsTableLastUpdatedErrors": "错误", + "offlinePatientsTableLastUpdatedNotYetSynchronized": "未同步", + "offlinePatientsTableLastUpdatedOutdatedData": "过时的数据", + "offlinePatientsTableNameNewlyRegistered": "新建", + "offlinePatientsTableRemoveFromOfflineList": "从列表中删除", + "offlinePatientsTableSearchLabel": "搜索此列表", + "offlinePatientsTableSearchPlaceholder": "搜索此列表", + "offlinePatientsTableTitle": "离线患者", + "offlinePatientsTableUpdatePatient": "更新患者", + "offlinePatientsTableUpdatePatients": "更新患者", + "offlinePatientSyncDetailsDownloadedHeader": "下载到此设备", + "offlinePatientSyncDetailsFailedHeader": "以下项目下载时出现错误", + "offlinePatientSyncDetailsFallbackErrorMessage": "未知错误。", + "offlinePatientSyncDetailsHeader": "离线患者详细信息", + "offlineReady": "离线就绪", + "offlineToolsAppMenuLink": "离线工具" +} diff --git a/packages/apps/esm-primary-navigation-app/translations/zh.json b/packages/apps/esm-primary-navigation-app/translations/zh.json new file mode 100644 index 000000000..5e610475c --- /dev/null +++ b/packages/apps/esm-primary-navigation-app/translations/zh.json @@ -0,0 +1,4 @@ +{ + "notifications": "通知", + "selectLocale": "选择区域" +} diff --git a/tools/i18next-parser.config.js b/tools/i18next-parser.config.js index 38e730662..e48acb3f7 100644 --- a/tools/i18next-parser.config.js +++ b/tools/i18next-parser.config.js @@ -42,7 +42,7 @@ module.exports = { lineEnding: 'auto', // Control the line ending. See options at https://github.com/ryanve/eol - locales: ['en', 'am', 'es', 'fr', 'km', 'he', 'ar'], + locales: ['en', 'am', 'es', 'fr', 'km', 'he', 'ar', 'zh'], // An array of the locales in your applications namespaceSeparator: ':', From c07c4f8a0bd9fdd736d304db9325790cbf7982fc Mon Sep 17 00:00:00 2001 From: Ian <52504170+ibacher@users.noreply.github.com> Date: Tue, 16 Jan 2024 10:08:59 -0500 Subject: [PATCH 37/37] (chore) Only trigger e2e tests when relevant code has changed (#888) * (chore) Only trigger e2e tests when relevant code has changed * Fix the outputs * Another fix-up * Try again --- .github/workflows/e2e.yml | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/.github/workflows/e2e.yml b/.github/workflows/e2e.yml index d40ece898..c5bbea56f 100644 --- a/.github/workflows/e2e.yml +++ b/.github/workflows/e2e.yml @@ -9,9 +9,43 @@ on: - main jobs: + changes: + runs-on: ubuntu-latest + permissions: + pull-requests: read + outputs: + test-changes: ${{ steps.changes.outputs.test-sources }} + + steps: + - name: Checkout repo + uses: actions/checkout@v4 + + - name: Check if any source code has changed + id: changes + uses: dorny/paths-filter@v2 + with: + filters: | + test-sources: + - 'packages/**/src/**/*!(.test).ts' + - 'packages/**/src/**/*!(.test).tsx' + - 'packages/**/src/**/*!(.test).js' + - 'packages/**/src/**/*!(.test).jsx' + - 'packages/**/src/**/*.scss' + - 'packages/**/src/routes.json' + - 'playwright.config.ts' + - 'e2e/**/*.ts' + - 'e2e/**/*.js' + - 'e2e/support/github/**/*.*' + - 'example.env' + - '.github/workflows/e2e.yml' + main: + needs: changes + if: ${{ needs.changes.outputs.test-changes == 'true' }} + runs-on: ubuntu-latest timeout-minutes: 15 + steps: - name: Checkout repo uses: actions/checkout@v4