diff --git a/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx new file mode 100644 index 000000000..46f3f75dd --- /dev/null +++ b/packages/apps/esm-offline-tools-app/src/components/offline-ready-modal.component.tsx @@ -0,0 +1,75 @@ +import React, { useCallback, useEffect, useState } from 'react'; +import { ModalBody, ModalFooter, ModalHeader, Button, InlineLoading } from '@carbon/react'; +import { useTranslation } from 'react-i18next'; +import { getCurrentOfflineMode, showToast } from '@openmrs/esm-framework'; + +export interface OfflineActionsProgressModalProps { + items?: Array; + closeModal: (active: boolean) => void; +} + +const OfflineReadyModal: React.FC = ({ closeModal, items }) => { + const { t } = useTranslation(); + const [isRunning, setIsRunning] = useState(true); + const [abortController, setAbortController] = useState(() => new AbortController()); + + async function dispatchOfflineEvent() { + window.dispatchEvent( + new CustomEvent(`openmrs:offline-enabled`, { + detail: getCurrentOfflineMode(), + }), + ); + + setIsRunning(false); + } + + useEffect(() => { + dispatchOfflineEvent(); + }, [abortController, items]); + + const handleClose = useCallback(() => { + if (isRunning) { + abortController.abort(); + + showToast({ + critical: true, + kind: 'warning', + description: t('unavailableOfflineFeatures', 'Some features may not be available offline.'), + title: t('offlinePreparationCanceled', 'Offline preparation canceled'), + }); + closeModal(false); + } else { + showToast({ + critical: true, + kind: 'success', + description: t('offlineModeIsReady', 'Offline mode is ready'), + title: t('offline', 'Offline'), + }); + closeModal(true); + } + }, [abortController, closeModal, isRunning, t]); + + return ( + <> + + + {isRunning && ( + + )} + + + + + + + ); +}; + +export default OfflineReadyModal; diff --git a/packages/apps/esm-offline-tools-app/src/index.ts b/packages/apps/esm-offline-tools-app/src/index.ts index 60a0ca689..370d167e9 100644 --- a/packages/apps/esm-offline-tools-app/src/index.ts +++ b/packages/apps/esm-offline-tools-app/src/index.ts @@ -1,4 +1,9 @@ -import { defineConfigSchema, getSyncLifecycle, registerBreadcrumbs } from '@openmrs/esm-framework'; +import { + defineConfigSchema, + getSyncLifecycle, + registerBreadcrumbs, + registerOfflineHandler, +} from '@openmrs/esm-framework'; import { routes } from './constants'; import { createDashboardLink } from './createDashboardLink'; import { dashboardMeta } from './dashboard.meta'; @@ -8,6 +13,7 @@ import offlineToolsComponent from './root.component'; import offlineToolsLinkComponent from './offline-tools-app-menu-link.component'; import offlineToolsNavItemsComponent from './nav/offline-tools-nav-menu.component'; import offlineToolsConfirmationModalComponent from './components/confirmation-modal.component'; +import offlineToolsOfflineReadyModalComponent from './components/offline-ready-modal.component'; import offlineToolsPatientsCardComponent from './offline-patients/patients-overview-card.component'; import offlineToolsActionsCardComponent from './offline-actions/offline-actions-overview-card.component'; import offlineToolsActionsComponent from './offline-actions/offline-actions.component'; @@ -36,6 +42,8 @@ export const offlineToolsNavItems = getSyncLifecycle(offlineToolsNavItemsCompone export const offlineToolsConfirmationModal = getSyncLifecycle(offlineToolsConfirmationModalComponent, options); +export const offlineToolsOfflineReadyModal = getSyncLifecycle(offlineToolsOfflineReadyModalComponent, options); + export const offlineToolsPatientsCard = getSyncLifecycle(offlineToolsPatientsCardComponent, options); export const offlineToolsActionsCard = getSyncLifecycle(offlineToolsActionsCardComponent, options); @@ -85,7 +93,7 @@ export const offlineToolsOptInButton = getSyncLifecycle(offlineToolsOptInButtonC export function startupApp() { defineConfigSchema(moduleName, {}); - setupOffline(); + registerOfflineHandler(setupOffline); setupSynchronizingOfflineActionsNotifications(); registerBreadcrumbs([ diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx index 140e779dc..cc5f217ba 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.extension.tsx @@ -1,8 +1,13 @@ -import React from 'react'; +import React, { useState, useCallback } from 'react'; import { useTranslation } from 'react-i18next'; -import { Toggle } from '@carbon/react'; +import { Button } from '@carbon/react'; import { Network_3 } from '@carbon/react/icons'; -import { getCurrentOfflineMode, setCurrentOfflineMode } from '@openmrs/esm-framework/src/internal'; +import { + getCurrentOfflineMode, + setCurrentOfflineMode, + showModal, + useConnectivity, +} from '@openmrs/esm-framework/src/internal'; import styles from './offline-actions-mode-button.scss'; import { SwitcherItem } from '@carbon/react'; @@ -12,25 +17,41 @@ function doNotCloseMenu(ev: React.SyntheticEvent) { const OfflineActionsModeButton: React.FC = () => { const { t } = useTranslation(); - const [active, setActive] = React.useState(() => getCurrentOfflineMode().active); - const toggle = React.useCallback(() => { - setActive((value) => { - const active = !value; - setCurrentOfflineMode(active ? 'on' : 'off'); - return active; + const isOnline = useConnectivity(); + const [active, setActive] = useState(() => getCurrentOfflineMode().active); + + const toggle = useCallback(() => { + const dispose = showModal('offline-tools-offline-ready-modal', { + closeModal: (result) => { + setActive(result); + setCurrentOfflineMode(result ? 'on' : 'off'); + dispose(); + }, }); - }, []); + }, [setActive]); + + const handleRefresh = useCallback(() => { + toggle(); + }, [toggle]); return ( - -
- -

- {t('offlineReady', 'Offline Ready')} -

-
- -
+ isOnline && ( + +
+ +

{t('offlineReady', 'Offline Ready')}

+
+ {active ? ( + + ) : ( + + )} +
+ ) ); }; diff --git a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss index 6d77bb0a8..565871148 100644 --- a/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss +++ b/packages/apps/esm-offline-tools-app/src/offline-actions/offline-actions-mode-button.scss @@ -3,22 +3,8 @@ .panelItemContainer a { display: flex; - justify-content: space-between; align-items: center; - - :global(.cds--toggle-input__label .cds--toggle__switch) { - margin-top: 0 !important; - } - - :global(.cds--toggle) { - /* setting the width prevents the toggle from changing size when the text changes */ - width: 76px; - margin: 0 1rem; - } - - :global(.cds--toggle__text) { - color: $ui-02; - } + justify-content: space-between; } .panelItemContainer div { diff --git a/packages/apps/esm-offline-tools-app/src/routes.json b/packages/apps/esm-offline-tools-app/src/routes.json index c6f314480..a4b4f3586 100644 --- a/packages/apps/esm-offline-tools-app/src/routes.json +++ b/packages/apps/esm-offline-tools-app/src/routes.json @@ -31,6 +31,12 @@ "online": true, "offline": true }, + { + "name": "offline-tools-offline-ready-modal", + "component": "offlineToolsOfflineReadyModal", + "online": true, + "offline": true + }, { "name": "offline-tools-dashboard-patients-card", "slot": "offline-tools-dashboard-cards", diff --git a/packages/apps/esm-offline-tools-app/translations/am.json b/packages/apps/esm-offline-tools-app/translations/am.json index f74f103e2..e2629712d 100644 --- a/packages/apps/esm-offline-tools-app/translations/am.json +++ b/packages/apps/esm-offline-tools-app/translations/am.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "Home", "homeHeader": "Offline home", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "loading": "Loading", + "never": "Never", + "offline": "Offline", "offlineActions": "Offline actions", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -25,6 +31,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", @@ -52,8 +59,12 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "Upload", "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", "offlineActionsSynchronizationNotificationCanceling": "Canceling...", diff --git a/packages/apps/esm-offline-tools-app/translations/ar.json b/packages/apps/esm-offline-tools-app/translations/ar.json index 0a6174dd6..663183b83 100644 --- a/packages/apps/esm-offline-tools-app/translations/ar.json +++ b/packages/apps/esm-offline-tools-app/translations/ar.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "لا يوجد {{displayText}} لعرضه", "home": "الرئيسية", "homeHeader": "الصفحة الرئيسية بدون اتصال", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "المرضى", "homeOverviewCardPatientsNewlyRegistered": "مُسجل حديثًا", "homeOverviewCardView": "عرض", + "lastRun": "Last Run", + "loading": "Loading", + "never": "Never", + "offline": "Offline", "offlineActions": "الأنشطة بدون اتصال", "offlineActionsDeleteConfirmationModalCancel": "إلغاء", "offlineActionsDeleteConfirmationModalConfirm": "حذف نهائي", @@ -29,6 +35,7 @@ "offlineActionsTableError": "خطأ", "offlineActionsTablePatient": "المريض", "offlineActionsUpdateOfflinePatients": "تحديث المرضى بدون اتصال", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "المرضى بدون اتصال", "offlinePatients_lower": "المرضى بدون اتصال", "offlinePatientsHeader": "المرضى بدون اتصال", @@ -56,8 +63,12 @@ "offlinePatientSyncDetailsFailedHeader": "حدث خطأ أثناء تحميل العناصر التالية", "offlinePatientSyncDetailsFallbackErrorMessage": "خطأ غير معروف.", "offlinePatientSyncDetailsHeader": "تفاصيل المريض بدون اتصال", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "جاهز للعمل بدون اتصال", "offlineToolsAppMenuLink": "أدوات العمل بدون اتصال", + "preparingOfflineMode": "Preparing for offline mode", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "تحميل", "offlineActionsSynchronizationNotificationSynchronized": "انتهت مزامنة الإجراءات غير المتصلة.", "offlineActionsSynchronizationNotificationCanceling": "إلغاء...", diff --git a/packages/apps/esm-offline-tools-app/translations/en.json b/packages/apps/esm-offline-tools-app/translations/en.json index bc0e5f924..5a6d80037 100644 --- a/packages/apps/esm-offline-tools-app/translations/en.json +++ b/packages/apps/esm-offline-tools-app/translations/en.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "Home", "homeHeader": "Offline home", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "loading": "Loading", + "never": "Never", + "offline": "Offline", "offlineActions": "Offline Actions", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -25,6 +31,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", @@ -52,8 +59,12 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "Upload", "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", "offlineActionsSynchronizationNotificationCanceling": "Canceling...", diff --git a/packages/apps/esm-offline-tools-app/translations/es.json b/packages/apps/esm-offline-tools-app/translations/es.json index 255b87085..0d04abf9c 100644 --- a/packages/apps/esm-offline-tools-app/translations/es.json +++ b/packages/apps/esm-offline-tools-app/translations/es.json @@ -1,4 +1,6 @@ { + "cancel": "Cancelar", + "confirm": "Confirmar", "emptyStateText": "No hay {{displayText}} para mostrar", "home": "Inicio", "homeHeader": "Inicio offline", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "Pacientes", "homeOverviewCardPatientsNewlyRegistered": "Recién registrados", "homeOverviewCardView": "Ver", + "lastRun": "Última carrera", + "loading": "Loading", + "never": "Nunca", + "offline": "Offline", "offlineActions": "Acciones offline", "offlineActionsDeleteConfirmationModalCancel": "Cancelar", "offlineActionsDeleteConfirmationModalConfirm": "Eliminar para siempre", @@ -26,6 +32,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Paciente", "offlineActionsUpdateOfflinePatients": "Actualizar pacientes offline", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Pacientes offline", "offlinePatients_lower": "pacientes offline", "offlinePatientsHeader": "Pacientes offline", @@ -53,8 +60,12 @@ "offlinePatientSyncDetailsFailedHeader": "Hubo un error al descargar los siguientes elementos", "offlinePatientSyncDetailsFallbackErrorMessage": "Error desconocido.", "offlinePatientSyncDetailsHeader": "Detalles de pacientes offline", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Listo offline", "offlineToolsAppMenuLink": "Herramientas offline", + "preparingOfflineMode": "Preparando modo sin conexión", + "refresh": "Actualizar", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "Subir", "offlineActionsSynchronizationNotificationSynchronized": "La sincronización de acciones sin conexión ha finalizado.", "offlineActionsSynchronizationNotificationCanceling": "Cancelando...", diff --git a/packages/apps/esm-offline-tools-app/translations/fr.json b/packages/apps/esm-offline-tools-app/translations/fr.json index b0fd9277e..c50c3e8c0 100644 --- a/packages/apps/esm-offline-tools-app/translations/fr.json +++ b/packages/apps/esm-offline-tools-app/translations/fr.json @@ -1,4 +1,6 @@ { + "cancel": "Annuler", + "confirm": "Confirmer", "emptyStateText": "There are no {{displayText}} to display", "home": "Accueil", "homeHeader": "Accueil hors ligne", @@ -9,8 +11,12 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Nouvellement enregistré", "homeOverviewCardView": "Voir", + "lastRun": "Dernière course", + "loading": "Loading", + "never": "Jamais", + "offline": "Offline", "offlineActions": "Actions hors ligne", - "offlineActionsDeleteConfirmationModalCancel": "Annuller", + "offlineActionsDeleteConfirmationModalCancel": "Annuler", "offlineActionsDeleteConfirmationModalConfirm": "Supprimer pour toujours", "offlineActionsDeleteConfirmationModalContent": "Êtes-vous sûr de vouloir supprimer toutes les actions hors ligne sélectionnées? Il ne sera pas possible de revenir en arrière.", "offlineActionsDeleteConfirmationModalTitle": "Supprimer les actions hors ligne", @@ -26,10 +32,11 @@ "offlineActionsTableError": "Erreur", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Mettre à jour les patients hors ligne", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Patients hors ligne", - "offlinePatientsTableDeleteConfirmationModalCancel": "Annuller", + "offlinePatientsTableDeleteConfirmationModalCancel": "Annuler", "offlinePatientsTableDeleteConfirmationModalConfirm": "Enlever les patients", "offlinePatientsTableDeleteConfirmationModalContent": "Êtes-vous sûr que de vouloir supprimer tous les patients sélectionnés de la liste hors ligne? Leurs graphiques ne seront plus disponibles en mode hors ligne et tout patient nouvellement enregistré sera supprimé pour toujours.", "offlinePatientsTableDeleteConfirmationModalTitle": "Enlever les patients hors ligne", @@ -53,8 +60,12 @@ "offlinePatientSyncDetailsFailedHeader": "Une erreur est survenue en téléchargeant les éléments suivants", "offlinePatientSyncDetailsFallbackErrorMessage": "Erreur inconnue.", "offlinePatientSyncDetailsHeader": "Détails des patients hors ligne", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Prêt pour être hors ligne", "offlineToolsAppMenuLink": "Outils hors ligne", + "preparingOfflineMode": "Préparation du mode hors ligne", + "refresh": "rafraîchir", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "Téléversement", "offlineActionsSynchronizationNotificationSynchronized": "La synchronisation des actions hors ligne est terminée.", "offlineActionsSynchronizationNotificationCanceling": "Annulation...", diff --git a/packages/apps/esm-offline-tools-app/translations/he.json b/packages/apps/esm-offline-tools-app/translations/he.json index 623ebc699..ba7195932 100644 --- a/packages/apps/esm-offline-tools-app/translations/he.json +++ b/packages/apps/esm-offline-tools-app/translations/he.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "דף הבית", "homeHeader": "דף הבית במצב לא מקוון", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "מטופלים", "homeOverviewCardPatientsNewlyRegistered": "רשומים חדשים", "homeOverviewCardView": "צפה", + "lastRun": "Last Run", + "loading": "Loading", + "never": "Never", + "offline": "Offline", "offlineActions": "פעולות לא מקוונות", "offlineActionsDeleteConfirmationModalCancel": "ביטול", "offlineActionsDeleteConfirmationModalConfirm": "מחיקה לצמיתות", @@ -27,6 +33,7 @@ "offlineActionsTableError": "שגיאה", "offlineActionsTablePatient": "מטופל", "offlineActionsUpdateOfflinePatients": "עדכן מטופלים לא מקוונים", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "מטופלים לא מקוונים", @@ -54,8 +61,12 @@ "offlinePatientSyncDetailsFailedHeader": "אירעה שגיאה בהורדת הפריטים הבאים", "offlinePatientSyncDetailsFallbackErrorMessage": "שגיאה לא ידועה.", "offlinePatientSyncDetailsHeader": "פרטי מטופל לא מקוון", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "מצב לא מקוון מוכן", "offlineToolsAppMenuLink": "כלי לא מקוונים", + "preparingOfflineMode": "Preparing for offline mode", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "העלאה", "offlineActionsSynchronizationNotificationSynchronized": "הסנכרון של הפעולות במצב לא מקוון הושלם.", "offlineActionsSynchronizationNotificationCanceling": "מבטל...", diff --git a/packages/apps/esm-offline-tools-app/translations/km.json b/packages/apps/esm-offline-tools-app/translations/km.json index bec8343b5..16cff7362 100644 --- a/packages/apps/esm-offline-tools-app/translations/km.json +++ b/packages/apps/esm-offline-tools-app/translations/km.json @@ -1,4 +1,6 @@ { + "cancel": "Cancel", + "confirm": "Confirm", "emptyStateText": "There are no {{displayText}} to display", "home": "ផ្ទះ", "homeHeader": "Offline home", @@ -9,6 +11,10 @@ "homeOverviewCardPatientsHeader": "Patients", "homeOverviewCardPatientsNewlyRegistered": "Newly registered", "homeOverviewCardView": "View", + "lastRun": "Last Run", + "loading": "Loading", + "never": "Never", + "offline": "Offline", "offlineActions": "សកម្មភាពក្រៅបណ្តាញ", "offlineActionsDeleteConfirmationModalCancel": "Cancel", "offlineActionsDeleteConfirmationModalConfirm": "Delete forever", @@ -24,6 +30,7 @@ "offlineActionsTableError": "Error", "offlineActionsTablePatient": "Patient", "offlineActionsUpdateOfflinePatients": "Update offline patients", + "offlineModeIsReady": "Offline mode is ready", "offlinePatients": "Offline patients", "offlinePatients_lower": "offline patients", "offlinePatientsHeader": "Offline patients", @@ -51,8 +58,12 @@ "offlinePatientSyncDetailsFailedHeader": "There was an error downloading the following items", "offlinePatientSyncDetailsFallbackErrorMessage": "Unknown error.", "offlinePatientSyncDetailsHeader": "Offline patient details", + "offlinePreparationCanceled": "Offline preparation canceled", "offlineReady": "Offline Ready", "offlineToolsAppMenuLink": "Offline tools", + "preparingOfflineMode": "Preparing for offline mode", + "refresh": "Refresh", + "unavailableOfflineFeatures": "Some features may not be available offline.", "offlineActionsSynchronizationNotificationTitle": "Upload", "offlineActionsSynchronizationNotificationSynchronized": "The offline action synchronization has finished.", "offlineActionsSynchronizationNotificationCanceling": "Canceling...", diff --git a/packages/framework/esm-offline/src/mode.ts b/packages/framework/esm-offline/src/mode.ts index 92725ef4e..0412605d3 100644 --- a/packages/framework/esm-offline/src/mode.ts +++ b/packages/framework/esm-offline/src/mode.ts @@ -32,21 +32,25 @@ async function isPrivateBrowsing() { } export type OfflineMode = 'on' | 'off' | 'unavailable'; +export type OfflineHandler = () => void | Promise; export interface OfflineModeResult { current: OfflineMode; notAvailable: boolean; active: boolean; + lastRun: string; } -const offlineModeStorageKey = 'openmrs3:offline-mode'; +const offlineModeStorageKey = 'openmrs:offline-mode'; let offlineMode: OfflineMode = 'unavailable'; +let lastRun: string = ''; export function getCurrentOfflineMode(): OfflineModeResult { return { current: offlineMode, notAvailable: offlineMode === 'unavailable', active: offlineMode === 'on', + lastRun: lastRun, }; } @@ -55,6 +59,11 @@ export function setCurrentOfflineMode(mode: OfflineMode) { localStorage.setItem(offlineModeStorageKey, mode === 'on' ? 'active' : 'disabled'); offlineMode = mode; } + lastRun = new Date().toLocaleString(); +} + +export function registerOfflineHandler(setupOffline: OfflineHandler) { + window.addEventListener('openmrs:offline-enabled', setupOffline); } export async function activateOfflineCapability() { diff --git a/packages/framework/esm-offline/src/public.ts b/packages/framework/esm-offline/src/public.ts index 9142c8f54..7a16dcf7a 100644 --- a/packages/framework/esm-offline/src/public.ts +++ b/packages/framework/esm-offline/src/public.ts @@ -1,4 +1,4 @@ -export { type OfflineMode, type OfflineModeResult, getCurrentOfflineMode } from './mode'; +export { type OfflineMode, type OfflineModeResult, getCurrentOfflineMode, registerOfflineHandler } from './mode'; export * from './offline-patient-data'; export * from './service-worker-messaging'; export * from './service-worker-http-headers';