Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix(app-platform): upgrade platform tools to use vite and react 18 #414

Open
wants to merge 9 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,5 @@
![React 18](https://img.shields.io/badge/react-18-blue)

# Data entry app

[Live demo development branch](https://dhis2-data-entry.netlify.app/#/)
2 changes: 1 addition & 1 deletion d2.config.js
Original file line number Diff line number Diff line change
@@ -15,7 +15,7 @@ const config = {
},
},
entryPoints: {
app: './src/app/app-wrapper.js',
app: './src/app/app-wrapper.jsx',
},
direction: 'auto',
}
29 changes: 12 additions & 17 deletions package.json
Original file line number Diff line number Diff line change
@@ -31,27 +31,28 @@
"@babel/plugin-syntax-dynamic-import": "^7.8.3",
"@badeball/cypress-cucumber-preprocessor": "^16.0.0",
"@cypress/webpack-preprocessor": "^5.17.0",
"@dhis2/cli-app-scripts": "^11.7.2",
"@dhis2/cli-style": "^10.7.4",
"@dhis2/cli-app-scripts": "^12.3.0",
"@dhis2/cli-style": "^10.7.6",
"@dhis2/cypress-commands": "^10.0.1",
"@dhis2/cypress-plugins": "^10.0.1",
"@dhis2/d2-i18n": "1.1.3",
"@testing-library/jest-dom": "5.16.5",
"@testing-library/react": "12.1.5",
"@testing-library/react-hooks": "7.0.2",
"@testing-library/user-event": "13.5.0",
"@reportportal/agent-js-cypress": "^5.1.3",
"@reportportal/agent-js-jest": "^5.0.6",
"@testing-library/dom": "^10.4.0",
"@testing-library/jest-dom": "^6.6.3",
"@testing-library/react": "^16.2.0",
"@testing-library/user-event": "^14.6.1",
"cypress": "^12.8.1",
"enzyme": "3.11.0",
"enzyme-adapter-react-16": "1.15.7",
"eslint-plugin-cypress": "2.12.1",
"fake-indexeddb": "4.0.1",
"identity-obj-proxy": "^3.0.0",
"jest-extended": "^4.0.2",
"start-server-and-test": "1.15.4"
},
"dependencies": {
"@dhis2/app-runtime": "^3.10.2",
"@dhis2/multi-calendar-dates": "^1.3.1",
"@dhis2/ui": "^9.11.8",
"@dhis2/app-runtime": "^3.13.1",
"@dhis2/multi-calendar-dates": "^1.3.2",
"@dhis2/ui": "^10.1.11",
"@dhis2/ui-forms": "7.16.3",
"@tanstack/react-query": "4.24.10",
"@tanstack/react-query-devtools": "4.24.14",
@@ -79,11 +80,5 @@
},
"engines": {
"node": ">=14.0.0"
},
"resolutions": {
"@dhis2/multi-calendar-dates": "^1.3.2",
"@dhis2/ui": "^9.2.0",
"@dhis2/app-runtime": "^3.10.2",
"@dhis2/d2-i18n": "1.1.3"
}
}
12 changes: 4 additions & 8 deletions src/app/app-wrapper.js → src/app/app-wrapper.jsx
Original file line number Diff line number Diff line change
@@ -5,12 +5,12 @@ import PropTypes from 'prop-types'
import React from 'react'
import { HashRouter, Route } from 'react-router-dom'
import { QueryParamProvider } from 'use-query-params'
import PrintAreaProvider from '../data-workspace/print-area/print-area-provider.js'
import PrintAreaProvider from '../data-workspace/print-area/print-area-provider.jsx'
import { RightHandPanelProvider } from '../right-hand-panel/index.js'
import { LockedProvider } from '../shared/index.js'
import '../locales/index.js'
import App from './app.js'
import { ConfiguredQueryClientProvider } from './query-client/configured-query-client-provider.js'
import App from './app.jsx'
import { ConfiguredQueryClientProvider } from './query-client/configured-query-client-provider.jsx'
import useQueryClient from './query-client/use-query-client.js'

const enableRQDevtools = process.env.REACT_APP_ENABLE_RQ_DEVTOOLS === 'true'
@@ -31,7 +31,7 @@ const enableRQDevtools = process.env.REACT_APP_ENABLE_RQ_DEVTOOLS === 'true'
export function OuterComponents({
children,
// This way we can use a different router in tests when needed
router: Router,
router: Router = HashRouter,
queryClient: customQueryClient,
}) {
const queryClient = useQueryClient()
@@ -60,10 +60,6 @@ export function OuterComponents({
)
}

OuterComponents.defaultProps = {
router: HashRouter,
}

OuterComponents.propTypes = {
children: PropTypes.any.isRequired,
queryClient: PropTypes.instanceOf(QueryClient).isRequired,
2 changes: 1 addition & 1 deletion src/app/app.js → src/app/app.jsx
Original file line number Diff line number Diff line change
@@ -14,7 +14,7 @@ import {
validationResultsSidebarId,
} from '../shared/index.js'
import { Layout } from './layout/index.js'
import LoadApp from './load-app.js'
import LoadApp from './load-app.jsx'

const idSidebarMap = {
[contextualHelpSidebarId]: ContextualHelpSidebar,
2 changes: 1 addition & 1 deletion src/app/app.test.js → src/app/app.test.jsx
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { QueryClient } from '@tanstack/react-query'
import React from 'react'
import { render } from '../test-utils/index.js'
import App from './app.js'
import App from './app.jsx'

describe('<App />', () => {
it('renders without crashing', () => {
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { render } from '../../test-utils/index.js'
import AuthWall from './auth-wall.js'
import AuthWall from './auth-wall.jsx'

describe('<AuthWall />', () => {
it('shows an error message for unauthorized users', () => {
2 changes: 1 addition & 1 deletion src/app/auth/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as AuthWall } from './auth-wall.js'
export { default as AuthWall } from './auth-wall.jsx'
2 changes: 1 addition & 1 deletion src/app/layout/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as Layout } from './layout.js'
export { default as Layout } from './layout.jsx'
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
import React from 'react'
import { render } from '../../test-utils/index.js'
import Layout from './layout.js'
import Layout from './layout.jsx'

describe('<Layout />', () => {
it('renders a node passed to the header prop', () => {
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import React from 'react'
import { useHighlightedFieldStore } from '../shared/index.js'
import styles from './bottom-bar.module.css'
import DataItemBar from './data-item-bar.js'
import MainToolBar from './main-tool-bar.js'
import DataItemBar from './data-item-bar.jsx'
import MainToolBar from './main-tool-bar.jsx'

export default function BottomBar() {
const highlightedField = useHighlightedFieldStore((state) =>
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -1,12 +1,12 @@
import { waitFor } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

Check warning on line 2 in src/bottom-bar/complete-button.test.jsx

GitHub Actions / lint / lint

Using exported name 'userEvent' as identifier for default export
import React from 'react'
import { useMetadata } from '../shared/metadata/use-metadata.js'
import { useDataSetId } from '../shared/use-context-selection/use-context-selection.js'
import { useDataValueSet } from '../shared/use-data-value-set/use-data-value-set.js'
import { useImperativeValidate } from '../shared/validation/use-imperative-validate.js'
import { render } from '../test-utils/render.js'
import CompleteButton from './complete-button.js'
import { render } from '../test-utils/render.jsx'
import CompleteButton from './complete-button.jsx'

const mockShow = jest.fn()
const mockSetFormCompletion = jest
@@ -142,19 +142,19 @@
useImperativeValidate.mockReturnValue(mockValidate)
})

it('validates form and completes when clicked', () => {
it('validates form and completes when clicked', async () => {
mockIsComplete.mockReturnValue(false)
useDataSetId.mockReturnValue(['data_set_id_1'])
useDataValueSet.mockReturnValue({ data: MOCK_DATA })
useMetadata.mockReturnValue({ data: MOCK_METADATA })
const { getByText } = render(<CompleteButton />)

userEvent.click(getByText('Mark complete'))
await userEvent.click(getByText('Mark complete'))
expect(mockValidate).toHaveBeenCalledOnce()
expect(mockSetFormCompletion).toHaveBeenCalledWith({ completed: true })
})

it('completes if the compulsoryFieldsCompleteOnly:true but there are no compulsory data element operands', () => {
it('completes if the compulsoryFieldsCompleteOnly:true but there are no compulsory data element operands', async () => {
mockIsComplete.mockReturnValue(false)
useDataSetId.mockReturnValue([
'data_set_id_compulsory_validation_without_cdeo',
@@ -163,7 +163,7 @@
useMetadata.mockReturnValue({ data: MOCK_METADATA })
const { getByText } = render(<CompleteButton />)

userEvent.click(getByText('Mark complete'))
await userEvent.click(getByText('Mark complete'))
expect(mockValidate).toHaveBeenCalledOnce()
expect(mockSetFormCompletion).toHaveBeenCalledWith({ completed: true })
// completeAttempted only set if the complete is rejected due to compulsory data element operands
@@ -179,7 +179,7 @@
useMetadata.mockReturnValue({ data: MOCK_METADATA })
const { getByText } = render(<CompleteButton />)

userEvent.click(getByText('Mark complete'))
await userEvent.click(getByText('Mark complete'))
expect(mockValidate).not.toHaveBeenCalled()
expect(mockSetFormCompletion).not.toHaveBeenCalled()
expect(mockSetCompleteAttempted).toHaveBeenCalledWith(true)
@@ -190,7 +190,7 @@
)
})

it('completes if the compulsoryFieldsCompleteOnly:true and there are compulsory data element operands but all have values', () => {
it('completes if the compulsoryFieldsCompleteOnly:true and there are compulsory data element operands but all have values', async () => {
mockIsComplete.mockReturnValue(false)
useDataSetId.mockReturnValue([
'data_set_id_compulsory_validation_with_cdeo',
@@ -199,21 +199,21 @@
useMetadata.mockReturnValue({ data: MOCK_METADATA })
const { getByText } = render(<CompleteButton />)

userEvent.click(getByText('Mark complete'))
await userEvent.click(getByText('Mark complete'))
expect(mockValidate).toHaveBeenCalledOnce()
expect(mockSetFormCompletion).toHaveBeenCalledWith({ completed: true })
// completeAttempted only set if the complete is rejected due to compulsory data element operands
expect(mockSetCompleteAttempted).not.toHaveBeenCalled()
})

it('marks form as incomplete if form is completed', () => {
it('marks form as incomplete if form is completed', async () => {
mockIsComplete.mockReturnValue(true)
useDataSetId.mockReturnValue(['data_set_id_1'])
useDataValueSet.mockReturnValue({ data: MOCK_DATA })
useMetadata.mockReturnValue({ data: MOCK_METADATA })
const { getByText } = render(<CompleteButton />)

userEvent.click(getByText('Mark incomplete'))
await userEvent.click(getByText('Mark incomplete'))
expect(mockValidate).not.toHaveBeenCalledOnce()
expect(mockSetFormCompletion).toHaveBeenCalledWith({ completed: false })
})
File renamed without changes.
File renamed without changes.
File renamed without changes.
Original file line number Diff line number Diff line change
@@ -2,8 +2,8 @@ import { useConfig } from '@dhis2/app-runtime'
import { render as testingLibraryRender } from '@testing-library/react'
import React from 'react'
import { useLockedContext } from '../shared/locked-status/use-locked-context.js'
import { render } from '../test-utils/render.js'
import FormExpiryInfo from './form-expiry-info.js'
import { render } from '../test-utils/render.jsx'
import FormExpiryInfo from './form-expiry-info.jsx'

jest.mock('@dhis2/app-runtime', () => ({
...jest.requireActual('@dhis2/app-runtime'),
2 changes: 1 addition & 1 deletion src/bottom-bar/index.js
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
export { default as BottomBar } from './bottom-bar.js'
export { default as BottomBar } from './bottom-bar.jsx'
export * from './validation-results-sidebar/index.js'
Original file line number Diff line number Diff line change
@@ -13,9 +13,9 @@ import {
validationResultsSidebarId,
useValidationStore,
} from '../shared/index.js'
import CompleteButton from './complete-button.js'
import ErrorSummary from './error-summary.js'
import FormExpiryInfo from './form-expiry-info.js'
import CompleteButton from './complete-button.jsx'
import ErrorSummary from './error-summary.jsx'
import FormExpiryInfo from './form-expiry-info.jsx'
import styles from './main-tool-bar.module.css'

function ValidationButtonTooltip({ validateDisabled, offline, children }) {
2 changes: 1 addition & 1 deletion src/bottom-bar/validation-results-sidebar/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as ValidationResultsSidebar } from './validation-results-sidebar.js'
export { default as ValidationResultsSidebar } from './validation-results-sidebar.jsx'
Original file line number Diff line number Diff line change
@@ -8,7 +8,7 @@ import {
ImportanceLevelPropTypes,
ValidationRuleViolationWithMetaDataPropTypes,
} from './validation-result-prop-types.js'
import ValidationRuleExpression from './validation-rule-expression.js'
import ValidationRuleExpression from './validation-rule-expression.jsx'

const ValidationPriortyGroup = ({ level, validationViolations = [] }) => {
if (validationViolations?.length === 0) {
Original file line number Diff line number Diff line change
@@ -12,11 +12,11 @@ import {
useValidationResult,
useValidationStore,
} from '../../shared/index.js'
import ValidationCommentsViolations from './validation-comments-violations.js'
import ValidationCommentsViolations from './validation-comments-violations.jsx'
import { validationLevels } from './validation-config.js'
import ValidationPriortyGroup from './validation-priority-group.js'
import ValidationPriortyGroup from './validation-priority-group.jsx'
import styles from './validation-results-sidebar.module.css'
import ValidationSummaryBox from './validation-summary-box.js'
import ValidationSummaryBox from './validation-summary-box.jsx'

export default function ValidationResultsSidebar({ hide }) {
const [dataChangedSinceValidation, setDataChangedSinceValidation] =
Original file line number Diff line number Diff line change
@@ -1,12 +1,9 @@
import {
fireEvent,
screen,
waitForElementToBeRemoved,
} from '@testing-library/react'
import { screen, waitForElementToBeRemoved } from '@testing-library/react'
import userEvent from '@testing-library/user-event'

Check warning on line 2 in src/bottom-bar/validation-results-sidebar/validation-results-sidebar.test.jsx

GitHub Actions / lint / lint

Using exported name 'userEvent' as identifier for default export
import React from 'react'
import { MemoryRouter } from 'react-router-dom'
import { render } from '../../test-utils/render.js'
import ValidationResultsSidebar from './validation-results-sidebar.js'
import { render } from '../../test-utils/render.jsx'
import ValidationResultsSidebar from './validation-results-sidebar.jsx'

describe('ValidationResultsSidebar', () => {
const hide = jest.fn()
@@ -218,11 +215,10 @@
getByText('There was a problem running validation')
).toBeDefined()

fireEvent.click(getByText('Run validation again'))
await userEvent.click(getByText('Run validation again'))

await findByText('Running validation...')
await findByText('2 medium priority alerts')
expect(queryByText('There was a problem running validation')).toBeNull()
expect(getByText('2 medium priority alerts')).toBeDefined()
})
it('should show empty data', async () => {
const overrideOptions = {
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import React from 'react'
import { ValidationRuleViolationWithMetaDataPropTypes } from './validation-result-prop-types.js'
import ValidationRuleExpressionWithStaticDescription from './validation-rule-expression-with-description.js'
import ValidationRuleExpressionWithValues from './validation-rule-expression-with-values.js'
import ValidationRuleExpressionWithStaticDescription from './validation-rule-expression-with-description.jsx'
import ValidationRuleExpressionWithValues from './validation-rule-expression-with-values.jsx'

/**
* operators that have a description, not a formula with a right and left side values
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import {
useAttributeOptionComboSelection,
useOrgUnit,
} from '../../shared/index.js'
import CategoriesMenu from './categories-menu.js'
import CategoriesMenu from './categories-menu.jsx'
import useSelected from './use-selected.js'
import useSelectorBarItemLabel from './use-selector-bar-item-label.js'
import useSelectorBarItemValue from './use-selector-bar-item-value.js'
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as AttributeOptionComboSelectorBarItem } from './attribute-option-combo-selector-bar-item.js'
export { default as AttributeOptionComboSelectorBarItem } from './attribute-option-combo-selector-bar-item.jsx'
Original file line number Diff line number Diff line change
@@ -12,7 +12,7 @@ import { OrgUnitSetSelectorBarItem } from '../org-unit-selector-bar-item/index.j
import { PeriodSelectorBarItem } from '../period-selector-bar-item/index.js'
import { SectionFilterSelectorBarItem } from '../section-filter-selector-bar-item/index.js'
import styles from './context-selection.module.css'
import RightHandSideContent from './right-hand-side-content.js'
import RightHandSideContent from './right-hand-side-content.jsx'
import useShouldHideClearButton from './use-should-hide-clear-button.js'

export default function ContextSelector({ setSelectionHasNoFormMessage }) {
2 changes: 1 addition & 1 deletion src/context-selection/context-selection/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as ContextSelection } from './context-selection.js'
export { default as ContextSelection } from './context-selection.jsx'
Original file line number Diff line number Diff line change
@@ -3,7 +3,7 @@ import { Divider } from '@dhis2/ui'
import PropTypes from 'prop-types'
import React, { useState } from 'react'
import { ExpandableUnit } from '../../shared/index.js'
import Cell from './cell.js'
import Cell from './cell.jsx'
import styles from './cells-legend.module.css'

function CellsLegendSymbol({ name, state }) {
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
import i18n from '@dhis2/d2-i18n'
import React from 'react'
import { Sidebar, SidebarProps, Title } from '../../shared/index.js'
import CellsLegend from './cells-legend.js'
import Shortcuts from './shortcuts.js'
import CellsLegend from './cells-legend.jsx'
import Shortcuts from './shortcuts.jsx'

export default function ContextualHelpSidebar({ hide }) {
return (
2 changes: 1 addition & 1 deletion src/context-selection/contextual-help-sidebar/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as ContextualHelpSidebar } from './contextual-help-sidebar.js'
export { default as ContextualHelpSidebar } from './contextual-help-sidebar.jsx'
2 changes: 1 addition & 1 deletion src/context-selection/data-set-selector-bar-item/index.js
Original file line number Diff line number Diff line change
@@ -1 +1 @@
export { default as DataSetSelectorBarItem } from './data-set-selector-bar-item.js'
export { default as DataSetSelectorBarItem } from './data-set-selector-bar-item.jsx'
2 changes: 1 addition & 1 deletion src/context-selection/menu-select/index.js
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
import MenuSelect from './menu-select.js'
import MenuSelect from './menu-select.jsx'

export { MenuSelect }
Loading

Unchanged files with check annotations Beta

}
return periods.reverse()
}, [

Check warning on line 110 in src/context-selection/period-selector-bar-item/use-periods.js

GitHub Actions / lint / lint

React Hook useMemo has an unnecessary dependency: 'currentDayString'. Either exclude it or remove the dependency array
periodType,
currentDayString,
year,