diff --git a/CHANGELOG.md b/CHANGELOG.md index 0031f4487..72d45f769 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,12 @@ +## [8.2.3](https://github.com/dhis2/app-platform/compare/v8.2.2...v8.2.3) (2021-10-14) + + +### Bug Fixes + +* **cli:** run yarn install after fixing yarn.lock by deduplicating ([#676](https://github.com/dhis2/app-platform/issues/676)) ([a32f969](https://github.com/dhis2/app-platform/commit/a32f9697d2ac6acecd58a7647d121f8659e14499)) +* **cli:** wrap App component in CustomDataProvider in boilerplate test ([#678](https://github.com/dhis2/app-platform/issues/678)) ([88be6eb](https://github.com/dhis2/app-platform/commit/88be6eb58b7ed340801523518488e0ddfe656c01)) +* **pwa:** update gracefully despite missing clients info ([#679](https://github.com/dhis2/app-platform/issues/679)) ([c7fe509](https://github.com/dhis2/app-platform/commit/c7fe5093e89a45dbb06d44d245e5d08936396180)) + ## [8.2.2](https://github.com/dhis2/app-platform/compare/v8.2.1...v8.2.2) (2021-10-11) diff --git a/adapter/i18n/en.pot b/adapter/i18n/en.pot index 75484c550..cf42c5617 100644 --- a/adapter/i18n/en.pot +++ b/adapter/i18n/en.pot @@ -5,8 +5,8 @@ msgstr "" "Content-Type: text/plain; charset=utf-8\n" "Content-Transfer-Encoding: 8bit\n" "Plural-Forms: nplurals=2; plural=(n != 1)\n" -"POT-Creation-Date: 2021-10-06T14:48:14.669Z\n" -"PO-Revision-Date: 2021-10-06T14:48:14.669Z\n" +"POT-Creation-Date: 2021-10-12T12:20:51.045Z\n" +"PO-Revision-Date: 2021-10-12T12:20:51.045Z\n" msgid "An error occurred in the DHIS2 application." msgstr "An error occurred in the DHIS2 application." @@ -59,6 +59,13 @@ msgstr "" "data will be lost. Save any data you need to, then click 'Reload' when " "ready." +msgid "" +"Updating will reload all open instances of this app, and any unsaved data " +"will be lost. Save any data you need to, then click 'Reload' when ready." +msgstr "" +"Updating will reload all open instances of this app, and any unsaved data " +"will be lost. Save any data you need to, then click 'Reload' when ready." + msgid "Cancel" msgstr "Cancel" diff --git a/adapter/package.json b/adapter/package.json index c77118262..542067cd4 100644 --- a/adapter/package.json +++ b/adapter/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-adapter", - "version": "8.2.2", + "version": "8.2.3", "repository": { "type": "git", "url": "https://github.com/amcgee/dhis2-app-platform", @@ -21,11 +21,11 @@ "build" ], "dependencies": { - "@dhis2/pwa": "8.2.2", + "@dhis2/pwa": "8.2.3", "moment": "^2.24.0" }, "devDependencies": { - "@dhis2/cli-app-scripts": "8.2.2", + "@dhis2/cli-app-scripts": "8.2.3", "@testing-library/react": "^12.0.0", "enzyme": "^3.11.0", "enzyme-adapter-react-16": "^1.15.5", diff --git a/adapter/src/components/PWAUpdateManager.js b/adapter/src/components/PWAUpdateManager.js index f557df432..696fa33d0 100644 --- a/adapter/src/components/PWAUpdateManager.js +++ b/adapter/src/components/PWAUpdateManager.js @@ -16,10 +16,15 @@ function ConfirmReloadModal({ clientsCount, onCancel, onConfirm }) { {i18n.t('Save your data')} - {i18n.t( - "Updating will reload all {{n}} open instances of this app, and any unsaved data will be lost. Save any data you need to, then click 'Reload' when ready.", - { n: clientsCount } - )} + {clientsCount + ? i18n.t( + "Updating will reload all {{n}} open instances of this app, and any unsaved data will be lost. Save any data you need to, then click 'Reload' when ready.", + { n: clientsCount } + ) + : // Fallback if clientsCount is unavailable: + i18n.t( + "Updating will reload all open instances of this app, and any unsaved data will be lost. Save any data you need to, then click 'Reload' when ready." + )} @@ -47,7 +52,7 @@ ConfirmReloadModal.propTypes = { */ export default function PWAUpdateManager({ offlineInterface }) { const [confirmReloadModalOpen, setConfirmReloadModalOpen] = useState(false) - const [clientsCountState, setClientsCountState] = useState(1) + const [clientsCountState, setClientsCountState] = useState(null) const { show } = useAlert( i18n.t("There's an update available for this app."), ({ onConfirm }) => ({ @@ -59,16 +64,25 @@ export default function PWAUpdateManager({ offlineInterface }) { }) ) - const confirmReload = async () => { - const { clientsCount } = await offlineInterface.getClientsInfo() - setClientsCountState(clientsCount) - if (clientsCount <= 1) { - // Just one client; go ahead and reload - offlineInterface.useNewSW() - } else { - // Multiple clients open; warn about data loss before reloading - setConfirmReloadModalOpen(true) - } + const confirmReload = () => { + offlineInterface + .getClientsInfo() + .then(({ clientsCount }) => { + setClientsCountState(clientsCount) + if (clientsCount === 1) { + // Just one client; go ahead and reload + offlineInterface.useNewSW() + } else { + // Multiple clients; warn about data loss before reloading + setConfirmReloadModalOpen(true) + } + }) + .catch(reason => { + // Didn't get clients info + console.warn(reason) + // Go ahead with confirmation modal with `null` as clientsCount + setConfirmReloadModalOpen(true) + }) } useEffect(() => { diff --git a/cli/config/init.App.test.js b/cli/config/init.App.test.js index fe9b67174..0a72d6b49 100644 --- a/cli/config/init.App.test.js +++ b/cli/config/init.App.test.js @@ -1,9 +1,15 @@ +import { CustomDataProvider } from '@dhis2/app-runtime' import React from 'react' import ReactDOM from 'react-dom' import App from './App' it('renders without crashing', () => { const div = document.createElement('div') - ReactDOM.render(, div) + ReactDOM.render( + + + , + div + ) ReactDOM.unmountComponentAtNode(div) }) diff --git a/cli/package.json b/cli/package.json index 4b654afb8..1bc287d52 100644 --- a/cli/package.json +++ b/cli/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/cli-app-scripts", - "version": "8.2.2", + "version": "8.2.3", "engines": { "node": ">=12" }, @@ -28,7 +28,7 @@ "@babel/preset-env": "^7.14.7", "@babel/preset-react": "^7.0.0", "@babel/preset-typescript": "^7.6.0", - "@dhis2/app-shell": "8.2.2", + "@dhis2/app-shell": "8.2.3", "@dhis2/cli-helpers-engine": "^3.0.0", "@jest/core": "^27.0.6", "@yarnpkg/lockfile": "^1.1.0", diff --git a/cli/src/commands/deduplicate.js b/cli/src/commands/deduplicate.js index a39dc37b9..1f4eb6b85 100644 --- a/cli/src/commands/deduplicate.js +++ b/cli/src/commands/deduplicate.js @@ -14,6 +14,12 @@ const handler = async ({ cwd }) => { const deduped = fixDuplicates(yarnLock) fs.writeFileSync(paths.yarnLock, deduped) + if (deduped !== yarnLock) { + reporter.info( + `Run ${chalk.bold('yarn install')} to deduplicate node_modules` + ) + } + const duplicates = listDuplicates(deduped) if (duplicates.size > 0) { reporter.error('Failed to deduplicate the following packages:') diff --git a/cli/src/lib/validators/validateLockfile.js b/cli/src/lib/validators/validateLockfile.js index ae6e68eb1..53c92d41d 100644 --- a/cli/src/lib/validators/validateLockfile.js +++ b/cli/src/lib/validators/validateLockfile.js @@ -1,5 +1,5 @@ const fs = require('fs') -const { reporter, prompt } = require('@dhis2/cli-helpers-engine') +const { reporter, prompt, exec } = require('@dhis2/cli-helpers-engine') const { listDuplicates, fixDuplicates } = require('../yarnDeduplicate') const singletonDependencies = [ @@ -52,6 +52,11 @@ exports.validateLockfile = async (pkg, { paths, offerFix = false }) => { } const dedupedYarnLock = fixDuplicates(yarnLock) fs.writeFileSync(paths.yarnLock, dedupedYarnLock) + await exec({ + cmd: 'yarn', + args: ['install'], + cwd: paths.base, + }) return listSingletonDuplicates(dedupedYarnLock).size === 0 } diff --git a/docs/getting-started.md b/docs/getting-started.md index 9f0c5c391..ca045b400 100644 --- a/docs/getting-started.md +++ b/docs/getting-started.md @@ -9,6 +9,7 @@ The Application Platform provides common build system, development tools, runtim The baseline features built-in to any platform application include: - Build and development tooling ([`@dhis2/cli-app-scripts`](scripts)) + - I18n extract/generate - Manifest generation - Dependency injection @@ -16,7 +17,8 @@ The baseline features built-in to any platform application include: - Transpilation & Bundling - App-shell encapsulation - Publication & Release - - Application runtime support ([`@dhis2/app-runtime`](https://runtime.dhis2.nu)) + +- Application runtime support ([`@dhis2/app-runtime`](https://runtime.dhis2.nu)) - UI Components ([@dhis2/ui](https://ui.dhis2.nu)) - API Data fetching - Translations diff --git a/examples/pwa-app/package.json b/examples/pwa-app/package.json index 2f5561060..032009a59 100644 --- a/examples/pwa-app/package.json +++ b/examples/pwa-app/package.json @@ -1,6 +1,6 @@ { "name": "pwa-app", - "version": "8.2.2", + "version": "8.2.3", "description": "", "license": "BSD-3-Clause", "private": true, diff --git a/examples/simple-app/package.json b/examples/simple-app/package.json index 702a1ae79..481d46fa9 100644 --- a/examples/simple-app/package.json +++ b/examples/simple-app/package.json @@ -1,6 +1,6 @@ { "name": "simple-app", - "version": "8.2.2", + "version": "8.2.3", "repository": "https://github.com/amcgee/dhis2-app-platform", "author": "Austin McGee ", "license": "BSD-3-Clause", diff --git a/package.json b/package.json index 18ea7ae39..9a798c9bc 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "root", - "version": "8.2.2", + "version": "8.2.3", "private": true, "repository": { "type": "git", diff --git a/pwa/package.json b/pwa/package.json index 45a9dfedd..e6d2d8fee 100644 --- a/pwa/package.json +++ b/pwa/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/pwa", - "version": "8.2.2", + "version": "8.2.3", "description": "", "license": "BSD-3-Clause", "publishConfig": { @@ -13,7 +13,7 @@ "deploy": "d2-app-scripts deploy" }, "devDependencies": { - "@dhis2/cli-app-scripts": "8.2.2" + "@dhis2/cli-app-scripts": "8.2.3" }, "dependencies": { "idb": "^6.0.0", diff --git a/pwa/src/offline-interface/offline-interface.js b/pwa/src/offline-interface/offline-interface.js index f09b4aa3e..5239661b9 100644 --- a/pwa/src/offline-interface/offline-interface.js +++ b/pwa/src/offline-interface/offline-interface.js @@ -65,8 +65,7 @@ export class OfflineInterface { } /** - * Requests clients info from the active service worker. Works for - * both first activation and SW update by using `reg.active` worker. + * Requests clients info from the active service worker. * @returns {Promise} */ getClientsInfo() { @@ -75,15 +74,16 @@ export class OfflineInterface { if (!registration || !registration.active) { reject('There is no active service worker') } - // Send request message to SW - registration.active.postMessage({ type: swMsgs.getClientsInfo }) + // Send request message to newest SW + const newestSW = registration.waiting || registration.active + newestSW.postMessage({ type: swMsgs.getClientsInfo }) // Resolve with payload received from SW `clientsInfo` message this.offlineEvents.once(swMsgs.clientsInfo, resolve) // Clean up potentially unused listeners eventually setTimeout(() => { reject('Request for clients info timed out') this.offlineEvents.removeAllListeners(swMsgs.clientsInfo) - }, 10000) + }, 2000) }) }) } diff --git a/shell/package.json b/shell/package.json index 310171b43..07e66d0a2 100644 --- a/shell/package.json +++ b/shell/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-shell", - "version": "8.2.2", + "version": "8.2.3", "repository": { "type": "git", "url": "https://github.com/amcgee/dhis2-app-platform", @@ -12,10 +12,10 @@ "access": "public" }, "dependencies": { - "@dhis2/app-adapter": "8.2.2", + "@dhis2/app-adapter": "8.2.3", "@dhis2/app-runtime": "^3.2.3", "@dhis2/d2-i18n": "^1.1.0", - "@dhis2/pwa": "8.2.2", + "@dhis2/pwa": "8.2.3", "@dhis2/ui": "^7.2.0", "classnames": "^2.2.6", "moment": "^2.29.1", diff --git a/shell/src/App.test.js b/shell/src/App.test.js index 0a72d6b49..fe9b67174 100644 --- a/shell/src/App.test.js +++ b/shell/src/App.test.js @@ -1,15 +1,9 @@ -import { CustomDataProvider } from '@dhis2/app-runtime' import React from 'react' import ReactDOM from 'react-dom' import App from './App' it('renders without crashing', () => { const div = document.createElement('div') - ReactDOM.render( - - - , - div - ) + ReactDOM.render(, div) ReactDOM.unmountComponentAtNode(div) })