Open tmfrnz opened 2 years ago
While there are some solutions available (see subsequent comment) that we may also consider, here is a list of issues and ideas to address them:
The application code is already being cached and available offline, using the offline-plugin for webpack. We could also consider to change the response strategy to "cache-first" (webpack config, see also offline-plugin options)
In addition, the client needs to cache the app data (retrieved from server) for future offline use and make sure it remains available when re-opening or re-loading the app while offline.
To make sure to always have the latest data available, the local cache should be updated with every remote server response (when online).
Instead of only loading data as needed for each and every component (as the client currently does, e.g. configured here), it might be good to always load all tables when loading the app.
Also consider
Authentication obviously won't work when working offline, so we will need to consider how to handle these.
A simple way could be
The app needs to periodically check the online-status in the background and inform user when status changes (also when back online).
Potentially, we may want to allow users to optionally enable "offline-mode" even when online
When in "offline-mode" a local API should respond to API calls just like the server would - this way the majority of the app can abstract from the online-status.
Specifically
The current API request is handled here https://github.com/dumparkltd/advocacy-tracker-client/blob/master/app/utils/api-request.js
As the client already validates all data on "save", it might not be required to have those validation rules also checked again by the local API. Regardless, the validation rules should be reviewed in order to minimise issues when synchronising with the server (see below)
When leaving offline-mode and coming back online, the app should check if there are any local changes that are more recent than the last load from the remote server.
To easily identify any relevant records it might be good to simply store this as a "changed_locally" flag in a separate column in the cached data.
If there are no changes, the app can just flush the local cache and re-load all data, optionally prompting the user to confirm.
When there are local changes, the user should be prompted to start writing those changes to the server. Here the easiest strategy would be to make those changes one-by-one, possibly grouped into multiple batches:
While this could also all happen quietly in the background, I would suggest to prompt the user in every step:
While the data is being updated on the server (one-by-one), the listed records could be visually marked according to the server response, indicating success or any errors (that could be due to failed validation on the server (we want to minimise this by reflecting those rules also on the client, see above), or outdated data (not applicable to steps 1 and 2)), and allowing the user to either update the data locally where applicable (e.g. validation issues or outdated data) and sync again or dismiss and delete the local change.
Once all local changes have been written to the server, the app can flush the local cache and re-load all data, ideally prompting the user to confirm.
Would require a synchronisation mechanism when app comes back online, specifically also including a mechanism to resolve conflicts (currently the server application just rejects updates when a record has been updated in the meantime)