From 818677589c454d59f943c19346f9d6868747d1cf Mon Sep 17 00:00:00 2001 From: Rene Pot Date: Tue, 14 Nov 2023 09:11:54 +0100 Subject: [PATCH 1/8] docs: fix links (#1359) * docs: fix links * docs: fix links * docs: fix more links * docs: fix link to playground * docs: change docs build --- README.md | 2 +- docs/advanced/offline/README.md | 4 +-- docs/advanced/offline/useOnlineStatus.md | 2 +- docs/components/DataMutation.md | 30 +++++++++++----------- docs/components/DataQuery.md | 32 ++++++++++++------------ docs/components/README.md | 6 ++--- docs/hooks/README.md | 14 +++++------ docs/hooks/useConfig.md | 4 +-- docs/hooks/useDataEngine.md | 4 +-- docs/hooks/useDataMutation.md | 32 ++++++++++++------------ docs/hooks/useDataQuery.md | 32 ++++++++++++------------ docs/index.html | 18 +++++++++++++ docs/provider.md | 6 ++--- docs/types/Config.md | 4 +-- docs/types/Mutation.md | 2 +- docs/types/Query.md | 2 +- package.json | 2 +- 17 files changed, 107 insertions(+), 89 deletions(-) create mode 100644 docs/index.html diff --git a/README.md b/README.md index 4fc98a0dd..4f640356a 100644 --- a/README.md +++ b/README.md @@ -21,7 +21,7 @@ A query REPL platform application is also available at `./examples/query-playgro Running `yarn build` at root will automatically update the example app's copy, and running `yarn start` will build the runtime and then start the example. -A [`DHIS2 App Platform`](https://platform.dhis2.nu) example is available at [./examples/query-playground](./examples/query-playground). This is a full, deployable DHIS2 application and a live standalone version is available at [runtime.dhis2.nu/playground](https://runtime.dhis2.nu/playground) +A [`DHIS2 App Platform`](https://platform.dhis2.nu) example is available at [./examples/query-playground](./examples/query-playground). This is a full, deployable DHIS2 application and a live standalone version is available at [every play instance](https://play.dhis2.org), such as the `dev` instance [play.dhis2.org/dev](https://play.dhis2.org/dev/api/apps/query-playground/index.html). ## Release diff --git a/docs/advanced/offline/README.md b/docs/advanced/offline/README.md index 15afd54c4..6cfa9a90d 100644 --- a/docs/advanced/offline/README.md +++ b/docs/advanced/offline/README.md @@ -2,9 +2,9 @@ !> **WARNING** These features are considered **experimental** and are **subject to breaking changes outside of the normal release cycle.** -The app platform provides some support for PWA features, including a `manifest.json` file for installability and service worker which can provide offline caching. In addition to those features, the app runtime provides support for ["cacheable sections"](advanced/offline/CacheableSections), which are sections of an app that can be individually cached on-demand. The [`useCacheableSection` hook](advanced/offline/CacheableSections#usecacheablesection-api) and the [`CacheableSection` component](advanced/offline/CacheableSections#cacheablesection-api) provide the controls for the section and the wrapper for the section, respectively. The [`useCachedSections` hook](advanced/offline/CacheableSections#usecachedsections-api) returns a list of sections that are stored in the cache and a function that can delete them. +The app platform provides some support for PWA features, including a `manifest.json` file for installability and service worker which can provide offline caching. In addition to those features, the app runtime provides support for ["cacheable sections"](./CacheableSections.md), which are sections of an app that can be individually cached on-demand. The [`useCacheableSection` hook](./CacheableSections.md#usecacheablesection-api) and the [`CacheableSection` component](./CacheableSections.md#cacheablesection-api) provide the controls for the section and the wrapper for the section, respectively. The [`useCachedSections` hook](./CacheableSections.md#usecachedsections-api) returns a list of sections that are stored in the cache and a function that can delete them. -An important tool for offline-capable apps is the [`useDhis2ConnectionStatus` hook](advanced/offline/useDhis2ConnectionStatus.md), which can be used to determine whether or not the app can connect to the DHIS2 server. There is also a [`useOnlineStatus` hook](advanced/offline/useOnlineStatus.md) which returns whether or not the client is connected to the internet, but `useDhis2ConnectionStatus` is probably the one you want to use. On instances where DHIS2 is deployed locally in an environment without internet, `useOnlineStatus` can cause problems, because it will always return `false` even though the app can communicate with the DHIS2 server and therefore function just fine. `useDhis2ConnectionStatus` was created to address this problem. +An important tool for offline-capable apps is the [`useDhis2ConnectionStatus` hook](./useDhis2ConnectionStatus.md), which can be used to determine whether or not the app can connect to the DHIS2 server. There is also a [`useOnlineStatus` hook](./useOnlineStatus.md) which returns whether or not the client is connected to the internet, but `useDhis2ConnectionStatus` is probably the one you want to use. On instances where DHIS2 is deployed locally in an environment without internet, `useOnlineStatus` can cause problems, because it will always return `false` even though the app can communicate with the DHIS2 server and therefore function just fine. `useDhis2ConnectionStatus` was created to address this problem. ## Examples diff --git a/docs/advanced/offline/useOnlineStatus.md b/docs/advanced/offline/useOnlineStatus.md index 366a797fc..8491b5904 100644 --- a/docs/advanced/offline/useOnlineStatus.md +++ b/docs/advanced/offline/useOnlineStatus.md @@ -1,6 +1,6 @@ # useOnlineStatus -!> This hook only detects whether or not you're connected to the internet, which could be problematic for DHIS2 instances that are hosted locally or offline, where what really matters is whether or not you can communicate with the DHIS2 server. The [`useDhis2ConnectionStatus` hook](advanced/offline/useDhis2ConnectionStatus) is usually better for that reason, and is therefore recommended. +!> This hook only detects whether or not you're connected to the internet, which could be problematic for DHIS2 instances that are hosted locally or offline, where what really matters is whether or not you can communicate with the DHIS2 server. The [`useDhis2ConnectionStatus` hook](./useDhis2ConnectionStatus.md) is usually better for that reason, and is therefore recommended. The `useOnlineStatus` returns whether the client is online or offline. It debounces the returned values by default to prevent rapid changes of any UI elements that depend on the online status. diff --git a/docs/components/DataMutation.md b/docs/components/DataMutation.md index fa8dc8f2c..914f02c0c 100644 --- a/docs/components/DataMutation.md +++ b/docs/components/DataMutation.md @@ -1,6 +1,6 @@ # DataMutation Component -A thin wrapper around the [useDataMutation](hooks/useDataMutation.md) hook +A thin wrapper around the [useDataMutation](../hooks/useDataMutation.md) hook ## Basic Usage @@ -19,13 +19,13 @@ return ( ## Input Props -| Name | Type | Required | Description | -| :------------: | :-----------------------------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------- | -| **mutation** | [_Mutation_](types/Mutation.md) | **required** | The Mutation definition describing the requested operation | -| **variables** | _Object_ | | Variables to be passed to the dynamic portions of the mutation | -| **onComplete** | _Function_ | | Callback function to be called on successfull completion of the mutation. Called with the response data as the only argument. | -| **onError** | _Function_ | | Callback function to be called on failure of the mutation. Called with the error instance as the only argument. | -| **lazy** | _boolean_ | | If false, run the mutation immediately after the component mounts.
_**Default**: `true`_ | +| Name | Type | Required | Description | +| :------------: | :--------------------------------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------- | +| **mutation** | [_Mutation_](../types/Mutation.md) | **required** | The Mutation definition describing the requested operation | +| **variables** | _Object_ | | Variables to be passed to the dynamic portions of the mutation | +| **onComplete** | _Function_ | | Callback function to be called on successfull completion of the mutation. Called with the response data as the only argument. | +| **onError** | _Function_ | | Callback function to be called on failure of the mutation. Called with the error instance as the only argument. | +| **lazy** | _boolean_ | | If false, run the mutation immediately after the component mounts.
_**Default**: `true`_ | ## Render Function Props @@ -34,13 +34,13 @@ The render function is called whenever the state of the mutation changes. It is 1. `mutate` - a function which can be called to trigger the mutation (for instance in an onClick callback) 2. `state` - an object containing the following properties: -| Name | Type | Description | -| :---------: | :-------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **called** | _boolean_ | **true** if the mutation has been triggered through a call to the `mutate` function or on component mount with `lazy: false` | -| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | -| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | -| **data** | _MutationResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | -| **engine** | [_Data Engine_](advanced/DataEngine) | A reference to the DataEngine instance | +| Name | Type | Description | +| :---------: | :----------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **called** | _boolean_ | **true** if the mutation has been triggered through a call to the `mutate` function or on component mount with `lazy: false` | +| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | +| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | +| **data** | _MutationResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | +| **engine** | [_Data Engine_](../advanced/DataEngine.md) | A reference to the DataEngine instance | ## Example diff --git a/docs/components/DataQuery.md b/docs/components/DataQuery.md index 5f1b49a14..a5a741d25 100644 --- a/docs/components/DataQuery.md +++ b/docs/components/DataQuery.md @@ -1,6 +1,6 @@ # DataQuery Component -A thin wrapper around the [useDataQuery](hooks/useDataQuery.md) hook +A thin wrapper around the [useDataQuery](../hooks/useDataQuery.md) hook ## Basic Usage @@ -19,24 +19,24 @@ return ( ## Input Props -| Name | Type | Required | Description | -| :------------: | :-----------------------: | :----------: | -------------------------------------------------------------------------------------------------------------------------- | -| **query** | [_Query_](types/Query.md) | **required** | The Query definition describing the requested data | -| **variables** | _Object_ | | Variables to be passed to the dynamic portions of the query | -| **onComplete** | _Function_ | | Callback function to be called on successfull completion of the query. Called with the response data as the only argument. | -| **onError** | _Function_ | | Callback function to be called on failure of the query. Called with the error instance as the only argument. | -| **lazy** | _boolean_ | | If true, wait until `refetch` is called before fetching data.
_**Default**: `false`_ | +| Name | Type | Required | Description | +| :------------: | :--------------------------: | :----------: | -------------------------------------------------------------------------------------------------------------------------- | +| **query** | [_Query_](../types/Query.md) | **required** | The Query definition describing the requested data | +| **variables** | _Object_ | | Variables to be passed to the dynamic portions of the query | +| **onComplete** | _Function_ | | Callback function to be called on successfull completion of the query. Called with the response data as the only argument. | +| **onError** | _Function_ | | Callback function to be called on failure of the query. Called with the error instance as the only argument. | +| **lazy** | _boolean_ | | If true, wait until `refetch` is called before fetching data.
_**Default**: `false`_ | ## Render Function Props -| Name | Type | Description | -| :---------: | :----------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **called** | _boolean_ | **true** if the data request has been initiated with either `lazy: false` or `refetch()` at least once | -| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | -| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | -| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | -| **refetch** | _Function_ | This function can be called to refetch the data. Any in-flight HTTP requests will automatically be aborted. | -| **engine** | [_Data Engine_](advanced/DataEngine) | A reference to the DataEngine instance | +| Name | Type | Description | +| :---------: | :----------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **called** | _boolean_ | **true** if the data request has been initiated with either `lazy: false` or `refetch()` at least once | +| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | +| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | +| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | +| **refetch** | _Function_ | This function can be called to refetch the data. Any in-flight HTTP requests will automatically be aborted. | +| **engine** | [_Data Engine_](../advanced/DataEngine.md) | A reference to the DataEngine instance | ## Example diff --git a/docs/components/README.md b/docs/components/README.md index 3deab07b0..f790d06a4 100644 --- a/docs/components/README.md +++ b/docs/components/README.md @@ -1,6 +1,6 @@ # React Components -As an alternative to [React Hooks](hooks/), the DHIS2 Application Runtime support render-prop React components. The following Components are supported: +As an alternative to [React Hooks](../hooks/README.md), the DHIS2 Application Runtime support render-prop React components. The following Components are supported: -- [**DataQuery**](components/DataQuery) - a data fetching Component wrapper around the [useDataQuery](hooks/useDataQuery) hook. -- [**DataMutation**](components/DataMutation) - a Component wrapper around the [useDataMutation](hooks/useDataMutation) hook. +- [**DataQuery**](./DataQuery.md) - a data fetching Component wrapper around the [useDataQuery](../hooks/useDataQuery.md) hook. +- [**DataMutation**](./DataMutation.md) - a Component wrapper around the [useDataMutation](../hooks/useDataMutation.md) hook. diff --git a/docs/hooks/README.md b/docs/hooks/README.md index d27c5d037..bde9780a2 100644 --- a/docs/hooks/README.md +++ b/docs/hooks/README.md @@ -2,11 +2,11 @@ The DHIS2 Application Runtime supports [React Hooks](https://reactjs.org/docs/hooks-intro.html) (introduced in React 16.8). The following hooks are supported: -- [**useConfig**](hooks/useConfig) - Access the raw application configuration object -- [**useDataQuery**](hooks/useDataQuery) - Fetch data from the DHIS2 Core server API without worrying about HTTP requests! -- [**useDataMutation**](hooks/useDataMutation) - Mutate resources in the DHIS2 Core server API without worrying about HTTP requests! -- [**useDataEngine**](hooks/useDataEngine) _(Advanced)_ - Access the underlying [Data Engine](advanced/DataEngine) instance -- [**useAlert**](hooks/useAlert) - Add an alert to the central alerts-context -- [**useAlerts**](hooks/useAlert) - Read the alerts from the alerts-context +- [**useConfig**](./useConfig.md) - Access the raw application configuration object +- [**useDataQuery**](./useDataQuery.md) - Fetch data from the DHIS2 Core server API without worrying about HTTP requests! +- [**useDataMutation**](./useDataMutation.md) - Mutate resources in the DHIS2 Core server API without worrying about HTTP requests! +- [**useDataEngine**](./useDataEngine.md) _(Advanced)_ - Access the underlying [Data Engine](../advanced/DataEngine.md) instance +- [**useAlert**](./useAlert.md) - Add an alert to the central alerts-context +- [**useAlerts**](./useAlerts.md) - Read the alerts from the alerts-context -While these Hooks are incredibly powerful and usually preferable, some [Components](components/) are also provided which conveniently wrap their corresponding Hooks. +While these Hooks are incredibly powerful and usually preferable, some [Components](../components/README.md) are also provided which conveniently wrap their corresponding Hooks. diff --git a/docs/hooks/useConfig.md b/docs/hooks/useConfig.md index 93e39d61b..0c8aefc62 100644 --- a/docs/hooks/useConfig.md +++ b/docs/hooks/useConfig.md @@ -1,6 +1,6 @@ # useConfig Hook -Access the application configuration passed to the top-level [Provider](provider.md) +Access the application configuration passed to the top-level [Provider](../provider.md) ## Basic Usage: @@ -17,7 +17,7 @@ _None_ ## Output -This hook returns an object of type [Config](types/Config.md). +This hook returns an object of type [Config](../types/Config.md). ## Example diff --git a/docs/hooks/useDataEngine.md b/docs/hooks/useDataEngine.md index bbd2c1fc5..d22582392 100644 --- a/docs/hooks/useDataEngine.md +++ b/docs/hooks/useDataEngine.md @@ -1,6 +1,6 @@ # useDataEngine hook -Get access to the [Data Engine](advanced/DataEngine) instance for non-React contexts. +Get access to the [Data Engine](../advanced/DataEngine.md) instance for non-React contexts. ## Basic Usage: @@ -19,4 +19,4 @@ engine.mutate(mutation, { }) ``` -> See [Using with Redux](advanced/redux) for an advanced example +> See [Using with Redux](../advanced/redux.md) for an advanced example diff --git a/docs/hooks/useDataMutation.md b/docs/hooks/useDataMutation.md index 69b322626..0cc049419 100644 --- a/docs/hooks/useDataMutation.md +++ b/docs/hooks/useDataMutation.md @@ -16,25 +16,25 @@ const [mutate, { called, loading, error, data }] = useDataMutation( ## Input -| Name | Type | Required | Description | -| :--------------------: | :-----------------------------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------- | -| **mutation** | [_Mutation_](types/Mutation.md) | **required** | The Mutation definition describing the requested action | -| **options** | _Object_ | | An optional set of query options | -| **options.variables** | _Object_ | | Variables to be passed to the dynamic portions of the mutation | -| **options.onComplete** | _Function_ | | Callback function to be called on successfull completion of the mutation. Called with the response data as the only argument. | -| **options.onError** | _Function_ | | Callback function to be called on failure of the mutation. Called with the error instance as the only argument. | -| **options.lazy** | _boolean_ | | If false, run the mutation immediately after the component mounts.
_**Default**: `true`_ | +| Name | Type | Required | Description | +| :--------------------: | :--------------------------------: | :----------: | ----------------------------------------------------------------------------------------------------------------------------- | +| **mutation** | [_Mutation_](../types/Mutation.md) | **required** | The Mutation definition describing the requested action | +| **options** | _Object_ | | An optional set of query options | +| **options.variables** | _Object_ | | Variables to be passed to the dynamic portions of the mutation | +| **options.onComplete** | _Function_ | | Callback function to be called on successfull completion of the mutation. Called with the response data as the only argument. | +| **options.onError** | _Function_ | | Callback function to be called on failure of the mutation. Called with the error instance as the only argument. | +| **options.lazy** | _boolean_ | | If false, run the mutation immediately after the component mounts.
_**Default**: `true`_ | ## Output -| Name | Type | Description | -| :---------: | :----------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **mutate** | _Function_ | This function can be called to execute the mutation. Any in-flight HTTP requests will automatically be aborted. | -| **called** | _boolean_ | **true** if the mutation has been triggered by a call to the `mutate` function or on component mount with `lazy: false` | -| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | -| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | -| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | -| **engine** | [_Data Engine_](advanced/DataEngine) | A reference to the DataEngine instance | +| Name | Type | Description | +| :---------: | :----------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **mutate** | _Function_ | This function can be called to execute the mutation. Any in-flight HTTP requests will automatically be aborted. | +| **called** | _boolean_ | **true** if the mutation has been triggered by a call to the `mutate` function or on component mount with `lazy: false` | +| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | +| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | +| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | +| **engine** | [_Data Engine_](../advanced/DataEngine.md) | A reference to the DataEngine instance | ## Example diff --git a/docs/hooks/useDataQuery.md b/docs/hooks/useDataQuery.md index dd6b4a161..b5478d546 100644 --- a/docs/hooks/useDataQuery.md +++ b/docs/hooks/useDataQuery.md @@ -13,25 +13,25 @@ const { loading, error, data, refetch } = useDataQuery(query, options) ## Input -| Name | Type | Required | Description | -| :--------------------: | :--------------------: | :----------: | --------------------------------------------------------------------------------------------------------------------------- | -| **query** | [_Query_](types/Query) | **required** | The Query definition describing the requested data | -| **options** | _Object_ | | An optional set of query options | -| **options.variables** | _Object_ | | Variables to be passed to the dynamic portions of the query (can also be passed via the refetch function, see Output below) | -| **options.onComplete** | _Function_ | | Callback function to be called on successfull completion of the query. Called with the response data as the only argument. | -| **options.onError** | _Function_ | | Callback function to be called on failure of the query. Called with the error instance as the only argument. | -| **options.lazy** | _boolean_ | | If true, wait until `refetch` is called before fetching data.
_**Default**: `false`_ | +| Name | Type | Required | Description | +| :--------------------: | :--------------------------: | :----------: | --------------------------------------------------------------------------------------------------------------------------- | +| **query** | [_Query_](../types/Query.md) | **required** | The Query definition describing the requested data | +| **options** | _Object_ | | An optional set of query options | +| **options.variables** | _Object_ | | Variables to be passed to the dynamic portions of the query (can also be passed via the refetch function, see Output below) | +| **options.onComplete** | _Function_ | | Callback function to be called on successfull completion of the query. Called with the response data as the only argument. | +| **options.onError** | _Function_ | | Callback function to be called on failure of the query. Called with the error instance as the only argument. | +| **options.lazy** | _boolean_ | | If true, wait until `refetch` is called before fetching data.
_**Default**: `false`_ | ## Output -| Name | Type | Description | -| :---------: | :----------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | -| **called** | _boolean_ | **true** if the data request has been initiated with either `lazy: false` or `refetch()` at least once | -| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | -| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | -| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | -| **refetch** | _Function_ | This function can be called to refetch the data and can accept variables (see Examples below). Any in-flight HTTP requests will automatically be aborted. | -| **engine** | [_Data Engine_](advanced/DataEngine) | A reference to the DataEngine instance | +| Name | Type | Description | +| :---------: | :----------------------------------------: | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | +| **called** | _boolean_ | **true** if the data request has been initiated with either `lazy: false` or `refetch()` at least once | +| **loading** | _boolean_ | **true** if the data is not yet available and no error has yet been encountered | +| **error** | _Error_
or
_undefined_ | **undefined** if no error has occurred, otherwise the Error which was thrown | +| **data** | _QueryResult_
or
_undefined_ | **undefined** if the data is loading or an error has occurred, otherwise a map from the name of each **QueryDefinition** defined in the **Query** to the resulting data for that query | +| **refetch** | _Function_ | This function can be called to refetch the data and can accept variables (see Examples below). Any in-flight HTTP requests will automatically be aborted. | +| **engine** | [_Data Engine_](../advanced/DataEngine.md) | A reference to the DataEngine instance | ## Examples diff --git a/docs/index.html b/docs/index.html new file mode 100644 index 000000000..4fb409912 --- /dev/null +++ b/docs/index.html @@ -0,0 +1,18 @@ + + + + + Redirecting to Developer Portal + + +

Redirecting to Developer Portal...

+ + + + diff --git a/docs/provider.md b/docs/provider.md index 706abebc9..516167da2 100644 --- a/docs/provider.md +++ b/docs/provider.md @@ -2,9 +2,9 @@ ## Input Props -| Name | Type | Description | -| :--------: | :-------------------------: | ----------------------------- | -| **config** | [_Config_](types/Config.md) | The application configuration | +| Name | Type | Description | +| :--------: | :---------------------------: | ----------------------------- | +| **config** | [_Config_](./types/Config.md) | The application configuration | ## Example diff --git a/docs/types/Config.md b/docs/types/Config.md index 8d0c221ac..85c0b42ec 100644 --- a/docs/types/Config.md +++ b/docs/types/Config.md @@ -1,8 +1,8 @@ # Config Type The Application Config type is a required input to the top-level -[Provider](provider), and can be accessed from within an application -with the [useConfig](hooks/useConfig) hook. +[Provider](../provider.md), and can be accessed from within an application +with the [useConfig](../hooks/useConfig.md) hook. | Property | Type | Description | | :------------: | :------: | --------------------------------------------------------------------------------------------------------------- | diff --git a/docs/types/Mutation.md b/docs/types/Mutation.md index 4067e997d..78b057ad0 100644 --- a/docs/types/Mutation.md +++ b/docs/types/Mutation.md @@ -1,6 +1,6 @@ # Mutation -The Mutation type is used to define declarative data mutations. It is required input for the [useDataMutation](hooks/useDataMutation.md) hook, [DataMutation](components/DataMutation.md) component, and [DataEngine.mutate](advanced/DataEngine) method. +The Mutation type is used to define declarative data mutations. It is required input for the [useDataMutation](../hooks/useDataMutation.md) hook, [DataMutation](../components/DataMutation.md) component, and [DataEngine.mutate](../advanced/DataEngine.md) method. A mutation defines a destructive operation performed on a collection or instance of a particular resource. diff --git a/docs/types/Query.md b/docs/types/Query.md index 4698021db..4952c33b2 100644 --- a/docs/types/Query.md +++ b/docs/types/Query.md @@ -1,6 +1,6 @@ # Data Queries -The Query type is used to define declarative data requests. It is required input for the [useDataQuery](hooks/useDataQuery.md) hook and [DataQuery](components/DataQuery.md) component. +The Query type is used to define declarative data requests. It is required input for the [useDataQuery](../hooks/useDataQuery.md) hook and [DataQuery](../components/DataQuery.md) component. ## Query diff --git a/package.json b/package.json index 22786c650..8093f3ff4 100644 --- a/package.json +++ b/package.json @@ -49,7 +49,7 @@ "test": "yarn test:services && yarn test:runtime", "format": "d2-style apply js --all --no-stage && d2-style apply text --all --no-stage", "start": "yarn build && cd examples/query-playground && yarn start", - "docs:build": "d2-utils-docsite build ./docs -o ./dist && yarn build:playground", + "docs:build": "mkdir -p dist && cp docs/index.html dist/ && yarn build:playground", "docs:serve": "d2-utils-docsite serve ./docs -o ./dist", "lint": "d2-style check js && d2-style check text" }, From 6b72dc08936b21a85f33701c0cf6276da8323697 Mon Sep 17 00:00:00 2001 From: ismay Date: Wed, 15 Nov 2023 09:34:32 +0100 Subject: [PATCH 2/8] ci: add base rebuild workflow --- .github/workflows/rebuild-docs.yml | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) create mode 100644 .github/workflows/rebuild-docs.yml diff --git a/.github/workflows/rebuild-docs.yml b/.github/workflows/rebuild-docs.yml new file mode 100644 index 000000000..d9fad6b8e --- /dev/null +++ b/.github/workflows/rebuild-docs.yml @@ -0,0 +1,18 @@ +name: 'dhis2: rebuild developer docs' + +on: + push: + branches: + - master + paths: + - 'docs/**' + +concurrency: + group: ${{ github.workflow}}-${{ github.ref }} + cancel-in-progress: true + +jobs: + rebuild-docs: + runs-on: ubuntu-latest + steps: + - run: curl -X POST -d {} https://api.netlify.com/build_hooks/${{ secrets.NETLIFY_DEVELOPER_DOCS_TOKEN }} From f32d52b0617cdf9b0fb10b96032b4973f48aad75 Mon Sep 17 00:00:00 2001 From: ismay Date: Wed, 15 Nov 2023 09:38:32 +0100 Subject: [PATCH 3/8] ci: add app-runtime specific files --- .github/workflows/rebuild-docs.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/rebuild-docs.yml b/.github/workflows/rebuild-docs.yml index d9fad6b8e..a9fe4dcd8 100644 --- a/.github/workflows/rebuild-docs.yml +++ b/.github/workflows/rebuild-docs.yml @@ -6,6 +6,7 @@ on: - master paths: - 'docs/**' + - 'CHANGELOG.md' concurrency: group: ${{ github.workflow}}-${{ github.ref }} From 3253800087e24675b0b677d53c6815038796768a Mon Sep 17 00:00:00 2001 From: Rene Pot Date: Wed, 29 Nov 2023 12:56:41 +0100 Subject: [PATCH 4/8] docs: improvements for developer portal (#1362) * docs: fix links * docs: fix links * docs: fix more links * docs: fix link to playground * docs: change docs build * docs: changed formatting for warning * docs: properly change notices for docusaurus * docs: fix linting --- docs/advanced/offline/README.md | 4 +++- docs/advanced/offline/useOnlineStatus.md | 4 +++- docs/advanced/services.md | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-) diff --git a/docs/advanced/offline/README.md b/docs/advanced/offline/README.md index 6cfa9a90d..847bffd80 100644 --- a/docs/advanced/offline/README.md +++ b/docs/advanced/offline/README.md @@ -1,6 +1,8 @@ # Offline tools -!> **WARNING** These features are considered **experimental** and are **subject to breaking changes outside of the normal release cycle.** +:::warning Experimental +These features are considered **experimental** and are **subject to breaking changes outside of the normal release cycle.** +::: The app platform provides some support for PWA features, including a `manifest.json` file for installability and service worker which can provide offline caching. In addition to those features, the app runtime provides support for ["cacheable sections"](./CacheableSections.md), which are sections of an app that can be individually cached on-demand. The [`useCacheableSection` hook](./CacheableSections.md#usecacheablesection-api) and the [`CacheableSection` component](./CacheableSections.md#cacheablesection-api) provide the controls for the section and the wrapper for the section, respectively. The [`useCachedSections` hook](./CacheableSections.md#usecachedsections-api) returns a list of sections that are stored in the cache and a function that can delete them. diff --git a/docs/advanced/offline/useOnlineStatus.md b/docs/advanced/offline/useOnlineStatus.md index 8491b5904..5ee5a2606 100644 --- a/docs/advanced/offline/useOnlineStatus.md +++ b/docs/advanced/offline/useOnlineStatus.md @@ -1,6 +1,8 @@ # useOnlineStatus -!> This hook only detects whether or not you're connected to the internet, which could be problematic for DHIS2 instances that are hosted locally or offline, where what really matters is whether or not you can communicate with the DHIS2 server. The [`useDhis2ConnectionStatus` hook](./useDhis2ConnectionStatus.md) is usually better for that reason, and is therefore recommended. +:::info Internet Only +This hook only detects whether or not you're connected to the internet, which could be problematic for DHIS2 instances that are hosted locally or offline, where what really matters is whether or not you can communicate with the DHIS2 server. The [`useDhis2ConnectionStatus` hook](./useDhis2ConnectionStatus.md) is usually better for that reason, and is therefore recommended. +::: The `useOnlineStatus` returns whether the client is online or offline. It debounces the returned values by default to prevent rapid changes of any UI elements that depend on the online status. diff --git a/docs/advanced/services.md b/docs/advanced/services.md index 7462f7832..7e9646591 100644 --- a/docs/advanced/services.md +++ b/docs/advanced/services.md @@ -1,6 +1,8 @@ # Services -!> **NOTE**
Services are purely a concept **internal** to `@dhis2/app-runtime` - you don't need to care about them to use it. +:::caution Note +Services are purely a concept **internal** to `@dhis2/app-runtime` - you don't need to care about them to use it. +::: Internally, `@dhis2/app-runtime` is composed of several functionally-isolated **services**. Each of these services is a private (unpublished) npm package which is bundled into the final `@dhis2/app-runtime` library at build-time. Each services exposes a relevant Context provider as well as various Hook and Component interfaces which are re-exported by the `@dhis2/app-runtime` public package. There are currently only 2 services, but more will be added soon. From a2831e6eefef94dd2c81721d40a98ca89c53fee6 Mon Sep 17 00:00:00 2001 From: Kai Vandivier <49666798+KaiVandivier@users.noreply.github.com> Date: Tue, 12 Dec 2023 14:28:42 +0100 Subject: [PATCH 5/8] feat: add value-independent hook for setting online status message [LIBS-369] (#1363) * feat: add value-indepent hook for setting online status message * fix: export new hooks * docs: custom status message * fix: reinstate undefined; remove checks --- .../offline/CustomOnlineStatusMessage.md | 46 ++++++++++++++ .../offline/custom-online-status-message.png | Bin 0 -> 77942 bytes .../offline/useDhis2ConnectionStatus.md | 2 + runtime/src/index.ts | 2 + services/offline/src/index.ts | 6 +- .../offline/src/lib/online-status-message.tsx | 60 ++++++++++-------- services/offline/src/types.ts | 9 --- 7 files changed, 89 insertions(+), 36 deletions(-) create mode 100644 docs/advanced/offline/CustomOnlineStatusMessage.md create mode 100644 docs/advanced/offline/custom-online-status-message.png diff --git a/docs/advanced/offline/CustomOnlineStatusMessage.md b/docs/advanced/offline/CustomOnlineStatusMessage.md new file mode 100644 index 000000000..c70b0b805 --- /dev/null +++ b/docs/advanced/offline/CustomOnlineStatusMessage.md @@ -0,0 +1,46 @@ +# Custom Connection Status Message + +By default, the header bar shows either an "Online" or "Offline" message based on whether the app can connect to the DHIS2 server. If it's useful for an app to share other relevant info in that badge, for example "3 changes saved locally", then it's possible to set a custom message there: + +![Custom online status message](custom-online-status-message.png) + +## Hooks + +```ts +import { + useSetOnlineStatusMessage, + useOnlineStatusMessageValue, + useOnlineStatusMessage, +} from '@dhis2/app-runtime' +``` + +### `useSetOnlineStatusMessage` + +It's most likely that you'll only use `useSetOnlineStatusMessage()`, a hook that returns a `setState` function. It can set the value in the Header Bar without causing a rerender for itself. + +`setOnlineStatusMessage()` accepts a `ReactNode`-type object, so icons or other components can be added to the badge, but don't go crazy. A simple string is also a valid `ReactNode`: + +```ts +const setOnlineStatusMessage: (message: ReactNode) => void = + useSetOnlineStatusMessage() +``` + +### `useOnlineStatusMessageValue` + +This hook returns just the value: + +```ts +const onlineStatusMessage: ReactNode = useOnlineStatusMessageValue() +``` + +### `useOnlineStatusMessage` + +This hook returns both the value and the `set` function: + +```ts +const { onlineMessage, setOnlineStatusMessage } = useOnlineStatusMessage() +``` + +## Example + +You can see an example in use in the [Aggregate Data Entry app](https://github.com/dhis2/aggregate-data-entry-app/blob/dadd61392ea010a8017a19a25eaf76f885d9eea7/src/data-workspace/use-handle-headerbar-status.js) diff --git a/docs/advanced/offline/custom-online-status-message.png b/docs/advanced/offline/custom-online-status-message.png new file mode 100644 index 0000000000000000000000000000000000000000..ac88416140a2b75d7ce8815717fe161768422ff9 GIT binary patch literal 77942 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
9t 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�G!YUE226Yp}(!{*F;EiRjPYkx2cIZP~wX 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

jxRl|uFWt8ewve{lTmEhbmPO}* z-L+#3^f9{j0Op%FAQM230`8w`C-rIhDlQ6I9weXNKsJ4QnInJ6L7)kE1MFrVHu$Z_ zwD{S!V50c*ba}rRb229;`H_Npye*u3QS>67`Jc~V_Z^MZ0sq6_5hD=L<$$-q?Fb53 zyqBYcErtZNN(jAjxa#zdGd7x!7KX5dZ%W`nj8}wqm2g!v*$SqFqLx^w6mk=JZ{e|J zpmrC}rwuREg5k3OUhG3^A%OCD*{$u={Xpw@N@(Cz&ijl4 zZjc6K|4IE#^G=aEG!%Gt7ay>yT%l`f_fgu5I(Q7yua9dvEq;ywe+FbY4;0p&HIA18 zzs>|7l4Nb}exGB4A%Jt@y({2kx zTDmeq#W0{i9As013i`hRZgf1xVev#%`<8h&dx6kW#t%m@_s*4rEPAGR7KC6ghyZB{ zeltCWl$UU%C8z<@Nx1-5nsGQ2rF4e1`dwtZv;q{w9Xw1Lw&%LaI@VC^^9FA>f*-b= z$(5VSXI}?1#W+aAQ>Ms%5Q7U@v3Ns<%gAgf&fo#DOaLr_hStJC`h*eKm??-|N&y}^ zuL2TS(C&K2BFbyEmvZXh2J2+aT?AV+Ul-%{oLG>`m2EDdGVG zhn^fKeHNoTCy><2!#X{JS)Q@YE8nip!>@N!09)K$R(q0;*ASUieTG2wFq-H;1o&YC z2e|{Bg1}LFATD#NSr!29iJCwOGiSpaLY1g=x-F69y$_Ff6f9{8W*g%B0z(>3@~nxa zBVFFL(*UaaK%GsDADp7iN>lgl{+cmPF4coJ`*2Jz$t%xW>)#5Vs zP2<$1+RnKgCPRFI4yp~axmx*Xg4k}lzI0pg!nsIK;6P520a;Z=QSGktq&Ar4uTA9q zM|l+2lkZW!!)LirWCm$1%W#3Geiz$c?n1&?fWeZj?o3c>2R>l%Gbhc5;RHOU!Q!PmzM|A&IXY!M4&+zd^loghsE?axpXPsf6=QR8Z2}*B_v`a=n0*3mUE8b_9xi z0ds|i4b=wo|a1eDyF@ZiOFu110g zxsu)4bVixKO{pE=&skE z^O|@yQ>c+A2J&$M|55CW$P6%H2B&E69D30BD~WJ^QaRCw`ZI;&)d0?V*QHXPAu)jB zI%8-(1}JqTDFNE;4%6fNK;Zw_1rl=_n3_+gNO!3=Vts)eJ-ecH8L&W&TPg4_S&%!R znk9|dB?BpZ8K5jYvim^*@M}FsfG#DE%E5pCPiB}6ZEL$$`BdB>@GL(!@V^@KTc^Jn zp%94C9r>Y04+bBgc)1MedH~$}05QE>A?0VK^q(XooWxT2Lby^E30@yHyqJQ|kzk01 z??(lny>}*~@uR6+TI6U-U$hh+-&#cIA1}ECvH!suz#jhq$^hqXIOdZ9-*tfVb1LTw zuAjLhCkleQrT undefined, -} - -const OnlineStatusMessageContext = - React.createContext(defaultApi) - -export const useOnlineStatusMessage = (): OnlineStatusMessageContextAPI => { - const { onlineStatusMessage, setOnlineStatusMessage } = - useContext(OnlineStatusMessageContext) +type SetOnlineStatusMessage = (message: ReactNode) => void - return { - onlineStatusMessage, - setOnlineStatusMessage, - } -} +// 'get' and 'set' contexts are separated so 'setter' consumers that don't +// actually need the value don't have to rerender when the value changes: +const OnlineStatusMessageValueContext = + React.createContext(undefined) +const SetOnlineStatusMessageContext = + React.createContext(() => undefined) export const OnlineStatusMessageProvider = ({ children, }: { children: ReactNode }): ReactElement => { - const [onlineStatusMessage, setOnlineStatusMessage] = useState() + const [onlineStatusMessage, setOnlineStatusMessage] = useState() // note: not undefined return ( - - {children} - + + + {children} + + ) } + +export const useOnlineStatusMessageValue = () => { + return useContext(OnlineStatusMessageValueContext) +} + +export const useSetOnlineStatusMessage = () => { + return useContext(SetOnlineStatusMessageContext) +} + +// combination of both getter and setter (also provides backward compatability) +export const useOnlineStatusMessage = () => { + const onlineStatusMessage = useOnlineStatusMessageValue() + const setOnlineStatusMessage = useSetOnlineStatusMessage() + + return { + onlineStatusMessage, + setOnlineStatusMessage, + } +} diff --git a/services/offline/src/types.ts b/services/offline/src/types.ts index 730d9f13c..37580b406 100644 --- a/services/offline/src/types.ts +++ b/services/offline/src/types.ts @@ -1,5 +1,3 @@ -import { ReactNode } from 'react' - // Cacheable Section types export type RecordingState = 'default' | 'pending' | 'error' | 'recording' @@ -66,10 +64,3 @@ export interface OfflineInterface { getCachedSections: () => Promise removeSection: (id: string) => Promise } - -// Online status types - -export type OnlineStatusMessageContextAPI = { - onlineStatusMessage?: ReactNode - setOnlineStatusMessage: (additionalInfo: ReactNode) => void -} From 96bcecab01cc015431a6c4ff6e7d02bde422f5b6 Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Tue, 12 Dec 2023 13:34:39 +0000 Subject: [PATCH 6/8] chore(release): cut 3.10.0 [skip ci] # [3.10.0](https://github.com/dhis2/app-runtime/compare/v3.9.4...v3.10.0) (2023-12-12) ### Features * add value-independent hook for setting online status message [LIBS-369] ([#1363](https://github.com/dhis2/app-runtime/issues/1363)) ([a2831e6](https://github.com/dhis2/app-runtime/commit/a2831e6eefef94dd2c81721d40a98ca89c53fee6)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- runtime/package.json | 10 +++++----- services/alerts/package.json | 2 +- services/config/package.json | 2 +- services/data/package.json | 4 ++-- services/offline/package.json | 4 ++-- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 97094a03a..26229d1a6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +# [3.10.0](https://github.com/dhis2/app-runtime/compare/v3.9.4...v3.10.0) (2023-12-12) + + +### Features + +* add value-independent hook for setting online status message [LIBS-369] ([#1363](https://github.com/dhis2/app-runtime/issues/1363)) ([a2831e6](https://github.com/dhis2/app-runtime/commit/a2831e6eefef94dd2c81721d40a98ca89c53fee6)) + ## [3.9.4](https://github.com/dhis2/app-runtime/compare/v3.9.3...v3.9.4) (2023-06-19) diff --git a/package.json b/package.json index 8093f3ff4..14339183f 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "3.9.4", + "version": "3.10.0", "description": "A singular runtime dependency for applications on the DHIS2 platform", "repository": "https://github.com/dhis2/app-runtime.git", "author": "Austin McGee ", diff --git a/runtime/package.json b/runtime/package.json index 6c32d836d..b8bdb9d17 100644 --- a/runtime/package.json +++ b/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@dhis2/app-runtime", "description": "A singular runtime dependency for applications on the DHIS2 platform", - "version": "3.9.4", + "version": "3.10.0", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "./build/types/index.d.ts", @@ -23,10 +23,10 @@ "build/**" ], "dependencies": { - "@dhis2/app-service-config": "3.9.4", - "@dhis2/app-service-data": "3.9.4", - "@dhis2/app-service-alerts": "3.9.4", - "@dhis2/app-service-offline": "3.9.4" + "@dhis2/app-service-config": "3.10.0", + "@dhis2/app-service-data": "3.10.0", + "@dhis2/app-service-alerts": "3.10.0", + "@dhis2/app-service-offline": "3.10.0" }, "peerDependencies": { "prop-types": "^15.7.2", diff --git a/services/alerts/package.json b/services/alerts/package.json index 20486ee19..b7d12d8ee 100644 --- a/services/alerts/package.json +++ b/services/alerts/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-alerts", - "version": "3.9.4", + "version": "3.10.0", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "./build/types/index.d.ts", diff --git a/services/config/package.json b/services/config/package.json index f5675e573..f09e12a11 100644 --- a/services/config/package.json +++ b/services/config/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-config", - "version": "3.9.4", + "version": "3.10.0", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", diff --git a/services/data/package.json b/services/data/package.json index bc783c446..d9d2c7cad 100644 --- a/services/data/package.json +++ b/services/data/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-data", - "version": "3.9.4", + "version": "3.10.0", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", @@ -22,7 +22,7 @@ "build/**" ], "peerDependencies": { - "@dhis2/app-service-config": "3.9.4", + "@dhis2/app-service-config": "3.10.0", "@dhis2/cli-app-scripts": "^7.1.1", "prop-types": "^15.7.2", "react": "^16.8", diff --git a/services/offline/package.json b/services/offline/package.json index dc86f3008..ff9050b01 100644 --- a/services/offline/package.json +++ b/services/offline/package.json @@ -1,7 +1,7 @@ { "name": "@dhis2/app-service-offline", "description": "A runtime service for online/offline detection and offline caching", - "version": "3.9.4", + "version": "3.10.0", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", @@ -33,7 +33,7 @@ "coverage": "yarn test --coverage" }, "peerDependencies": { - "@dhis2/app-service-config": "3.9.4", + "@dhis2/app-service-config": "3.10.0", "prop-types": "^15.7.2", "react": "^16.8.6", "react-dom": "^16.8.6" From d15bce1869dc9fde2bdc7728f90e65d29332c861 Mon Sep 17 00:00:00 2001 From: Kai Vandivier <49666798+KaiVandivier@users.noreply.github.com> Date: Thu, 14 Dec 2023 12:27:02 +0100 Subject: [PATCH 7/8] fix: handle low cli-app-scripts version [LIBS-501] (#1349) * fix: handle low cli-app-scripts version * fix: validate isConnected --- .../dhis2-connection-status.test.tsx | 6 ++-- .../dhis2-connection-status.tsx | 32 ++++++++++++------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.test.tsx b/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.test.tsx index 71f44328e..c5801d93d 100644 --- a/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.test.tsx +++ b/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.test.tsx @@ -155,9 +155,9 @@ describe('initialization to the right values based on offline interface', () => wrapper: customWrapper, }) - expect(result.current.isConnected).toBe(false) - expect(result.current.isDisconnected).toBe(true) - expect(result.current.lastConnected).toEqual(testCurrentDate) + expect(result.current.isConnected).toBe(true) + expect(result.current.isDisconnected).toBe(false) + expect(result.current.lastConnected).toBe(null) }) }) diff --git a/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.tsx b/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.tsx index accf3ac69..35bf1b2ac 100644 --- a/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.tsx +++ b/services/offline/src/lib/dhis2-connection-status/dhis2-connection-status.tsx @@ -181,6 +181,16 @@ export const Dhis2ConnectionStatusProvider = ({ }, [pingAndHandleStatus, serverVersion]) useEffect(() => { + if (!offlineInterface.subscribeToDhis2ConnectionStatus) { + // Missing this functionality from the offline interface -- + // use a ping on startup to get the status + smartIntervalRef.current?.invokeCallbackImmediately() + console.warn( + 'Please upgrade to @dhis2/cli-app-scripts@>10.3.8 for full connection status features' + ) + return + } + const unsubscribe = offlineInterface.subscribeToDhis2ConnectionStatus({ onUpdate, }) @@ -190,23 +200,23 @@ export const Dhis2ConnectionStatusProvider = ({ }, [offlineInterface, onUpdate]) // Memoize this value to prevent unnecessary rerenders of context provider - const contextValue = useMemo( - () => ({ - // in the unlikely circumstance that offlineInterface.latestIsConnected - // is `null` when this initializes, fail safe by defaulting to - // `isConnected: false` - isConnected: Boolean(isConnected), - isDisconnected: !isConnected, - lastConnected: isConnected + const contextValue = useMemo(() => { + // in the unlikely circumstance that offlineInterface.latestIsConnected + // is `null` or `undefined` when this initializes, fail safe by defaulting to + // `isConnected: true`. A ping or SW update should update the status shortly. + const validatedIsConnected = isConnected ?? true + return { + isConnected: validatedIsConnected, + isDisconnected: !validatedIsConnected, + lastConnected: validatedIsConnected ? null : // Only evaluate if disconnected, since local storage // is synchronous and disk-based. // If lastConnected is not set in localStorage though, set it. // (relevant on startup) getLastConnected(appName) || updateLastConnected(appName), - }), - [isConnected, appName] - ) + } + }, [isConnected, appName]) return ( From f034768a4e4154ecfb09e5e2ff6f4b082541d03b Mon Sep 17 00:00:00 2001 From: "@dhis2-bot" Date: Thu, 14 Dec 2023 12:48:22 +0000 Subject: [PATCH 8/8] chore(release): cut 3.10.1 [skip ci] ## [3.10.1](https://github.com/dhis2/app-runtime/compare/v3.10.0...v3.10.1) (2023-12-14) ### Bug Fixes * handle low cli-app-scripts version [LIBS-501] ([#1349](https://github.com/dhis2/app-runtime/issues/1349)) ([d15bce1](https://github.com/dhis2/app-runtime/commit/d15bce1869dc9fde2bdc7728f90e65d29332c861)) --- CHANGELOG.md | 7 +++++++ package.json | 2 +- runtime/package.json | 10 +++++----- services/alerts/package.json | 2 +- services/config/package.json | 2 +- services/data/package.json | 4 ++-- services/offline/package.json | 4 ++-- 7 files changed, 19 insertions(+), 12 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 26229d1a6..32012c471 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,10 @@ +## [3.10.1](https://github.com/dhis2/app-runtime/compare/v3.10.0...v3.10.1) (2023-12-14) + + +### Bug Fixes + +* handle low cli-app-scripts version [LIBS-501] ([#1349](https://github.com/dhis2/app-runtime/issues/1349)) ([d15bce1](https://github.com/dhis2/app-runtime/commit/d15bce1869dc9fde2bdc7728f90e65d29332c861)) + # [3.10.0](https://github.com/dhis2/app-runtime/compare/v3.9.4...v3.10.0) (2023-12-12) diff --git a/package.json b/package.json index 14339183f..977f5a6d2 100644 --- a/package.json +++ b/package.json @@ -1,5 +1,5 @@ { - "version": "3.10.0", + "version": "3.10.1", "description": "A singular runtime dependency for applications on the DHIS2 platform", "repository": "https://github.com/dhis2/app-runtime.git", "author": "Austin McGee ", diff --git a/runtime/package.json b/runtime/package.json index b8bdb9d17..dbbe6be9a 100644 --- a/runtime/package.json +++ b/runtime/package.json @@ -1,7 +1,7 @@ { "name": "@dhis2/app-runtime", "description": "A singular runtime dependency for applications on the DHIS2 platform", - "version": "3.10.0", + "version": "3.10.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "./build/types/index.d.ts", @@ -23,10 +23,10 @@ "build/**" ], "dependencies": { - "@dhis2/app-service-config": "3.10.0", - "@dhis2/app-service-data": "3.10.0", - "@dhis2/app-service-alerts": "3.10.0", - "@dhis2/app-service-offline": "3.10.0" + "@dhis2/app-service-config": "3.10.1", + "@dhis2/app-service-data": "3.10.1", + "@dhis2/app-service-alerts": "3.10.1", + "@dhis2/app-service-offline": "3.10.1" }, "peerDependencies": { "prop-types": "^15.7.2", diff --git a/services/alerts/package.json b/services/alerts/package.json index b7d12d8ee..c185ad579 100644 --- a/services/alerts/package.json +++ b/services/alerts/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-alerts", - "version": "3.10.0", + "version": "3.10.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "./build/types/index.d.ts", diff --git a/services/config/package.json b/services/config/package.json index f09e12a11..ad06c34a7 100644 --- a/services/config/package.json +++ b/services/config/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-config", - "version": "3.10.0", + "version": "3.10.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", diff --git a/services/data/package.json b/services/data/package.json index d9d2c7cad..7e474d118 100644 --- a/services/data/package.json +++ b/services/data/package.json @@ -1,6 +1,6 @@ { "name": "@dhis2/app-service-data", - "version": "3.10.0", + "version": "3.10.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", @@ -22,7 +22,7 @@ "build/**" ], "peerDependencies": { - "@dhis2/app-service-config": "3.10.0", + "@dhis2/app-service-config": "3.10.1", "@dhis2/cli-app-scripts": "^7.1.1", "prop-types": "^15.7.2", "react": "^16.8", diff --git a/services/offline/package.json b/services/offline/package.json index ff9050b01..69aef9003 100644 --- a/services/offline/package.json +++ b/services/offline/package.json @@ -1,7 +1,7 @@ { "name": "@dhis2/app-service-offline", "description": "A runtime service for online/offline detection and offline caching", - "version": "3.10.0", + "version": "3.10.1", "main": "./build/cjs/index.js", "module": "./build/es/index.js", "types": "build/types/index.d.ts", @@ -33,7 +33,7 @@ "coverage": "yarn test --coverage" }, "peerDependencies": { - "@dhis2/app-service-config": "3.10.0", + "@dhis2/app-service-config": "3.10.1", "prop-types": "^15.7.2", "react": "^16.8.6", "react-dom": "^16.8.6"