Skip to content

Commit

Permalink
Merge branch 'master' into chore-catch-up-with-master
Browse files Browse the repository at this point in the history
  • Loading branch information
KaiVandivier committed Aug 10, 2023
2 parents b0f4732 + a3490e0 commit 90fef9f
Show file tree
Hide file tree
Showing 25 changed files with 639 additions and 459 deletions.
55 changes: 44 additions & 11 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,26 +1,59 @@
# [10.4.0-alpha.2](https://github.com/dhis2/app-platform/compare/v10.4.0-alpha.1...v10.4.0-alpha.2) (2023-06-16)
## [10.3.9](https://github.com/dhis2/app-platform/compare/v10.3.8...v10.3.9) (2023-05-16)


### Bug Fixes

* update app-runtime dependencies ([3433129](https://github.com/dhis2/app-platform/commit/343312996e4879f186ecbdf58f1f9816cca8c7f1))
* move precache route to reenable navigation handler on login redirects [LIBS-473] ([#809](https://github.com/dhis2/app-platform/issues/809)) ([1ff29b6](https://github.com/dhis2/app-platform/commit/1ff29b645ec07e0bcce76efedbc08f1b76014a42))

# [10.4.0-alpha.1](https://github.com/dhis2/app-platform/compare/v10.3.1...v10.4.0-alpha.1) (2023-03-13)
## [10.3.8](https://github.com/dhis2/app-platform/compare/v10.3.7...v10.3.8) (2023-05-03)


### Bug Fixes

* merge in master branch of app-platform ([5c637c0](https://github.com/dhis2/app-platform/commit/5c637c0e6c344c9372f679f4e997b5430e2a26cc))
* pass props with spread operator ([bd4dccb](https://github.com/dhis2/app-platform/commit/bd4dccb370823651322d9ea89b3c6112d281b824))
* simplify error reset logic ([d40dfba](https://github.com/dhis2/app-platform/commit/d40dfba50cc9fa2e8ada03bf03cc9e4b52ef28bc))
* style adapter package file ([d5e17e1](https://github.com/dhis2/app-platform/commit/d5e17e1ae44a14efc1a4c03291c86e566be964de))
* **pwa:** avoid crashing when SW is not available [LIBS-499] ([#807](https://github.com/dhis2/app-platform/issues/807)) ([b681022](https://github.com/dhis2/app-platform/commit/b68102248fad98303dd2c01d954f4430b1934a25))

## [10.3.7](https://github.com/dhis2/app-platform/compare/v10.3.6...v10.3.7) (2023-04-27)

### Features

* implement plugin wrapper (receiver in plugin) (alpha) ([#786](https://github.com/dhis2/app-platform/issues/786)) ([d4f1ee2](https://github.com/dhis2/app-platform/commit/d4f1ee21e50bb6d0d79a4cf402d7efe6b99458e8))
* plugin error handling ([7fd0605](https://github.com/dhis2/app-platform/commit/7fd0605c3e4ff52f30a1fb3bd0d8da2168f583f5))
* plugin handling ([7ee8ed6](https://github.com/dhis2/app-platform/commit/7ee8ed68b888e3bebb61858fd9002ad2c8c0cd4c))
### Bug Fixes

* omit `moment-locales` from precache ([#806](https://github.com/dhis2/app-platform/issues/806)) ([c8d5494](https://github.com/dhis2/app-platform/commit/c8d5494c5eaf6a2f021166d208a1cc289701a47a))

## [10.3.6](https://github.com/dhis2/app-platform/compare/v10.3.5...v10.3.6) (2023-03-22)


### Bug Fixes

* **cli:** fix envs to fix plugins in dev ([#799](https://github.com/dhis2/app-platform/issues/799)) ([ba29cea](https://github.com/dhis2/app-platform/commit/ba29ceacfe5a25d42a406f80a9896ccbc7bc82f8))

## [10.3.5](https://github.com/dhis2/app-platform/compare/v10.3.4...v10.3.5) (2023-03-17)


### Bug Fixes

* **pwa:** bump ui version for headerbar connection status [LIBS-315] ([#797](https://github.com/dhis2/app-platform/issues/797)) ([61ff0a4](https://github.com/dhis2/app-platform/commit/61ff0a49e63189d892403db8df24c57e170dac0a))

## [10.3.4](https://github.com/dhis2/app-platform/compare/v10.3.3...v10.3.4) (2023-03-16)


### Bug Fixes

* make loading placeholders transparent ([#795](https://github.com/dhis2/app-platform/issues/795)) ([6e64756](https://github.com/dhis2/app-platform/commit/6e64756325b366b413acbdce8dd0d6b70632d118))

## [10.3.3](https://github.com/dhis2/app-platform/compare/v10.3.2...v10.3.3) (2023-03-13)


### Bug Fixes

* **plugins:** inject precache manifest correctly ([#792](https://github.com/dhis2/app-platform/issues/792)) ([c0d172e](https://github.com/dhis2/app-platform/commit/c0d172ec362182ce978e43b16e9c411ec61e5039))
* **pwa:** add config option to omit files from precache [LIBS-482] ([#793](https://github.com/dhis2/app-platform/issues/793)) ([d089dda](https://github.com/dhis2/app-platform/commit/d089dda25433ca52f84c42c9369fce95419e4f83))

## [10.3.2](https://github.com/dhis2/app-platform/compare/v10.3.1...v10.3.2) (2023-03-10)


### Bug Fixes

* **plugins:** omit launch paths when unused [LIBS-477] ([#791](https://github.com/dhis2/app-platform/issues/791)) ([e49a51f](https://github.com/dhis2/app-platform/commit/e49a51fec39a323350c71d4e09caff836aab2262))

## [10.3.1](https://github.com/dhis2/app-platform/compare/v10.3.0...v10.3.1) (2023-03-06)

Expand Down
2 changes: 1 addition & 1 deletion adapter/src/components/LoadingMask.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import { Layer, CenteredContent, CircularLoader, layers } from '@dhis2/ui'
import React from 'react'

export const LoadingMask = () => (
<Layer translucent level={layers.alert}>
<Layer level={layers.alert}>
<CenteredContent>
<CircularLoader />
</CenteredContent>
Expand Down
12 changes: 12 additions & 0 deletions cli/config/d2.pwa.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,18 @@ module.exports = {
* https://developers.google.com/web/tools/workbox/modules/workbox-precaching#explanation_of_the_precache_list
*/
additionalManifestEntries: [],
/**
* By default, all the contents of the `build` folder are added to
* the precache to give the app the best chances of functioning
* completely while offline. Developers may choose to omit some
* of these files (for example, thousands of font or image files)
* if they cause cache bloat and the app can work fine without
* them precached. See LIBS-482
*
* The globs should be relative to the public dir of the built app.
* Used in injectPrecacheManifest.js
*/
globsToOmitFromPrecache: [],
},
},
}
6 changes: 5 additions & 1 deletion cli/config/plugin.webpack.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -188,7 +188,11 @@ module.exports = ({ env: webpackEnv, config, paths }) => {
resourceRegExp: /^\.\/locale$/,
contextRegExp: /moment$/,
}),
// dhis2: Inject plugin static assets to the existing SW's precache manifest
// dhis2: Inject plugin static assets to the existing SW's precache
// manifest. Don't need to do in dev because precaching isn't done
// in dev environments.
// Check the actual NODE_ENV because `isProduction` is currently
// always true due to a bug (see src/lib/plugin/start.js)
process.env.NODE_ENV === 'production' &&
new WorkboxWebpackPlugin.InjectManifest({
swSrc: paths.shellBuildServiceWorker,
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/build.js
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,7 @@ const handler = async ({
const paths = makePaths(cwd)

mode = mode || (dev && 'development') || getNodeEnv() || 'production'
process.env.BABEL_ENV = process.env.NODE_ENV = mode
loadEnvFiles(paths, mode)

reporter.print(chalk.green.bold('Build parameters:'))
Expand Down
1 change: 1 addition & 0 deletions cli/src/commands/start.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@ const handler = async ({
const paths = makePaths(cwd)

const mode = 'development'
process.env.BABEL_ENV = process.env.NODE_ENV = mode
loadEnvFiles(paths, mode)

const config = parseConfig(paths)
Expand Down
41 changes: 36 additions & 5 deletions cli/src/lib/generateManifests.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,28 @@
const { reporter, chalk } = require('@dhis2/cli-helpers-engine')
const fs = require('fs-extra')

/**
* Gets the original `entrypoints` property in d2.config.js
* without applying defaults. Used to detect if there is actually
* supposed to be an app entrypoint for this... app. Temporary until
* the build process is redesigned to allow building plugins without
* apps (LIBS-479)
*/
const getOriginalEntrypoints = (paths) => {
try {
if (fs.existsSync(paths.config)) {
reporter.debug('Loading d2 config at', paths.config)
// NB: this import can be confounded by previous object mutations
const originalConfig = require(paths.config)
reporter.debug('loaded', originalConfig)
return originalConfig.entryPoints // may be undefined
}
} catch (e) {
reporter.error('Failed to load d2 config!')
reporter.error(e)
process.exit(1)
}
}
const parseCustomAuthorities = (authorities) => {
if (!authorities) {
return undefined
Expand Down Expand Up @@ -93,11 +115,20 @@ module.exports = (paths, config, publicUrl) => {
},
],
start_url: '.',
display: 'browser',
display: 'standalone',
theme_color: '#ffffff',
background_color: '#f4f6f8',
}

const includesPlugin = Boolean(config.entryPoints.plugin)
// If there's a plugin, there might not be an app intended to be exposed,
// in which case omit the app launch path. Check the original d2.config
// without added defaults to see if an app is intended.
// If there's not a plugin, default to 'true'
const shouldIncludeAppLaunchPath = includesPlugin
? Boolean(getOriginalEntrypoints(paths)?.app)
: true

// Legacy manifest
const manifestWebapp = {
app_hub_id: config.id,
Expand All @@ -108,8 +139,8 @@ module.exports = (paths, config, publicUrl) => {
version: config.version,
core_app: config.coreApp,

launch_path: paths.launchPath,
plugin_launch_path: paths.pluginLaunchPath,
launch_path: shouldIncludeAppLaunchPath ? paths.launchPath : undefined,
plugin_launch_path: includesPlugin ? paths.pluginLaunchPath : undefined,
default_locale: 'en',
activities: {
dhis: {
Expand Down Expand Up @@ -148,8 +179,8 @@ module.exports = (paths, config, publicUrl) => {
const appConfig = { ...config }
delete appConfig['entryPoints']
appConfig.entryPoints = {
app: paths.launchPath,
plugin: config.entryPoints.plugin ? paths.pluginLaunchPath : undefined,
app: shouldIncludeAppLaunchPath ? paths.launchPath : undefined,
plugin: includesPlugin ? paths.pluginLaunchPath : undefined,
}
delete appConfig['pwa']

Expand Down
7 changes: 5 additions & 2 deletions cli/src/lib/parseConfig.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
const { reporter, chalk } = require('@dhis2/cli-helpers-engine')
const fs = require('fs-extra')
const { defaultsDeep, has, isPlainObject } = require('lodash')
const { defaultsDeep, cloneDeep, has, isPlainObject } = require('lodash')
const parseAuthorString = require('parse-author')

const requiredConfigFields = {
Expand Down Expand Up @@ -83,7 +83,10 @@ const parseConfig = (paths) => {

if (fs.existsSync(paths.config)) {
reporter.debug('Loading d2 config at', paths.config)
config = require(paths.config)
const importedConfig = require(paths.config)
// Make sure not to overwrite imported object
// (need to use it later in generateManifest)
config = cloneDeep(importedConfig)
reporter.debug('loaded', config)
}
if (fs.existsSync(paths.package)) {
Expand Down
4 changes: 0 additions & 4 deletions cli/src/lib/plugin/build.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
// Based on CRA build script

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'production'
process.env.NODE_ENV = 'production'

const { reporter } = require('@dhis2/cli-helpers-engine')
const webpack = require('webpack')
const webpackConfigFactory = require('../../../config/plugin.webpack.config')
Expand Down
4 changes: 0 additions & 4 deletions cli/src/lib/plugin/start.js
Original file line number Diff line number Diff line change
@@ -1,9 +1,5 @@
// Based on CRA start script

// Do this as the first thing so that any code reading it knows the right env.
process.env.BABEL_ENV = 'development'
process.env.NODE_ENV = 'development'

const getPublicUrlOrPath = require('react-dev-utils/getPublicUrlOrPath')
const webpack = require('webpack')
const WebpackDevServer = require('webpack-dev-server')
Expand Down
9 changes: 7 additions & 2 deletions cli/src/lib/pwa/injectPrecacheManifest.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,14 @@ module.exports = function injectPrecacheManifest(paths, config) {
swDest: paths.shellBuildServiceWorker,
globDirectory: paths.shellBuildOutput,
globPatterns: ['**/*'],
// Skip index.html and `static` directory;
// Skip index.html, (plugin.html,) and `static` directory;
// CRA's workbox-webpack-plugin handles it smartly
globIgnores: ['static/**/*', paths.launchPath],
globIgnores: [
'static/**/*',
paths.launchPath,
paths.pluginLaunchPath,
...config.pwa.caching.globsToOmitFromPrecache,
],
additionalManifestEntries: config.pwa.caching.additionalManifestEntries,
injectionPoint: 'self.__WB_BUILD_MANIFEST',
// Skip revision hashing for files with hash or semver in name:
Expand Down
12 changes: 11 additions & 1 deletion docs/config/d2-config-js-reference.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ The following configuration properties are supported:
| **entryPoints.lib** | _string_ or _object_ | **./src/index** | The path to the library entrypoint(s) (not used for applications). Supports [conditional exports](https://nodejs.org/dist/latest-v16.x/docs/api/packages.html#packages_conditional_exports) |
| **dataStoreNamespace** | _string_ | | The DataStore and UserDataStore namespace to reserve for this application. The reserved namespace **must** be suitably unique, as other apps will fail to install if they attempt to reserve the same namespace - see the [webapp manifest docs](https://docs.dhis2.org/en/develop/loading-apps.html) |
| **customAuthorities** | _Array(string)_ | | An array of custom authorities to create when installing the app, these do not provide security protections in the DHIS2 REST API but can be assigned to user roles and used to modify the interface displayed to a user - see the [webapp manifest docs](https://docs.dhis2.org/en/develop/loading-apps.html) |
| **minDHIS2Version** | _string_ | | The minimum DHIS2 version the App supports (eg. '2.35'). Required when uploading an app to the App Hub. |
| **minDHIS2Version** | _string_ | | The minimum DHIS2 version the App supports (eg. '2.35'). Required when uploading an app to the App Hub. The app's major version in the app's package.json needs to be increased when changing this property. |
| **maxDHIS2Version** | _string_ | | The maximum DHIS2 version the App supports. |
| **coreApp** | _boolean_ | **false** | **ADVANCED** If true, build an app artifact to be included as a root-level core application |
| **standalone** | _boolean_ | **false** | **ADVANCED** If true, do NOT include a static BaseURL in the production app artifact. This includes the `Server` field in the login dialog, which is usually hidden and pre-configured in production. |
Expand Down Expand Up @@ -52,3 +52,13 @@ const config = {

module.exports = config
```

## Setting the DHIS2 version

The `minDHIS2Version` and `maxDHIS2Version` allow specifying which DHIS2 version the app is compatible with. This can be used to have multiple versions of the app on the App Hub, each with their own range of supported DHIS2 versions.

For example, let's say you want to adjust your app to a breaking change in the DHIS2 api. Let's assume that the code on your app's default branch (`main`) has not yet been adapted to the breaking change and that you're working with DHIS2's workflows:

1. Set the `maxDHIS2Version` in `d2.config.js` to the last DHIS2 version that's still compatible with the code on `main`.
1. Branch `main` to a maintenance branch. The recommended naming pattern is `N.x`, where `N` should be replaced with the app's current major version (i.e. `100.x`, `101.x`, etc.). See also [semantic-release's documentation on branches](https://semantic-release.gitbook.io/semantic-release/usage/configuration#branches). The app's version can be found in `package.json`, look for the `version` field.
1. On `main` update the `minDHIS2Version` to the first DHIS2 version that contains the breaking change. It's important to publish the `minDHIS2Version` change as a breaking change. An easy way to do that is to include the `BREAKING CHANGE` label in the commit that changes the `minDHIS2Version` (see the [semantic-release documentation](https://semantic-release.gitbook.io/semantic-release/#commit-message-format) on their commit conventions).
1 change: 1 addition & 0 deletions docs/pwa/pwa.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ You can opt in to PWA features using options in `d2.config.js`. Here are the opt
| `pwa.caching.patternsToOmitFromCacheableSections` | Array of RegExps or Strings | Similar to the above setting, except this is a list of URL patterns to omit from _cacheable (recorded) sections_. Requests with URLs that are filtered out from cacheable sections can still be cached in the app shell cache, unless they are filtered out from the app shell as well using the setting above. When choosing these URL filters, note that it is better to _cache too many things_ than to risk _not caching an important part of the section_ which could break the offline functionality of the section, so choose your filter patterns accordingly. |
| `pwa.caching.patternsToOmit` | Array of RegExps or Strings | Deprecated; superceded by `patternsToOmitFromAppShell`. The new option takes precedence. |
| `pwa.caching.additionalManifestEntries` | Array of Objects with signature `{ revision: String, url: String }` | A list of files that can be added to the precache manifest. Note that the service worker uses Workbox to precache all static assets that end up in the ‘build’ folder after the CRA compilation and build step during the d2-app-scripts build process. The format of this list must match the [required format for Workbox precache manifests](https://developers.google.com/web/tools/workbox/modules/workbox-precaching#explanation_of_the_precache_list), i.e. it must include a revision hash to inform when that file needs to be updated in the precache. |
| `pwa.caching.globsToOmitFromPrecache` | An array of **glob** Strings | A list of globs that will cause matching files to be omitted from precaching. The globs should be **relative to the 'public' directory** of the built app. For example, if you have a folder of fonts in your app in `./public/fonts/` that you want to omit from precaching, you can use the glob `'fonts/**'` in this array. The omitted files can still be cached at runtime later. |

### Offline caching

Expand Down
2 changes: 2 additions & 0 deletions examples/pwa-app/d2.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@ const config = {
caching: {
// For the purposes of this demo, to simulate dashboard content:
patternsToOmitFromAppShell: ['visualizations'],
// To test precache filtering: (relative to PUBLIC_DIR)
globsToOmitFromPrecache: ['exclude-from-precache/**'],
},
},

Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Empty file.
Empty file.
Loading

0 comments on commit 90fef9f

Please sign in to comment.